drv_spim.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include <stdint.h>
  2. #include <string.h>
  3. #include "board.h"
  4. #include "drv_spim.h"
  5. #include "rtconfig.h"
  6. #include <rtthread.h>
  7. #include <rtdevice.h>
  8. #define DBG_LEVEL DBG_LOG
  9. #include <rtdbg.h>
  10. /* #define LOG_TAG "drv.spim" */
  11. #ifdef BSP_USING_SPIM
  12. #if defined(BSP_USING_SPIM0) || defined(BSP_USING_SPIM1) || defined(BSP_USING_SPIM2) || defined(BSP_USING_SPIM3)
  13. static struct nrfx_drv_spim_config spim_config[] =
  14. {
  15. #ifdef BSP_USING_SPIM0
  16. NRFX_SPIM0_CONFIG,
  17. #endif
  18. #ifdef BSP_USING_SPIM1
  19. NRFX_SPIM1_CONFIG,
  20. #endif
  21. #ifdef BSP_USING_SPIM2
  22. NRFX_SPIM2_CONFIG,
  23. #endif
  24. #ifdef BSP_USING_SPIM3
  25. NRFX_SPIM3_CONFIG,
  26. #endif
  27. };
  28. static struct nrfx_drv_spim spim_bus_obj[sizeof(spim_config) / sizeof(spim_config[0])];
  29. /* Configure SPIM bus pins using the menuconfig */
  30. static struct nrfx_drv_spim_pin_config bsp_spim_pin[] =
  31. {
  32. #ifdef BSP_USING_SPIM0
  33. {
  34. .sck_pin = BSP_SPIM0_SCK_PIN,
  35. .mosi_pin = BSP_SPIM0_MOSI_PIN,
  36. .miso_pin = BSP_SPIM0_MISO_PIN,
  37. .ss_pin = BSP_SPIM0_SS_PIN
  38. },
  39. #endif
  40. #ifdef BSP_USING_SPIM1
  41. {
  42. .sck_pin = BSP_SPIM1_SCK_PIN,
  43. .mosi_pin = BSP_SPIM1_MOSI_PIN,
  44. .miso_pin = BSP_SPIM1_MISO_PIN,
  45. .ss_pin = BSP_SPIM1_SS_PIN
  46. },
  47. #endif
  48. #ifdef BSP_USING_SPIM2
  49. {
  50. .sck_pin = BSP_SPIM2_SCK_PIN,
  51. .mosi_pin = BSP_SPIM2_MOSI_PIN,
  52. .miso_pin = BSP_SPIM2_MISO_PIN,
  53. .ss_pin = BSP_SPIM2_SS_PIN
  54. },
  55. #endif
  56. #ifdef BSP_USING_SPIM3
  57. {
  58. .sck_pin = BSP_SPIM3_SCK_PIN,
  59. .mosi_pin = BSP_SPIM3_MOSI_PIN,
  60. .miso_pin = BSP_SPIM3_MISO_PIN,
  61. .ss_pin = BSP_SPIM3_SS_PIN
  62. },
  63. #endif
  64. };
  65. static rt_uint8_t spim_index_find(struct rt_spi_bus *spi_bus)
  66. {
  67. for (int i = 0; i < sizeof(spim_config) / sizeof(spim_config[0]); i++)
  68. {
  69. if(spi_bus == &spim_bus_obj[i].spim_bus)
  70. return i;
  71. }
  72. return 0xFF;
  73. }
  74. /**
  75. * spi event handler function
  76. */
  77. #ifdef BSP_USING_SPIM0
  78. static void spim0_handler(const nrfx_spim_evt_t *p_event, void *p_context)
  79. {
  80. LOG_I("\nspim0_handler");
  81. }
  82. #endif
  83. #ifdef BSP_USING_SPIM1
  84. static void spim1_handler(const nrfx_spim_evt_t *p_event, void *p_context)
  85. {
  86. LOG_I("\nspim1_handler");
  87. }
  88. #endif
  89. #ifdef BSP_USING_SPIM2
  90. static void spim2_handler(const nrfx_spim_evt_t *p_event, void *p_context)
  91. {
  92. return;
  93. }
  94. #endif
  95. #ifdef BSP_USING_SPIM3
  96. static void spim3_handler(const nrfx_spim_evt_t *p_event, void *p_context)
  97. {
  98. return;
  99. }
  100. #endif
  101. nrfx_spim_evt_handler_t spim_handler[] = {
  102. #ifdef BSP_USING_SPIM0
  103. spim0_handler,
  104. #endif
  105. #ifdef BSP_USING_SPIM1
  106. spim1_handler,
  107. #endif
  108. #ifdef BSP_USING_SPIM2
  109. spim2_handler,
  110. #endif
  111. #ifdef BSP_USING_SPIM3
  112. spim3_handler,
  113. #endif
  114. };
  115. /**
  116. * @brief This function config spi bus
  117. * @param device
  118. * @param configuration
  119. * @retval RT_EOK / -RT_ERROR
  120. */
  121. static rt_err_t spim_configure(struct rt_spi_device *device,
  122. struct rt_spi_configuration *configuration)
  123. {
  124. RT_ASSERT(device != RT_NULL);
  125. RT_ASSERT(device->bus != RT_NULL);
  126. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  127. RT_ASSERT(configuration != RT_NULL);
  128. rt_uint8_t index = spim_index_find(device->bus);
  129. RT_ASSERT(index != 0xFF);
  130. nrfx_spim_t spim = spim_bus_obj[index].spim;
  131. nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG(bsp_spim_pin[index].sck_pin,
  132. bsp_spim_pin[index].mosi_pin,
  133. bsp_spim_pin[index].miso_pin,
  134. bsp_spim_pin[index].ss_pin);
  135. config.ss_active_high = false;
  136. /* spi config ss pin */
  137. /* spi config bit order */
  138. if(configuration->mode & RT_SPI_MSB)
  139. {
  140. config.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST;
  141. }
  142. else
  143. {
  144. config.bit_order = NRF_SPIM_BIT_ORDER_LSB_FIRST;
  145. }
  146. /* spi mode config */
  147. switch (configuration->mode & NRF_SPIM_MODE_3)
  148. {
  149. case NRF_SPIM_MODE_0/* RT_SPI_CPOL:0 , RT_SPI_CPHA:0 */:
  150. config.mode = NRF_SPIM_MODE_0;
  151. break;
  152. case NRF_SPIM_MODE_1/* RT_SPI_CPOL:0 , RT_SPI_CPHA:1 */:
  153. config.mode = NRF_SPIM_MODE_1;
  154. break;
  155. case NRF_SPIM_MODE_2/* RT_SPI_CPOL:1 , RT_SPI_CPHA:0 */:
  156. config.mode = NRF_SPIM_MODE_2;
  157. break;
  158. case NRF_SPIM_MODE_3/* RT_SPI_CPOL:1 , RT_SPI_CPHA:1 */:
  159. config.mode = NRF_SPIM_MODE_3;
  160. break;
  161. default:
  162. LOG_E("spim_configure mode error %x\n",configuration->mode);
  163. return -RT_ERROR;
  164. }
  165. /* spi frequency config */
  166. switch (configuration->max_hz / 1000)
  167. {
  168. case 125:
  169. config.frequency = NRF_SPIM_FREQ_125K;
  170. break;
  171. case 250:
  172. config.frequency = NRF_SPIM_FREQ_250K;
  173. break;
  174. case 500:
  175. config.frequency = NRF_SPIM_FREQ_500K;
  176. break;
  177. case 1000:
  178. config.frequency = NRF_SPIM_FREQ_1M;
  179. break;
  180. case 2000:
  181. config.frequency = NRF_SPIM_FREQ_2M;
  182. break;
  183. case 4000:
  184. config.frequency = NRF_SPIM_FREQ_4M;
  185. break;
  186. case 8000:
  187. config.frequency = NRF_SPIM_FREQ_8M;
  188. break;
  189. case 16000:
  190. config.frequency = NRF_SPIM_FREQ_16M;
  191. break;
  192. case 32000:
  193. config.frequency = NRF_SPIM_FREQ_32M;
  194. break;
  195. default:
  196. LOG_E("spim_configure rate error %d\n",configuration->max_hz);
  197. break;
  198. }
  199. rt_memcpy((void*)&spim_bus_obj[index].spim_config, (void*)&config, sizeof(nrfx_spim_config_t));
  200. void * context = RT_NULL;
  201. nrfx_spim_evt_handler_t handler = RT_NULL; /* spi send callback handler ,default NULL */
  202. /* create and init completion */
  203. struct rt_completion *cpt = (struct rt_completion*)rt_malloc(sizeof(struct rt_completion));
  204. rt_completion_init(cpt);
  205. /* create and init message about spim */
  206. struct spi_dma_message *mess = (struct spi_dma_message*)rt_malloc(sizeof(struct spi_dma_message));
  207. /* step 1: cs pin */
  208. mess->cs_pin = device->cs_pin;
  209. /* step 2: cs pin behavior */
  210. mess->cs_take = 0;
  211. mess->cs_release = 0;
  212. /* step 3 */
  213. mess->use_hw_ss = config.use_hw_ss;
  214. /* step 4: cs pin active */
  215. mess->ss_active_high = config.ss_active_high;
  216. /* step 6 */
  217. mess->cpt = cpt;
  218. context = (void*)mess;
  219. handler = spim_handler[index];
  220. nrfx_err_t nrf_ret = nrfx_spim_init(&spim, &config, handler, context);
  221. if(NRFX_SUCCESS == nrf_ret)
  222. return RT_EOK;
  223. else
  224. LOG_E("spim configure fail. %x", nrf_ret);
  225. return -RT_ERROR;
  226. }
  227. static rt_ssize_t spimxfer(struct rt_spi_device *device, struct rt_spi_message *message)
  228. {
  229. RT_ASSERT(device != RT_NULL);
  230. RT_ASSERT(device->bus != RT_NULL);
  231. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  232. rt_uint8_t index = spim_index_find(device->bus);
  233. nrfx_err_t nrf_ret;
  234. RT_ASSERT(index != 0xFF);
  235. nrfx_spim_t * p_instance = &(spim_bus_obj[index].spim);
  236. nrfx_spim_xfer_desc_t p_xfer_desc = NRFX_SPIM_XFER_TRX(message->send_buf, message->length, message->recv_buf, message->length);
  237. if(message->send_buf == RT_NULL)
  238. {
  239. p_xfer_desc.tx_length = 0;
  240. }
  241. if(message->recv_buf == RT_NULL)
  242. {
  243. p_xfer_desc.rx_length = 0;
  244. }
  245. nrf_ret = rtt_nrfx_spim_xfer(p_instance, &p_xfer_desc, 0, message, device);
  246. if( NRFX_SUCCESS != nrf_ret)
  247. {
  248. LOG_E("SPIM data transfer fail. %x", nrf_ret);
  249. return 0;
  250. }
  251. else
  252. {
  253. return message->length;
  254. }
  255. }
  256. /* spi bus callback function */
  257. static const struct rt_spi_ops nrfx_spim_ops =
  258. {
  259. .configure = spim_configure,
  260. .xfer = spimxfer,
  261. };
  262. /*spim bus init*/
  263. static int rt_hw_spim_bus_init(void)
  264. {
  265. rt_err_t result = -RT_ERROR;
  266. for (int i = 0; i < sizeof(spim_config) / sizeof(spim_config[0]); i++)
  267. {
  268. spim_bus_obj[i].spim = spim_config[i].spi;
  269. spim_bus_obj[i].spim_bus.parent.user_data = &spim_config[i]; /* SPI INSTANCE */
  270. result = rt_spi_bus_register(&spim_bus_obj[i].spim_bus, spim_config[i].bus_name, &nrfx_spim_ops);
  271. RT_ASSERT(result == RT_EOK);
  272. }
  273. return result;
  274. }
  275. int rt_hw_spim_init(void)
  276. {
  277. return rt_hw_spim_bus_init();
  278. }
  279. INIT_BOARD_EXPORT(rt_hw_spim_init);
  280. #endif /* BSP_USING_SPIM0 || BSP_USING_SPIM1 || BSP_USING_SPIM2 || BSP_USING_SPIM3 */
  281. #endif /*BSP_USING_SPIM*/