drv_spi.c 11 KB

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