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