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