bsp_spi.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. //SPI 1.0V
  2. /*
  3. 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.
  4. 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].
  5. 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.
  6. 重点:发送X个字节的数据,接受Y个字节的数据,则接收缓冲区至少有X+Y个字节的长度,而接收到的数据从rx_buffer[x]开始,长度为y。
  7. */
  8. /*********************************************************************
  9. * INCLUDES
  10. */
  11. #include "bsp_spi.h"
  12. static void spiCallbackFunc(nrf_drv_spi_evt_t const *pEvent, void *arg);
  13. /*********************************************************************
  14. * LOCAL VARIABLES
  15. */
  16. static volatile bool s_transferOk = true; // SPI数据传输完成标志
  17. static const nrf_drv_spi_t s_spiHandle = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); // SPI instance
  18. static const uint8_t s_cs_list[SPI_CS_NUMBER] = SPI_CS_LIST; // SPI 片选列表
  19. /*********************************************************************
  20. * LOCAL FUNCTIONS
  21. */
  22. /**
  23. @brief SPI中断处理回调函数
  24. @param 无
  25. @return 无
  26. */
  27. static void spiCallbackFunc(nrf_drv_spi_evt_t const *pEvent, void *arg)
  28. {
  29. //事件类型只有NRF_DRV_SPI_EVENT_DONE
  30. s_transferOk = true;
  31. }
  32. /**
  33. @brief SPI片选引脚检查
  34. @param CsPin_number -[in] 片选引脚
  35. @return 错误代码
  36. */
  37. static uint32_t SPI_CsCheck(uint32_t CsPin_number)
  38. {
  39. uint32_t i;
  40. for(i = 0; i < SPI_CS_NUMBER; i++)
  41. {
  42. if(s_cs_list[i] == CsPin_number)
  43. return SPI_OP_SUCCESS;
  44. }
  45. return SPI_ERROR_CS;
  46. }
  47. /**
  48. @brief SPI片选信号设置
  49. @param CsPin_number -[in] 片选引脚
  50. @param pinState -[in] 引脚状态
  51. @return 错误代码
  52. */
  53. static uint32_t SPI_CsSet(uint32_t CsPin_number , uint8_t pinState)
  54. {
  55. uint32_t err_code;
  56. if((err_code = SPI_CsCheck(CsPin_number)) != SPI_OP_SUCCESS)return err_code;
  57. if(pinState == BOARD_SPI_CS_OFF)
  58. {
  59. nrf_gpio_pin_write(CsPin_number, 1);
  60. }
  61. else if(pinState == BOARD_SPI_CS_ON)
  62. {
  63. nrf_gpio_pin_write(CsPin_number, 0);
  64. }
  65. return SPI_OP_SUCCESS;
  66. }
  67. /**
  68. @brief SPI读出写入数据
  69. @param CsPin_number -[in] 片选引脚
  70. @param pWriteData -[in] 写入数据
  71. @param writeDataLen -[in] 写入数据长度
  72. @param pReadData -[out] 读出数据
  73. @param readDataLen -[in] 读出数据长度
  74. @return 错误代码
  75. */
  76. static uint32_t SPI_ReadWriteData(uint32_t CsPin_number, uint8_t *pWriteData, uint8_t writeDataLen, uint8_t *pReadData, uint8_t readDataLen)
  77. {
  78. uint32_t err_code;
  79. uint32_t wait_time_out = WAIT_TIME_VALUE;
  80. if((err_code = SPI_CsCheck(CsPin_number)) != SPI_OP_SUCCESS)return err_code;
  81. SPI_CsSet(CsPin_number,BOARD_SPI_CS_ON); //片选信号开
  82. s_transferOk = false;
  83. APP_ERROR_CHECK(nrf_drv_spi_transfer(&s_spiHandle, pWriteData, writeDataLen, pReadData, readDataLen));
  84. while(!s_transferOk)
  85. {
  86. if(wait_time_out--){
  87. nrf_pwr_mgmt_run();
  88. }
  89. else{
  90. SPI_CsSet(CsPin_number,BOARD_SPI_CS_OFF); //片选信号关
  91. return SPI_ERROR_TIMEOUT;
  92. }
  93. } // Error in SPI or transfer already in progress.
  94. SPI_CsSet(CsPin_number,BOARD_SPI_CS_OFF); //片选信号关
  95. return SPI_OP_SUCCESS;
  96. }
  97. /**
  98. @brief SPI读写寄存器数据
  99. @param CsPin_number -[in] 片选引脚
  100. @param reg_addr -[in] 操作的寄存器地址
  101. @param ReadWriteFlag -[in] 读写标志位
  102. @param pData -[in/out] 指向需要操作的数据
  103. @param DataLen -[in] 数据长度
  104. @return 错误代码
  105. */
  106. static uint32_t SPI_ReadWriteReg(uint32_t CsPin_number, uint8_t reg_addr, uint8_t ReadWriteFlag, uint8_t *pData, uint8_t DataLen)
  107. {
  108. static uint8_t temp_buff[260];
  109. uint32_t err_code;
  110. uint8_t addr;
  111. if((err_code = SPI_CsCheck(CsPin_number)) != SPI_OP_SUCCESS)return err_code;
  112. if(ReadWriteFlag == SPI_READ)
  113. {
  114. addr = 0x80 | reg_addr;
  115. err_code = SPI_ReadWriteData(CsPin_number, &addr, 1, temp_buff, DataLen+1); //DataLen+1是因为第一个字节是写地址回应时的垃圾数据
  116. if(err_code != SPI_OP_SUCCESS) return err_code;
  117. memcpy(pData, &temp_buff[1], DataLen);
  118. }
  119. else
  120. {
  121. temp_buff[0] = reg_addr;
  122. memcpy(&temp_buff[1], pData, DataLen);
  123. err_code = SPI_ReadWriteData(CsPin_number, temp_buff, DataLen+1, NULL, 0);
  124. if(err_code != SPI_OP_SUCCESS) return err_code;
  125. }
  126. return SPI_OP_SUCCESS;
  127. }
  128. /*********************************************************************
  129. * PUBLIC FUNCTIONS
  130. */
  131. /****************************************************接口****************************************************/
  132. /**
  133. @brief SPI的初始化函数
  134. @param 无
  135. @return 无
  136. */
  137. void SPI_Init(void)
  138. {
  139. ret_code_t errCode;
  140. nrf_drv_spi_config_t spiConfig = NRF_DRV_SPI_DEFAULT_CONFIG; // 使用SPI默认配置
  141. // 配置SPI端口,注意CSN不要在这设置,另外用GPIO口控制
  142. spiConfig.miso_pin = BOARD_SPI0_MISO_IO;
  143. spiConfig.mosi_pin = BOARD_SPI0_MOSI_IO;
  144. spiConfig.sck_pin = BOARD_SPI0_CLK_IO;
  145. spiConfig.mode = NRF_DRV_SPI_MODE_0;
  146. spiConfig.frequency = SPI_FREQUENCY;
  147. spiConfig.irq_priority = 3; // 在定时器中使用优先级需小于6
  148. errCode = nrf_drv_spi_init(&s_spiHandle, &spiConfig, spiCallbackFunc, NULL);
  149. APP_ERROR_CHECK(errCode);
  150. uint32_t i;
  151. for(i = 0; i < SPI_CS_NUMBER; i++)
  152. {
  153. nrf_gpio_cfg_output(s_cs_list[i]);
  154. }
  155. }
  156. /**
  157. @brief SPI只读寄存器数据
  158. @param CsPin_number -[in] 片选引脚
  159. @param reg_addr -[in] 操作的寄存器地址
  160. @param pData -[in/out] 指向需要操作的数据
  161. @param DataLen -[in] 数据长度
  162. @return 错误代码
  163. */
  164. uint32_t SPI_OnlyReadReg(uint32_t CsPin_number, uint8_t reg_addr, uint8_t *pData, uint8_t DataLen)
  165. {
  166. return SPI_ReadWriteReg(CsPin_number, reg_addr, SPI_READ, pData, DataLen);
  167. }
  168. /**
  169. @brief SPI只写寄存器数据
  170. @param CsPin_number -[in] 片选引脚
  171. @param reg_addr -[in] 操作的寄存器地址
  172. @param pData -[in/out] 指向需要操作的数据
  173. @param DataLen -[in] 数据长度
  174. @return 错误代码
  175. */
  176. uint32_t SPI_OnlyWriteReg(uint32_t CsPin_number, uint8_t reg_addr, uint8_t *pData, uint8_t DataLen)
  177. {
  178. return SPI_ReadWriteReg(CsPin_number, reg_addr, SPI_WRITE, pData, DataLen);
  179. }
  180. /**
  181. @brief 开启SPI
  182. @param 无
  183. @return 错误代码
  184. */
  185. uint32_t SPI_Enable(void)
  186. {
  187. SPI_Init();
  188. return SPI_OP_SUCCESS;
  189. }
  190. /**
  191. @brief 禁用SPI
  192. @param 无
  193. @return 无
  194. */
  195. uint32_t SPI_Disable(void)
  196. {
  197. uint32_t i;
  198. //所有片选信号关
  199. for(i = 0; i < SPI_CS_NUMBER; i++)
  200. {
  201. SPI_CsSet(s_cs_list[i],BOARD_SPI_CS_OFF);
  202. }
  203. nrf_drv_spi_uninit(&s_spiHandle);
  204. /*I think you're experiencing this increase from this errata since TWI and SPI shares resources internally,
  205. this errata may also occur when using SPI. Please try this after disabling the SPI:
  206. *(volatile uint32_t *)0x40003FFC = 0;
  207. *(volatile uint32_t *)0x40003FFC;
  208. *(volatile uint32_t *)0x40003FFC = 1;
  209. If SPI1 is used the address is 40004FFC.
  210. */
  211. *(volatile uint32_t *)0x40003FFC = 0;
  212. *(volatile uint32_t *)0x40003FFC;
  213. *(volatile uint32_t *)0x40003FFC = 1;
  214. return SPI_OP_SUCCESS;
  215. }