1 /*
2  * Copyright (c) 2006-2025, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-12-20     BruceOu      first implementation
9  */
10 #include "drv_spi.h"
11 
12 #ifdef RT_USING_SPI
13 
14 #if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4)
15 #define LOG_TAG              "drv.spi"
16 
17 #include <rtdbg.h>
18 
19 #ifdef BSP_USING_SPI0
20 static struct rt_spi_bus spi_bus0;
21 #endif
22 #ifdef BSP_USING_SPI1
23 static struct rt_spi_bus spi_bus1;
24 #endif
25 #ifdef BSP_USING_SPI2
26 static struct rt_spi_bus spi_bus2;
27 #endif
28 #ifdef BSP_USING_SPI3
29 static struct rt_spi_bus spi_bus3;
30 #endif
31 #ifdef BSP_USING_SPI4
32 static struct rt_spi_bus spi_bus4;
33 #endif
34 
35 static const struct gd32_spi spi_bus_obj[] = {
36 
37 #ifdef BSP_USING_SPI0
38     {
39         SPI0,
40         "spi0",
41         RCU_SPI0,
42         RCU_GPIOA,
43         &spi_bus0,
44         GPIOA,
45 #if defined SOC_SERIES_GD32F4xx
46         GPIO_AF_5,
47 #endif
48 #if defined SOC_SERIES_GD32E23x
49         GPIO_AF_0,
50 #endif
51         GPIO_PIN_5,
52         GPIO_PIN_6,
53         GPIO_PIN_7,
54     },
55 #endif /* BSP_USING_SPI0 */
56 
57 #ifdef BSP_USING_SPI1
58     {
59         SPI1,
60         "spi1",
61         RCU_SPI1,
62         RCU_GPIOB,
63         &spi_bus1,
64         GPIOB,
65 #if defined SOC_SERIES_GD32F4xx
66         GPIO_AF_5,
67 #endif
68 #if defined SOC_SERIES_GD32E23x
69         GPIO_AF_0,
70 #endif
71 
72 #if defined SOC_SERIES_GD32E23x
73         GPIO_PIN_13,
74 #else
75         GPIO_PIN_12,
76 #endif
77         GPIO_PIN_14,
78         GPIO_PIN_15,
79     },
80 #endif /* BSP_USING_SPI1 */
81 
82 #ifdef BSP_USING_SPI2
83     {
84         SPI2,
85         "spi2",
86         RCU_SPI2,
87         RCU_GPIOB,
88         &spi_bus2,
89         GPIOB,
90 #if defined SOC_SERIES_GD32F4xx
91         GPIO_AF_6,
92 #endif
93         GPIO_PIN_3,
94         GPIO_PIN_4,
95         GPIO_PIN_5,
96     },
97 #endif /* BSP_USING_SPI2 */
98 
99 #ifdef BSP_USING_SPI3
100     {
101         SPI3,
102         "spi3",
103         RCU_SPI3,
104         RCU_GPIOE,
105         &spi_bus3,
106         GPIOB,
107 #if defined SOC_SERIES_GD32F4xx
108         GPIO_AF_5,
109 #endif
110         GPIO_PIN_2,
111         GPIO_PIN_5,
112         GPIO_PIN_6,
113     },
114 #endif /* BSP_USING_SPI3 */
115 
116 #ifdef BSP_USING_SPI4
117     {
118         SPI4,
119         "spi4",
120         RCU_SPI4,
121         RCU_GPIOF,
122         &spi_bus4,
123         GPIOF,
124 #if defined SOC_SERIES_GD32F4xx
125         GPIO_AF_5,
126 #endif
127         GPIO_PIN_7,
128         GPIO_PIN_8,
129         GPIO_PIN_9,
130     }
131 #endif /* BSP_USING_SPI4 */
132 };
133 
134 /* private rt-thread spi ops function */
135 static rt_err_t spi_configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
136 static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* message);
137 
138 static struct rt_spi_ops gd32_spi_ops =
139 {
140     .configure = spi_configure,
141     .xfer = spixfer,
142 };
143 
144 /**
145 * @brief SPI Initialization
146 * @param gd32_spi: SPI BUS
147 * @retval None
148 */
gd32_spi_init(struct gd32_spi * gd32_spi)149 static void gd32_spi_init(struct gd32_spi *gd32_spi)
150 {
151     /* enable SPI clock */
152     rcu_periph_clock_enable(gd32_spi->spi_clk);
153     rcu_periph_clock_enable(gd32_spi->gpio_clk);
154 
155 #if defined SOC_SERIES_GD32F4xx || defined SOC_SERIES_GD32E23x
156     /*GPIO pin configuration*/
157     gpio_af_set(gd32_spi->spi_port, gd32_spi->alt_func_num, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
158 
159     gpio_mode_set(gd32_spi->spi_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
160     #if defined SOC_SERIES_GD32E23x
161     gpio_output_options_set(gd32_spi->spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
162     #else
163     gpio_output_options_set(gd32_spi->spi_port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, gd32_spi->sck_pin | gd32_spi->mosi_pin | gd32_spi->miso_pin);
164     #endif
165 #else
166     /* Init SPI SCK MOSI */
167     gpio_init(gd32_spi->spi_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, gd32_spi->sck_pin | gd32_spi->mosi_pin);
168 
169     /* Init SPI MISO */
170     gpio_init(gd32_spi->spi_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, gd32_spi->miso_pin);
171 #endif
172 
173 }
174 
spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * configuration)175 static rt_err_t spi_configure(struct rt_spi_device* device,
176                           struct rt_spi_configuration* configuration)
177 {
178     struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus;
179     struct gd32_spi *spi_device = (struct gd32_spi *)spi_bus->parent.user_data;
180     spi_parameter_struct spi_init_struct;
181     uint32_t spi_periph = spi_device->spi_periph;
182 
183     RT_ASSERT(device != RT_NULL);
184     RT_ASSERT(configuration != RT_NULL);
185 
186     /* Init SPI */
187     gd32_spi_init(spi_device);
188 
189     /* data_width */
190     if(configuration->data_width <= 8)
191     {
192         spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
193     }
194     else if(configuration->data_width <= 16)
195     {
196         spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT;
197     }
198     else
199     {
200         return -RT_EIO;
201     }
202 
203     /* baudrate */
204     {
205         rcu_clock_freq_enum spi_src;
206         uint32_t spi_apb_clock;
207         uint32_t max_hz;
208 
209         max_hz = configuration->max_hz;
210 
211         LOG_D("sys   freq: %d\n", rcu_clock_freq_get(CK_SYS));
212         LOG_D("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2));
213         LOG_D("max   freq: %d\n", max_hz);
214 
215         #if defined SOC_SERIES_GD32E23x
216         spi_src = CK_APB2;
217         #else
218         if (spi_periph == SPI1 || spi_periph == SPI2)
219         {
220             spi_src = CK_APB1;
221         }
222         else
223         {
224             spi_src = CK_APB2;
225         }
226         #endif
227         spi_apb_clock = rcu_clock_freq_get(spi_src);
228 
229         if(max_hz >= spi_apb_clock/2)
230         {
231             spi_init_struct.prescale = SPI_PSC_2;
232         }
233         else if (max_hz >= spi_apb_clock/4)
234         {
235             spi_init_struct.prescale = SPI_PSC_4;
236         }
237         else if (max_hz >= spi_apb_clock/8)
238         {
239             spi_init_struct.prescale = SPI_PSC_8;
240         }
241         else if (max_hz >= spi_apb_clock/16)
242         {
243             spi_init_struct.prescale = SPI_PSC_16;
244         }
245         else if (max_hz >= spi_apb_clock/32)
246         {
247             spi_init_struct.prescale = SPI_PSC_32;
248         }
249         else if (max_hz >= spi_apb_clock/64)
250         {
251             spi_init_struct.prescale = SPI_PSC_64;
252         }
253         else if (max_hz >= spi_apb_clock/128)
254         {
255             spi_init_struct.prescale = SPI_PSC_128;
256         }
257         else
258         {
259             /*  min prescaler 256 */
260             spi_init_struct.prescale = SPI_PSC_256;
261         }
262     } /* baudrate */
263 
264     switch(configuration->mode & RT_SPI_MODE_3)
265     {
266     case RT_SPI_MODE_0:
267         spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
268         break;
269     case RT_SPI_MODE_1:
270         spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE;
271         break;
272     case RT_SPI_MODE_2:
273         spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE;
274         break;
275     case RT_SPI_MODE_3:
276         spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
277         break;
278     }
279 
280     /* MSB or LSB */
281     if(configuration->mode & RT_SPI_MSB)
282     {
283         spi_init_struct.endian = SPI_ENDIAN_MSB;
284     }
285     else
286     {
287         spi_init_struct.endian = SPI_ENDIAN_LSB;
288     }
289 
290     spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
291     spi_init_struct.device_mode = SPI_MASTER;
292     spi_init_struct.nss = SPI_NSS_SOFT;
293 
294     spi_crc_off(spi_periph);
295 
296     /* init SPI */
297     spi_init(spi_periph, &spi_init_struct);
298     /* Enable SPI_MASTER */
299     spi_enable(spi_periph);
300 
301     return RT_EOK;
302 };
303 
spixfer(struct rt_spi_device * device,struct rt_spi_message * message)304 static rt_ssize_t spixfer(struct rt_spi_device* device, struct rt_spi_message* message)
305 {
306     struct rt_spi_bus * gd32_spi_bus = (struct rt_spi_bus *)device->bus;
307     struct gd32_spi *spi_device = (struct gd32_spi *)gd32_spi_bus->parent.user_data;
308     struct rt_spi_configuration * config = &device->config;
309     rt_base_t cs_pin = (rt_base_t)device->parent.user_data;
310     uint32_t spi_periph = spi_device->spi_periph;
311 
312     RT_ASSERT(device != NULL);
313     RT_ASSERT(message != NULL);
314 
315     /* take CS */
316     if(message->cs_take)
317     {
318         rt_pin_write(cs_pin, PIN_LOW);
319         LOG_D("spi take cs\n");
320     }
321 
322     {
323         if(config->data_width <= 8)
324         {
325             const rt_uint8_t * send_ptr = message->send_buf;
326             rt_uint8_t * recv_ptr = message->recv_buf;
327             rt_uint32_t size = message->length;
328 
329             LOG_D("spi poll transfer start: %d\n", size);
330 
331             while(size--)
332             {
333                 rt_uint8_t data = 0xFF;
334 
335                 if(send_ptr != RT_NULL)
336                 {
337                     data = *send_ptr++;
338                 }
339 
340                 /* Todo: replace register read/write by gd32f4 lib */
341                 /* Wait until the transmit buffer is empty */
342                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
343                 /* Send the byte */
344                 spi_i2s_data_transmit(spi_periph, data);
345 
346                 /* Wait until a data is received */
347                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
348                 /* Get the received data */
349                 data = spi_i2s_data_receive(spi_periph);
350 
351                 if(recv_ptr != RT_NULL)
352                 {
353                     *recv_ptr++ = data;
354                 }
355             }
356             LOG_D("spi poll transfer finsh\n");
357         }
358         else if(config->data_width <= 16)
359         {
360             const rt_uint16_t * send_ptr = message->send_buf;
361             rt_uint16_t * recv_ptr = message->recv_buf;
362             rt_uint32_t size = message->length;
363 
364             while(size--)
365             {
366                 rt_uint16_t data = 0xFF;
367 
368                 if(send_ptr != RT_NULL)
369                 {
370                     data = *send_ptr++;
371                 }
372 
373                 /* Wait until the transmit buffer is empty */
374                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE));
375                 /* Send the byte */
376                 spi_i2s_data_transmit(spi_periph, data);
377 
378                 /* Wait until a data is received */
379                 while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE));
380                 /* Get the received data */
381                 data = spi_i2s_data_receive(spi_periph);
382 
383                 if(recv_ptr != RT_NULL)
384                 {
385                     *recv_ptr++ = data;
386                 }
387             }
388         }
389     }
390 
391     /* release CS */
392     if(message->cs_release)
393     {
394         rt_pin_write(cs_pin, PIN_HIGH);
395         LOG_D("spi release cs\n");
396     }
397 
398     return message->length;
399 };
400 
401 /**
402   * Attach the spi device to SPI bus, this function must be used after initialization.
403   */
rt_hw_spi_device_attach(const char * bus_name,const char * device_name,rt_base_t cs_pin)404 rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
405 {
406     RT_ASSERT(bus_name != RT_NULL);
407     RT_ASSERT(device_name != RT_NULL);
408 
409     rt_err_t result;
410     struct rt_spi_device *spi_device;
411 
412     /* attach the device to spi bus*/
413     spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
414     RT_ASSERT(spi_device != RT_NULL);
415 
416     if(cs_pin != PIN_NONE)
417     {
418         /* initialize the cs pin && select the slave*/
419         rt_pin_mode(cs_pin, PIN_MODE_OUTPUT);
420         rt_pin_write(cs_pin, PIN_HIGH);
421     }
422 
423     result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
424 
425     if (result != RT_EOK)
426     {
427         LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
428     }
429 
430     RT_ASSERT(result == RT_EOK);
431 
432     LOG_D("%s attach to %s done", device_name, bus_name);
433 
434     return result;
435 }
436 
rt_hw_spi_init(void)437 int rt_hw_spi_init(void)
438 {
439     int result = 0;
440     int i;
441 
442     for (i = 0; i < sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0]); i++)
443     {
444         spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i];
445 
446         result = rt_spi_bus_register(spi_bus_obj[i].spi_bus, spi_bus_obj[i].bus_name, &gd32_spi_ops);
447 
448         RT_ASSERT(result == RT_EOK);
449 
450         LOG_D("%s bus init done", spi_bus_obj[i].bus_name);
451     }
452 
453     return result;
454 }
455 
456 INIT_BOARD_EXPORT(rt_hw_spi_init);
457 
458 #endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4*/
459 #endif /* RT_USING_SPI */
460 
461