stm32_spi.c 10 KB

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