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