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