1 /*!
2  * @file        qpm32f10x_qspi.c
3  *
4  * @brief       This file contains all the functions for the QSPI peripheral
5  *
6  * @version     V1.0.1
7  *
8  * @date        2022-12-31
9  *
10  * @attention
11  *
12  *  Copyright (C) 2022-2023 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Includes */
27 #include "apm32s10x_qspi.h"
28 
29 /** @addtogroup APM32S10x_StdPeriphDriver
30   @{
31 */
32 
33 /** @addtogroup QSPI_Driver  QSPI Driver
34   @{
35 */
36 
37 /** @defgroup QSPI_Functions Functions
38   @{
39 */
40 
41 /*!
42  * @brief       Reset QSPI peripheral registers to their default values
43  *
44  * @param       None
45  *
46  * @retval      None
47  */
QSPI_Reset(void)48 void QSPI_Reset(void)
49 {
50     volatile uint32_t dummy = 0;
51 
52     QSPI->IOSW = QSPI_IOSW_RESET_VALUE;
53     QSPI->SSIEN = QSPI_SSIEN_RESET_VALUE;
54     QSPI->INTEN = QSPI_INTEN_RESET_VALUE;
55     dummy = QSPI->ICF;
56     QSPI->CTRL1 = QSPI_CTRL1_RESET_VALUE;
57     QSPI->CTRL2 = QSPI_CTRL2_RESET_VALUE;
58     QSPI->CTRL3 = QSPI_CTRL3_RESET_VALUE;
59     QSPI->SLAEN = QSPI_SLAEN_RESET_VALUE;
60     QSPI->BR = QSPI_BR_RESET_VALUE;
61     QSPI->TFL = QSPI_TFL_RESET_VALUE;
62     QSPI->RFL = QSPI_RFL_RESET_VALUE;
63     QSPI->TFTL = QSPI_TFTL_RESET_VALUE;
64     QSPI->RFTL = QSPI_RFTL_RESET_VALUE;
65     QSPI->STS = QSPI_STS_RESET_VALUE;
66     QSPI->RSD = QSPI_RSD_RESET_VALUE;
67 }
68 
69 /*!
70  * @brief       Configure the QSPI peripheral according to the specified parameters in the qspiConfig
71  *
72  * @param       qspiConfig: Pointer to a QSPI_Config_T structure that contains the configuration information
73  *
74  * @retval      None
75  */
QSPI_Config(QSPI_Config_T * qspiConfig)76 void QSPI_Config(QSPI_Config_T* qspiConfig)
77 {
78     QSPI->CTRL1_B.CPHA = qspiConfig->clockPhase;
79     QSPI->CTRL1_B.CPOL = qspiConfig->clockPolarity;
80     QSPI->CTRL1_B.FRF = qspiConfig->frameFormat;
81     QSPI->CTRL1_B.DFS = qspiConfig->dataFrameSize;;
82     QSPI->CTRL1_B.SSTEN = qspiConfig->selectSlaveToggle;
83 
84     QSPI->BR = qspiConfig->clockDiv;
85 }
86 
87 /*!
88  * @brief       Fill each qspiConfig member with its default value
89  *
90  * @param       qspiConfig: Pointer to a QSPI_Config_T structure which will be initialized
91  *
92  * @retval      None
93  */
QSPI_ConfigStructInit(QSPI_Config_T * qspiConfig)94 void QSPI_ConfigStructInit(QSPI_Config_T* qspiConfig)
95 {
96     qspiConfig->clockPhase = QSPI_CLKPHA_2EDGE;
97     qspiConfig->clockPolarity = QSPI_CLKPOL_LOW;
98     qspiConfig->clockDiv = 0;
99 
100     qspiConfig->frameFormat = QSPI_FRF_STANDARD;
101     qspiConfig->dataFrameSize = QSPI_DFS_8BIT;
102     qspiConfig->selectSlaveToggle = QSPI_SST_DISABLE;
103 }
104 
105 /*!
106  * @brief       Configure frame number
107  *
108  * @param       num: Configs a 16bit frame number
109  *
110  * @retval      None
111  */
QSPI_ConfigFrameNum(uint16_t num)112 void QSPI_ConfigFrameNum(uint16_t num)
113 {
114     QSPI->CTRL2_B.NDF = num;
115 }
116 
117 /*!
118  * @brief       Configure data frame size
119  *
120  * @param       dfs: Specifies the data frame size
121  *                   The parameter can be one of following values:
122  *                   @arg QSPI_DFS_4BIT  : Specifies data frame size to 4bit
123  *                   @arg QSPI_DFS_5BIT  : Specifies data frame size to 5bit
124  *                   @arg QSPI_DFS_6BIT  : Specifies data frame size to 6bit
125  *                   @arg QSPI_DFS_7BIT  : Specifies data frame size to 7bit
126  *                   @arg QSPI_DFS_8BIT  : Specifies data frame size to 8bit
127  *                   @arg QSPI_DFS_9BIT  : Specifies data frame size to 9bit
128  *                   @arg QSPI_DFS_10BIT : Specifies data frame size to 10bit
129  *                   @arg QSPI_DFS_11BIT : Specifies data frame size to 11bit
130  *                   @arg QSPI_DFS_12BIT : Specifies data frame size to 12bit
131  *                   @arg QSPI_DFS_13BIT : Specifies data frame size to 13bit
132  *                   @arg QSPI_DFS_14BIT : Specifies data frame size to 14bit
133  *                   @arg QSPI_DFS_15BIT : Specifies data frame size to 15bit
134  *                   @arg QSPI_DFS_16BIT : Specifies data frame size to 16bit
135  *                   @arg QSPI_DFS_17BIT : Specifies data frame size to 17bit
136  *                   @arg QSPI_DFS_18BIT : Specifies data frame size to 18bit
137  *                   @arg QSPI_DFS_19BIT : Specifies data frame size to 19bit
138  *                   @arg QSPI_DFS_20BIT : Specifies data frame size to 20bit
139  *                   @arg QSPI_DFS_21BIT : Specifies data frame size to 21bit
140  *                   @arg QSPI_DFS_22BIT : Specifies data frame size to 22bit
141  *                   @arg QSPI_DFS_23BIT : Specifies data frame size to 23bit
142  *                   @arg QSPI_DFS_24BIT : Specifies data frame size to 24bit
143  *                   @arg QSPI_DFS_25BIT : Specifies data frame size to 25bit
144  *                   @arg QSPI_DFS_26BIT : Specifies data frame size to 26bit
145  *                   @arg QSPI_DFS_27BIT : Specifies data frame size to 27bit
146  *                   @arg QSPI_DFS_28BIT : Specifies data frame size to 28bit
147  *                   @arg QSPI_DFS_29BIT : Specifies data frame size to 29bit
148  *                   @arg QSPI_DFS_30BIT : Specifies data frame size to 30bit
149  *                   @arg QSPI_DFS_31BIT : Specifies data frame size to 31bit
150  *                   @arg QSPI_DFS_32BIT : Specifies data frame size to 32bit
151  *
152  * @retval      None
153  */
QSPI_ConfigDataFrameSize(QSPI_DFS_T dfs)154 void QSPI_ConfigDataFrameSize(QSPI_DFS_T dfs)
155 {
156     QSPI->CTRL1_B.DFS = dfs;
157 }
158 
159 /*!
160  * @brief       Configure frame format
161  *
162  * @param       frameFormat
163  *
164  * @retval      None
165  */
QSPI_ConfigFrameFormat(QSPI_FRF_T frameFormat)166 void QSPI_ConfigFrameFormat(QSPI_FRF_T frameFormat)
167 {
168     QSPI->CTRL1_B.FRF = frameFormat;
169 }
170 
171 /*!
172  * @brief       Enable QSPI
173  *
174  * @param       None
175  *
176  * @retval      None
177  */
QSPI_Enable(void)178 void QSPI_Enable(void)
179 {
180     QSPI->SSIEN_B.EN = BIT_SET;
181 }
182 
183 /*!
184  * @brief       Disable QSPI
185  *
186  * @param       None
187  *
188  * @retval      None
189  */
QSPI_Disable(void)190 void QSPI_Disable(void)
191 {
192     QSPI->SSIEN_B.EN = BIT_RESET;
193 }
194 
195 /*!
196  * @brief       Read Tx FIFO number of data
197  *
198  * @param       None
199  *
200  * @retval      None
201  */
QSPI_ReadTxFifoDataNum(void)202 uint8_t QSPI_ReadTxFifoDataNum(void)
203 {
204     return (uint8_t)QSPI->TFL_B.TFL;
205 }
206 
207 /*!
208  * @brief       Read Rx FIFO number of data
209  *
210  * @param       None
211  *
212  * @retval      Returns Rx FIFO number of data
213  */
QSPI_ReadRxFifoDataNum(void)214 uint8_t QSPI_ReadRxFifoDataNum(void)
215 {
216     return (uint8_t)QSPI->RFL_B.RFL;
217 }
218 
219 /*!
220  * @brief       Configure rx FIFO threshold
221  *
222  * @param       threshold: Speicifes rx FIFO threshold with a 3bit value
223  *
224  * @retval      None
225  */
QSPI_ConfigRxFifoThreshold(uint8_t threshold)226 void QSPI_ConfigRxFifoThreshold(uint8_t threshold)
227 {
228     QSPI->RFTL_B.RFT = threshold;
229 }
230 
231 /*!
232  * @brief       Congfigure Tx FIFO threshold
233  *
234  * @param       threshold: Speicifes Tx FIFO threshold with a 3bit value
235  *
236  * @retval      None
237  */
QSPI_ConfigTxFifoThreshold(uint8_t threshold)238 void QSPI_ConfigTxFifoThreshold(uint8_t threshold)
239 {
240     QSPI->TFTL_B.TFTH = threshold;
241 }
242 
243 /*!
244  * @brief       Congfigure Tx FIFO empty threshold
245  *
246  * @param       threshold: Speicifes Tx FIFO empty threshold with a 3bit value
247  *
248  * @retval      None
249  */
QSPI_ConfigTxFifoEmptyThreshold(uint8_t threshold)250 void QSPI_ConfigTxFifoEmptyThreshold(uint8_t threshold)
251 {
252     QSPI->TFTL_B.TFT = threshold;
253 }
254 
255 /*!
256  * @brief       Configure RX sample edge
257  *
258  * @param       rse: Specifies the sample edge
259  *                   The parameter can be one of following values:
260  *                   @arg QSPI_RSE_RISING : rising edge sample
261  *                   @arg QSPI_RSE_FALLING: falling edge sample
262  *
263  * @retval      None
264  */
QSPI_ConfigRxSampleEdge(QSPI_RSE_T rse)265 void QSPI_ConfigRxSampleEdge(QSPI_RSE_T rse)
266 {
267     QSPI->RSD_B.RSE = rse;
268 }
269 
270 /*!
271  * @brief       Set RX sample delay
272  *
273  * @param       delay: Specifies the sample delay with a 8-bit value
274  *
275  * @retval      None
276  */
QSPI_ConfigRxSampleDelay(uint8_t delay)277 void QSPI_ConfigRxSampleDelay(uint8_t delay)
278 {
279     QSPI->RSD_B.RSD = delay;
280 }
281 
282 /*!
283  * @brief       Clock stretch enable
284  *
285  * @param       None
286  *
287  * @retval      None
288  */
QSPI_EnableClockStretch(void)289 void QSPI_EnableClockStretch(void)
290 {
291     QSPI->CTRL3_B.CSEN = BIT_SET;
292 }
293 
294 /*!
295  * @brief       Clock stretch disable
296  *
297  * @param       None
298  *
299  * @retval      None
300  */
QSPI_DisableClockStretch(void)301 void QSPI_DisableClockStretch(void)
302 {
303     QSPI->CTRL3_B.CSEN = BIT_RESET;
304 }
305 
306 /*!
307  * @brief       Configure instruction length
308  *
309  * @param       len: Specifies the length of instruction
310  *                   The parameter can be one of following values:
311  *                   @arg QSPI_INST_LEN_0     : no instruction
312  *                   @arg QSPI_INST_LEN_4BIT  : 4-bit instruction
313  *                   @arg QSPI_INST_LEN_8BIT  : 8-bit instruction
314  *                   @arg QSPI_INST_LEN_16BIT : 16-bit instruction
315  *
316  * @retval      None
317  */
QSPI_ConfigInstLen(QSPI_INST_LEN_T len)318 void QSPI_ConfigInstLen(QSPI_INST_LEN_T len)
319 {
320     QSPI->CTRL3_B.INSLEN = len;
321 }
322 
323 /*!
324  * @brief       Configure address length
325  *
326  * @param       len: Specifies the address length
327  *                   The parameter can be one of following values:
328  *                   @arg QSPI_ADDR_LEN_0     : no address
329  *                   @arg QSPI_ADDR_LEN_4BIT  : 4-bit address length
330  *                   @arg QSPI_ADDR_LEN_8BIT, : 8-bit address length
331  *                   @arg QSPI_ADDR_LEN_12BIT : 12-bit address length
332  *                   @arg QSPI_ADDR_LEN_16BIT : 16-bit address length
333  *                   @arg QSPI_ADDR_LEN_20BIT : 20-bit address length
334  *                   @arg QSPI_ADDR_LEN_24BIT : 24-bit address length
335  *                   @arg QSPI_ADDR_LEN_28BIT : 28-bit address length
336  *                   @arg QSPI_ADDR_LEN_32BIT : 32-bit address length
337  *                   @arg QSPI_ADDR_LEN_36BIT : 36-bit address length
338  *                   @arg QSPI_ADDR_LEN_40BIT : 40-bit address length
339  *                   @arg QSPI_ADDR_LEN_44BIT : 44-bit address length
340  *                   @arg QSPI_ADDR_LEN_48BIT : 48-bit address length
341  *                   @arg QSPI_ADDR_LEN_52BIT : 52-bit address length
342  *                   @arg QSPI_ADDR_LEN_56BIT : 56-bit address length
343  *                   @arg QSPI_ADDR_LEN_60BIT : 60-bit address length
344  *
345  * @retval      None
346  */
QSPI_ConfigAddrLen(QSPI_ADDR_LEN_T len)347 void QSPI_ConfigAddrLen(QSPI_ADDR_LEN_T len)
348 {
349     QSPI->CTRL3_B.ADDRLEN = len;
350 }
351 
352 /*!
353  * @brief       Configure instruction and address type
354  *
355  * @param       type: Specifies the instruction and address type
356  *                    The parameter can be one of following values:
357  *                    @arg QSPI_INST_ADDR_TYPE_STANDARD : Tx instruction in standard SPI mode,
358  *                                                         Tx address in standard SPI mode
359  *                    @arg QSPI_INST_TYPE_STANDARD      : Tx instruction in standard SPI mode,
360  *                                                         Tx address in mode of SPI_FRF
361  *                    @arg QSPI_INST_ADDR_TYPE_FRF      : Tx instruction in mode of SPI_FRF,
362  *                                                         Tx address in mode of SPI_FRF
363  *
364  * @retval      None
365  */
QSPI_ConfigInstAddrType(QSPI_INST_ADDR_TYPE_T type)366 void QSPI_ConfigInstAddrType(QSPI_INST_ADDR_TYPE_T type)
367 {
368     QSPI->CTRL3_B.IAT = type;
369 }
370 
371 /*!
372  * @brief       Configure wait cycle number
373  *
374  * @param       cycle: Specifies the wait cycle number with a 5-bit value
375  *
376  * @retval      None
377  */
QSPI_ConfigWaitCycle(uint8_t cycle)378 void QSPI_ConfigWaitCycle(uint8_t cycle)
379 {
380     QSPI->CTRL3_B.WAITCYC = cycle;
381 }
382 
383 /*!
384  * @brief       Open QSPI GPIO
385  *
386  * @param       None
387  *
388  * @retval      None
389  */
QSPI_OpenIO(void)390 void QSPI_OpenIO(void)
391 {
392     QSPI->IOSW_B.IOSW = BIT_SET;
393 }
394 
395 /*!
396  * @brief       Close QSPI GPIO
397  *
398  * @param       None
399  *
400  * @retval      None
401  */
QSPI_CloseIO(void)402 void QSPI_CloseIO(void)
403 {
404     QSPI->IOSW_B.IOSW = BIT_RESET;
405 }
406 
407 /*!
408  * @brief       Set transmission mode
409  *
410  * @param       mode: Specifies the transmission mode
411  *                    The parameter can be one of following values:
412  *                    @arg QSPI_TRANS_MODE_TX_RX       : TX and RX mode
413  *                    @arg QSPI_TRANS_MODE_TX          : TX mode only
414  *                    @arg QSPI_TRANS_MODE_RX          : RX mode only
415  *                    @arg QSPI_TRANS_MODE_EEPROM_READ : EEPROM read mode
416  *
417  * @retval      None
418  */
QSPI_ConfigTansMode(QSPI_TRANS_MODE_T mode)419 void QSPI_ConfigTansMode(QSPI_TRANS_MODE_T mode)
420 {
421     QSPI->CTRL1_B.TXMODE = mode;
422 }
423 
424 /*!
425  * @brief       Transmit data
426  *
427  * @param       data: Data to be transmited
428  *
429  * @retval      None
430  */
QSPI_TxData(uint32_t data)431 void QSPI_TxData(uint32_t data)
432 {
433     QSPI->DATA = data;
434 }
435 
436 /*!
437  * @brief       Return the most recent received data
438  *
439  * @param       None
440  *
441  * @retval      The received data
442  */
QSPI_RxData(void)443 uint32_t QSPI_RxData(void)
444 {
445     return (uint32_t)QSPI->DATA;
446 }
447 
448 /*!
449  * @brief       Enable Slave
450  *
451  * @param       None
452  *
453  * @retval      None
454  */
QSPI_EnableSlave(void)455 void QSPI_EnableSlave(void)
456 {
457     QSPI->SLAEN_B.SLAEN = BIT_SET;
458 }
459 
460 /*!
461  * @brief       Disable slave
462  *
463  * @param       None
464  *
465  * @retval      None
466  */
QSPI_DisableSlave(void)467 void QSPI_DisableSlave(void)
468 {
469     QSPI->SLAEN_B.SLAEN = BIT_RESET;
470 }
471 
472 /*!
473  * @brief       Enable the specified QSPI interrupts
474  *
475  * @param       interrupt:  Specifies the QSPI interrupt sources
476  *                          The parameter can be combination of following values:
477  *                          @arg QSPI_INT_TFE:      TX FIFO empty interrupt
478  *                          @arg QSPI_INT_TFO:      TX FIFO overflow interrupt
479  *                          @arg QSPI_INT_RFU:      RX FIFO underflow interrupt
480  *                          @arg QSPI_INT_RFO:      RX FIFO overflow interrupt
481  *                          @arg QSPI_INT_RFF:      RX FIFO full interrupt
482  *                          @arg QSPI_INT_MST:      Master interrupt
483  *
484  * @retval      None
485  */
QSPI_EnableInterrupt(uint32_t interrupt)486 void QSPI_EnableInterrupt(uint32_t interrupt)
487 {
488     QSPI->INTEN |= interrupt;
489 }
490 
491 /*!
492  * @brief       Disable the specified QSPI interrupts
493  *
494  * @param       interrupt:  Specifies the QSPI interrupt sources
495  *                          The parameter can be combination of following values:
496  *                          @arg QSPI_INT_TFE:      TX FIFO empty interrupt
497  *                          @arg QSPI_INT_TFO:      TX FIFO overflow interrupt
498  *                          @arg QSPI_INT_RFU:      RX FIFO underflow interrupt
499  *                          @arg QSPI_INT_RFO:      RX FIFO overflow interrupt
500  *                          @arg QSPI_INT_RFF:      RX FIFO full interrupt
501  *                          @arg QSPI_INT_MST:      Master interrupt
502  *
503  * @retval      None
504  */
QSPI_DisableInterrupt(uint32_t interrupt)505 void QSPI_DisableInterrupt(uint32_t interrupt)
506 {
507     QSPI->INTEN &= (uint32_t)~interrupt;
508 }
509 
510 /*!
511  * @brief       Read specified QSPI flag
512  *
513  * @param       flag:   Specifies the flag to be checked
514  *                      The parameter can be one of following values:
515  *                      @arg QSPI_FLAG_BUSY:    Busy flag
516  *                      @arg QSPI_FLAG_TFNF:    TX FIFO not full flag
517  *                      @arg QSPI_FLAG_TFE:     TX FIFO empty flag
518  *                      @arg QSPI_FLAG_RFNE:    RX FIFO not empty flag
519  *                      @arg QSPI_FLAG_RFF:     RX FIFO full flag
520  *                      @arg QSPI_FLAG_DCE:     Data collision error
521  *
522  * @retval      The new state of flag (SET or RESET)
523  */
QSPI_ReadStatusFlag(QSPI_FLAG_T flag)524 uint8_t QSPI_ReadStatusFlag(QSPI_FLAG_T flag)
525 {
526     uint8_t ret = RESET;
527 
528     ret = QSPI->STS & flag ? SET : RESET;
529 
530     return ret;
531 }
532 
533 /*!
534  * @brief       Clear specified QSPI flag
535  *
536  * @param       None
537  *
538  * @retval      None
539  *
540  * @note        This funtion only clear Data collision error flag(QSPI_FLAG_DCE)
541  */
QSPI_ClearStatusFlag(void)542 void QSPI_ClearStatusFlag(void)
543 {
544     volatile uint32_t dummy = 0;
545 
546     dummy = QSPI->STS;
547 }
548 
549 /*!
550  * @brief       Read specified QSPI interrupt flag
551  *
552  * @param       flag:   Specifies the interrupt flag to be checked
553  *                      The parameter can be one of following values:
554  *                      @arg QSPI_INT_FLAG_TFE:     TX FIFO empty interrupt flag
555  *                      @arg QSPI_INT_FLAG_TFO:     TX FIFO overflow interrupt flag
556  *                      @arg QSPI_INT_FLAG_RFU:     RX FIFO underflow interrupt flag
557  *                      @arg QSPI_INT_FLAG_RFO:     RX FIFO overflow interrupt flag
558  *                      @arg QSPI_INT_FLAG_RFF:     RX FIFO full interrupt flag
559  *                      @arg QSPI_INT_FLAG_MST:     Master interrupt flag
560  *
561  * @retval      The new state of flag (SET or RESET)
562  */
QSPI_ReadIntFlag(QSPI_INT_FLAG_T flag)563 uint8_t QSPI_ReadIntFlag(QSPI_INT_FLAG_T flag)
564 {
565     uint8_t ret = RESET;
566 
567     ret = QSPI->ISTS & flag ? SET : RESET;
568 
569     return ret;
570 }
571 
572 /*!
573  * @brief       Clear specified QSPI interrupt flag
574  *
575  * @param       flag:   Specifies the interrupt flag to be checked
576  *                      The parameter can be one of following values:
577  *                      @arg QSPI_INT_FLAG_TFO:     TX FIFO overflow interrupt flag
578  *                      @arg QSPI_INT_FLAG_RFU:     RX FIFO underflow interrupt flag
579  *                      @arg QSPI_INT_FLAG_RFO:     RX FIFO overflow interrupt flag
580  *                      @arg QSPI_INT_FLAG_MST:     Master interrupt flag
581  *
582  * @retval      None
583  */
QSPI_ClearIntFlag(uint32_t flag)584 void QSPI_ClearIntFlag(uint32_t flag)
585 {
586     volatile uint32_t dummy = 0;
587 
588     if (flag & QSPI_INT_FLAG_TFO)
589     {
590         dummy = QSPI->TFOIC;
591     }
592     else if (flag & QSPI_INT_FLAG_RFO)
593     {
594         dummy = QSPI->RFOIC;
595     }
596     else if (flag & QSPI_INT_FLAG_RFU)
597     {
598         dummy = QSPI->RFUIC;
599     }
600     else if (flag & QSPI_INT_FLAG_MST)
601     {
602         dummy = QSPI->MIC;
603     }
604 }
605 
606 /**@} end of group QSPI_Functions */
607 /**@} end of group QSPI_Driver */
608 /**@} end of group APM32S10x_StdPeriphDriver */
609