123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- //SPI 1.0V
- /*
- When you call nrf_drv_spi_transfer(&m_spi_m, tx_buffer, tx_bytes, rx_buffer, rx_bytes), specify value for tx_bytes, it is the number of bytes you want to put on the SPI master-out pin; rx_bytes refers to the number of bytes you want to fill for the rx_buffer, beginning at the start of your transaction.
- For example, a register read on a SPI peripheral requires first writing the address of register you want to read, SPI peripheral will return the value of that register as soon as you finish writing the address. In this case tx_bytes is 1, rx_bytes is 2. When the call completes with call back, you will get the read from rx_buffer[1].
- In general, if you want to tx x bytes, and receive y bytes after x bytes has been transferred, rx_buffer needs to be the size of (x + y). A valid read back value will start at rx_buffer[x] for the length of y.
- 重点:发送X个字节的数据,接受Y个字节的数据,则接收缓冲区至少有X+Y个字节的长度,而接收到的数据从rx_buffer[x]开始,长度为y。
- */
-
-
- /*********************************************************************
- * INCLUDES
- */
- #include "bsp_spi.h"
- static void spiCallbackFunc(nrf_drv_spi_evt_t const *pEvent, void *arg);
- /*********************************************************************
- * LOCAL VARIABLES
- */
- static volatile bool s_transferOk = true; // SPI数据传输完成标志
- static const nrf_drv_spi_t s_spiHandle = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); // SPI instance
- static const uint8_t s_cs_list[SPI_CS_NUMBER] = SPI_CS_LIST; // SPI 片选列表
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- /**
- @brief SPI中断处理回调函数
- @param 无
- @return 无
- */
- static void spiCallbackFunc(nrf_drv_spi_evt_t const *pEvent, void *arg)
- {
- //事件类型只有NRF_DRV_SPI_EVENT_DONE
- s_transferOk = true;
- }
- /**
- @brief SPI片选引脚检查
- @param CsPin_number -[in] 片选引脚
- @return 错误代码
- */
- static uint32_t SPI_CsCheck(uint32_t CsPin_number)
- {
- uint32_t i;
-
- for(i = 0; i < SPI_CS_NUMBER; i++)
- {
- if(s_cs_list[i] == CsPin_number)
- return SPI_OP_SUCCESS;
- }
-
- return SPI_ERROR_CS;
- }
- /**
- @brief SPI片选信号设置
- @param CsPin_number -[in] 片选引脚
- @param pinState -[in] 引脚状态
- @return 错误代码
- */
- static uint32_t SPI_CsSet(uint32_t CsPin_number , uint8_t pinState)
- {
- uint32_t err_code;
- if((err_code = SPI_CsCheck(CsPin_number)) != SPI_OP_SUCCESS)return err_code;
-
- if(pinState == BOARD_SPI_CS_OFF)
- {
- nrf_gpio_pin_write(CsPin_number, 1);
- }
- else if(pinState == BOARD_SPI_CS_ON)
- {
- nrf_gpio_pin_write(CsPin_number, 0);
- }
-
- return SPI_OP_SUCCESS;
- }
- /**
- @brief SPI读出写入数据
- @param CsPin_number -[in] 片选引脚
- @param pWriteData -[in] 写入数据
- @param writeDataLen -[in] 写入数据长度
- @param pReadData -[out] 读出数据
- @param readDataLen -[in] 读出数据长度
- @return 错误代码
- */
- static uint32_t SPI_ReadWriteData(uint32_t CsPin_number, uint8_t *pWriteData, uint8_t writeDataLen, uint8_t *pReadData, uint8_t readDataLen)
- {
-
- uint32_t err_code;
- uint32_t wait_time_out = WAIT_TIME_VALUE;
- if((err_code = SPI_CsCheck(CsPin_number)) != SPI_OP_SUCCESS)return err_code;
-
- SPI_CsSet(CsPin_number,BOARD_SPI_CS_ON); //片选信号开
-
- s_transferOk = false;
-
- APP_ERROR_CHECK(nrf_drv_spi_transfer(&s_spiHandle, pWriteData, writeDataLen, pReadData, readDataLen));
- while(!s_transferOk)
- {
- if(wait_time_out--){
- nrf_pwr_mgmt_run();
- }
- else{
- SPI_CsSet(CsPin_number,BOARD_SPI_CS_OFF); //片选信号关
- return SPI_ERROR_TIMEOUT;
- }
- } // Error in SPI or transfer already in progress.
-
- SPI_CsSet(CsPin_number,BOARD_SPI_CS_OFF); //片选信号关
- return SPI_OP_SUCCESS;
- }
- /**
- @brief SPI读写寄存器数据
- @param CsPin_number -[in] 片选引脚
- @param reg_addr -[in] 操作的寄存器地址
- @param ReadWriteFlag -[in] 读写标志位
- @param pData -[in/out] 指向需要操作的数据
- @param DataLen -[in] 数据长度
- @return 错误代码
- */
- static uint32_t SPI_ReadWriteReg(uint32_t CsPin_number, uint8_t reg_addr, uint8_t ReadWriteFlag, uint8_t *pData, uint8_t DataLen)
- {
- static uint8_t temp_buff[260];
- uint32_t err_code;
- uint8_t addr;
-
- if((err_code = SPI_CsCheck(CsPin_number)) != SPI_OP_SUCCESS)return err_code;
-
- if(ReadWriteFlag == SPI_READ)
- {
- addr = 0x80 | reg_addr;
-
- err_code = SPI_ReadWriteData(CsPin_number, &addr, 1, temp_buff, DataLen+1); //DataLen+1是因为第一个字节是写地址回应时的垃圾数据
- if(err_code != SPI_OP_SUCCESS) return err_code;
-
- memcpy(pData, &temp_buff[1], DataLen);
- }
- else
- {
- temp_buff[0] = reg_addr;
- memcpy(&temp_buff[1], pData, DataLen);
-
- err_code = SPI_ReadWriteData(CsPin_number, temp_buff, DataLen+1, NULL, 0);
- if(err_code != SPI_OP_SUCCESS) return err_code;
- }
-
- return SPI_OP_SUCCESS;
- }
- /*********************************************************************
- * PUBLIC FUNCTIONS
- */
- /****************************************************接口****************************************************/
- /**
- @brief SPI的初始化函数
- @param 无
- @return 无
- */
- void SPI_Init(void)
- {
- ret_code_t errCode;
-
- nrf_drv_spi_config_t spiConfig = NRF_DRV_SPI_DEFAULT_CONFIG; // 使用SPI默认配置
- // 配置SPI端口,注意CSN不要在这设置,另外用GPIO口控制
- spiConfig.miso_pin = BOARD_SPI0_MISO_IO;
- spiConfig.mosi_pin = BOARD_SPI0_MOSI_IO;
- spiConfig.sck_pin = BOARD_SPI0_CLK_IO;
- spiConfig.mode = NRF_DRV_SPI_MODE_0;
- spiConfig.frequency = SPI_FREQUENCY;
- spiConfig.irq_priority = 3; // 在定时器中使用优先级需小于6
-
- errCode = nrf_drv_spi_init(&s_spiHandle, &spiConfig, spiCallbackFunc, NULL);
- APP_ERROR_CHECK(errCode);
-
- uint32_t i;
- for(i = 0; i < SPI_CS_NUMBER; i++)
- {
- nrf_gpio_cfg_output(s_cs_list[i]);
- }
-
- }
- /**
- @brief SPI只读寄存器数据
- @param CsPin_number -[in] 片选引脚
- @param reg_addr -[in] 操作的寄存器地址
- @param pData -[in/out] 指向需要操作的数据
- @param DataLen -[in] 数据长度
- @return 错误代码
- */
- uint32_t SPI_OnlyReadReg(uint32_t CsPin_number, uint8_t reg_addr, uint8_t *pData, uint8_t DataLen)
- {
- return SPI_ReadWriteReg(CsPin_number, reg_addr, SPI_READ, pData, DataLen);
- }
- /**
- @brief SPI只写寄存器数据
- @param CsPin_number -[in] 片选引脚
- @param reg_addr -[in] 操作的寄存器地址
- @param pData -[in/out] 指向需要操作的数据
- @param DataLen -[in] 数据长度
- @return 错误代码
- */
- uint32_t SPI_OnlyWriteReg(uint32_t CsPin_number, uint8_t reg_addr, uint8_t *pData, uint8_t DataLen)
- {
- return SPI_ReadWriteReg(CsPin_number, reg_addr, SPI_WRITE, pData, DataLen);
- }
- /**
- @brief 开启SPI
- @param 无
- @return 错误代码
- */
- uint32_t SPI_Enable(void)
- {
- SPI_Init();
- return SPI_OP_SUCCESS;
- }
- /**
- @brief 禁用SPI
- @param 无
- @return 无
- */
- uint32_t SPI_Disable(void)
- {
-
- uint32_t i;
-
- //所有片选信号关
- for(i = 0; i < SPI_CS_NUMBER; i++)
- {
- SPI_CsSet(s_cs_list[i],BOARD_SPI_CS_OFF);
- }
-
-
- nrf_drv_spi_uninit(&s_spiHandle);
-
-
- /*I think you're experiencing this increase from this errata since TWI and SPI shares resources internally,
- this errata may also occur when using SPI. Please try this after disabling the SPI:
-
- *(volatile uint32_t *)0x40003FFC = 0;
- *(volatile uint32_t *)0x40003FFC;
- *(volatile uint32_t *)0x40003FFC = 1;
- If SPI1 is used the address is 40004FFC.
- */
-
- *(volatile uint32_t *)0x40003FFC = 0;
- *(volatile uint32_t *)0x40003FFC;
- *(volatile uint32_t *)0x40003FFC = 1;
-
- return SPI_OP_SUCCESS;
- }
|