1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2022-03-04     stevetong459      first version
9  * 2022-07-15     Aligagago         add APM32F4 series MCU support
10  * 2022-12-26     luobeihai         add APM32F0 series MCU support
11  * 2023-03-28     luobeihai         add APM32E1/S1 series MCU support
12  */
13 
14 #include "drv_spi.h"
15 
16 //#define DRV_DEBUG
17 #define LOG_TAG               "drv.spi"
18 #include "drv_log.h"
19 
20 #if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3)
21 
22 static struct apm32_spi_config spi_config[] = {
23 #ifdef BSP_USING_SPI1
24     {SPI1, "spi1"},
25 #endif
26 
27 #ifdef BSP_USING_SPI2
28     {SPI2, "spi2"},
29 #endif
30 
31 #ifdef BSP_USING_SPI3
32     {SPI3, "spi3"},
33 #endif
34 };
35 
36 static struct apm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
37 
38 /**
39   * Attach the spi device to SPI bus, this function must be used after initialization.
40   */
rt_hw_spi_device_attach(const char * bus_name,const char * device_name,GPIO_T * cs_gpiox,uint16_t cs_gpio_pin)41 rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_T *cs_gpiox, uint16_t cs_gpio_pin)
42 {
43     RT_ASSERT(bus_name != RT_NULL);
44     RT_ASSERT(device_name != RT_NULL);
45 
46     rt_err_t result;
47     struct rt_spi_device *spi_device;
48     struct apm32_spi_cs *cs_pin;
49     GPIO_Config_T GPIO_InitStructure;
50 
51     /* initialize the cs pin && select the slave */
52 #if defined(SOC_SERIES_APM32F0)
53     GPIO_ConfigStructInit(&GPIO_InitStructure);
54     GPIO_InitStructure.pin = cs_gpio_pin;
55     GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
56     GPIO_InitStructure.mode = GPIO_MODE_OUT;
57     GPIO_InitStructure.outtype = GPIO_OUT_TYPE_PP;
58     GPIO_InitStructure.pupd = GPIO_PUPD_NO;
59     GPIO_Config(cs_gpiox, &GPIO_InitStructure);
60     GPIO_WriteBitValue(cs_gpiox, cs_gpio_pin, Bit_SET);
61 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1)
62     GPIO_ConfigStructInit(&GPIO_InitStructure);
63     GPIO_InitStructure.pin = cs_gpio_pin;
64     GPIO_InitStructure.mode = GPIO_MODE_OUT_PP;
65     GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
66     GPIO_Config(cs_gpiox, &GPIO_InitStructure);
67     GPIO_WriteBitValue(cs_gpiox, cs_gpio_pin, BIT_SET);
68 #elif defined(SOC_SERIES_APM32F4)
69     GPIO_ConfigStructInit(&GPIO_InitStructure);
70     GPIO_InitStructure.pin = cs_gpio_pin;
71     GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
72     GPIO_InitStructure.mode = GPIO_MODE_OUT;
73     GPIO_InitStructure.otype = GPIO_OTYPE_PP;
74     GPIO_InitStructure.pupd = GPIO_PUPD_NOPULL;
75     GPIO_Config(cs_gpiox, &GPIO_InitStructure);
76     GPIO_WriteBitValue(cs_gpiox, cs_gpio_pin, BIT_SET);
77 #endif
78 
79     /* attach the device to spi bus */
80     spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
81     RT_ASSERT(spi_device != RT_NULL);
82     cs_pin = (struct apm32_spi_cs *)rt_malloc(sizeof(struct apm32_spi_cs));
83     RT_ASSERT(cs_pin != RT_NULL);
84     cs_pin->GPIOx = cs_gpiox;
85     cs_pin->GPIO_Pin = cs_gpio_pin;
86     result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
87 
88     if (result != RT_EOK)
89     {
90         LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
91     }
92 
93     RT_ASSERT(result == RT_EOK);
94 
95     LOG_D("%s attach to %s done", device_name, bus_name);
96 
97     return result;
98 }
99 
apm32_spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * cfg)100 static rt_err_t apm32_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
101 {
102     RT_ASSERT(device != RT_NULL);
103     RT_ASSERT(cfg != RT_NULL);
104 
105     SPI_Config_T hw_spi_config;
106 
107     struct rt_spi_bus * apm32_spi_bus = (struct rt_spi_bus *)device->bus;
108     struct apm32_spi *spi_device = (struct apm32_spi *)apm32_spi_bus->parent.user_data;
109     SPI_T *spi = spi_device->config->spi_x;
110 
111     uint32_t hw_spi_apb_clock;
112 #if (DBG_LVL == DBG_LOG)
113     uint32_t hw_spi_sys_clock = RCM_ReadSYSCLKFreq();
114 #endif
115 
116     /* apm32 spi gpio init and enable clock */
117     extern void apm32_msp_spi_init(void *Instance);
118     apm32_msp_spi_init(spi);
119 
120     /* apm32 spi init */
121     hw_spi_config.mode = (cfg->mode & RT_SPI_SLAVE) ? SPI_MODE_SLAVE : SPI_MODE_MASTER;
122     hw_spi_config.direction = (cfg->mode & RT_SPI_3WIRE) ? SPI_DIRECTION_1LINE_RX : SPI_DIRECTION_2LINES_FULLDUPLEX;
123     hw_spi_config.phase = (cfg->mode & RT_SPI_CPHA) ? SPI_CLKPHA_2EDGE : SPI_CLKPHA_1EDGE;
124     hw_spi_config.polarity = (cfg->mode & RT_SPI_CPOL) ? SPI_CLKPOL_HIGH : SPI_CLKPOL_LOW;
125 #if defined(SOC_SERIES_APM32F0)
126     hw_spi_config.slaveSelect = (cfg->mode & RT_SPI_NO_CS) ? SPI_SSC_DISABLE : SPI_SSC_ENABLE;
127     hw_spi_config.firstBit = (cfg->mode & RT_SPI_MSB) ? SPI_FIRST_BIT_MSB : SPI_FIRST_BIT_LSB;
128 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
129     || defined(SOC_SERIES_APM32F4)
130     hw_spi_config.nss = (cfg->mode & RT_SPI_NO_CS) ? SPI_NSS_HARD : SPI_NSS_SOFT;
131     hw_spi_config.firstBit = (cfg->mode & RT_SPI_MSB) ? SPI_FIRSTBIT_MSB : SPI_FIRSTBIT_LSB;
132 #endif
133 
134     if (cfg->data_width == 8)
135     {
136         hw_spi_config.length = SPI_DATA_LENGTH_8B;
137     }
138     else if (cfg->data_width == 16)
139     {
140         hw_spi_config.length = SPI_DATA_LENGTH_16B;
141     }
142     else
143     {
144         return -RT_EIO;
145     }
146 
147 #if defined(SOC_SERIES_APM32F0)
148     hw_spi_apb_clock = RCM_ReadPCLKFreq();
149 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
150     || defined(SOC_SERIES_APM32F4)
151     if (spi == SPI1)
152     {
153         RCM_ReadPCLKFreq(NULL, &hw_spi_apb_clock);
154     }
155     else
156     {
157         RCM_ReadPCLKFreq(&hw_spi_apb_clock, NULL);
158     }
159 #endif
160 
161     if (cfg->max_hz >= hw_spi_apb_clock / 2)
162     {
163         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_2;
164     }
165     else if (cfg->max_hz >= hw_spi_apb_clock / 4)
166     {
167         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_4;
168     }
169     else if (cfg->max_hz >= hw_spi_apb_clock / 8)
170     {
171         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_8;
172     }
173     else if (cfg->max_hz >= hw_spi_apb_clock / 16)
174     {
175         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_16;
176     }
177     else if (cfg->max_hz >= hw_spi_apb_clock / 32)
178     {
179         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_32;
180     }
181     else if (cfg->max_hz >= hw_spi_apb_clock / 64)
182     {
183         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_64;
184     }
185     else if (cfg->max_hz >= hw_spi_apb_clock / 128)
186     {
187         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_128;
188     }
189     else
190     {
191         /* min prescaler 256 */
192         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_256;
193     }
194 
195     LOG_D("sys freq: %d, pclk2 freq: %d, SPI limiting freq: %d, BaudRatePrescaler: %d",
196           hw_spi_sys_clock, hw_spi_apb_clock, cfg->max_hz, hw_spi_config.baudrateDiv);
197 
198 #if defined(SOC_SERIES_APM32F0)
199     SPI_DisableCRC(spi);
200     SPI_EnableSSoutput(spi);
201     SPI_ConfigFIFOThreshold(spi, SPI_RXFIFO_QUARTER);
202 #endif
203 
204     SPI_Config(spi, &hw_spi_config);
205     SPI_Enable(spi);
206 
207     return RT_EOK;
208 }
209 
apm32_spi_xfer(struct rt_spi_device * device,struct rt_spi_message * message)210 static rt_ssize_t apm32_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
211 {
212     RT_ASSERT(device != NULL);
213     RT_ASSERT(message != NULL);
214 
215     struct rt_spi_configuration *config = &device->config;
216 
217     struct apm32_spi_cs *cs = device->parent.user_data;
218 
219     struct rt_spi_bus * apm32_spi_bus = (struct rt_spi_bus *)device->bus;
220     struct apm32_spi *spi_device = (struct apm32_spi *)apm32_spi_bus->parent.user_data;
221     SPI_T *spi = spi_device->config->spi_x;
222 
223     /* take CS */
224     if (message->cs_take)
225     {
226 #if defined(SOC_SERIES_APM32F0)
227         GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, (GPIO_BSRET_T)RESET);
228 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
229     || defined(SOC_SERIES_APM32F4)
230         GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, RESET);
231 #endif
232         LOG_D("spi take cs\n");
233     }
234 
235     if (config->data_width <= 8)
236     {
237         const rt_uint8_t *send_ptr = message->send_buf;
238         rt_uint8_t *recv_ptr = message->recv_buf;
239         rt_uint32_t size = message->length;
240 
241         LOG_D("spi poll transfer start: %d\n", size);
242 
243         while (size--)
244         {
245             rt_uint8_t data = 0xFF;
246 
247             if (send_ptr != RT_NULL)
248             {
249                 data = *send_ptr++;
250             }
251 
252 #if defined(SOC_SERIES_APM32F0)
253             /* Wait until the transmit buffer is empty */
254             while (SPI_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
255             SPI_TxData8(spi, data);
256 
257             /* Wait until a data is received */
258             while (SPI_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
259             data = SPI_RxData8(spi);
260 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32F4)
261             /* Wait until the transmit buffer is empty */
262             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
263             SPI_I2S_TxData(spi, data);
264 
265             /* Wait until a data is received */
266             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
267             data = SPI_I2S_RxData(spi);
268 #elif defined(SOC_SERIES_APM32S1)
269             /* Wait until the transmit buffer is empty */
270             while (SPI_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
271             SPI_TxData(spi, data);
272 
273             /* Wait until a data is received */
274             while (SPI_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
275             data = SPI_RxData(spi);
276 #endif
277 
278             if (recv_ptr != RT_NULL)
279             {
280                 *recv_ptr++ = data;
281             }
282         }
283         LOG_D("spi poll transfer finsh\n");
284     }
285     else if (config->data_width <= 16)
286     {
287         const rt_uint16_t *send_ptr = message->send_buf;
288         rt_uint16_t *recv_ptr = message->recv_buf;
289         rt_uint32_t size = message->length;
290 
291         while (size--)
292         {
293             rt_uint16_t data = 0xFF;
294 
295             if (send_ptr != RT_NULL)
296             {
297                 data = *send_ptr++;
298             }
299 
300 #if defined(SOC_SERIES_APM32F0)
301             /* Wait until the transmit buffer is empty */
302             while (SPI_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
303             SPI_I2S_TxData16(spi, data);
304 
305             /* Wait until a data is received */
306             while (SPI_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
307             data = SPI_I2S_RxData16(spi);
308 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32F4)
309             /* Wait until the transmit buffer is empty */
310             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
311             /* Send the byte */
312             SPI_I2S_TxData(spi, data);
313 
314             /* Wait until a data is received */
315             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
316             /* Get the received data */
317             data = SPI_I2S_RxData(spi);
318 #elif defined(SOC_SERIES_APM32S1)
319             /* Wait until the transmit buffer is empty */
320             while (SPI_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
321             /* Send the byte */
322             SPI_TxData(spi, data);
323 
324             /* Wait until a data is received */
325             while (SPI_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
326             /* Get the received data */
327             data = SPI_RxData(spi);
328 #endif
329 
330             if (recv_ptr != RT_NULL)
331             {
332                 *recv_ptr++ = data;
333             }
334         }
335     }
336 
337     /* release CS */
338     if (message->cs_release)
339     {
340 #if defined(SOC_SERIES_APM32F0)
341         GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, (GPIO_BSRET_T)SET);
342 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
343     || defined(SOC_SERIES_APM32F4)
344         GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, SET);
345 #endif
346         LOG_D("spi release cs\n");
347     }
348 
349     return message->length;
350 };
351 
352 static const struct rt_spi_ops apm32_spi_ops =
353 {
354     apm32_spi_configure,
355     apm32_spi_xfer
356 };
357 
rt_hw_spi_init(void)358 static int rt_hw_spi_init(void)
359 {
360     rt_err_t result;
361 
362     for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
363     {
364         spi_bus_obj[i].config = &spi_config[i];
365         spi_bus_obj[i].spi_bus.parent.user_data = (void *)&spi_bus_obj[i];
366         result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].spi_bus_name, &apm32_spi_ops);
367         RT_ASSERT(result == RT_EOK);
368 
369         LOG_D("%s bus init done", spi_config[i].spi_bus_name);
370     }
371 
372     return result;
373 }
374 INIT_BOARD_EXPORT(rt_hw_spi_init);
375 
376 #endif /* RT_USING_SPI */
377