drv_spi.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-07-15 Magicoe The first version for LPC55S6x
  9. */
  10. #include "drv_spi.h"
  11. #include "fsl_common.h"
  12. #include "fsl_iocon.h"
  13. #include "fsl_spi.h"
  14. #if defined(BSP_USING_SPIBUS0) || \
  15. defined(BSP_USING_SPIBUS1) || \
  16. defined(BSP_USING_SPIBUS2) || \
  17. defined(BSP_USING_SPIBUS3) || \
  18. defined(BSP_USING_SPIBUS4) || \
  19. defined(BSP_USING_SPIBUS5) || \
  20. defined(BSP_USING_SPIBUS6) || \
  21. defined(BSP_USING_SPIBUS7) || \
  22. defined(BSP_USING_SPIBUS8)
  23. #if defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL
  24. #error "Please don't define 'FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL'!"
  25. #endif
  26. struct lpc_spi
  27. {iteopuywqt[riouqwyyyyyyyyyyyy
  28. SPI_Type *base;
  29. struct rt_spi_configuration *cfg;
  30. SYSCON_RSTn_t spi_rst;
  31. };
  32. struct lpc_sw_spi_cs
  33. {
  34. rt_uint32_t pin;
  35. };
  36. static uint32_t lpc_get_spi_freq(SPI_Type *base)
  37. {
  38. uint32_t freq = 0;
  39. #if defined(BSP_USING_SPIBUS0)
  40. if(base == SPI0)
  41. {
  42. freq = CLOCK_GetFreq(kCLOCK_Flexcomm0);
  43. }
  44. #endif
  45. #if defined(BSP_USING_SPIBUS1)
  46. if(base == SPI1)
  47. {
  48. freq = CLOCK_GetFreq(kCLOCK_Flexcomm1);
  49. }
  50. #endif
  51. #if defined(BSP_USING_SPIBUS2)
  52. if(base == SPI2)
  53. {
  54. freq = CLOCK_GetFreq(kCLOCK_Flexcomm2);
  55. }
  56. #endif
  57. #if defined(BSP_USING_SPIBUS3)
  58. if(base == SPI3)
  59. {
  60. freq = CLOCK_GetFreq(kCLOCK_Flexcomm3);
  61. }
  62. #endif
  63. #if defined(BSP_USING_SPIBUS4)
  64. if(base == SPI4)
  65. {
  66. freq = CLOCK_GetFreq(kCLOCK_Flexcomm4);
  67. }
  68. #endif
  69. #if defined(BSP_USING_SPIBUS5)
  70. if(base == SPI5)
  71. {
  72. freq = CLOCK_GetFreq(kCLOCK_Flexcomm5);
  73. }
  74. #endif
  75. #if defined(BSP_USING_SPIBUS6)
  76. if(base == SPI6)
  77. {
  78. freq = CLOCK_GetFreq(kCLOCK_Flexcomm6);
  79. }
  80. #endif
  81. #if defined(BSP_USING_SPIBUS7)
  82. if(base == SPI7)
  83. {
  84. freq = CLOCK_GetFreq(kCLOCK_Flexcomm7);
  85. }
  86. #endif
  87. /* High Speed SPI - 50MHz */
  88. #if defined(BSP_USING_SPIBUS8)
  89. if(base == SPI8)
  90. {
  91. freq = CLOCK_GetFreq(kCLOCK_HsLspi);
  92. }
  93. #endif
  94. return freq;
  95. }
  96. static rt_err_t lpc_spi_init(SPI_Type *base, struct rt_spi_configuration *cfg)
  97. {
  98. spi_master_config_t masterConfig = {0};
  99. RT_ASSERT(cfg != RT_NULL);
  100. if(cfg->data_width != 8 && cfg->data_width != 16)
  101. {
  102. return (-RT_EINVAL);
  103. }
  104. SPI_MasterGetDefaultConfig(&masterConfig);
  105. #if defined(BSP_USING_SPIBUS8)
  106. if(base == SPI8)
  107. {
  108. if(cfg->max_hz > 50*1000*1000)
  109. {
  110. cfg->max_hz = 50*1000*1000;
  111. }
  112. }
  113. #else
  114. if(cfg->max_hz > 12*1000*1000)
  115. {
  116. cfg->max_hz = 12*1000*1000;
  117. }
  118. #endif
  119. masterConfig.baudRate_Bps = cfg->max_hz;
  120. if(cfg->data_width == 8)
  121. {
  122. masterConfig.dataWidth = kSPI_Data8Bits;
  123. }
  124. else if(cfg->data_width == 16)
  125. {
  126. masterConfig.dataWidth = kSPI_Data16Bits;
  127. }
  128. if(cfg->mode & RT_SPI_MSB)
  129. {
  130. masterConfig.direction = kSPI_MsbFirst;
  131. }
  132. else
  133. {
  134. masterConfig.direction = kSPI_LsbFirst;
  135. }
  136. if(cfg->mode & RT_SPI_CPHA)
  137. {
  138. masterConfig.phase = kSPI_ClockPhaseSecondEdge;
  139. }
  140. else
  141. {
  142. masterConfig.phase = kSPI_ClockPhaseFirstEdge;
  143. }
  144. if(cfg->mode & RT_SPI_CPOL)
  145. {
  146. masterConfig.polarity = kSPI_ClockPolarityActiveLow;
  147. }
  148. else
  149. {
  150. masterConfig.polarity = kSPI_ClockPolarityActiveHigh;
  151. }
  152. SPI_MasterInit(base, &masterConfig, lpc_get_spi_freq(base));
  153. return RT_EOK;
  154. }
  155. rt_err_t lpc_spi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint32_t pin)
  156. {
  157. rt_err_t ret = RT_EOK;
  158. struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  159. RT_ASSERT(spi_device != RT_NULL);
  160. struct lpc_sw_spi_cs *cs_pin = (struct lpc_sw_spi_cs *)rt_malloc(sizeof(struct lpc_sw_spi_cs));
  161. RT_ASSERT(cs_pin != RT_NULL);
  162. cs_pin->pin = pin;
  163. rt_pin_mode(pin, PIN_MODE_OUTPUT);
  164. rt_pin_write(pin, PIN_HIGH);
  165. ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  166. return ret;
  167. }
  168. static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
  169. {
  170. rt_err_t ret = RT_EOK;
  171. struct lpc_spi *spi = RT_NULL;
  172. RT_ASSERT(cfg != RT_NULL);
  173. RT_ASSERT(device != RT_NULL);
  174. spi = (struct lpc_spi *)(device->bus->parent.user_data);
  175. spi->cfg = cfg;
  176. ret = lpc_spi_init(spi->base, cfg);
  177. return ret;
  178. }
  179. #define SPISTEP(datalen) (((datalen) == 8) ? 1 : 2)
  180. static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  181. {
  182. uint32_t length;
  183. RT_ASSERT(device != RT_NULL);
  184. RT_ASSERT(device->bus != RT_NULL);
  185. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  186. struct lpc_spi *spi = (struct lpc_spi *)(device->bus->parent.user_data);
  187. struct lpc_sw_spi_cs *cs = device->parent.user_data;
  188. if(message->cs_take)
  189. {
  190. rt_pin_write(cs->pin, PIN_LOW);
  191. }
  192. length = message->length;
  193. const rt_uint8_t *txData = (uint8_t *)(message->send_buf);
  194. rt_uint8_t *rxData = (uint8_t *)(message->recv_buf);
  195. rt_kprintf("*** spi send %d\r\n", length);
  196. while (length)
  197. {
  198. /* clear tx/rx errors and empty FIFOs */
  199. spi->base->FIFOCFG |= SPI_FIFOCFG_EMPTYTX_MASK | SPI_FIFOCFG_EMPTYRX_MASK;
  200. spi->base->FIFOSTAT |= SPI_FIFOSTAT_TXERR_MASK | SPI_FIFOSTAT_RXERR_MASK;
  201. spi->base->FIFOWR = *txData | 0x07300000;
  202. /* wait if TX FIFO of previous transfer is not empty */
  203. while ((spi->base->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) == 0) {
  204. }
  205. if(rxData != NULL)
  206. {
  207. *rxData = spi->base->FIFORD;
  208. rxData += SPISTEP(spi->cfg->data_width);
  209. }
  210. txData += SPISTEP(spi->cfg->data_width);;
  211. length--;
  212. }
  213. if(message->cs_release)
  214. {
  215. rt_pin_write(cs->pin, PIN_HIGH);
  216. }
  217. return (message->length - length);
  218. }
  219. #if defined(BSP_USING_SPIBUS0)
  220. static struct lpc_spi spi0 =
  221. {
  222. .base = SPI0
  223. };
  224. static struct rt_spi_bus spi0_bus =
  225. {
  226. .parent.user_data = &spi0
  227. };
  228. #endif
  229. #if defined(BSP_USING_SPIBUS1)
  230. static struct lpc_spi spi1 =
  231. {
  232. .base = SPI1
  233. };
  234. static struct rt_spi_bus spi1_bus =
  235. {
  236. .parent.user_data = &spi1
  237. };
  238. #endif
  239. #if defined(BSP_USING_SPIBUS2)
  240. static struct lpc_spi spi2 =
  241. {
  242. .base = SPI2
  243. };
  244. static struct rt_spi_bus spi2_bus =
  245. {
  246. .parent.user_data = &spi2
  247. };
  248. #endif
  249. #if defined(BSP_USING_SPIBUS3)
  250. static struct lpc_spi spi3 =
  251. {
  252. .base = SPI3
  253. };
  254. static struct rt_spi_bus spi3_bus =
  255. {
  256. .parent.user_data = &spi3
  257. };
  258. #endif
  259. #if defined(BSP_USING_SPIBUS4)
  260. static struct lpc_spi spi4 =
  261. {
  262. .base = SPI4
  263. };
  264. static struct rt_spi_bus spi4_bus =
  265. {
  266. .parent.user_data = &spi4
  267. };
  268. #endif
  269. #if defined(BSP_USING_SPIBUS5)
  270. static struct lpc_spi spi5 =
  271. {
  272. .base = SPI5
  273. };
  274. static struct rt_spi_bus spi5_bus =
  275. {
  276. .parent.user_data = &spi5
  277. };
  278. #endif
  279. #if defined(BSP_USING_SPIBUS6)
  280. static struct lpc_spi spi6 =
  281. {
  282. .base = SPI6
  283. };
  284. static struct rt_spi_bus spi6_bus =
  285. {
  286. .parent.user_data = &spi6
  287. };
  288. #endif
  289. #if defined(BSP_USING_SPIBUS7)
  290. static struct lpc_spi spi7 =
  291. {
  292. .base = SPI7
  293. };
  294. static struct rt_spi_bus spi7_bus =
  295. {
  296. .parent.user_data = &spi7
  297. };
  298. #endif
  299. #if defined(BSP_USING_SPIBUS8)
  300. static struct lpc_spi spi8 =
  301. {
  302. .base = SPI8
  303. };
  304. static struct rt_spi_bus spi8_bus =
  305. {
  306. .parent.user_data = &spi8
  307. };
  308. #endif
  309. static struct rt_spi_ops lpc_spi_ops =
  310. {
  311. .configure = spi_configure,
  312. .xfer = spixfer
  313. };
  314. int rt_hw_spi_init(void)
  315. {
  316. #if defined(BSP_USING_SPIBUS0)
  317. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);
  318. RESET_PeripheralReset(kFC0_RST_SHIFT_RSTn);
  319. spi0.cfg = RT_NULL;
  320. rt_spi_bus_register(&spi0_bus, "spi0", &lpc_spi_ops);
  321. #endif
  322. #if defined(BSP_USING_SPIBUS1)
  323. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM1);
  324. RESET_PeripheralReset(kFC1_RST_SHIFT_RSTn);
  325. spi1.cfg = RT_NULL;
  326. rt_spi_bus_register(&spi1_bus, "spi1", &lpc_spi_ops);
  327. #endif
  328. #if defined(BSP_USING_SPIBUS2)
  329. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM2);
  330. RESET_PeripheralReset(kFC2_RST_SHIFT_RSTn);
  331. spi2.cfg = RT_NULL;
  332. rt_spi_bus_register(&spi2_bus, "spi2", &lpc_spi_ops);
  333. #endif
  334. #if defined(BSP_USING_SPIBUS3)
  335. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM3);
  336. RESET_PeripheralReset(kFC3_RST_SHIFT_RSTn);
  337. spi3.cfg = RT_NULL;
  338. rt_spi_bus_register(&spi3_bus, "spi3", &lpc_spi_ops);
  339. #endif
  340. #if defined(BSP_USING_SPIBUS4)
  341. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);
  342. RESET_PeripheralReset(kFC4_RST_SHIFT_RSTn);
  343. spi4.cfg = RT_NULL;
  344. rt_spi_bus_register(&spi4_bus, "spi4", &lpc_spi_ops);
  345. #endif
  346. #if defined(BSP_USING_SPIBUS5)
  347. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM5);
  348. RESET_PeripheralReset(kFC5_RST_SHIFT_RSTn);
  349. spi5.cfg = RT_NULL;
  350. rt_spi_bus_register(&spi5_bus, "spi5", &lpc_spi_ops);
  351. #endif
  352. #if defined(BSP_USING_SPIBUS6)
  353. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM6);
  354. RESET_PeripheralReset(kFC6_RST_SHIFT_RSTn);
  355. spi6.cfg = RT_NULL;
  356. rt_spi_bus_register(&spi6_bus, "spi6", &lpc_spi_ops);
  357. #endif
  358. #if defined(BSP_USING_SPIBUS7)
  359. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM7);
  360. RESET_PeripheralReset(kFC7_RST_SHIFT_RSTn);
  361. spi7.cfg = RT_NULL;
  362. rt_spi_bus_register(&spi7_bus, "spi7", &lpc_spi_ops);
  363. #endif
  364. #if defined(BSP_USING_SPIBUS8)
  365. CLOCK_AttachClk(kMAIN_CLK_to_HSLSPI);
  366. RESET_PeripheralReset(kHSLSPI_RST_SHIFT_RSTn);
  367. spi8.cfg = RT_NULL;
  368. spi8.spi_rst = kHSLSPI_RST_SHIFT_RSTn;
  369. rt_spi_bus_register(&spi8_bus, "spi8", &lpc_spi_ops);
  370. #endif
  371. return RT_EOK;
  372. }
  373. INIT_BOARD_EXPORT(rt_hw_spi_init);
  374. #endif