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-06 BalanceTWK first version
9 * 2022-04-16 wolfJane fix spixfer, add time out check
10 */
11
12 #include <board.h>
13 #include <rtthread.h>
14 #include <rtdevice.h>
15
16 #ifdef RT_USING_SPI
17 #ifdef BSP_USING_SPI
18
19 #if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6)
20
21 #include "drv_spi.h"
22 #define DRV_DEBUG
23 #define LOG_TAG "drv.spi"
24 #include <drv_log.h>
25
26 #define SPI_TIME_OUT (1000)
27
28 enum
29 {
30 #ifdef BSP_USING_SPI1
31 SPI1_INDEX,
32 #endif
33 #ifdef BSP_USING_SPI2
34 SPI2_INDEX,
35 #endif
36 #ifdef BSP_USING_SPI3
37 SPI3_INDEX,
38 #endif
39 #ifdef BSP_USING_SPI4
40 SPI4_INDEX,
41 #endif
42 #ifdef BSP_USING_SPI5
43 SPI5_INDEX,
44 #endif
45 #ifdef BSP_USING_SPI6
46 SPI6_INDEX,
47 #endif
48 };
49
50 struct n32_spi_config
51 {
52 SPI_Module *module;
53 char *bus_name;
54 };
55 /* n32 spi dirver class */
56 struct n32_spi
57 {
58 SPI_InitType SPI_InitStructure;
59 struct n32_spi_config *config;
60 struct rt_spi_configuration *cfg;
61
62 struct rt_spi_bus spi_bus;
63 };
64
65 static struct n32_spi_config spi_config[] =
66 {
67 #ifdef BSP_USING_SPI1
68 {
69 .module = SPI1,
70 .bus_name = "spi1",
71 },
72 #endif
73
74 #ifdef BSP_USING_SPI2
75 {
76 .module = SPI2,
77 .bus_name = "spi2",
78 },
79 #endif
80
81 #ifdef BSP_USING_SPI3
82 {
83 .module = SPI3,
84 .bus_name = "spi3",
85 },
86 #endif
87
88 };
89
90 static struct n32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
91
n32_spi_init(struct n32_spi * spi_drv,struct rt_spi_configuration * cfg)92 static rt_err_t n32_spi_init(struct n32_spi *spi_drv, struct rt_spi_configuration *cfg)
93 {
94 RT_ASSERT(spi_drv != RT_NULL);
95 RT_ASSERT(cfg != RT_NULL);
96
97 SPI_InitType *SPI_InitStructure = &spi_drv->SPI_InitStructure;
98 SPI_Module *spi_handle = spi_drv->config->module;
99
100 /* GPIO configuration ------------------------------------------------------*/
101 n32_msp_spi_init(spi_drv->config->module);
102
103 if (cfg->mode & RT_SPI_SLAVE)
104 {
105 /* SPI_InitStructure->SpiMode = SPI_MODE_SLAVE; */
106 return -RT_ERROR;
107 }
108 else
109 {
110 SPI_InitStructure->SpiMode = SPI_MODE_MASTER;
111 }
112
113 if (cfg->mode & RT_SPI_3WIRE)
114 {
115 SPI_InitStructure->DataDirection = SPI_DIR_SINGLELINE_TX;
116 }
117 else
118 {
119 SPI_InitStructure->DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
120 }
121
122 if (cfg->data_width == 8)
123 {
124 SPI_InitStructure->DataLen = SPI_DATA_SIZE_8BITS;
125 }
126 else if (cfg->data_width == 16)
127 {
128 SPI_InitStructure->DataLen = SPI_DATA_SIZE_16BITS;
129 }
130 else
131 {
132 return -RT_EIO;
133 }
134
135 if (cfg->mode & RT_SPI_CPHA)
136 {
137 SPI_InitStructure->CLKPHA = SPI_CLKPHA_SECOND_EDGE;
138 }
139 else
140 {
141 SPI_InitStructure->CLKPHA = SPI_CLKPHA_FIRST_EDGE;
142 }
143
144 if (cfg->mode & RT_SPI_CPOL)
145 {
146 SPI_InitStructure->CLKPOL = SPI_CLKPOL_HIGH;
147 }
148 else
149 {
150 SPI_InitStructure->CLKPOL = SPI_CLKPOL_LOW;
151 }
152
153 if (cfg->mode & RT_SPI_NO_CS)
154 {
155 SPI_InitStructure->NSS = SPI_NSS_HARD;
156 }
157 else
158 {
159 SPI_InitStructure->NSS = SPI_NSS_SOFT;
160 }
161
162 RCC_ClocksType RCC_Clock;
163 RCC_GetClocksFreqValue(&RCC_Clock);
164 rt_uint64_t SPI_APB_CLOCK;
165
166 if (SPI1 == spi_handle)
167 {
168 SPI_APB_CLOCK = RCC_Clock.Pclk1Freq;
169 }
170 else if (SPI2 == spi_handle || SPI3 == spi_handle)
171 {
172 SPI_APB_CLOCK = RCC_Clock.Pclk2Freq;
173 }
174
175 if (cfg->max_hz >= SPI_APB_CLOCK / 2)
176 {
177 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_2;
178 }
179 else if (cfg->max_hz >= SPI_APB_CLOCK / 4)
180 {
181 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_4;
182 }
183 else if (cfg->max_hz >= SPI_APB_CLOCK / 8)
184 {
185 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_8;
186 }
187 else if (cfg->max_hz >= SPI_APB_CLOCK / 16)
188 {
189 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_16;
190 }
191 else if (cfg->max_hz >= SPI_APB_CLOCK / 32)
192 {
193 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_32;
194 }
195 else if (cfg->max_hz >= SPI_APB_CLOCK / 64)
196 {
197 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_64;
198 }
199 else if (cfg->max_hz >= SPI_APB_CLOCK / 128)
200 {
201 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_128;
202 }
203 else
204 {
205 SPI_InitStructure->BaudRatePres = SPI_BR_PRESCALER_256;
206 }
207
208 if (cfg->mode & RT_SPI_MSB)
209 {
210 SPI_InitStructure->FirstBit = SPI_FB_MSB;
211 }
212 else
213 {
214 SPI_InitStructure->FirstBit = SPI_FB_LSB;
215 }
216
217 SPI_InitStructure->CRCPoly = 7;
218
219 SPI_Init(spi_handle, SPI_InitStructure);
220 /* Enable SPI_MASTER TXE interrupt */
221 SPI_I2S_EnableInt(spi_handle, SPI_I2S_INT_TE, ENABLE);
222
223 /* Enable SPI_MASTER */
224 SPI_Enable(spi_handle, ENABLE);
225
226 return RT_EOK;
227 }
228
spi_configure(struct rt_spi_device * device,struct rt_spi_configuration * configuration)229 static rt_err_t spi_configure(struct rt_spi_device *device,
230 struct rt_spi_configuration *configuration)
231 {
232 RT_ASSERT(device != RT_NULL);
233 RT_ASSERT(configuration != RT_NULL);
234
235 struct n32_spi *spi_drv = rt_container_of(device->bus, struct n32_spi, spi_bus);
236 spi_drv->cfg = configuration;
237
238 return n32_spi_init(spi_drv, configuration);
239 }
240
_spi_recv(SPI_Module * hspi,uint8_t * tx_buff,uint8_t * rx_buff,uint32_t length,uint32_t timeout)241 static rt_ssize_t _spi_recv(SPI_Module *hspi,
242 uint8_t *tx_buff,
243 uint8_t *rx_buff,
244 uint32_t length,
245 uint32_t timeout)
246 {
247 /* Init tickstart for timeout management*/
248 uint32_t tickstart = rt_tick_get();
249 uint8_t dat = 0;
250
251 if ((tx_buff == RT_NULL) && (rx_buff == RT_NULL) || (length == 0))
252 {
253 return -RT_EIO;
254 }
255
256 while (length--)
257 {
258 while (SPI_I2S_GetStatus(hspi, SPI_I2S_TE_FLAG) == RESET)
259 {
260 if ((rt_tick_get() - tickstart) > timeout)
261 {
262 return -RT_ETIMEOUT;
263 }
264 }
265 SPI_I2S_TransmitData(hspi, *tx_buff++);
266
267 while (SPI_I2S_GetStatus(hspi, SPI_I2S_RNE_FLAG) == RESET)
268 {
269 if ((rt_tick_get() - tickstart) > timeout)
270 {
271 return -RT_ETIMEOUT;
272 }
273 }
274 dat = SPI_I2S_ReceiveData(hspi);
275
276 if (rx_buff)
277 {
278 *rx_buff++ = dat;
279 }
280 }
281 return RT_EOK;
282 }
283
spixfer(struct rt_spi_device * device,struct rt_spi_message * message)284 static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
285 {
286 rt_size_t send_length;
287 rt_uint8_t *recv_buf;
288 const rt_uint8_t *send_buf;
289 rt_ssize_t stat = RT_EOK;
290
291 /* Check Direction parameter */
292 RT_ASSERT(device != RT_NULL);
293 RT_ASSERT(device->bus != RT_NULL);
294 RT_ASSERT(device->bus->parent.user_data != RT_NULL);
295 RT_ASSERT(message != RT_NULL);
296
297 struct n32_spi *spi_drv = rt_container_of(device->bus, struct n32_spi, spi_bus);
298 struct n32_hw_spi_cs *cs = device->parent.user_data;
299 SPI_Module *spi_handle = spi_drv->config->module;
300
301 if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
302 {
303 if (device->config.mode & RT_SPI_CS_HIGH)
304 {
305 GPIO_SetBits(cs->module, cs->pin);
306 }
307 else
308 {
309 GPIO_ResetBits(cs->module, cs->pin);
310 }
311 }
312
313 send_length = message->length;
314 recv_buf = message->recv_buf;
315 send_buf = message->send_buf;
316
317 /* start once data exchange in DMA mode */
318 if (message->send_buf && message->recv_buf)
319 {
320 LOG_D("%s:%d", __FUNCTION__, __LINE__);
321 stat = -RT_EIO;
322 }
323 else if (message->send_buf)
324 {
325 stat = _spi_recv(spi_handle,
326 (uint8_t *)send_buf,
327 RT_NULL,
328 send_length,
329 SPI_TIME_OUT);
330 }
331 else
332 {
333 rt_memset(recv_buf, 0xff, send_length);
334 stat = _spi_recv(spi_handle,
335 (uint8_t *)recv_buf,
336 (uint8_t *)recv_buf,
337 send_length,
338 SPI_TIME_OUT);
339 }
340
341 if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
342 {
343 if (device->config.mode & RT_SPI_CS_HIGH)
344 {
345 GPIO_ResetBits(cs->module, cs->pin);
346 }
347 else
348 {
349 GPIO_SetBits(cs->module, cs->pin);
350 }
351 }
352
353 if (stat != RT_EOK)
354 {
355 send_length = 0;
356 }
357
358 return send_length;
359 }
360
361 static const struct rt_spi_ops n32_spi_ops =
362 {
363 .configure = spi_configure,
364 .xfer = spixfer,
365 };
366
rt_hw_spi_bus_init(void)367 static int rt_hw_spi_bus_init(void)
368 {
369 rt_err_t result;
370 for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
371 {
372 spi_bus_obj[i].config = &spi_config[i];
373 spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
374 result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &n32_spi_ops);
375 RT_ASSERT(result == RT_EOK);
376
377 LOG_D("%s bus init done", spi_config[i].bus_name);
378 }
379
380 return result;
381 }
rt_hw_spi_init(void)382 int rt_hw_spi_init(void)
383 {
384 /* TODO: n32_get_dma_info(); */
385 return rt_hw_spi_bus_init();
386 }
387 INIT_BOARD_EXPORT(rt_hw_spi_init);
388
389
390 /**
391 * Attach the spi device to SPI bus, this function must be used after initialization.
392 */
rt_hw_spi_device_attach(const char * bus_name,const char * device_name,GPIO_Module * cs_gpiox,uint32_t cs_gpio_pin)393 rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_Module *cs_gpiox, uint32_t cs_gpio_pin)
394 {
395 rt_err_t result;
396 struct rt_spi_device *spi_device;
397 struct n32_hw_spi_cs *cs_pin;
398 GPIO_InitType GPIO_InitStructure;
399
400 RT_ASSERT(bus_name != RT_NULL);
401 RT_ASSERT(device_name != RT_NULL);
402
403
404 /* Enable the GPIO Clock */
405 if (cs_gpiox == GPIOA)
406 {
407 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
408 }
409 else if (cs_gpiox == GPIOB)
410 {
411 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
412 }
413 else if (cs_gpiox == GPIOC)
414 {
415 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);
416 }
417 else if (cs_gpiox == GPIOD)
418 {
419 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE);
420 }
421 else if (cs_gpiox == GPIOE)
422 {
423 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOE, ENABLE);
424 }
425 else if (cs_gpiox == GPIOF)
426 {
427 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOF, ENABLE);
428 }
429 else if (cs_gpiox == GPIOG)
430 {
431 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOG, ENABLE);
432 }
433
434 /* Configure the GPIO pin */
435 if (cs_gpio_pin <= GPIO_PIN_ALL)
436 {
437 GPIO_InitStructure.Pin = cs_gpio_pin;
438 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
439 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
440 GPIO_InitPeripheral(cs_gpiox, &GPIO_InitStructure);
441 }
442
443 /* attach the device to spi bus*/
444 spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
445 RT_ASSERT(spi_device != RT_NULL);
446 cs_pin = (struct n32_hw_spi_cs *)rt_malloc(sizeof(struct n32_hw_spi_cs));
447 RT_ASSERT(cs_pin != RT_NULL);
448 cs_pin->module = cs_gpiox;
449 cs_pin->pin = cs_gpio_pin;
450
451 result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
452
453 if (result != RT_EOK)
454 {
455 LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
456 }
457
458 RT_ASSERT(result == RT_EOK);
459
460 LOG_D("%s attach to %s done", device_name, bus_name);
461
462 return result;
463 }
464
465 #endif /* BSP_USING_SPIx */
466
467 #endif /* BSP_USING_SPI */
468 #endif /* RT_USING_SPI */
469
470