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