drv_spi.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2017-10-20 ZYH the first version
  10. * 2017-11-35 ZYH update to 3.0.0
  11. */
  12. #include <board.h>
  13. #include <drv_spi.h>
  14. #ifdef RT_USING_SPI
  15. #define SPIRXEVENT 0x01
  16. #define SPITXEVENT 0x02
  17. #define SPITIMEOUT 2
  18. #define SPICRCEN 0
  19. struct stm32_hw_spi_cs
  20. {
  21. rt_uint32_t pin;
  22. };
  23. struct stm32_spi
  24. {
  25. SPI_TypeDef *Instance;
  26. struct rt_spi_configuration *cfg;
  27. };
  28. static rt_err_t stm32_spi_init(SPI_TypeDef *spix, struct rt_spi_configuration *cfg)
  29. {
  30. SPI_HandleTypeDef hspi;
  31. hspi.Instance = spix;
  32. if (cfg->mode & RT_SPI_SLAVE)
  33. {
  34. hspi.Init.Mode = SPI_MODE_SLAVE;
  35. }
  36. else
  37. {
  38. hspi.Init.Mode = SPI_MODE_MASTER;
  39. }
  40. if (cfg->mode & RT_SPI_3WIRE)
  41. {
  42. hspi.Init.Direction = SPI_DIRECTION_1LINE;
  43. }
  44. else
  45. {
  46. hspi.Init.Direction = SPI_DIRECTION_2LINES;
  47. }
  48. if (cfg->data_width == 8)
  49. {
  50. hspi.Init.DataSize = SPI_DATASIZE_8BIT;
  51. }
  52. else if (cfg->data_width == 16)
  53. {
  54. hspi.Init.DataSize = SPI_DATASIZE_16BIT;
  55. }
  56. else
  57. {
  58. return RT_EIO;
  59. }
  60. if (cfg->mode & RT_SPI_CPHA)
  61. {
  62. hspi.Init.CLKPhase = SPI_PHASE_2EDGE;
  63. }
  64. else
  65. {
  66. hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
  67. }
  68. if (cfg->mode & RT_SPI_CPOL)
  69. {
  70. hspi.Init.CLKPolarity = SPI_POLARITY_HIGH;
  71. }
  72. else
  73. {
  74. hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
  75. }
  76. if (cfg->mode & RT_SPI_NO_CS)
  77. {
  78. hspi.Init.NSS = SPI_NSS_SOFT;
  79. }
  80. else
  81. {
  82. hspi.Init.NSS = SPI_NSS_SOFT;
  83. // hspi.Init.NSS = SPI_NSS_HARD_OUTPUT;
  84. }
  85. if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 2)
  86. {
  87. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  88. }
  89. else if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 4)
  90. {
  91. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  92. }
  93. else if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 8)
  94. {
  95. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  96. }
  97. else if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 16)
  98. {
  99. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  100. }
  101. else if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 32)
  102. {
  103. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  104. }
  105. else if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 64)
  106. {
  107. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  108. }
  109. else if (cfg->max_hz >= HAL_RCC_GetPCLK2Freq() / 128)
  110. {
  111. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  112. }
  113. else
  114. {
  115. /* min prescaler 256 */
  116. hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  117. }
  118. if (cfg->mode & RT_SPI_MSB)
  119. {
  120. hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
  121. }
  122. else
  123. {
  124. hspi.Init.FirstBit = SPI_FIRSTBIT_LSB;
  125. }
  126. hspi.Init.TIMode = SPI_TIMODE_DISABLE;
  127. hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  128. hspi.Init.CRCPolynomial = 7;
  129. hspi.State = HAL_SPI_STATE_RESET;
  130. if (HAL_SPI_Init(&hspi) != HAL_OK)
  131. {
  132. return RT_EIO;
  133. }
  134. __HAL_SPI_ENABLE(&hspi);
  135. return RT_EOK;
  136. }
  137. #define SPISTEP(datalen) (((datalen) == 8) ? 1 : 2)
  138. #define SPISEND_1(reg, ptr, datalen) \
  139. do \
  140. { \
  141. if (datalen == 8) \
  142. { \
  143. (reg) = *(rt_uint8_t *)(ptr); \
  144. } \
  145. else \
  146. { \
  147. (reg) = *(rt_uint16_t *)(ptr); \
  148. } \
  149. } while (0)
  150. #define SPIRECV_1(reg, ptr, datalen) \
  151. do \
  152. { \
  153. if (datalen == 8) \
  154. { \
  155. *(rt_uint8_t *)(ptr) = (reg); \
  156. } \
  157. else \
  158. { \
  159. *(rt_uint16_t *)(ptr) = reg; \
  160. } \
  161. } while (0)
  162. static rt_err_t spitxrx1b(struct stm32_spi *hspi, void *rcvb, const void *sndb)
  163. {
  164. rt_uint32_t padrcv = 0;
  165. rt_uint32_t padsnd = 0xFF;
  166. if (!rcvb && !sndb)
  167. {
  168. return RT_ERROR;
  169. }
  170. if (!rcvb)
  171. {
  172. rcvb = &padrcv;
  173. }
  174. if (!sndb)
  175. {
  176. sndb = &padsnd;
  177. }
  178. while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE) == RESET)
  179. ;
  180. SPISEND_1(hspi->Instance->DR, sndb, hspi->cfg->data_width);
  181. while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE) == RESET)
  182. ;
  183. SPIRECV_1(hspi->Instance->DR, rcvb, hspi->cfg->data_width);
  184. return RT_EOK;
  185. }
  186. static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  187. {
  188. rt_err_t res;
  189. RT_ASSERT(device != RT_NULL);
  190. RT_ASSERT(device->bus != RT_NULL);
  191. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  192. struct stm32_spi *hspi = (struct stm32_spi *)device->bus->parent.user_data;
  193. struct stm32_hw_spi_cs *cs = device->parent.user_data;
  194. if (message->cs_take)
  195. {
  196. rt_pin_write(cs->pin, 0);
  197. }
  198. const rt_uint8_t *sndb = message->send_buf;
  199. rt_uint8_t *rcvb = message->recv_buf;
  200. rt_int32_t length = message->length;
  201. while (length)
  202. {
  203. res = spitxrx1b(hspi, rcvb, sndb);
  204. if (rcvb)
  205. {
  206. rcvb += SPISTEP(hspi->cfg->data_width);
  207. }
  208. if (sndb)
  209. {
  210. sndb += SPISTEP(hspi->cfg->data_width);
  211. }
  212. if (res != RT_EOK)
  213. {
  214. break;
  215. }
  216. length--;
  217. }
  218. /* Wait until Busy flag is reset before disabling SPI */
  219. while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_BSY) == SET)
  220. ;
  221. if (message->cs_release)
  222. {
  223. rt_pin_write(cs->pin, 1);
  224. }
  225. return message->length - length;
  226. }
  227. rt_err_t spi_configure(struct rt_spi_device *device,
  228. struct rt_spi_configuration *configuration)
  229. {
  230. struct stm32_spi *hspi = (struct stm32_spi *)device->bus->parent.user_data;
  231. hspi->cfg = configuration;
  232. return stm32_spi_init(hspi->Instance, configuration);
  233. }
  234. const struct rt_spi_ops stm_spi_ops =
  235. {
  236. .configure = spi_configure,
  237. .xfer = spixfer,
  238. };
  239. struct rt_spi_bus _spi_bus1, _spi_bus2;
  240. struct stm32_spi _spi1, _spi2;
  241. int stm32_spi_register_bus(SPI_TypeDef *SPIx, const char *name)
  242. {
  243. struct rt_spi_bus *spi_bus;
  244. struct stm32_spi *spi;
  245. if (SPIx == SPI1)
  246. {
  247. spi_bus = &_spi_bus1;
  248. spi = &_spi1;
  249. }
  250. else if (SPIx == SPI2)
  251. {
  252. spi_bus = &_spi_bus2;
  253. spi = &_spi2;
  254. }
  255. else
  256. {
  257. return -1;
  258. }
  259. spi->Instance = SPIx;
  260. spi_bus->parent.user_data = spi;
  261. return rt_spi_bus_register(spi_bus, name, &stm_spi_ops);
  262. }
  263. rt_err_t stm32_spi_bus_attach_device(rt_uint32_t pin, const char *bus_name, const char *device_name)
  264. {
  265. struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  266. RT_ASSERT(spi_device != RT_NULL);
  267. struct stm32_hw_spi_cs *cs_pin = (struct stm32_hw_spi_cs *)rt_malloc(sizeof(struct stm32_hw_spi_cs));
  268. RT_ASSERT(cs_pin != RT_NULL);
  269. cs_pin->pin = pin;
  270. rt_pin_mode(pin, PIN_MODE_OUTPUT);
  271. rt_pin_write(pin, 1);
  272. return rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  273. }
  274. int stm32_hw_spi_init(void)
  275. {
  276. int result = 0;
  277. #ifdef RT_USING_SPI1
  278. result = stm32_spi_register_bus(SPI1, "spi1");
  279. #endif
  280. #ifdef RT_USING_SPI2
  281. result = stm32_spi_register_bus(SPI2, "spi2");
  282. #endif
  283. return result;
  284. }
  285. INIT_BOARD_EXPORT(stm32_hw_spi_init);
  286. void HAL_SPI_MspInit(SPI_HandleTypeDef *spiHandle)
  287. {
  288. GPIO_InitTypeDef GPIO_InitStruct;
  289. if (spiHandle->Instance == SPI1)
  290. {
  291. /* SPI1 clock enable */
  292. __HAL_RCC_SPI1_CLK_ENABLE();
  293. __HAL_RCC_GPIOA_CLK_ENABLE();
  294. /**SPI1 GPIO Configuration
  295. PA5 ------> SPI1_SCK
  296. PA6 ------> SPI1_MISO
  297. PA7 ------> SPI1_MOSI
  298. */
  299. GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7;
  300. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  301. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  302. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  303. GPIO_InitStruct.Pin = GPIO_PIN_6;
  304. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  305. GPIO_InitStruct.Pull = GPIO_NOPULL;
  306. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  307. }
  308. else if (spiHandle->Instance == SPI2)
  309. {
  310. /* SPI2 clock enable */
  311. __HAL_RCC_SPI2_CLK_ENABLE();
  312. __HAL_RCC_GPIOB_CLK_ENABLE();
  313. /**SPI2 GPIO Configuration
  314. PB13 ------> SPI2_SCK
  315. PB14 ------> SPI2_MISO
  316. PB15 ------> SPI2_MOSI
  317. */
  318. GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_15;
  319. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  320. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  321. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  322. GPIO_InitStruct.Pin = GPIO_PIN_14;
  323. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  324. GPIO_InitStruct.Pull = GPIO_NOPULL;
  325. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  326. }
  327. }
  328. void HAL_SPI_MspDeInit(SPI_HandleTypeDef *spiHandle)
  329. {
  330. if (spiHandle->Instance == SPI1)
  331. {
  332. /* Peripheral clock disable */
  333. __HAL_RCC_SPI1_CLK_DISABLE();
  334. /**SPI1 GPIO Configuration
  335. PA5 ------> SPI1_SCK
  336. PA6 ------> SPI1_MISO
  337. PA7 ------> SPI1_MOSI
  338. */
  339. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
  340. }
  341. else if (spiHandle->Instance == SPI2)
  342. {
  343. /* Peripheral clock disable */
  344. __HAL_RCC_SPI2_CLK_DISABLE();
  345. /**SPI2 GPIO Configuration
  346. PB13 ------> SPI2_SCK
  347. PB14 ------> SPI2_MISO
  348. PB15 ------> SPI2_MOSI
  349. */
  350. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
  351. }
  352. }
  353. #endif /*RT_USING_SPI*/