drv_spi_bus.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * File : drv_spi_bus.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006-2013, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2018-03-27 Liuguang the first version.
  13. */
  14. #include "drv_spi_bus.h"
  15. #include "fsl_common.h"
  16. #include "fsl_iomuxc.h"
  17. #include "fsl_lpspi.h"
  18. #ifdef RT_USING_SPI
  19. #define LPSPI_CLK_SOURCE (1U)
  20. #define LPSPI_CLK_SOURCE_DIVIDER (7U)
  21. #if defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL
  22. #error "Please don't define 'FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL'!"
  23. #endif
  24. struct rt1050_spi
  25. {
  26. LPSPI_Type *base;
  27. struct rt_spi_configuration *cfg;
  28. };
  29. struct rt1050_hw_spi_cs
  30. {
  31. rt_uint32_t pin;
  32. };
  33. static uint32_t rt1050_get_lpspi_freq(void)
  34. {
  35. uint32_t freq = 0;
  36. /* CLOCK_GetMux(kCLOCK_LpspiMux):
  37. 00b: derive clock from PLL3 PFD1 720M
  38. 01b: derive clock from PLL3 PFD0 720M
  39. 10b: derive clock from PLL2 528M
  40. 11b: derive clock from PLL2 PFD2 396M
  41. */
  42. switch(CLOCK_GetMux(kCLOCK_LpspiMux))
  43. {
  44. case 0:
  45. freq = CLOCK_GetFreq(kCLOCK_Usb1PllPfd1Clk);
  46. break;
  47. case 1:
  48. freq = CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk);
  49. break;
  50. case 2:
  51. freq = CLOCK_GetFreq(kCLOCK_SysPllClk);
  52. break;
  53. case 3:
  54. freq = CLOCK_GetFreq(kCLOCK_SysPllPfd2Clk);
  55. break;
  56. }
  57. freq /= (CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1U);
  58. return freq;
  59. }
  60. static rt_err_t rt1050_spi_init(LPSPI_Type *base, struct rt_spi_configuration *cfg)
  61. {
  62. lpspi_master_config_t masterConfig;
  63. if(cfg->data_width != 8 && cfg->data_width != 16 && cfg->data_width != 32)
  64. {
  65. return RT_EINVAL;
  66. }
  67. #if defined(RT_USING_SPIBUS1)
  68. if(base == LPSPI1)
  69. {
  70. IOMUXC_SetPinMux (IOMUXC_GPIO_EMC_27_LPSPI1_SCK, 0U);
  71. IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_27_LPSPI1_SCK, 0x10B0u);
  72. IOMUXC_SetPinMux (IOMUXC_GPIO_EMC_28_LPSPI1_SDO, 0U);
  73. IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_28_LPSPI1_SDO, 0x10B0u);
  74. IOMUXC_SetPinMux (IOMUXC_GPIO_EMC_29_LPSPI1_SDI, 0U);
  75. IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_29_LPSPI1_SDI, 0x10B0u);
  76. }
  77. #endif
  78. #if defined(RT_USING_SPIBUS2)
  79. if(base == LPSPI2)
  80. {
  81. IOMUXC_SetPinMux (IOMUXC_GPIO_SD_B1_07_LPSPI2_SCK, 0U);
  82. IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_07_LPSPI2_SCK, 0x10B0u);
  83. IOMUXC_SetPinMux (IOMUXC_GPIO_SD_B1_08_LPSPI2_SD0, 0U);
  84. IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_08_LPSPI2_SD0, 0x10B0u);
  85. IOMUXC_SetPinMux (IOMUXC_GPIO_SD_B1_09_LPSPI2_SDI, 0U);
  86. IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_09_LPSPI2_SDI, 0x10B0u);
  87. /* Optional IO config */
  88. //IOMUXC_SetPinMux (IOMUXC_GPIO_EMC_00_LPSPI2_SCK, 0U);
  89. //IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_00_LPSPI2_SCK, 0x10B0u);
  90. //IOMUXC_SetPinMux (IOMUXC_GPIO_EMC_02_LPSPI2_SDO, 0U);
  91. //IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_02_LPSPI2_SDO, 0x10B0u);
  92. //IOMUXC_SetPinMux (IOMUXC_GPIO_EMC_03_LPSPI2_SDI, 0U);
  93. //IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_03_LPSPI2_SDI, 0x10B0u);
  94. }
  95. #endif
  96. #if defined(RT_USING_SPIBUS3)
  97. if(base == LPSPI3)
  98. {
  99. IOMUXC_SetPinMux (IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI, 0U);
  100. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI, 0x10B0u);
  101. IOMUXC_SetPinMux (IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO, 0U);
  102. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO, 0x10B0u);
  103. IOMUXC_SetPinMux (IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK, 0U);
  104. IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK, 0x10B0u);
  105. }
  106. #endif
  107. #if defined(RT_USING_SPIBUS4)
  108. if(base == LPSPI4)
  109. {
  110. IOMUXC_SetPinMux (IOMUXC_GPIO_B0_01_LPSPI4_SDI, 0U);
  111. IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LPSPI4_SDI, 0x10B0u);
  112. IOMUXC_SetPinMux (IOMUXC_GPIO_B0_02_LPSPI4_SDO, 0U);
  113. IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LPSPI4_SDO, 0x10B0u);
  114. IOMUXC_SetPinMux (IOMUXC_GPIO_B0_03_LPSPI4_SCK, 0U);
  115. IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LPSPI4_SCK, 0x10B0u);
  116. /* Optional IO config */
  117. //IOMUXC_SetPinMux (IOMUXC_GPIO_B1_07_LPSPI4_SCK, 0U);
  118. //IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_07_LPSPI4_SCK, 0x10B0u);
  119. //IOMUXC_SetPinMux (IOMUXC_GPIO_B1_06_LPSPI4_SDO, 0U);
  120. //IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_06_LPSPI4_SDO, 0x10B0u);
  121. //IOMUXC_SetPinMux (IOMUXC_GPIO_B1_05_LPSPI4_SDI, 0U);
  122. //IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_05_LPSPI4_SDI, 0x10B0u);
  123. }
  124. #endif
  125. LPSPI_MasterGetDefaultConfig(&masterConfig);
  126. masterConfig.baudRate = cfg->max_hz;
  127. masterConfig.bitsPerFrame = cfg->data_width;
  128. if(cfg->mode & RT_SPI_MSB)
  129. {
  130. masterConfig.direction = kLPSPI_MsbFirst;
  131. }
  132. else
  133. {
  134. masterConfig.direction = kLPSPI_LsbFirst;
  135. }
  136. if(cfg->mode & RT_SPI_CPHA)
  137. {
  138. masterConfig.cpha = kLPSPI_ClockPhaseSecondEdge;
  139. }
  140. else
  141. {
  142. masterConfig.cpha = kLPSPI_ClockPhaseFirstEdge;
  143. }
  144. if(cfg->mode & RT_SPI_CPOL)
  145. {
  146. masterConfig.cpol = kLPSPI_ClockPolarityActiveLow;
  147. }
  148. else
  149. {
  150. masterConfig.cpol = kLPSPI_ClockPolarityActiveHigh;
  151. }
  152. masterConfig.pinCfg = kLPSPI_SdiInSdoOut;
  153. masterConfig.dataOutConfig = kLpspiDataOutTristate;
  154. masterConfig.pcsToSckDelayInNanoSec = 1000000000 / masterConfig.baudRate;
  155. masterConfig.lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.baudRate;
  156. masterConfig.betweenTransferDelayInNanoSec = 1000000000 / masterConfig.baudRate;
  157. LPSPI_MasterInit(base, &masterConfig, rt1050_get_lpspi_freq());
  158. base->CFGR1 |= LPSPI_CFGR1_PCSCFG_MASK;
  159. return RT_EOK;
  160. }
  161. rt_err_t rt1050_spi_bus_attach_device(const char *bus_name, const char *device_name, rt_uint32_t pin)
  162. {
  163. rt_err_t ret;
  164. struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  165. RT_ASSERT(spi_device != RT_NULL);
  166. struct rt1050_hw_spi_cs *cs_pin = (struct rt1050_hw_spi_cs *)rt_malloc(sizeof(struct rt1050_hw_spi_cs));
  167. RT_ASSERT(cs_pin != RT_NULL);
  168. cs_pin->pin = pin;
  169. rt_pin_mode(pin, PIN_MODE_OUTPUT);
  170. rt_pin_write(pin, PIN_HIGH);
  171. ret = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  172. return ret;
  173. }
  174. static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
  175. {
  176. rt_err_t ret;
  177. struct rt1050_spi *spi = RT_NULL;
  178. RT_ASSERT(cfg != RT_NULL);
  179. RT_ASSERT(device != RT_NULL);
  180. spi = (struct rt1050_spi *)(device->bus->parent.user_data);
  181. spi->cfg = cfg;
  182. ret = rt1050_spi_init(spi->base, cfg);
  183. return ret;
  184. }
  185. static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  186. {
  187. lpspi_transfer_t transfer;
  188. RT_ASSERT(device != RT_NULL);
  189. RT_ASSERT(device->bus != RT_NULL);
  190. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  191. struct rt1050_spi *spi = (struct rt1050_spi *)(device->bus->parent.user_data);
  192. struct rt1050_hw_spi_cs *cs = device->parent.user_data;
  193. if(message->cs_take)
  194. {
  195. rt_pin_write(cs->pin, PIN_LOW);
  196. }
  197. transfer.rxData = (uint8_t *)(message->recv_buf);
  198. transfer.txData = (uint8_t *)(message->send_buf);
  199. transfer.dataSize = message->length;
  200. status_t stat = LPSPI_MasterTransferBlocking(spi->base, &transfer);
  201. if(message->cs_release)
  202. {
  203. rt_pin_write(cs->pin, PIN_HIGH);
  204. }
  205. return message->length;
  206. }
  207. #if defined(RT_USING_SPIBUS1)
  208. static struct rt1050_spi spi1 =
  209. {
  210. .base = LPSPI1
  211. };
  212. static struct rt_spi_bus spi1_bus =
  213. {
  214. .parent.user_data = &spi1
  215. };
  216. #endif
  217. #if defined(RT_USING_SPIBUS2)
  218. static struct rt1050_spi spi2 =
  219. {
  220. .base = LPSPI2
  221. };
  222. static struct rt_spi_bus spi2_bus =
  223. {
  224. .parent.user_data = &spi2
  225. };
  226. #endif
  227. #if defined(RT_USING_SPIBUS3)
  228. static struct rt1050_spi spi3 =
  229. {
  230. .base = LPSPI3
  231. };
  232. static struct rt_spi_bus spi3_bus =
  233. {
  234. .parent.user_data = &spi3
  235. };
  236. #endif
  237. #if defined(RT_USING_SPIBUS4)
  238. static struct rt1050_spi spi4 =
  239. {
  240. .base = LPSPI4
  241. };
  242. static struct rt_spi_bus spi4_bus =
  243. {
  244. .parent.user_data = &spi4
  245. };
  246. #endif
  247. static struct rt_spi_ops rt1050_spi_ops =
  248. {
  249. .configure = spi_configure,
  250. .xfer = spixfer
  251. };
  252. int rt_hw_spi_bus_init(void)
  253. {
  254. #if defined(RT_USING_SPIBUS1) || defined(RT_USING_SPIBUS2) || \
  255. defined(RT_USING_SPIBUS3) || defined(RT_USING_SPIBUS4)
  256. CLOCK_SetMux(kCLOCK_LpspiMux, LPSPI_CLK_SOURCE);
  257. CLOCK_SetDiv(kCLOCK_LpspiDiv, LPSPI_CLK_SOURCE_DIVIDER);
  258. CLOCK_EnableClock(kCLOCK_Iomuxc);
  259. #endif
  260. #if defined(RT_USING_SPIBUS1)
  261. rt_spi_bus_register(&spi1_bus, "spibus1", &rt1050_spi_ops);
  262. #endif
  263. #if defined(RT_USING_SPIBUS2)
  264. rt_spi_bus_register(&spi2_bus, "spibus2", &rt1050_spi_ops);
  265. #endif
  266. #if defined(RT_USING_SPIBUS3)
  267. rt_spi_bus_register(&spi3_bus, "spibus3", &rt1050_spi_ops);
  268. #endif
  269. #if defined(RT_USING_SPIBUS4)
  270. rt_spi_bus_register(&spi4_bus, "spibus4", &rt1050_spi_ops);
  271. #endif
  272. return RT_EOK;
  273. }
  274. INIT_BOARD_EXPORT(rt_hw_spi_bus_init);
  275. #endif