1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-05-16 shelton first version
9 */
10
11 #include <rtdevice.h>
12 #include "drv_common.h"
13 #include "drv_qspi.h"
14
15 #ifdef BSP_USING_QSPI
16 #if !defined(BSP_USING_QSPI1) && !defined(BSP_USING_QSPI2)
17 #error "Please define at least one BSP_USING_QSPIx"
18 #endif
19
20 #define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
21 #define QSPI_FIFO_DEPTH (32 * 4)
22
23 #define DRV_DEBUG
24 #define LOG_TAG "drv.qspi"
25 #include <drv_log.h>
26
27 struct at32_qspi_bus
28 {
29 struct rt_spi_bus bus;
30
31 qspi_type *qspi_x;
32 char *bus_name;
33 };
34
35 enum
36 {
37 #ifdef BSP_USING_QSPI1
38 QSPI1_INDEX,
39 #endif
40 #ifdef BSP_USING_QSPI2
41 QSPI2_INDEX,
42 #endif
43 };
44
45 static struct at32_qspi_bus at32_qspi_obj[] =
46 {
47 #ifdef BSP_USING_QSPI1
48 QSPI1_BUS_CONFIG,
49 #endif
50
51 #ifdef BSP_USING_QSPI2
52 QSPI2_BUS_CONFIG,
53 #endif
54 };
55
at32_qspi_init(struct rt_qspi_device * device,struct rt_qspi_configuration * qspi_cfg)56 static int at32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configuration *qspi_cfg)
57 {
58 int result = RT_EOK;
59 unsigned int i = 0;
60 crm_clocks_freq_type clocks;
61 rt_uint8_t qspi_div_tab[] = {2, 4, 6, 8, 3, 5, 10, 12};
62
63 RT_ASSERT(device != RT_NULL);
64 RT_ASSERT(qspi_cfg != RT_NULL);
65
66 struct rt_spi_configuration *cfg = &qspi_cfg->parent;
67 struct at32_qspi_bus *qspi_bus = device->parent.bus->parent.user_data;
68
69 at32_msp_qspi_init(qspi_bus->qspi_x);
70
71 /* switch to cmd port */
72 qspi_xip_enable(qspi_bus->qspi_x, FALSE);
73
74 /* get clocks and config qspi clock div */
75 crm_clocks_freq_get(&clocks);
76
77 while (cfg->max_hz < clocks.ahb_freq / qspi_div_tab[i])
78 {
79 i++;
80 if (i == 8)
81 {
82 LOG_E("qspi init failed, qspi frequency(%d) is too low.", cfg->max_hz);
83 return -RT_ERROR;
84 }
85 }
86 /* set qspi sclk */
87 qspi_clk_division_set(qspi_bus->qspi_x, (qspi_clk_div_type)i);
88
89 if (!(cfg->mode & RT_SPI_CPOL))
90 {
91 /* qspi mode0 */
92 qspi_sck_mode_set(qspi_bus->qspi_x, QSPI_SCK_MODE_0);
93 }
94 else
95 {
96 /* qspi mode3 */
97 qspi_sck_mode_set(qspi_bus->qspi_x, QSPI_SCK_MODE_3);
98 }
99
100 /* flash size */
101 qspi_bus->qspi_x->fsize = POSITION_VAL(qspi_cfg->medium_size) - 1;
102
103 return result;
104 }
105
qspi_send_cmd(struct at32_qspi_bus * qspi_bus,struct rt_qspi_message * message,rt_bool_t dir)106 static void qspi_send_cmd(struct at32_qspi_bus *qspi_bus, struct rt_qspi_message *message, rt_bool_t dir)
107 {
108 qspi_cmd_type cmd;
109
110 RT_ASSERT(qspi_bus != RT_NULL);
111 RT_ASSERT(message != RT_NULL);
112
113 /* set qspi cmd struct */
114 cmd.instruction_code = message->instruction.content;
115 cmd.address_code = message->address.content;
116 cmd.second_dummy_cycle_num = message->dummy_cycles;
117
118 /* address length */
119 if (message->address.size == 0)
120 {
121 cmd.address_length = QSPI_CMD_ADRLEN_0_BYTE;
122 }
123 else if (message->address.size == 8)
124 {
125 cmd.address_length = QSPI_CMD_ADRLEN_1_BYTE;
126 }
127 else if (message->address.size == 16)
128 {
129 cmd.address_length = QSPI_CMD_ADRLEN_2_BYTE;
130 }
131 else if (message->address.size == 24)
132 {
133 cmd.address_length = QSPI_CMD_ADRLEN_3_BYTE;
134 }
135 else if (message->address.size == 32)
136 {
137 cmd.address_length = QSPI_CMD_ADRLEN_4_BYTE;
138 }
139
140 /* instruction length */
141 if (message->instruction.qspi_lines == 0)
142 {
143 cmd.instruction_length = QSPI_CMD_INSLEN_0_BYTE;
144 }
145 else
146 {
147 cmd.instruction_length = QSPI_CMD_INSLEN_1_BYTE;
148 }
149
150 /* operate mode */
151 switch(message->instruction.qspi_lines)
152 {
153 case 0:
154 case 1:
155 {
156 switch(message->address.qspi_lines)
157 {
158 case 0:
159 case 1:
160 {
161 switch(message->qspi_data_lines)
162 {
163 case 1:
164 {
165 cmd.operation_mode = QSPI_OPERATE_MODE_111;
166 break;
167 }
168 case 2:
169 {
170 cmd.operation_mode = QSPI_OPERATE_MODE_112;
171 break;
172 }
173 case 4:
174 {
175 cmd.operation_mode = QSPI_OPERATE_MODE_114;
176 break;
177 }
178 default:
179 {
180 cmd.operation_mode = QSPI_OPERATE_MODE_111;
181 break;
182 }
183 }
184 break;
185 }
186 case 2:
187 {
188 cmd.operation_mode = QSPI_OPERATE_MODE_122;
189 break;
190 }
191 case 4:
192 {
193 cmd.operation_mode = QSPI_OPERATE_MODE_144;
194 break;
195 }
196 }
197 break;
198 }
199 case 2:
200 {
201 cmd.operation_mode = QSPI_OPERATE_MODE_222;
202 break;
203 }
204 case 4:
205 {
206 cmd.operation_mode = QSPI_OPERATE_MODE_444;
207 break;
208 }
209 default:
210 {
211 cmd.operation_mode = QSPI_OPERATE_MODE_111;
212 break;
213 }
214 }
215
216 cmd.pe_mode_enable = FALSE;
217 cmd.pe_mode_operate_code = 0;
218 cmd.read_status_enable = FALSE;
219 cmd.read_status_config = QSPI_RSTSC_SW_ONCE;
220
221 if(dir == 1)
222 {
223 cmd.write_data_enable = TRUE;
224 }
225 else
226 {
227 cmd.write_data_enable = FALSE;
228 }
229
230 cmd.data_counter = message->parent.length;
231
232 qspi_cmd_operation_kick(qspi_bus->qspi_x, &cmd);
233
234 /* no date need to be processed, wait command completed. */
235 if(cmd.data_counter == 0)
236 {
237 while(qspi_flag_get(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG) == RESET);
238 qspi_flag_clear(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG);
239 }
240 }
241
qspi_data_transmit(struct at32_qspi_bus * qspi_bus,rt_uint8_t * buf,rt_uint32_t length,rt_uint32_t timeout)242 static error_status qspi_data_transmit(struct at32_qspi_bus *qspi_bus, rt_uint8_t* buf, rt_uint32_t length, rt_uint32_t timeout)
243 {
244 rt_uint32_t index = 0, ticks = 0, len = length;
245
246 for(index = 0; index < len; index++)
247 {
248 /* wait fifo ready */
249 ticks = 0;
250 while((qspi_flag_get(qspi_bus->qspi_x, QSPI_TXFIFORDY_FLAG) == RESET) && (ticks <= timeout))
251 {
252 ticks ++;
253 }
254 if(ticks >= timeout)
255 {
256 return ERROR;
257 }
258
259 /* write data */
260 qspi_byte_write(qspi_bus->qspi_x, *buf++);
261 }
262
263 /* wait command completed. */
264 ticks = 0;
265 while((qspi_flag_get(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG) == RESET) && (ticks <= timeout))
266 {
267 ticks++;
268 }
269 if(ticks >= timeout)
270 {
271 return ERROR;
272 }
273 /* clear cmdsts flag */
274 qspi_flag_clear(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG);
275
276 return SUCCESS;
277 }
278
qspi_data_receive(struct at32_qspi_bus * qspi_bus,rt_uint8_t * buf,rt_uint32_t length,rt_uint32_t timeout)279 static error_status qspi_data_receive(struct at32_qspi_bus *qspi_bus, rt_uint8_t* buf, rt_uint32_t length, rt_uint32_t timeout)
280 {
281 rt_uint32_t index = 0, ticks = 0, len = 0;
282
283 do
284 {
285 if(length >= QSPI_FIFO_DEPTH)
286 {
287 len = QSPI_FIFO_DEPTH;
288 }
289 else
290 {
291 len = length;
292 }
293
294 /* wait fifo ready */
295 ticks = 0;
296 while((qspi_flag_get(qspi_bus->qspi_x, QSPI_RXFIFORDY_FLAG) == RESET) && (ticks <= timeout))
297 {
298 ticks ++;
299 }
300 if(ticks >= timeout)
301 {
302 return ERROR;
303 }
304
305 /* read data */
306 for(index = 0; index < len; index++)
307 {
308 *buf++ = qspi_byte_read(qspi_bus->qspi_x);
309 }
310
311 length -= len;
312 } while(length);
313
314 /* wait command completed. */
315 ticks = 0;
316 while((qspi_flag_get(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG) == RESET) && (ticks <= timeout))
317 {
318 ticks++;
319 }
320 if(ticks >= timeout)
321 {
322 return ERROR;
323 }
324 /* clear cmdsts flag */
325 qspi_flag_clear(qspi_bus->qspi_x, QSPI_CMDSTS_FLAG);
326
327 return SUCCESS;
328 }
329
qspi_xfer(struct rt_spi_device * device,struct rt_spi_message * message)330 static rt_ssize_t qspi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
331 {
332 rt_size_t len = 0;
333
334 RT_ASSERT(device != RT_NULL);
335 RT_ASSERT(device->bus != RT_NULL);
336
337 struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message;
338 struct at32_qspi_bus *qspi_bus = device->bus->parent.user_data;
339
340 const rt_uint8_t *sndb = message->send_buf;
341 rt_uint8_t *rcvb = message->recv_buf;
342 rt_int32_t length = message->length;
343
344 #ifdef BSP_QSPI_USING_SOFTCS
345 if (message->cs_take && (device->cs_pin != PIN_NONE))
346 {
347 rt_pin_write(device->cs_pin, PIN_LOW);
348 }
349 #endif
350
351 /* send data */
352 if (sndb)
353 {
354 /* dir == 1, send */
355 qspi_send_cmd(qspi_bus, qspi_message, 1);
356
357 if (qspi_message->parent.length != 0)
358 {
359 if(qspi_data_transmit(qspi_bus, (rt_uint8_t *)sndb, length, 0xFFFF) == SUCCESS)
360 {
361 len = length;
362 }
363 else
364 {
365 LOG_E("qspi send data failed!");
366 goto __exit;
367 }
368 }
369 else
370 {
371 len = 1;
372 }
373 }
374 /* recv data */
375 else if (rcvb)
376 {
377 /* dir == 0, recv */
378 qspi_send_cmd(qspi_bus, qspi_message, 0);
379
380 if(qspi_data_receive(qspi_bus, (rt_uint8_t *)rcvb, length, 0xFFFF) == SUCCESS)
381 {
382 len = length;
383 }
384 else
385 {
386 LOG_E("qspi recv data failed!");
387 goto __exit;
388 }
389 }
390
391 __exit:
392 #ifdef BSP_QSPI_USING_SOFTCS
393 if (message->cs_release)
394 {
395 rt_pin_write(cs->pin, 1);
396 }
397 #endif
398 return len;
399 }
400
qspi_configure(struct rt_spi_device * device,struct rt_spi_configuration * configuration)401 static rt_err_t qspi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
402 {
403 RT_ASSERT(device != RT_NULL);
404 RT_ASSERT(configuration != RT_NULL);
405
406 struct rt_qspi_device *qspi_device = (struct rt_qspi_device *)device;
407 return at32_qspi_init(qspi_device, &qspi_device->config);
408 }
409
410 static const struct rt_spi_ops at32_qspi_ops =
411 {
412 .configure = qspi_configure,
413 .xfer = qspi_xfer,
414 };
415
416 /**
417 * @brief This function attach device to QSPI bus.
418 * @param device_name QSPI device name
419 * @param cs_pin QSPI cs pin number
420 * @param data_line_width QSPI data lines width, such as 1, 2, 4
421 * @param enter_qspi_mode Callback function that lets FLASH enter QSPI mode
422 * @param exit_qspi_mode Callback function that lets FLASH exit QSPI mode
423 * @retval 0 : success
424 * -1 : failed
425 */
rt_hw_qspi_device_attach(const char * bus_name,const char * device_name,rt_base_t cs_pin,rt_uint8_t data_line_width,void (* enter_qspi_mode)(),void (* exit_qspi_mode)())426 rt_err_t rt_hw_qspi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin, rt_uint8_t data_line_width, void (*enter_qspi_mode)(), void (*exit_qspi_mode)())
427 {
428 struct rt_qspi_device *qspi_device = RT_NULL;
429 rt_err_t result = RT_EOK;
430
431 RT_ASSERT(bus_name != RT_NULL);
432 RT_ASSERT(device_name != RT_NULL);
433 RT_ASSERT(data_line_width == 1 || data_line_width == 2 || data_line_width == 4);
434
435 qspi_device = (struct rt_qspi_device *)rt_malloc(sizeof(struct rt_qspi_device));
436 if (qspi_device == RT_NULL)
437 {
438 LOG_E("no memory, qspi bus attach device failed!");
439 result = -RT_ENOMEM;
440 goto __exit;
441 }
442
443 qspi_device->enter_qspi_mode = enter_qspi_mode;
444 qspi_device->exit_qspi_mode = exit_qspi_mode;
445 qspi_device->config.qspi_dl_width = data_line_width;
446
447 #ifdef BSP_QSPI_USING_SOFTCS
448 result = rt_spi_bus_attach_device_cspin(&qspi_device->parent, device_name, bus_name, cs_pin, RT_NULL);
449 #else
450 result = rt_spi_bus_attach_device_cspin(&qspi_device->parent, device_name, bus_name, PIN_NONE, RT_NULL);
451 #endif /* BSP_QSPI_USING_SOFTCS */
452
453 __exit:
454 if (result != RT_EOK)
455 {
456 if (qspi_device)
457 {
458 rt_free(qspi_device);
459 }
460 }
461
462 return result;
463 }
464
rt_hw_qspi_bus_init(void)465 static int rt_hw_qspi_bus_init(void)
466 {
467 int i = 0;
468 int result = RT_EOK;
469
470 for(i = 0; i < sizeof(at32_qspi_obj) / sizeof(at32_qspi_obj[0]); i++)
471 {
472 at32_qspi_obj[i].bus.parent.user_data = &at32_qspi_obj[i];
473
474 if(rt_qspi_bus_register(&at32_qspi_obj[i].bus, at32_qspi_obj[i].bus_name, &at32_qspi_ops) == RT_EOK)
475 {
476 LOG_D("%s register success", at32_qspi_obj[i].bus_name);
477 }
478 else
479 {
480 LOG_D("%s register failed", at32_qspi_obj[i].bus_name);
481 result = -RT_ERROR;
482 }
483 }
484
485 return result;
486 }
487
488 INIT_BOARD_EXPORT(rt_hw_qspi_bus_init);
489
490 #endif /* BSP_USING_QSPI */
491