1 /**************************************************************************//**
2  * @file     qspi.c
3  * @version  V3.00
4  * @brief    M2L31 series QSPI driver source file
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  * @copyright (C) 2023 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10 
11 /** @addtogroup Standard_Driver Standard Driver
12   @{
13 */
14 
15 /** @addtogroup QSPI_Driver QSPI Driver
16   @{
17 */
18 
19 
20 /** @addtogroup QSPI_EXPORTED_FUNCTIONS QSPI Exported Functions
21   @{
22 */
23 
24 /**
25   * @brief  This function make QSPI module be ready to transfer.
26   * @param[in]  qspi The pointer of the specified QSPI module.
27   * @param[in]  u32MasterSlave Decides the QSPI module is operating in master mode or in slave mode. (QSPI_SLAVE, QSPI_MASTER)
28   * @param[in]  u32QSPIMode Decides the transfer timing. (QSPI_MODE_0, QSPI_MODE_1, QSPI_MODE_2, QSPI_MODE_3)
29   * @param[in]  u32DataWidth Decides the data width of a QSPI transaction.
30   * @param[in]  u32BusClock The expected frequency of QSPI bus clock in Hz.
31   * @return Actual frequency of QSPI peripheral clock.
32   * @details By default, the QSPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
33   *          slave selection function is disabled.
34   *          In Slave mode, the u32BusClock shall be NULL and the QSPI clock divider setting will be 0.
35   *          The actual clock rate may be different from the target QSPI clock rate.
36   *          For example, if the QSPI source clock rate is 12 MHz and the target QSPI bus clock rate is 7 MHz, the
37   *          actual QSPI clock rate will be 6 MHz.
38   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
39   * @note   If u32BusClock >= system clock frequency, QSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
40   * @note   If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0.
41   * @note   In slave mode, the QSPI peripheral clock rate will be equal to APB clock rate.
42   */
QSPI_Open(QSPI_T * qspi,uint32_t u32MasterSlave,uint32_t u32QSPIMode,uint32_t u32DataWidth,uint32_t u32BusClock)43 uint32_t QSPI_Open(QSPI_T *qspi,
44                    uint32_t u32MasterSlave,
45                    uint32_t u32QSPIMode,
46                    uint32_t u32DataWidth,
47                    uint32_t u32BusClock)
48 {
49     uint32_t u32ClkSrc = 0U, u32Div, u32HCLKFreq, u32RetValue = 0U;
50 
51     if(u32DataWidth == 32U)
52     {
53         u32DataWidth = 0U;
54     }
55 
56     /* Get system clock frequency */
57     u32HCLKFreq = CLK_GetHCLKFreq();
58 
59     if(u32MasterSlave == QSPI_MASTER)
60     {
61         /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
62         qspi->SSCTL = QSPI_SS_ACTIVE_LOW;
63 
64         /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
65         qspi->CTL = u32MasterSlave | (u32DataWidth << QSPI_CTL_DWIDTH_Pos) | (u32QSPIMode) | QSPI_CTL_SPIEN_Msk;
66 
67         if(u32BusClock >= u32HCLKFreq)
68         {
69             /* Select PCLK as the clock source of QSPI */
70             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0;
71         }
72 
73         /* Check clock source of QSPI */
74         if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_HXT)
75         {
76             u32ClkSrc = __HXT; /* Clock source is HXT */
77         }
78         else if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PLL)
79         {
80             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
81         }
82         else if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PCLK0)
83         {
84             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
85         }
86         else
87         {
88             u32ClkSrc = __HIRC; /* Clock source is HIRC */
89         }
90 
91         if(u32BusClock >= u32HCLKFreq)
92         {
93             /* Set DIVIDER = 0 */
94             qspi->CLKDIV = 0U;
95             /* Return master peripheral clock rate */
96             u32RetValue = u32ClkSrc;
97         }
98         else if(u32BusClock >= u32ClkSrc)
99         {
100             /* Set DIVIDER = 0 */
101             qspi->CLKDIV = 0U;
102             /* Return master peripheral clock rate */
103             u32RetValue = u32ClkSrc;
104         }
105         else if(u32BusClock == 0U)
106         {
107             /* Set DIVIDER to the maximum value 0x1FF. f_qspi = f_qspi_clk_src / (DIVIDER + 1) */
108             qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
109             /* Return master peripheral clock rate */
110             u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
111         }
112         else
113         {
114             u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
115             if(u32Div > 0x1FFU)
116             {
117                 u32Div = 0x1FFU;
118                 qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
119                 /* Return master peripheral clock rate */
120                 u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
121             }
122             else
123             {
124                 qspi->CLKDIV = (qspi->CLKDIV & (~QSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << QSPI_CLKDIV_DIVIDER_Pos);
125                 /* Return master peripheral clock rate */
126                 u32RetValue = (u32ClkSrc / (u32Div + 1U));
127             }
128         }
129     }
130     else     /* For slave mode, force the QSPI peripheral clock rate to equal APB clock rate. */
131     {
132         /* Default setting: slave selection signal is low level active. */
133         qspi->SSCTL = QSPI_SS_ACTIVE_LOW;
134 
135         /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
136         qspi->CTL = u32MasterSlave | (u32DataWidth << QSPI_CTL_DWIDTH_Pos) | (u32QSPIMode) | QSPI_CTL_SPIEN_Msk;
137 
138         /* Set DIVIDER = 0 */
139         qspi->CLKDIV = 0U;
140 
141         /* Select PCLK as the clock source of QSPI */
142         CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0;
143         /* Return slave peripheral clock rate */
144         u32RetValue = CLK_GetPCLK0Freq();
145     }
146 
147     return u32RetValue;
148 }
149 
150 /**
151   * @brief  Disable QSPI controller.
152   * @param[in]  qspi The pointer of the specified QSPI module.
153   * @return None
154   * @details This function will reset QSPI controller.
155   */
QSPI_Close(QSPI_T * qspi)156 void QSPI_Close(QSPI_T *qspi)
157 {
158     /* Reset QSPI */
159     SYS->IPRST1 |= SYS_IPRST1_QSPI0RST_Msk;
160     SYS->IPRST1 &= ~SYS_IPRST1_QSPI0RST_Msk;
161 }
162 
163 /**
164   * @brief  Clear RX FIFO buffer.
165   * @param[in]  qspi The pointer of the specified QSPI module.
166   * @return None
167   * @details This function will clear QSPI RX FIFO buffer. The RXEMPTY (QSPI_STATUS[8]) will be set to 1.
168   */
QSPI_ClearRxFIFO(QSPI_T * qspi)169 void QSPI_ClearRxFIFO(QSPI_T *qspi)
170 {
171     qspi->FIFOCTL |= QSPI_FIFOCTL_RXFBCLR_Msk;
172 }
173 
174 /**
175   * @brief  Clear TX FIFO buffer.
176   * @param[in]  qspi The pointer of the specified QSPI module.
177   * @return None
178   * @details This function will clear QSPI TX FIFO buffer. The TXEMPTY (QSPI_STATUS[16]) will be set to 1.
179   * @note The TX shift register will not be cleared.
180   */
QSPI_ClearTxFIFO(QSPI_T * qspi)181 void QSPI_ClearTxFIFO(QSPI_T *qspi)
182 {
183     qspi->FIFOCTL |= QSPI_FIFOCTL_TXFBCLR_Msk;
184 }
185 
186 /**
187   * @brief  Disable the automatic slave selection function.
188   * @param[in]  qspi The pointer of the specified QSPI module.
189   * @return None
190   * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
191   */
QSPI_DisableAutoSS(QSPI_T * qspi)192 void QSPI_DisableAutoSS(QSPI_T *qspi)
193 {
194     qspi->SSCTL &= ~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SS_Msk);
195 }
196 
197 /**
198   * @brief  Enable the automatic slave selection function.
199   * @param[in]  qspi The pointer of the specified QSPI module.
200   * @param[in]  u32SSPinMask Specifies slave selection pins. (QSPI_SS)
201   * @param[in]  u32ActiveLevel Specifies the active level of slave selection signal. (QSPI_SS_ACTIVE_HIGH, QSPI_SS_ACTIVE_LOW)
202   * @return None
203   * @details This function will enable the automatic slave selection function. Only available in Master mode.
204   *          The slave selection pin and the active level will be set in this function.
205   */
QSPI_EnableAutoSS(QSPI_T * qspi,uint32_t u32SSPinMask,uint32_t u32ActiveLevel)206 void QSPI_EnableAutoSS(QSPI_T *qspi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
207 {
208     qspi->SSCTL = (qspi->SSCTL & (~(QSPI_SSCTL_AUTOSS_Msk | QSPI_SSCTL_SSACTPOL_Msk | QSPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | QSPI_SSCTL_AUTOSS_Msk);
209 }
210 
211 /**
212   * @brief  Set the QSPI bus clock.
213   * @param[in]  qspi The pointer of the specified QSPI module.
214   * @param[in]  u32BusClock The expected frequency of QSPI bus clock in Hz.
215   * @return Actual frequency of QSPI bus clock.
216   * @details This function is only available in Master mode. The actual clock rate may be different from the target QSPI bus clock rate.
217   *          For example, if the QSPI source clock rate is 12 MHz and the target QSPI bus clock rate is 7 MHz, the actual QSPI bus clock
218   *          rate will be 6 MHz.
219   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
220   * @note   If u32BusClock >= system clock frequency, QSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
221   * @note   If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0.
222   */
QSPI_SetBusClock(QSPI_T * qspi,uint32_t u32BusClock)223 uint32_t QSPI_SetBusClock(QSPI_T *qspi, uint32_t u32BusClock)
224 {
225     uint32_t u32ClkSrc, u32HCLKFreq;
226     uint32_t u32Div, u32RetValue;
227 
228     /* Get system clock frequency */
229     u32HCLKFreq = CLK_GetHCLKFreq();
230 
231     if(u32BusClock >= u32HCLKFreq)
232     {
233         /* Select PCLK as the clock source of QSPI */
234         CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_QSPI0SEL_Msk)) | CLK_CLKSEL2_QSPI0SEL_PCLK0;
235     }
236 
237     /* Check clock source of QSPI */
238     if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_HXT)
239     {
240         u32ClkSrc = __HXT; /* Clock source is HXT */
241     }
242     else if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PLL)
243     {
244         u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
245     }
246     else if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PCLK0)
247     {
248         u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
249     }
250     else
251     {
252         u32ClkSrc = __HIRC; /* Clock source is HIRC */
253     }
254 
255     if(u32BusClock >= u32HCLKFreq)
256     {
257         /* Set DIVIDER = 0 */
258         qspi->CLKDIV = 0U;
259         /* Return master peripheral clock rate */
260         u32RetValue = u32ClkSrc;
261     }
262     else if(u32BusClock >= u32ClkSrc)
263     {
264         /* Set DIVIDER = 0 */
265         qspi->CLKDIV = 0U;
266         /* Return master peripheral clock rate */
267         u32RetValue = u32ClkSrc;
268     }
269     else if(u32BusClock == 0U)
270     {
271         /* Set DIVIDER to the maximum value 0x1FF. f_qspi = f_qspi_clk_src / (DIVIDER + 1) */
272         qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
273         /* Return master peripheral clock rate */
274         u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
275     }
276     else
277     {
278         u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
279         if(u32Div > 0x1FFU)
280         {
281             u32Div = 0x1FFU;
282             qspi->CLKDIV |= QSPI_CLKDIV_DIVIDER_Msk;
283             /* Return master peripheral clock rate */
284             u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
285         }
286         else
287         {
288             qspi->CLKDIV = (qspi->CLKDIV & (~QSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << QSPI_CLKDIV_DIVIDER_Pos);
289             /* Return master peripheral clock rate */
290             u32RetValue = (u32ClkSrc / (u32Div + 1U));
291         }
292     }
293 
294     return u32RetValue;
295 }
296 
297 /**
298   * @brief  Configure FIFO threshold setting.
299   * @param[in]  qspi The pointer of the specified QSPI module.
300   * @param[in]  u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 7.
301   * @param[in]  u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 7.
302   * @return None
303   * @details Set TX FIFO threshold and RX FIFO threshold configurations.
304   */
QSPI_SetFIFO(QSPI_T * qspi,uint32_t u32TxThreshold,uint32_t u32RxThreshold)305 void QSPI_SetFIFO(QSPI_T *qspi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
306 {
307     qspi->FIFOCTL = (qspi->FIFOCTL & ~(QSPI_FIFOCTL_TXTH_Msk | QSPI_FIFOCTL_RXTH_Msk)) |
308                     (u32TxThreshold << QSPI_FIFOCTL_TXTH_Pos) |
309                     (u32RxThreshold << QSPI_FIFOCTL_RXTH_Pos);
310 }
311 
312 /**
313   * @brief  Get the actual frequency of QSPI bus clock. Only available in Master mode.
314   * @param[in]  qspi The pointer of the specified QSPI module.
315   * @return Actual QSPI bus clock frequency in Hz.
316   * @details This function will calculate the actual QSPI bus clock rate according to the QSPIxSEL and DIVIDER settings. Only available in Master mode.
317   */
QSPI_GetBusClock(QSPI_T * qspi)318 uint32_t QSPI_GetBusClock(QSPI_T *qspi)
319 {
320     uint32_t u32Div;
321     uint32_t u32ClkSrc = 0UL;
322 
323     /* Get DIVIDER setting */
324     u32Div = (qspi->CLKDIV & QSPI_CLKDIV_DIVIDER_Msk) >> QSPI_CLKDIV_DIVIDER_Pos;
325 
326     /* Check clock source of QSPI */
327     if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_HXT)
328     {
329         u32ClkSrc = __HXT; /* Clock source is HXT */
330     }
331     else if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PLL)
332     {
333         u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
334     }
335     else if((CLK->CLKSEL2 & CLK_CLKSEL2_QSPI0SEL_Msk) == CLK_CLKSEL2_QSPI0SEL_PCLK0)
336     {
337         u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
338     }
339     else
340     {
341         u32ClkSrc = __HIRC; /* Clock source is HIRC */
342     }
343 
344     /* Return QSPI bus clock rate */
345     return (u32ClkSrc / (u32Div + 1U));
346 }
347 
348 /**
349   * @brief  Enable interrupt function.
350   * @param[in]  qspi The pointer of the specified QSPI module.
351   * @param[in]  u32Mask The combination of all related interrupt enable bits.
352   *                     Each bit corresponds to a interrupt enable bit.
353   *                     This parameter decides which interrupts will be enabled. It is combination of:
354   *                       - \ref QSPI_UNIT_INT_MASK
355   *                       - \ref QSPI_SSACT_INT_MASK
356   *                       - \ref QSPI_SSINACT_INT_MASK
357   *                       - \ref QSPI_SLVUR_INT_MASK
358   *                       - \ref QSPI_SLVBE_INT_MASK
359   *                       - \ref QSPI_SLVTO_INT_MASK
360   *                       - \ref QSPI_TXUF_INT_MASK
361   *                       - \ref QSPI_FIFO_TXTH_INT_MASK
362   *                       - \ref QSPI_FIFO_RXTH_INT_MASK
363   *                       - \ref QSPI_FIFO_RXOV_INT_MASK
364   *                       - \ref QSPI_FIFO_RXTO_INT_MASK
365   *
366   * @return None
367   * @details Enable QSPI related interrupts specified by u32Mask parameter.
368   */
QSPI_EnableInt(QSPI_T * qspi,uint32_t u32Mask)369 void QSPI_EnableInt(QSPI_T *qspi, uint32_t u32Mask)
370 {
371     /* Enable unit transfer interrupt flag */
372     if((u32Mask & QSPI_UNIT_INT_MASK) == QSPI_UNIT_INT_MASK)
373     {
374         qspi->CTL |= QSPI_CTL_UNITIEN_Msk;
375     }
376 
377     /* Enable slave selection signal active interrupt flag */
378     if((u32Mask & QSPI_SSACT_INT_MASK) == QSPI_SSACT_INT_MASK)
379     {
380         qspi->SSCTL |= QSPI_SSCTL_SSACTIEN_Msk;
381     }
382 
383     /* Enable slave selection signal inactive interrupt flag */
384     if((u32Mask & QSPI_SSINACT_INT_MASK) == QSPI_SSINACT_INT_MASK)
385     {
386         qspi->SSCTL |= QSPI_SSCTL_SSINAIEN_Msk;
387     }
388 
389     /* Enable slave TX under run interrupt flag */
390     if((u32Mask & QSPI_SLVUR_INT_MASK) == QSPI_SLVUR_INT_MASK)
391     {
392         qspi->SSCTL |= QSPI_SSCTL_SLVURIEN_Msk;
393     }
394 
395     /* Enable slave bit count error interrupt flag */
396     if((u32Mask & QSPI_SLVBE_INT_MASK) == QSPI_SLVBE_INT_MASK)
397     {
398         qspi->SSCTL |= QSPI_SSCTL_SLVBEIEN_Msk;
399     }
400 
401     /* Enable slave mode time-out interrupt flag */
402     if((u32Mask & QSPI_SLVTO_INT_MASK) == QSPI_SLVTO_INT_MASK)
403     {
404         qspi->SSCTL |= QSPI_SSCTL_SLVTOIEN_Msk;
405     }
406 
407     /* Enable slave TX underflow interrupt flag */
408     if((u32Mask & QSPI_TXUF_INT_MASK) == QSPI_TXUF_INT_MASK)
409     {
410         qspi->FIFOCTL |= QSPI_FIFOCTL_TXUFIEN_Msk;
411     }
412 
413     /* Enable TX threshold interrupt flag */
414     if((u32Mask & QSPI_FIFO_TXTH_INT_MASK) == QSPI_FIFO_TXTH_INT_MASK)
415     {
416         qspi->FIFOCTL |= QSPI_FIFOCTL_TXTHIEN_Msk;
417     }
418 
419     /* Enable RX threshold interrupt flag */
420     if((u32Mask & QSPI_FIFO_RXTH_INT_MASK) == QSPI_FIFO_RXTH_INT_MASK)
421     {
422         qspi->FIFOCTL |= QSPI_FIFOCTL_RXTHIEN_Msk;
423     }
424 
425     /* Enable RX overrun interrupt flag */
426     if((u32Mask & QSPI_FIFO_RXOV_INT_MASK) == QSPI_FIFO_RXOV_INT_MASK)
427     {
428         qspi->FIFOCTL |= QSPI_FIFOCTL_RXOVIEN_Msk;
429     }
430 
431     /* Enable RX time-out interrupt flag */
432     if((u32Mask & QSPI_FIFO_RXTO_INT_MASK) == QSPI_FIFO_RXTO_INT_MASK)
433     {
434         qspi->FIFOCTL |= QSPI_FIFOCTL_RXTOIEN_Msk;
435     }
436 }
437 
438 /**
439   * @brief  Disable interrupt function.
440   * @param[in]  qspi The pointer of the specified QSPI module.
441   * @param[in]  u32Mask The combination of all related interrupt enable bits.
442   *                     Each bit corresponds to a interrupt bit.
443   *                     This parameter decides which interrupts will be disabled. It is combination of:
444   *                       - \ref QSPI_UNIT_INT_MASK
445   *                       - \ref QSPI_SSACT_INT_MASK
446   *                       - \ref QSPI_SSINACT_INT_MASK
447   *                       - \ref QSPI_SLVUR_INT_MASK
448   *                       - \ref QSPI_SLVBE_INT_MASK
449   *                       - \ref QSPI_SLVTO_INT_MASK
450   *                       - \ref QSPI_TXUF_INT_MASK
451   *                       - \ref QSPI_FIFO_TXTH_INT_MASK
452   *                       - \ref QSPI_FIFO_RXTH_INT_MASK
453   *                       - \ref QSPI_FIFO_RXOV_INT_MASK
454   *                       - \ref QSPI_FIFO_RXTO_INT_MASK
455   *
456   * @return None
457   * @details Disable QSPI related interrupts specified by u32Mask parameter.
458   */
QSPI_DisableInt(QSPI_T * qspi,uint32_t u32Mask)459 void QSPI_DisableInt(QSPI_T *qspi, uint32_t u32Mask)
460 {
461     /* Disable unit transfer interrupt flag */
462     if((u32Mask & QSPI_UNIT_INT_MASK) == QSPI_UNIT_INT_MASK)
463     {
464         qspi->CTL &= ~QSPI_CTL_UNITIEN_Msk;
465     }
466 
467     /* Disable slave selection signal active interrupt flag */
468     if((u32Mask & QSPI_SSACT_INT_MASK) == QSPI_SSACT_INT_MASK)
469     {
470         qspi->SSCTL &= ~QSPI_SSCTL_SSACTIEN_Msk;
471     }
472 
473     /* Disable slave selection signal inactive interrupt flag */
474     if((u32Mask & QSPI_SSINACT_INT_MASK) == QSPI_SSINACT_INT_MASK)
475     {
476         qspi->SSCTL &= ~QSPI_SSCTL_SSINAIEN_Msk;
477     }
478 
479     /* Disable slave TX under run interrupt flag */
480     if((u32Mask & QSPI_SLVUR_INT_MASK) == QSPI_SLVUR_INT_MASK)
481     {
482         qspi->SSCTL &= ~QSPI_SSCTL_SLVURIEN_Msk;
483     }
484 
485     /* Disable slave bit count error interrupt flag */
486     if((u32Mask & QSPI_SLVBE_INT_MASK) == QSPI_SLVBE_INT_MASK)
487     {
488         qspi->SSCTL &= ~QSPI_SSCTL_SLVBEIEN_Msk;
489     }
490 
491     /* Disable slave mode time-out interrupt flag */
492     if((u32Mask & QSPI_SLVTO_INT_MASK) == QSPI_SLVTO_INT_MASK)
493     {
494         qspi->SSCTL &= ~QSPI_SSCTL_SLVTOIEN_Msk;
495     }
496 
497     /* Disable slave TX underflow interrupt flag */
498     if((u32Mask & QSPI_TXUF_INT_MASK) == QSPI_TXUF_INT_MASK)
499     {
500         qspi->FIFOCTL &= ~QSPI_FIFOCTL_TXUFIEN_Msk;
501     }
502 
503     /* Disable TX threshold interrupt flag */
504     if((u32Mask & QSPI_FIFO_TXTH_INT_MASK) == QSPI_FIFO_TXTH_INT_MASK)
505     {
506         qspi->FIFOCTL &= ~QSPI_FIFOCTL_TXTHIEN_Msk;
507     }
508 
509     /* Disable RX threshold interrupt flag */
510     if((u32Mask & QSPI_FIFO_RXTH_INT_MASK) == QSPI_FIFO_RXTH_INT_MASK)
511     {
512         qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXTHIEN_Msk;
513     }
514 
515     /* Disable RX overrun interrupt flag */
516     if((u32Mask & QSPI_FIFO_RXOV_INT_MASK) == QSPI_FIFO_RXOV_INT_MASK)
517     {
518         qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXOVIEN_Msk;
519     }
520 
521     /* Disable RX time-out interrupt flag */
522     if((u32Mask & QSPI_FIFO_RXTO_INT_MASK) == QSPI_FIFO_RXTO_INT_MASK)
523     {
524         qspi->FIFOCTL &= ~QSPI_FIFOCTL_RXTOIEN_Msk;
525     }
526 }
527 
528 /**
529   * @brief  Get interrupt flag.
530   * @param[in]  qspi The pointer of the specified QSPI module.
531   * @param[in]  u32Mask The combination of all related interrupt sources.
532   *                     Each bit corresponds to a interrupt source.
533   *                     This parameter decides which interrupt flags will be read. It is combination of:
534   *                       - \ref QSPI_UNIT_INT_MASK
535   *                       - \ref QSPI_SSACT_INT_MASK
536   *                       - \ref QSPI_SSINACT_INT_MASK
537   *                       - \ref QSPI_SLVUR_INT_MASK
538   *                       - \ref QSPI_SLVBE_INT_MASK
539   *                       - \ref QSPI_SLVTO_INT_MASK
540   *                       - \ref QSPI_TXUF_INT_MASK
541   *                       - \ref QSPI_FIFO_TXTH_INT_MASK
542   *                       - \ref QSPI_FIFO_RXTH_INT_MASK
543   *                       - \ref QSPI_FIFO_RXOV_INT_MASK
544   *                       - \ref QSPI_FIFO_RXTO_INT_MASK
545   *
546   * @return Interrupt flags of selected sources.
547   * @details Get QSPI related interrupt flags specified by u32Mask parameter.
548   */
QSPI_GetIntFlag(QSPI_T * qspi,uint32_t u32Mask)549 uint32_t QSPI_GetIntFlag(QSPI_T *qspi, uint32_t u32Mask)
550 {
551     uint32_t u32IntFlag = 0U, u32TmpVal;
552 
553     u32TmpVal = qspi->STATUS & QSPI_STATUS_UNITIF_Msk;
554     /* Check unit transfer interrupt flag */
555     if((u32Mask & QSPI_UNIT_INT_MASK) && (u32TmpVal))
556     {
557         u32IntFlag |= QSPI_UNIT_INT_MASK;
558     }
559 
560     u32TmpVal = qspi->STATUS & QSPI_STATUS_SSACTIF_Msk;
561     /* Check slave selection signal active interrupt flag */
562     if((u32Mask & QSPI_SSACT_INT_MASK) && (u32TmpVal))
563     {
564         u32IntFlag |= QSPI_SSACT_INT_MASK;
565     }
566 
567     u32TmpVal = qspi->STATUS & QSPI_STATUS_SSINAIF_Msk;
568     /* Check slave selection signal inactive interrupt flag */
569     if((u32Mask & QSPI_SSINACT_INT_MASK) && (u32TmpVal))
570     {
571         u32IntFlag |= QSPI_SSINACT_INT_MASK;
572     }
573 
574     u32TmpVal = qspi->STATUS & QSPI_STATUS_SLVURIF_Msk;
575     /* Check slave TX under run interrupt flag */
576     if((u32Mask & QSPI_SLVUR_INT_MASK) && (u32TmpVal))
577     {
578         u32IntFlag |= QSPI_SLVUR_INT_MASK;
579     }
580 
581     u32TmpVal = qspi->STATUS & QSPI_STATUS_SLVBEIF_Msk;
582     /* Check slave bit count error interrupt flag */
583     if((u32Mask & QSPI_SLVBE_INT_MASK) && (u32TmpVal))
584     {
585         u32IntFlag |= QSPI_SLVBE_INT_MASK;
586     }
587 
588     u32TmpVal = qspi->STATUS & QSPI_STATUS_SLVTOIF_Msk;
589     /* Check slave mode time-out interrupt flag */
590     if((u32Mask & QSPI_SLVTO_INT_MASK) && (u32TmpVal))
591     {
592         u32IntFlag |= QSPI_SLVTO_INT_MASK;
593     }
594 
595     u32TmpVal = qspi->STATUS & QSPI_STATUS_TXUFIF_Msk;
596     /* Check slave TX underflow interrupt flag */
597     if((u32Mask & QSPI_TXUF_INT_MASK) && (u32TmpVal))
598     {
599         u32IntFlag |= QSPI_TXUF_INT_MASK;
600     }
601 
602     u32TmpVal = qspi->STATUS & QSPI_STATUS_TXTHIF_Msk;
603     /* Check TX threshold interrupt flag */
604     if((u32Mask & QSPI_FIFO_TXTH_INT_MASK) && (u32TmpVal))
605     {
606         u32IntFlag |= QSPI_FIFO_TXTH_INT_MASK;
607     }
608 
609     u32TmpVal = qspi->STATUS & QSPI_STATUS_RXTHIF_Msk;
610     /* Check RX threshold interrupt flag */
611     if((u32Mask & QSPI_FIFO_RXTH_INT_MASK) && (u32TmpVal))
612     {
613         u32IntFlag |= QSPI_FIFO_RXTH_INT_MASK;
614     }
615 
616     u32TmpVal = qspi->STATUS & QSPI_STATUS_RXOVIF_Msk;
617     /* Check RX overrun interrupt flag */
618     if((u32Mask & QSPI_FIFO_RXOV_INT_MASK) && (u32TmpVal))
619     {
620         u32IntFlag |= QSPI_FIFO_RXOV_INT_MASK;
621     }
622 
623     u32TmpVal = qspi->STATUS & QSPI_STATUS_RXTOIF_Msk;
624     /* Check RX time-out interrupt flag */
625     if((u32Mask & QSPI_FIFO_RXTO_INT_MASK) && (u32TmpVal))
626     {
627         u32IntFlag |= QSPI_FIFO_RXTO_INT_MASK;
628     }
629 
630     return u32IntFlag;
631 }
632 
633 /**
634   * @brief  Clear interrupt flag.
635   * @param[in]  qspi The pointer of the specified QSPI module.
636   * @param[in]  u32Mask The combination of all related interrupt sources.
637   *                     Each bit corresponds to a interrupt source.
638   *                     This parameter decides which interrupt flags will be cleared. It could be the combination of:
639   *                       - \ref QSPI_UNIT_INT_MASK
640   *                       - \ref QSPI_SSACT_INT_MASK
641   *                       - \ref QSPI_SSINACT_INT_MASK
642   *                       - \ref QSPI_SLVUR_INT_MASK
643   *                       - \ref QSPI_SLVBE_INT_MASK
644   *                       - \ref QSPI_SLVTO_INT_MASK
645   *                       - \ref QSPI_TXUF_INT_MASK
646   *                       - \ref QSPI_FIFO_RXOV_INT_MASK
647   *                       - \ref QSPI_FIFO_RXTO_INT_MASK
648   *
649   * @return None
650   * @details Clear QSPI related interrupt flags specified by u32Mask parameter.
651   */
QSPI_ClearIntFlag(QSPI_T * qspi,uint32_t u32Mask)652 void QSPI_ClearIntFlag(QSPI_T *qspi, uint32_t u32Mask)
653 {
654     if(u32Mask & QSPI_UNIT_INT_MASK)
655     {
656         qspi->STATUS = QSPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
657     }
658 
659     if(u32Mask & QSPI_SSACT_INT_MASK)
660     {
661         qspi->STATUS = QSPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
662     }
663 
664     if(u32Mask & QSPI_SSINACT_INT_MASK)
665     {
666         qspi->STATUS = QSPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
667     }
668 
669     if(u32Mask & QSPI_SLVUR_INT_MASK)
670     {
671         qspi->STATUS = QSPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
672     }
673 
674     if(u32Mask & QSPI_SLVBE_INT_MASK)
675     {
676         qspi->STATUS = QSPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
677     }
678 
679     if(u32Mask & QSPI_SLVTO_INT_MASK)
680     {
681         qspi->STATUS = QSPI_STATUS_SLVTOIF_Msk; /* Clear slave mode time-out interrupt flag */
682     }
683 
684     if(u32Mask & QSPI_TXUF_INT_MASK)
685     {
686         qspi->STATUS = QSPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
687     }
688 
689     if(u32Mask & QSPI_FIFO_RXOV_INT_MASK)
690     {
691         qspi->STATUS = QSPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
692     }
693 
694     if(u32Mask & QSPI_FIFO_RXTO_INT_MASK)
695     {
696         qspi->STATUS = QSPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
697     }
698 }
699 
700 /**
701   * @brief  Get QSPI status.
702   * @param[in]  qspi The pointer of the specified QSPI module.
703   * @param[in]  u32Mask The combination of all related sources.
704   *                     Each bit corresponds to a source.
705   *                     This parameter decides which flags will be read. It is combination of:
706   *                       - \ref QSPI_BUSY_MASK
707   *                       - \ref QSPI_RX_EMPTY_MASK
708   *                       - \ref QSPI_RX_FULL_MASK
709   *                       - \ref QSPI_TX_EMPTY_MASK
710   *                       - \ref QSPI_TX_FULL_MASK
711   *                       - \ref QSPI_TXRX_RESET_MASK
712   *                       - \ref QSPI_SPIEN_STS_MASK
713   *                       - \ref QSPI_SSLINE_STS_MASK
714   *
715   * @return Flags of selected sources.
716   * @details Get QSPI related status specified by u32Mask parameter.
717   */
QSPI_GetStatus(QSPI_T * qspi,uint32_t u32Mask)718 uint32_t QSPI_GetStatus(QSPI_T *qspi, uint32_t u32Mask)
719 {
720     uint32_t u32Flag = 0U, u32TmpValue;
721 
722     u32TmpValue = qspi->STATUS & QSPI_STATUS_BUSY_Msk;
723     /* Check busy status */
724     if((u32Mask & QSPI_BUSY_MASK) && (u32TmpValue))
725     {
726         u32Flag |= QSPI_BUSY_MASK;
727     }
728 
729     u32TmpValue = qspi->STATUS & QSPI_STATUS_RXEMPTY_Msk;
730     /* Check RX empty flag */
731     if((u32Mask & QSPI_RX_EMPTY_MASK) && (u32TmpValue))
732     {
733         u32Flag |= QSPI_RX_EMPTY_MASK;
734     }
735 
736     u32TmpValue = qspi->STATUS & QSPI_STATUS_RXFULL_Msk;
737     /* Check RX full flag */
738     if((u32Mask & QSPI_RX_FULL_MASK) && (u32TmpValue))
739     {
740         u32Flag |= QSPI_RX_FULL_MASK;
741     }
742 
743     u32TmpValue = qspi->STATUS & QSPI_STATUS_TXEMPTY_Msk;
744     /* Check TX empty flag */
745     if((u32Mask & QSPI_TX_EMPTY_MASK) && (u32TmpValue))
746     {
747         u32Flag |= QSPI_TX_EMPTY_MASK;
748     }
749 
750     u32TmpValue = qspi->STATUS & QSPI_STATUS_TXFULL_Msk;
751     /* Check TX full flag */
752     if((u32Mask & QSPI_TX_FULL_MASK) && (u32TmpValue))
753     {
754         u32Flag |= QSPI_TX_FULL_MASK;
755     }
756 
757     u32TmpValue = qspi->STATUS & QSPI_STATUS_TXRXRST_Msk;
758     /* Check TX/RX reset flag */
759     if((u32Mask & QSPI_TXRX_RESET_MASK) && (u32TmpValue))
760     {
761         u32Flag |= QSPI_TXRX_RESET_MASK;
762     }
763 
764     u32TmpValue = qspi->STATUS & QSPI_STATUS_SPIENSTS_Msk;
765     /* Check SPIEN flag */
766     if((u32Mask & QSPI_SPIEN_STS_MASK) && (u32TmpValue))
767     {
768         u32Flag |= QSPI_SPIEN_STS_MASK;
769     }
770 
771     u32TmpValue = qspi->STATUS & QSPI_STATUS_SSLINE_Msk;
772     /* Check QSPIx_SS line status */
773     if((u32Mask & QSPI_SSLINE_STS_MASK) && (u32TmpValue))
774     {
775         u32Flag |= QSPI_SSLINE_STS_MASK;
776     }
777 
778     return u32Flag;
779 }
780 
781 /**
782   * @brief  Get QSPI status2.
783   * @param[in]  qspi The pointer of the specified QSPI module.
784   * @param[in]  u32Mask The combination of all related sources.
785   *                     Each bit corresponds to a source.
786   *                     This parameter decides which flags will be read. It is combination of:
787   *                       - \ref QSPI_SLVBENUM_MASK
788   *
789   * @return Flags of selected sources.
790   * @details Get QSPI related status specified by u32Mask parameter.
791   */
QSPI_GetStatus2(QSPI_T * qspi,uint32_t u32Mask)792 uint32_t QSPI_GetStatus2(QSPI_T *qspi, uint32_t u32Mask)
793 {
794     uint32_t u32TmpStatus;
795     uint32_t u32Number = 0U;
796 
797     u32TmpStatus = qspi->STATUS2;
798 
799     /* Check effective bit number of uncompleted RX data status */
800     if(u32Mask & QSPI_SLVBENUM_MASK)
801     {
802         u32Number = (u32TmpStatus & QSPI_STATUS2_SLVBENUM_Msk) >> QSPI_STATUS2_SLVBENUM_Pos;
803     }
804 
805     return u32Number;
806 }
807 
808 /*@}*/ /* end of group QSPI_EXPORTED_FUNCTIONS */
809 
810 /*@}*/ /* end of group QSPI_Driver */
811 
812 /*@}*/ /* end of group Standard_Driver */
813 
814 /*** (C) COPYRIGHT 2023 Nuvoton Technology Corp. ***/