1 /**************************************************************************//**
2  * @file     qspi.c
3  * @version  V3.00
4  * @brief    M2354 series QSPI driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 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   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
39   * @note   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   * @note   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   * @note   If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0.
43   * @note   In slave mode for Secure, the QSPI peripheral clock rate will equal to APB clock rate.
44   * @note   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   * @note 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   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
261   * @note   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   * @note   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   * @note   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 /**
827   * @brief  Get QSPI status2.
828   * @param[in]  qspi The pointer of the specified QSPI module.
829   * @param[in]  u32Mask The combination of all related sources.
830   *                     Each bit corresponds to a source.
831   *                     This parameter decides which flags will be read. It is combination of:
832   *                       - \ref QSPI_SLVBENUM_MASK
833   *
834   * @return Flags of selected sources.
835   * @details Get QSPI related status specified by u32Mask parameter.
836   */
QSPI_GetStatus2(QSPI_T * qspi,uint32_t u32Mask)837 uint32_t QSPI_GetStatus2(QSPI_T *qspi, uint32_t u32Mask)
838 {
839     uint32_t u32TmpStatus;
840     uint32_t u32Number = 0UL;
841 
842     u32TmpStatus = qspi->STATUS2;
843 
844     /* Check effective bit number of uncompleted RX data status */
845     if(u32Mask & QSPI_SLVBENUM_MASK)
846     {
847         u32Number = (u32TmpStatus & QSPI_STATUS2_SLVBENUM_Msk) >> QSPI_STATUS2_SLVBENUM_Pos;
848     }
849 
850     return u32Number;
851 }
852 
853 /**@}*/ /* end of group QSPI_EXPORTED_FUNCTIONS */
854 
855 /**@}*/ /* end of group QSPI_Driver */
856 
857 /**@}*/ /* end of group Standard_Driver */
858