cc26xxspi.c文件:
#include "cc26xxspi.h"
#include "ti/sysbios/knl/Clock.h"
#include
#include
#include "sdi_task.h"
#include "icall.h"
#include
static void spi_callback_fun(SPI_Handle handle,SPI_Transaction *transaction);
//配置GPIO模式
PIN_Config SPI_CSN[2] =
{
CC2640R2_LAUNCHXL_SPI0_CSN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
PIN_TERMINATE
};
SPICC26XXDMA_Object _spiCC26XXDMAObjects[CC2640R2_LAUNCHXL_SPICOUNT];
const SPICC26XXDMA_HWAttrsV1 _spiCC26XXDMAHWAttrs[CC2640R2_LAUNCHXL_SPICOUNT] = {
{
.baseAddr = SSI0_BASE,
.intNum = INT_SSI0_COMB,
.intPriority = ~0,
.swiPriority = 0,
.powerMngrId = PowerCC26XX_PERIPH_SSI0,
.defaultTxBufValue = 0,
.rxChannelBitMask = 1<
.misoPin = CC2640R2_LAUNCHXL_SPI0_MISO,
.clkPin = CC2640R2_LAUNCHXL_SPI0_CLK,
.csnPin = PIN_UNASSIGNED
},
{
.baseAddr = SSI1_BASE,
.intNum = INT_SSI1_COMB,
.intPriority = ~0,
.swiPriority = 0,
.powerMngrId = PowerCC26XX_PERIPH_SSI1,
.defaultTxBufValue = 0,
.rxChannelBitMask = 1<
.misoPin = CC2640R2_LAUNCHXL_SPI1_MISO,
.clkPin = CC2640R2_LAUNCHXL_SPI1_CLK,
.csnPin = CC2640R2_LAUNCHXL_SPI1_CSN
}
};
const SPI_Config cc26xxSPI_config[CC2640R2_LAUNCHXL_SPICOUNT] = {
{
.fxnTablePtr = &SPICC26XXDMA_fxnTable,
.object = &_spiCC26XXDMAObjects[CC2640R2_LAUNCHXL_SPI0],
.hwAttrs = &_spiCC26XXDMAHWAttrs[CC2640R2_LAUNCHXL_SPI0]
},
{
.fxnTablePtr = &SPICC26XXDMA_fxnTable,
.object = &_spiCC26XXDMAObjects[CC2640R2_LAUNCHXL_SPI1],
.hwAttrs = &_spiCC26XXDMAHWAttrs[CC2640R2_LAUNCHXL_SPI1]
},
};
//SPI 句柄及参数
static SPI_Handle cc2640_SPI_Handle;
static SPI_Params cc2640_SPI_Params;
static SPI_Transaction transaction;
//SPI 片选端口
PIN_State spi_csn_state;
PIN_Handle spi_csn_handle;
//SPI初始化函数
void cc2640xxSPI_Init(void)
{
SPI_Params_init(&cc2640_SPI_Params);
cc2640_SPI_Params.transferMode = SPI_MODE_BLOCKING; //配置SPI阻塞模式
cc2640_SPI_Params.transferTimeout = SPI_WAIT_FOREVER; //永远等待
cc2640_SPI_Params.transferCallbackFxn = NULL; //回调函数指针
cc2640_SPI_Params.mode = SPI_MASTER; //主机模式
cc2640_SPI_Params.bitRate = 2e6; //2MHZ
cc2640_SPI_Params.dataSize = 8; //8bit模式
cc2640_SPI_Params.frameFormat = SPI_POL0_PHA0; //时钟为低电平,第一个时钟沿采样
spi_csn_handle = PIN_open(&spi_csn_state,SPI_CSN);
cc26xxSPI_config[CC2640R2_LAUNCHXL_SPI0].fxnTablePtr->initFxn((SPI_Handle)&cc26xxSPI_config[CC2640R2_LAUNCHXL_SPI0]);
cc2640_SPI_Handle = cc26xxSPI_config[CC2640R2_LAUNCHXL_SPI0].fxnTablePtr->openFxn((SPI_Handle)&cc26xxSPI_config[CC2640R2_LAUNCHXL_SPI0],&cc2640_SPI_Params);
}
//SPI传输回调函数
static void spi_callback_fun(SPI_Handle handle,SPI_Transaction *transaction)
{
for(;;);
}
//设置SPI片选信号
void spi_csn_set(PIN_Id pin_x,bool pin_state)
{
if (pin_state == CC2640R2_SPI_CS_OFF)
{
PIN_setOutputValue(spi_csn_handle,pin_x,1);
}
else if (pin_state == CC2640R2_SPI_CS_ON)
{
PIN_setOutputValue(spi_csn_handle,pin_x,0);
}
}
//SPI 写函数
void spi_read_write_data(uint8_t *write_data,uint8_t *read_data,uint8_t len)
{
transaction.count = len; //写入的数据长度
transaction.arg = NULL;
transaction.txBuf = write_data; //发送缓冲区
transaction.rxBuf = read_data; //接收缓冲区
cc26xxSPI_config[CC2640R2_LAUNCHXL_SPI0].fxnTablePtr->transferFxn(cc2640_SPI_Handle,&transaction); //启动SPI传输
}
cc26xxspi.h文件:
#ifndef __CC26XXSPI_H
#define __CC26XXSPI_H
#include "board.h"
#include "ti/sysbios/knl/Task.h"
extern PIN_State spi_csn_state;
extern PIN_Handle spi_csn_handle;
/* SPI */
#define CC2640R2_SPI_CS_ON 0
#define CC2640R2_SPI_CS_OFF 1
/*SPI CS*/
#define SPI_CS_HIGH spi_csn_set(IOID_11,CC2640R2_SPI_CS_OFF)
#define SPI_CS_LOW spi_csn_set(IOID_11,CC2640R2_SPI_CS_ON)
/* SPI Board */
#define CC2640R2_LAUNCHXL_SPI0_MISO IOID_8 /* RF1.20 */
#define CC2640R2_LAUNCHXL_SPI0_MOSI IOID_9 /* RF1.18 */
#define CC2640R2_LAUNCHXL_SPI0_CLK IOID_10 /* RF1.16 */
#define CC2640R2_LAUNCHXL_SPI0_CSN IOID_11 /* SPI CS */
#define CC2640R2_LAUNCHXL_SPI1_MISO PIN_UNASSIGNED
#define CC2640R2_LAUNCHXL_SPI1_MOSI PIN_UNASSIGNED
#define CC2640R2_LAUNCHXL_SPI1_CLK PIN_UNASSIGNED
#define CC2640R2_LAUNCHXL_SPI1_CSN PIN_UNASSIGNED
/*!
* @def CC2640R2_LAUNCHXL_SPIName
* @brief Enum of SPI names
*/
typedef enum CC2640R2_LAUNCHXL_SPIName {
CC2640R2_LAUNCHXL_SPI0 = 0,
CC2640R2_LAUNCHXL_SPI1,
CC2640R2_LAUNCHXL_SPICOUNT
} CC2640R2_LAUNCHXL_SPIName;
void cc2640xxSPI_Init(void);
void spi_csn_set(PIN_Id pin_x,bool pin_state);
void spi_read_write_data(uint8_t *write_data,uint8_t *read_data,uint8_t len);
#endif
主函数测试代码:
逻辑分析仪截图:
NRF24L01写入写地址命令:
NRF24L01写入地址:
NRF24L01读取地址:
本次测试采用NRF24L01作为SPI从机设备,写入NRF24L01地址,再从地址寄存器读出地址进行校验,结果写入地址与读出地址一致SPI通信成功。