1 /**************************************************************************//**
2 * @file qspi.c
3 * @version V3.00
4 * @brief M2351 series QSPI driver source file
5 *
6 * @copyright SPDX-License-Identifier: Apache-2.0
7 * @copyright Copyright (C) 2017-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 If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
39 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 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 If u32BusClock >= QSPI peripheral clock source, DIVIDER will be set to 0.
43 In slave mode for Secure, the QSPI peripheral clock rate will equal to APB clock rate.
44 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 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 If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
261 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 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 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 /*@}*/ /* end of group QSPI_EXPORTED_FUNCTIONS */
827
828 /*@}*/ /* end of group QSPI_Driver */
829
830 /*@}*/ /* end of group Standard_Driver */
831
832