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