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