drv_spi.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-02-22 airm2m first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "drivers/dev_spi.h"
  13. #include "board.h"
  14. #include "drv_spi.h"
  15. #ifdef BSP_USING_SPI
  16. #define LOG_TAG "drv.spi"
  17. #include "drv_log.h"
  18. #ifndef ITEM_NUM
  19. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  20. #endif
  21. struct spi_bus_device
  22. {
  23. struct rt_spi_bus parent;
  24. char *name;
  25. SPI_TypeDef *periph;
  26. rt_base_t cs_pin;
  27. struct rt_spi_device spi_device;
  28. };
  29. static struct spi_bus_device spi_bus_device_list[] = {
  30. #ifdef BSP_USING_SPI1
  31. {.periph = SPI1,
  32. .name = "spi1"},
  33. #endif
  34. #ifdef BSP_USING_SPI2
  35. {.periph = SPI2,
  36. .name = "spi2"},
  37. #endif
  38. };
  39. /**
  40. * Attach the spi device to SPI bus, this function must be used after initialization.
  41. */
  42. rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin)
  43. {
  44. rt_err_t result;
  45. struct rt_spi_bus *spi_bus;
  46. struct spi_bus_device *spi_bus_dev;
  47. RT_ASSERT(bus_name != RT_NULL);
  48. RT_ASSERT(device_name != RT_NULL);
  49. spi_bus = (struct rt_spi_bus *)rt_device_find(bus_name);
  50. RT_ASSERT(spi_bus != RT_NULL);
  51. spi_bus_dev = (struct spi_bus_device *)spi_bus;
  52. spi_bus_dev->cs_pin = pin;
  53. //often active low, output from master
  54. rt_pin_mode(spi_bus_dev->cs_pin, PIN_MODE_OUTPUT);
  55. rt_pin_write(spi_bus_dev->cs_pin, PIN_HIGH);
  56. result = rt_spi_bus_attach_device(&spi_bus_dev->spi_device, device_name, bus_name, RT_NULL);
  57. if (result != RT_EOK)
  58. {
  59. LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
  60. }
  61. LOG_D("%s attach to %s done", device_name, bus_name);
  62. return result;
  63. }
  64. static rt_err_t air32_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
  65. {
  66. struct rt_spi_bus *spi_bus;
  67. struct spi_bus_device *spi_bus_dev;
  68. rt_uint32_t spi_clock;
  69. SPI_InitTypeDef SPI_InitStruct;
  70. RT_ASSERT(device != RT_NULL);
  71. RT_ASSERT(configuration != RT_NULL);
  72. //device is not RT_NULL, so spi_bus not need check
  73. spi_bus = (struct rt_spi_bus *)device->bus;
  74. spi_bus_dev = (struct spi_bus_device *)spi_bus;
  75. air32_spi_clock_and_io_init(spi_bus_dev->periph);
  76. spi_clock = air32_spi_clock_get(spi_bus_dev->periph);
  77. if (configuration->data_width <= 8)
  78. {
  79. SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
  80. }
  81. else if (configuration->data_width <= 16)
  82. {
  83. SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b;
  84. }
  85. else
  86. {
  87. return -RT_EIO;
  88. }
  89. if (configuration->max_hz >= spi_clock / 2)
  90. {
  91. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  92. }
  93. else if (configuration->max_hz >= spi_clock / 4)
  94. {
  95. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  96. }
  97. else if (configuration->max_hz >= spi_clock / 8)
  98. {
  99. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  100. }
  101. else if (configuration->max_hz >= spi_clock / 16)
  102. {
  103. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
  104. }
  105. else if (configuration->max_hz >= spi_clock / 32)
  106. {
  107. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
  108. }
  109. else if (configuration->max_hz >= spi_clock / 64)
  110. {
  111. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
  112. }
  113. else if (configuration->max_hz >= spi_clock / 128)
  114. {
  115. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
  116. }
  117. else
  118. {
  119. /* min prescaler 256 */
  120. SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  121. }
  122. switch (configuration->mode & RT_SPI_MODE_3)
  123. {
  124. case RT_SPI_MODE_0:
  125. SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
  126. SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
  127. break;
  128. case RT_SPI_MODE_1:
  129. SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
  130. SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
  131. break;
  132. case RT_SPI_MODE_2:
  133. SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
  134. SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
  135. break;
  136. case RT_SPI_MODE_3:
  137. SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
  138. SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
  139. break;
  140. }
  141. /* MSB or LSB */
  142. if (configuration->mode & RT_SPI_MSB)
  143. {
  144. SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
  145. }
  146. else
  147. {
  148. SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_LSB;
  149. }
  150. SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  151. SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
  152. SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
  153. SPI_Init(spi_bus_dev->periph, &SPI_InitStruct);
  154. /* Enable SPI_MASTER */
  155. SPI_Cmd(spi_bus_dev->periph, ENABLE);
  156. return RT_EOK;
  157. };
  158. static rt_uint32_t air32_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  159. {
  160. struct rt_spi_bus *spi_bus;
  161. struct spi_bus_device *spi_bus_dev;
  162. struct rt_spi_configuration *config;
  163. RT_ASSERT(device != NULL);
  164. RT_ASSERT(message != NULL);
  165. //device is not RT_NULL, so spi_bus not need check
  166. spi_bus = (struct rt_spi_bus *)device->bus;
  167. spi_bus_dev = (struct spi_bus_device *)spi_bus;
  168. config = &device->config;
  169. /* take CS */
  170. if (message->cs_take)
  171. {
  172. rt_pin_write(spi_bus_dev->cs_pin, PIN_LOW);
  173. LOG_D("spi take cs\n");
  174. }
  175. if (config->data_width <= 8)
  176. {
  177. const rt_uint8_t *send_ptr = message->send_buf;
  178. rt_uint8_t *recv_ptr = message->recv_buf;
  179. rt_uint32_t size = message->length;
  180. rt_uint8_t data;
  181. LOG_D("spi poll transfer start: %d\n", size);
  182. while (size--)
  183. {
  184. data = 0xFF;
  185. if (send_ptr != RT_NULL)
  186. {
  187. data = *send_ptr++;
  188. }
  189. //Wait until the transmit buffer is empty
  190. while (SPI_I2S_GetFlagStatus(spi_bus_dev->periph, SPI_I2S_FLAG_TXE) == RESET);
  191. // Send the byte
  192. SPI_I2S_SendData(spi_bus_dev->periph, data);
  193. //Wait until a data is received
  194. while (SPI_I2S_GetFlagStatus(spi_bus_dev->periph, SPI_I2S_FLAG_RXNE) == RESET);
  195. // Get the received data
  196. data = SPI_I2S_ReceiveData(spi_bus_dev->periph);
  197. if (recv_ptr != RT_NULL)
  198. {
  199. *recv_ptr++ = data;
  200. }
  201. }
  202. LOG_D("spi poll transfer finsh\n");
  203. }
  204. else if (config->data_width <= 16)
  205. {
  206. const rt_uint16_t *send_ptr = message->send_buf;
  207. rt_uint16_t *recv_ptr = message->recv_buf;
  208. rt_uint32_t size = message->length;
  209. rt_uint16_t data;
  210. while (size--)
  211. {
  212. data = 0xFF;
  213. if (send_ptr != RT_NULL)
  214. {
  215. data = *send_ptr++;
  216. }
  217. //Wait until the transmit buffer is empty
  218. while (RESET == SPI_I2S_GetFlagStatus(spi_bus_dev->periph, SPI_I2S_FLAG_TXE))
  219. ;
  220. // Send the byte
  221. SPI_I2S_SendData(spi_bus_dev->periph, data);
  222. //Wait until a data is received
  223. while (RESET == SPI_I2S_GetFlagStatus(spi_bus_dev->periph, SPI_I2S_FLAG_RXNE))
  224. ;
  225. // Get the received data
  226. data = SPI_I2S_ReceiveData(spi_bus_dev->periph);
  227. if (recv_ptr != RT_NULL)
  228. {
  229. *recv_ptr++ = data;
  230. }
  231. }
  232. }
  233. /* release CS */
  234. if (message->cs_release)
  235. {
  236. rt_pin_write(spi_bus_dev->cs_pin, PIN_HIGH);
  237. LOG_D("spi release cs\n");
  238. }
  239. return message->length;
  240. };
  241. static struct rt_spi_ops spi_ops = {
  242. .configure = air32_spi_configure,
  243. .xfer = air32_spi_xfer};
  244. int rt_hw_spi_init(void)
  245. {
  246. int index;
  247. for (index = 0; index < ITEM_NUM(spi_bus_device_list); index++)
  248. {
  249. rt_spi_bus_register(&spi_bus_device_list[index].parent, spi_bus_device_list[index].name, &spi_ops);
  250. }
  251. return RT_EOK;
  252. }
  253. INIT_BOARD_EXPORT(rt_hw_spi_init);
  254. #endif /* BSP_USING_SPI */