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