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