drv_spi.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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-06-04 BruceOu first implementation
  9. */
  10. #include "drv_spi.h"
  11. #ifdef RT_USING_SPI
  12. #if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2)
  13. #define LOG_TAG "drv.spi"
  14. #include <rtdbg.h>
  15. #ifdef BSP_USING_SPI0
  16. static struct rt_spi_bus spi_bus0;
  17. #endif
  18. #ifdef BSP_USING_SPI1
  19. static struct rt_spi_bus spi_bus1;
  20. #endif
  21. #ifdef BSP_USING_SPI2
  22. static struct rt_spi_bus spi_bus2;
  23. #endif
  24. static const struct gd32_spi spi_bus_obj[] = {
  25. #ifdef BSP_USING_SPI0
  26. {
  27. SPI0,
  28. "spi0",
  29. RCU_SPI0,
  30. RCU_GPIOA,
  31. &spi_bus0,
  32. GPIOA,
  33. GPIO_PIN_5,
  34. GPIO_PIN_6,
  35. GPIO_PIN_7,
  36. }
  37. #endif /* BSP_USING_SPI0 */
  38. #ifdef BSP_USING_SPI1
  39. {
  40. SPI1,
  41. "spi1",
  42. RCU_SPI1,
  43. RCU_GPIOB,
  44. &spi_bus1,
  45. GPIOB,
  46. GPIO_PIN_12,
  47. GPIO_PIN_14,
  48. GPIO_PIN_15,
  49. }
  50. #endif /* BSP_USING_SPI1 */
  51. #ifdef BSP_USING_SPI2
  52. {
  53. SPI2,
  54. "spi2",
  55. RCU_SPI2,
  56. RCU_GPIOB,
  57. &spi_bus2,
  58. GPIOB,
  59. GPIO_PIN_3,
  60. GPIO_PIN_4,
  61. GPIO_PIN_5,
  62. }
  63. #endif /* BSP_USING_SPI2 */
  64. };
  65. /* private rt-thread spi ops function */
  66. static rt_err_t spi_configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
  67. static rt_uint32_t spixfer(struct rt_spi_device* device, struct rt_spi_message* message);
  68. static struct rt_spi_ops gd32_spi_ops =
  69. {
  70. .configure = spi_configure,
  71. .xfer = spixfer,
  72. };
  73. /**
  74. * @brief SPI Initialization
  75. * @param gd32_spi: SPI BUS
  76. * @retval None
  77. */
  78. static void gd32_spi_init(struct gd32_spi *gd32_spi)
  79. {
  80. /* enable SPI clock */
  81. rcu_periph_clock_enable(gd32_spi->spi_clk);
  82. rcu_periph_clock_enable(gd32_spi->gpio_clk);
  83. /* Init SPI SCK MOSI */
  84. gpio_init(gd32_spi->spi_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin | gd32_spi->mosi_pin);
  85. /* Init SPI MISO */
  86. gpio_init(gd32_spi->spi_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, gd32_spi->miso_pin);
  87. }
  88. static rt_err_t spi_configure(struct rt_spi_device* device,
  89. struct rt_spi_configuration* configuration)
  90. {
  91. struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus;
  92. struct gd32_spi *spi_device = (struct gd32_spi *)spi_bus->parent.user_data;
  93. spi_parameter_struct spi_init_struct;
  94. uint32_t spi_periph = spi_device->spi_periph;
  95. RT_ASSERT(device != RT_NULL);
  96. RT_ASSERT(configuration != RT_NULL);
  97. //Init SPI
  98. gd32_spi_init(spi_device);
  99. /* data_width */
  100. if(configuration->data_width <= 8)
  101. {
  102. spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
  103. }
  104. else if(configuration->data_width <= 16)
  105. {
  106. spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT;
  107. }
  108. else
  109. {
  110. return -RT_EIO;
  111. }
  112. /* baudrate */
  113. {
  114. rcu_clock_freq_enum spi_src;
  115. uint32_t spi_apb_clock;
  116. uint32_t max_hz;
  117. max_hz = configuration->max_hz;
  118. LOG_D("sys freq: %d\n", rcu_clock_freq_get(CK_SYS));
  119. LOG_D("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2));
  120. LOG_D("max freq: %d\n", max_hz);
  121. if (spi_periph == SPI1 || spi_periph == SPI2)
  122. {
  123. spi_src = CK_APB1;
  124. }
  125. else
  126. {
  127. spi_src = CK_APB2;
  128. }
  129. spi_apb_clock = rcu_clock_freq_get(spi_src);
  130. if(max_hz >= spi_apb_clock/2)
  131. {
  132. spi_init_struct.prescale = SPI_PSC_2;
  133. }
  134. else if (max_hz >= spi_apb_clock/4)
  135. {
  136. spi_init_struct.prescale = SPI_PSC_4;
  137. }
  138. else if (max_hz >= spi_apb_clock/8)
  139. {
  140. spi_init_struct.prescale = SPI_PSC_8;
  141. }
  142. else if (max_hz >= spi_apb_clock/16)
  143. {
  144. spi_init_struct.prescale = SPI_PSC_16;
  145. }
  146. else if (max_hz >= spi_apb_clock/32)
  147. {
  148. spi_init_struct.prescale = SPI_PSC_32;
  149. }
  150. else if (max_hz >= spi_apb_clock/64)
  151. {
  152. spi_init_struct.prescale = SPI_PSC_64;
  153. }
  154. else if (max_hz >= spi_apb_clock/128)
  155. {
  156. spi_init_struct.prescale = SPI_PSC_128;
  157. }
  158. else
  159. {
  160. /* min prescaler 256 */
  161. spi_init_struct.prescale = SPI_PSC_256;
  162. }
  163. } /* baudrate */
  164. switch(configuration->mode & RT_SPI_MODE_3)
  165. {
  166. case RT_SPI_MODE_0:
  167. spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
  168. break;
  169. case RT_SPI_MODE_1:
  170. spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
  171. break;
  172. case RT_SPI_MODE_2:
  173. spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
  174. break;
  175. case RT_SPI_MODE_3:
  176. spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
  177. break;
  178. }
  179. /* MSB or LSB */
  180. if(configuration->mode & RT_SPI_MSB)
  181. {
  182. spi_init_struct.endian = SPI_ENDIAN_MSB;
  183. }
  184. else
  185. {
  186. spi_init_struct.endian = SPI_ENDIAN_LSB;
  187. }
  188. spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
  189. spi_init_struct.device_mode = SPI_MASTER;
  190. spi_init_struct.nss = SPI_NSS_SOFT;
  191. spi_crc_off(spi_periph);
  192. /* init SPI */
  193. spi_init(spi_periph, &spi_init_struct);
  194. /* Enable SPI_MASTER */
  195. spi_enable(spi_periph);
  196. return RT_EOK;
  197. };
  198. static rt_uint32_t spixfer(struct rt_spi_device* device, struct rt_spi_message* message)
  199. {
  200. struct rt_spi_bus * gd32_spi_bus = (struct rt_spi_bus *)device->bus;
  201. struct gd32_spi *spi_device = (struct gd32_spi *)gd32_spi_bus->parent.user_data;
  202. struct rt_spi_configuration * config = &device->config;
  203. struct gd32_spi_cs * gd32_spi_cs = device->parent.user_data;
  204. uint32_t spi_periph = spi_device->spi_periph;
  205. RT_ASSERT(device != NULL);
  206. RT_ASSERT(message != NULL);
  207. /* take CS */
  208. if(message->cs_take)
  209. {
  210. gpio_bit_reset(gd32_spi_cs->GPIOx, gd32_spi_cs->GPIO_Pin);
  211. LOG_D("spi take cs\n");
  212. }
  213. {
  214. if(config->data_width <= 8)
  215. {
  216. const rt_uint8_t * send_ptr = message->send_buf;
  217. rt_uint8_t * recv_ptr = message->recv_buf;
  218. rt_uint32_t size = message->length;
  219. LOG_D("spi poll transfer start: %d\n", size);
  220. while(size--)
  221. {
  222. rt_uint8_t data = 0xFF;
  223. if(send_ptr != RT_NULL)
  224. {
  225. data = *send_ptr++;
  226. }
  227. // Todo: replace register read/write by gd32f4 lib
  228. //Wait until the transmit buffer is empty
  229. while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
  230. // Send the byte
  231. spi_i2s_data_transmit(spi_periph, data);
  232. //Wait until a data is received
  233. while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
  234. // Get the received data
  235. data = spi_i2s_data_receive(spi_periph);
  236. if(recv_ptr != RT_NULL)
  237. {
  238. *recv_ptr++ = data;
  239. }
  240. }
  241. LOG_D("spi poll transfer finsh\n");
  242. }
  243. else if(config->data_width <= 16)
  244. {
  245. const rt_uint16_t * send_ptr = message->send_buf;
  246. rt_uint16_t * recv_ptr = message->recv_buf;
  247. rt_uint32_t size = message->length;
  248. while(size--)
  249. {
  250. rt_uint16_t data = 0xFF;
  251. if(send_ptr != RT_NULL)
  252. {
  253. data = *send_ptr++;
  254. }
  255. //Wait until the transmit buffer is empty
  256. while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
  257. // Send the byte
  258. spi_i2s_data_transmit(spi_periph, data);
  259. //Wait until a data is received
  260. while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
  261. // Get the received data
  262. data = spi_i2s_data_receive(spi_periph);
  263. if(recv_ptr != RT_NULL)
  264. {
  265. *recv_ptr++ = data;
  266. }
  267. }
  268. }
  269. }
  270. /* release CS */
  271. if(message->cs_release)
  272. {
  273. gpio_bit_set(gd32_spi_cs->GPIOx, gd32_spi_cs->GPIO_Pin);
  274. LOG_D("spi release cs\n");
  275. }
  276. return message->length;
  277. };
  278. int rt_hw_spi_init(void)
  279. {
  280. int result = 0;
  281. int i;
  282. for (i = 0; i < sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0]); i++)
  283. {
  284. spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i];
  285. result = rt_spi_bus_register(spi_bus_obj[i].spi_bus, spi_bus_obj[i].bus_name, &gd32_spi_ops);
  286. RT_ASSERT(result == RT_EOK);
  287. LOG_D("%s bus init done", spi_bus_obj[i].bus_name);
  288. }
  289. return result;
  290. }
  291. INIT_BOARD_EXPORT(rt_hw_spi_init);
  292. #endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 */
  293. #endif /* RT_USING_SPI */