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