1 /**************************************************************************//**
2 * @file lpspi.c
3 * @version V3.00
4 * @brief M2L31 series LPSPI driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11 /** @addtogroup Standard_Driver Standard Driver
12 @{
13 */
14
15 /** @addtogroup LPSPI_Driver LPSPI Driver
16 @{
17 */
18
19 /** @addtogroup LPSPI_EXPORTED_FUNCTIONS LPSPI Exported Functions
20 @{
21 */
22
23 /**
24 * @brief This function make LPSPI module be ready to transfer.
25 * @param[in] lpspi The pointer of the specified LPSPI module.
26 * @param[in] u32MasterSlave Decides the LPSPI module is operating in master mode or in slave mode. (LPSPI_SLAVE, LPSPI_MASTER)
27 * @param[in] u32SPIMode Decides the transfer timing. (LPSPI_MODE_0, LPSPI_MODE_1, LPSPI_MODE_2, LPSPI_MODE_3)
28 * @param[in] u32DataWidth Decides the data width of a LPSPI transaction.
29 * @param[in] u32BusClock The expected frequency of LPSPI bus clock in Hz.
30 * @return Actual frequency of LPSPI peripheral clock.
31 * @details By default, the LPSPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
32 * slave selection function is disabled.
33 * In Slave mode, the u32BusClock shall be NULL and the LPSPI clock divider setting will be 0.
34 * The actual clock rate may be different from the target LPSPI clock rate.
35 * For example, if the LPSPI source clock rate is 12 MHz and the target LPSPI bus clock rate is 7 MHz, the
36 * actual LPSPI clock rate will be 6MHz.
37 * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
38 * @note If u32BusClock >= system clock frequency, LPSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
39 * @note If u32BusClock >= LPSPI peripheral clock source, DIVIDER will be set to 0.
40 * @note In slave mode, the LPSPI peripheral clock rate will be equal to APB clock rate.
41 */
LPSPI_Open(LPSPI_T * lpspi,uint32_t u32MasterSlave,uint32_t u32SPIMode,uint32_t u32DataWidth,uint32_t u32BusClock)42 uint32_t LPSPI_Open(LPSPI_T *lpspi,
43 uint32_t u32MasterSlave,
44 uint32_t u32SPIMode,
45 uint32_t u32DataWidth,
46 uint32_t u32BusClock)
47 {
48 uint32_t u32ClkSrc = 0U, u32Div, u32RetValue=0U;
49
50 if(u32DataWidth == 32U)
51 {
52 u32DataWidth = 0U;
53 }
54
55 if(u32MasterSlave == LPSPI_MASTER)
56 {
57 /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
58 lpspi->SSCTL = LPSPI_SS_ACTIVE_LOW;
59
60 /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
61 lpspi->CTL = u32MasterSlave | (u32DataWidth << LPSPI_CTL_DWIDTH_Pos) | (u32SPIMode) | LPSPI_CTL_SPIEN_Msk;
62
63 /* Check clock source of LPSPI */
64 if(lpspi == LPSPI0)
65 {
66 if((LPSCC->CLKSEL0 & (~LPSCC_CLKSEL0_LPSPI0SEL_Msk)) == LPSCC_CLKSEL0_LPSPI0SEL_HIRC)
67 {
68 u32ClkSrc = __HIRC; /* Clock source is HIRC */
69 }
70 else
71 {
72 u32ClkSrc = __MIRC; /* Clock source is MIRC */
73 }
74 }
75
76 if(u32BusClock >= u32ClkSrc)
77 {
78 /* Set DIVIDER = 0 */
79 lpspi->CLKDIV = 0U;
80 /* Return master peripheral clock rate */
81 u32RetValue = u32ClkSrc;
82 }
83 else if(u32BusClock == 0U)
84 {
85 /* Set DIVIDER to the maximum value 0xFF. f_lpspi = f_spi_clk_src / (DIVIDER + 1) */
86 lpspi->CLKDIV |= LPSPI_CLKDIV_DIVIDER_Msk;
87 /* Return master peripheral clock rate */
88 u32RetValue = (u32ClkSrc / (0xFFU + 1U));
89 }
90 else
91 {
92 u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
93 if(u32Div > 0xFFU)
94 {
95 u32Div = 0xFFU;
96 lpspi->CLKDIV |= LPSPI_CLKDIV_DIVIDER_Msk;
97 /* Return master peripheral clock rate */
98 u32RetValue = (u32ClkSrc / (0xFFU + 1U));
99 }
100 else
101 {
102 lpspi->CLKDIV = (lpspi->CLKDIV & (~LPSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << LPSPI_CLKDIV_DIVIDER_Pos);
103 /* Return master peripheral clock rate */
104 u32RetValue = (u32ClkSrc / (u32Div + 1U));
105 }
106 }
107 }
108 else /* For slave mode, force the LPSPI peripheral clock rate to equal APB clock rate. */
109 {
110 /* Default setting: slave selection signal is low level active. */
111 lpspi->SSCTL = LPSPI_SS_ACTIVE_LOW;
112
113 /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
114 lpspi->CTL = u32MasterSlave | (u32DataWidth << LPSPI_CTL_DWIDTH_Pos) | (u32SPIMode) | LPSPI_CTL_SPIEN_Msk;
115
116 /* Set DIVIDER = 0 */
117 lpspi->CLKDIV = 0U;
118
119 /* Select PCLK as the clock source of LPSPI */
120 if(lpspi == LPSPI0)
121 {
122 if((LPSCC->CLKSEL0 & (~LPSCC_CLKSEL0_LPSPI0SEL_Msk)) == LPSCC_CLKSEL0_LPSPI0SEL_HIRC)
123 {
124 u32RetValue = __HIRC; /* Clock source is HIRC */
125 }
126 else
127 {
128 u32RetValue = __MIRC; /* Clock source is MIRC */
129 }
130 }
131 }
132 return u32RetValue;
133 }
134
135 /**
136 * @brief Disable LPSPI controller.
137 * @param[in] lpspi The pointer of the specified LPSPI module.
138 * @return None
139 * @details This function will reset LPSPI controller.
140 */
LPSPI_Close(LPSPI_T * lpspi)141 void LPSPI_Close(LPSPI_T *lpspi)
142 {
143 if(lpspi == LPSPI0)
144 {
145 /* Reset LPSPI */
146 LPSCC->IPRST0 |= LPSCC_IPRST0_LPSPI0RST_Msk;
147 LPSCC->IPRST0 &= ~LPSCC_IPRST0_LPSPI0RST_Msk;
148 }
149 }
150
151 /**
152 * @brief Clear RX FIFO buffer.
153 * @param[in] lpspi The pointer of the specified LPSPI module.
154 * @return None
155 * @details This function will clear LPSPI RX FIFO buffer. The RXEMPTY (LPSPI_STATUS[8]) will be set to 1.
156 */
LPSPI_ClearRxFIFO(LPSPI_T * lpspi)157 void LPSPI_ClearRxFIFO(LPSPI_T *lpspi)
158 {
159 lpspi->FIFOCTL |= LPSPI_FIFOCTL_RXFBCLR_Msk;
160 }
161
162 /**
163 * @brief Clear TX FIFO buffer.
164 * @param[in] lpspi The pointer of the specified LPSPI module.
165 * @return None
166 * @details This function will clear LPSPI TX FIFO buffer. The TXEMPTY (LPSPI_STATUS[16]) will be set to 1.
167 * @note The TX shift register will not be cleared.
168 */
LPSPI_ClearTxFIFO(LPSPI_T * lpspi)169 void LPSPI_ClearTxFIFO(LPSPI_T *lpspi)
170 {
171 lpspi->FIFOCTL |= LPSPI_FIFOCTL_TXFBCLR_Msk;
172 }
173
174 /**
175 * @brief Disable the automatic slave selection function.
176 * @param[in] lpspi The pointer of the specified LPSPI module.
177 * @return None
178 * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
179 */
LPSPI_DisableAutoSS(LPSPI_T * lpspi)180 void LPSPI_DisableAutoSS(LPSPI_T *lpspi)
181 {
182 lpspi->SSCTL &= ~(LPSPI_SSCTL_AUTOSS_Msk | LPSPI_SSCTL_SS_Msk);
183 }
184
185 /**
186 * @brief Enable the automatic slave selection function.
187 * @param[in] lpspi The pointer of the specified LPSPI module.
188 * @param[in] u32SSPinMask Specifies slave selection pins. (LPSPI_SS)
189 * @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (LPSPI_SS_ACTIVE_HIGH, LPSPI_SS_ACTIVE_LOW)
190 * @return None
191 * @details This function will enable the automatic slave selection function. Only available in Master mode.
192 * The slave selection pin and the active level will be set in this function.
193 */
LPSPI_EnableAutoSS(LPSPI_T * lpspi,uint32_t u32SSPinMask,uint32_t u32ActiveLevel)194 void LPSPI_EnableAutoSS(LPSPI_T *lpspi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
195 {
196 lpspi->SSCTL = (lpspi->SSCTL & (~(LPSPI_SSCTL_AUTOSS_Msk | LPSPI_SSCTL_SSACTPOL_Msk | LPSPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | LPSPI_SSCTL_AUTOSS_Msk);
197 }
198
199 /**
200 * @brief Set the LPSPI bus clock.
201 * @param[in] lpspi The pointer of the specified LPSPI module.
202 * @param[in] u32BusClock The expected frequency of LPSPI bus clock in Hz.
203 * @return Actual frequency of LPSPI bus clock.
204 * @details This function is only available in Master mode. The actual clock rate may be different from the target LPSPI bus clock rate.
205 * For example, if the LPSPI source clock rate is 12 MHz and the target LPSPI bus clock rate is 7 MHz, the actual LPSPI bus clock
206 * rate will be 6 MHz.
207 * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
208 * @note If u32BusClock >= system clock frequency, LPSPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
209 * @note If u32BusClock >= LPSPI peripheral clock source, DIVIDER will be set to 0.
210 */
LPSPI_SetBusClock(LPSPI_T * lpspi,uint32_t u32BusClock)211 uint32_t LPSPI_SetBusClock(LPSPI_T *lpspi, uint32_t u32BusClock)
212 {
213 uint32_t u32ClkSrc;
214 uint32_t u32Div, u32RetValue;
215
216 /* Check clock source of LPSPI */
217 if(lpspi == LPSPI0)
218 {
219 if((LPSCC->CLKSEL0 & (~LPSCC_CLKSEL0_LPSPI0SEL_Msk)) == LPSCC_CLKSEL0_LPSPI0SEL_HIRC)
220 {
221 u32ClkSrc = __HIRC; /* Clock source is HIRC */
222 }
223 else
224 {
225 u32ClkSrc = __MIRC; /* Clock source is MIRC */
226 }
227 }
228 else
229 {
230 u32RetValue = 0;
231 return u32RetValue;
232 }
233
234 if(u32BusClock >= u32ClkSrc)
235 {
236 /* Set DIVIDER = 0 */
237 lpspi->CLKDIV = 0U;
238 /* Return master peripheral clock rate */
239 u32RetValue = u32ClkSrc;
240 }
241 else if(u32BusClock == 0U)
242 {
243 /* Set DIVIDER to the maximum value 0xFF. f_lpspi = f_spi_clk_src / (DIVIDER + 1) */
244 lpspi->CLKDIV |= LPSPI_CLKDIV_DIVIDER_Msk;
245 /* Return master peripheral clock rate */
246 u32RetValue = (u32ClkSrc / (0xFFU + 1U));
247 }
248 else
249 {
250 u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
251 if(u32Div > 0x1FFU)
252 {
253 u32Div = 0x1FFU;
254 lpspi->CLKDIV |= LPSPI_CLKDIV_DIVIDER_Msk;
255 /* Return master peripheral clock rate */
256 u32RetValue = (u32ClkSrc / (0xFFU + 1U));
257 }
258 else
259 {
260 lpspi->CLKDIV = (lpspi->CLKDIV & (~LPSPI_CLKDIV_DIVIDER_Msk)) | (u32Div << LPSPI_CLKDIV_DIVIDER_Pos);
261 /* Return master peripheral clock rate */
262 u32RetValue = (u32ClkSrc / (u32Div + 1U));
263 }
264 }
265
266 return u32RetValue;
267 }
268
269 /**
270 * @brief Configure FIFO threshold setting.
271 * @param[in] lpspi The pointer of the specified LPSPI module.
272 * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3. If data width is 8~16 bits, it could be 0 ~ 7.
273 * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3. If data width is 8~16 bits, it could be 0 ~ 7.
274 * @return None
275 * @details Set TX FIFO threshold and RX FIFO threshold configurations.
276 */
LPSPI_SetFIFO(LPSPI_T * lpspi,uint32_t u32TxThreshold,uint32_t u32RxThreshold)277 void LPSPI_SetFIFO(LPSPI_T *lpspi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
278 {
279 lpspi->FIFOCTL = (lpspi->FIFOCTL & ~(LPSPI_FIFOCTL_TXTH_Msk | LPSPI_FIFOCTL_RXTH_Msk)) |
280 (u32TxThreshold << LPSPI_FIFOCTL_TXTH_Pos) |
281 (u32RxThreshold << LPSPI_FIFOCTL_RXTH_Pos);
282 }
283
284 /**
285 * @brief Get the actual frequency of LPSPI bus clock. Only available in Master mode.
286 * @param[in] lpspi The pointer of the specified LPSPI module.
287 * @return Actual LPSPI bus clock frequency in Hz.
288 * @details This function will calculate the actual LPSPI bus clock rate according to the SPInSEL and DIVIDER settings. Only available in Master mode.
289 */
LPSPI_GetBusClock(LPSPI_T * lpspi)290 uint32_t LPSPI_GetBusClock(LPSPI_T *lpspi)
291 {
292 uint32_t u32Div;
293 uint32_t u32ClkSrc;
294
295 /* Get DIVIDER setting */
296 u32Div = (lpspi->CLKDIV & LPSPI_CLKDIV_DIVIDER_Msk) >> LPSPI_CLKDIV_DIVIDER_Pos;
297
298 /* Check clock source of LPSPI */
299 if(lpspi == LPSPI0)
300 {
301 if((LPSCC->CLKSEL0 & (~LPSCC_CLKSEL0_LPSPI0SEL_Msk)) == LPSCC_CLKSEL0_LPSPI0SEL_HIRC)
302 {
303 u32ClkSrc = __HIRC; /* Clock source is HIRC */
304 }
305 else
306 {
307 u32ClkSrc = __MIRC; /* Clock source is MIRC */
308 }
309 }
310 /* Return LPSPI bus clock rate */
311 return (u32ClkSrc / (u32Div + 1U));
312 }
313
314 /**
315 * @brief Enable interrupt function.
316 * @param[in] lpspi The pointer of the specified LPSPI module.
317 * @param[in] u32Mask The combination of all related interrupt enable bits.
318 * Each bit corresponds to a interrupt enable bit.
319 * This parameter decides which interrupts will be enabled. It is combination of:
320 * - \ref LPSPI_UNIT_INT_MASK
321 * - \ref LPSPI_SSACT_INT_MASK
322 * - \ref LPSPI_SSINACT_INT_MASK
323 * - \ref LPSPI_SLVUR_INT_MASK
324 * - \ref LPSPI_SLVBE_INT_MASK
325 * - \ref LPSPI_TXUF_INT_MASK
326 * - \ref LPSPI_FIFO_TXTH_INT_MASK
327 * - \ref LPSPI_FIFO_RXTH_INT_MASK
328 * - \ref LPSPI_FIFO_RXOV_INT_MASK
329 * - \ref LPSPI_FIFO_RXTO_INT_MASK
330 *
331 * @return None
332 * @details Enable LPSPI related interrupts specified by u32Mask parameter.
333 */
LPSPI_EnableInt(LPSPI_T * lpspi,uint32_t u32Mask)334 void LPSPI_EnableInt(LPSPI_T *lpspi, uint32_t u32Mask)
335 {
336 /* Enable unit transfer interrupt flag */
337 if((u32Mask & LPSPI_UNIT_INT_MASK) == LPSPI_UNIT_INT_MASK)
338 {
339 lpspi->CTL |= LPSPI_CTL_UNITIEN_Msk;
340 }
341
342 /* Enable slave selection signal active interrupt flag */
343 if((u32Mask & LPSPI_SSACT_INT_MASK) == LPSPI_SSACT_INT_MASK)
344 {
345 lpspi->SSCTL |= LPSPI_SSCTL_SSACTIEN_Msk;
346 }
347
348 /* Enable slave selection signal inactive interrupt flag */
349 if((u32Mask & LPSPI_SSINACT_INT_MASK) == LPSPI_SSINACT_INT_MASK)
350 {
351 lpspi->SSCTL |= LPSPI_SSCTL_SSINAIEN_Msk;
352 }
353
354 /* Enable slave TX under run interrupt flag */
355 if((u32Mask & LPSPI_SLVUR_INT_MASK) == LPSPI_SLVUR_INT_MASK)
356 {
357 lpspi->SSCTL |= LPSPI_SSCTL_SLVURIEN_Msk;
358 }
359
360 /* Enable slave bit count error interrupt flag */
361 if((u32Mask & LPSPI_SLVBE_INT_MASK) == LPSPI_SLVBE_INT_MASK)
362 {
363 lpspi->SSCTL |= LPSPI_SSCTL_SLVBEIEN_Msk;
364 }
365
366 /* Enable slave TX underflow interrupt flag */
367 if((u32Mask & LPSPI_TXUF_INT_MASK) == LPSPI_TXUF_INT_MASK)
368 {
369 lpspi->FIFOCTL |= LPSPI_FIFOCTL_TXUFIEN_Msk;
370 }
371
372 /* Enable TX threshold interrupt flag */
373 if((u32Mask & LPSPI_FIFO_TXTH_INT_MASK) == LPSPI_FIFO_TXTH_INT_MASK)
374 {
375 lpspi->FIFOCTL |= LPSPI_FIFOCTL_TXTHIEN_Msk;
376 }
377
378 /* Enable RX threshold interrupt flag */
379 if((u32Mask & LPSPI_FIFO_RXTH_INT_MASK) == LPSPI_FIFO_RXTH_INT_MASK)
380 {
381 lpspi->FIFOCTL |= LPSPI_FIFOCTL_RXTHIEN_Msk;
382 }
383
384 /* Enable RX overrun interrupt flag */
385 if((u32Mask & LPSPI_FIFO_RXOV_INT_MASK) == LPSPI_FIFO_RXOV_INT_MASK)
386 {
387 lpspi->FIFOCTL |= LPSPI_FIFOCTL_RXOVIEN_Msk;
388 }
389
390 /* Enable RX time-out interrupt flag */
391 if((u32Mask & LPSPI_FIFO_RXTO_INT_MASK) == LPSPI_FIFO_RXTO_INT_MASK)
392 {
393 lpspi->FIFOCTL |= LPSPI_FIFOCTL_RXTOIEN_Msk;
394 }
395 }
396
397 /**
398 * @brief Disable interrupt function.
399 * @param[in] lpspi The pointer of the specified LPSPI module.
400 * @param[in] u32Mask The combination of all related interrupt enable bits.
401 * Each bit corresponds to a interrupt bit.
402 * This parameter decides which interrupts will be disabled. It is combination of:
403 * - \ref LPSPI_UNIT_INT_MASK
404 * - \ref LPSPI_SSACT_INT_MASK
405 * - \ref LPSPI_SSINACT_INT_MASK
406 * - \ref LPSPI_SLVUR_INT_MASK
407 * - \ref LPSPI_SLVBE_INT_MASK
408 * - \ref LPSPI_TXUF_INT_MASK
409 * - \ref LPSPI_FIFO_TXTH_INT_MASK
410 * - \ref LPSPI_FIFO_RXTH_INT_MASK
411 * - \ref LPSPI_FIFO_RXOV_INT_MASK
412 * - \ref LPSPI_FIFO_RXTO_INT_MASK
413 *
414 * @return None
415 * @details Disable LPSPI related interrupts specified by u32Mask parameter.
416 */
LPSPI_DisableInt(LPSPI_T * lpspi,uint32_t u32Mask)417 void LPSPI_DisableInt(LPSPI_T *lpspi, uint32_t u32Mask)
418 {
419 /* Disable unit transfer interrupt flag */
420 if((u32Mask & LPSPI_UNIT_INT_MASK) == LPSPI_UNIT_INT_MASK)
421 {
422 lpspi->CTL &= ~LPSPI_CTL_UNITIEN_Msk;
423 }
424
425 /* Disable slave selection signal active interrupt flag */
426 if((u32Mask & LPSPI_SSACT_INT_MASK) == LPSPI_SSACT_INT_MASK)
427 {
428 lpspi->SSCTL &= ~LPSPI_SSCTL_SSACTIEN_Msk;
429 }
430
431 /* Disable slave selection signal inactive interrupt flag */
432 if((u32Mask & LPSPI_SSINACT_INT_MASK) == LPSPI_SSINACT_INT_MASK)
433 {
434 lpspi->SSCTL &= ~LPSPI_SSCTL_SSINAIEN_Msk;
435 }
436
437 /* Disable slave TX under run interrupt flag */
438 if((u32Mask & LPSPI_SLVUR_INT_MASK) == LPSPI_SLVUR_INT_MASK)
439 {
440 lpspi->SSCTL &= ~LPSPI_SSCTL_SLVURIEN_Msk;
441 }
442
443 /* Disable slave bit count error interrupt flag */
444 if((u32Mask & LPSPI_SLVBE_INT_MASK) == LPSPI_SLVBE_INT_MASK)
445 {
446 lpspi->SSCTL &= ~LPSPI_SSCTL_SLVBEIEN_Msk;
447 }
448
449 /* Disable slave TX underflow interrupt flag */
450 if((u32Mask & LPSPI_TXUF_INT_MASK) == LPSPI_TXUF_INT_MASK)
451 {
452 lpspi->FIFOCTL &= ~LPSPI_FIFOCTL_TXUFIEN_Msk;
453 }
454
455 /* Disable TX threshold interrupt flag */
456 if((u32Mask & LPSPI_FIFO_TXTH_INT_MASK) == LPSPI_FIFO_TXTH_INT_MASK)
457 {
458 lpspi->FIFOCTL &= ~LPSPI_FIFOCTL_TXTHIEN_Msk;
459 }
460
461 /* Disable RX threshold interrupt flag */
462 if((u32Mask & LPSPI_FIFO_RXTH_INT_MASK) == LPSPI_FIFO_RXTH_INT_MASK)
463 {
464 lpspi->FIFOCTL &= ~LPSPI_FIFOCTL_RXTHIEN_Msk;
465 }
466
467 /* Disable RX overrun interrupt flag */
468 if((u32Mask & LPSPI_FIFO_RXOV_INT_MASK) == LPSPI_FIFO_RXOV_INT_MASK)
469 {
470 lpspi->FIFOCTL &= ~LPSPI_FIFOCTL_RXOVIEN_Msk;
471 }
472
473 /* Disable RX time-out interrupt flag */
474 if((u32Mask & LPSPI_FIFO_RXTO_INT_MASK) == LPSPI_FIFO_RXTO_INT_MASK)
475 {
476 lpspi->FIFOCTL &= ~LPSPI_FIFOCTL_RXTOIEN_Msk;
477 }
478 }
479
480 /**
481 * @brief Get interrupt flag.
482 * @param[in] lpspi The pointer of the specified LPSPI module.
483 * @param[in] u32Mask The combination of all related interrupt sources.
484 * Each bit corresponds to a interrupt source.
485 * This parameter decides which interrupt flags will be read. It is combination of:
486 * - \ref LPSPI_UNIT_INT_MASK
487 * - \ref LPSPI_SSACT_INT_MASK
488 * - \ref LPSPI_SSINACT_INT_MASK
489 * - \ref LPSPI_SLVUR_INT_MASK
490 * - \ref LPSPI_SLVBE_INT_MASK
491 * - \ref LPSPI_TXUF_INT_MASK
492 * - \ref LPSPI_FIFO_TXTH_INT_MASK
493 * - \ref LPSPI_FIFO_RXTH_INT_MASK
494 * - \ref LPSPI_FIFO_RXOV_INT_MASK
495 * - \ref LPSPI_FIFO_RXTO_INT_MASK
496 *
497 * @return Interrupt flags of selected sources.
498 * @details Get LPSPI related interrupt flags specified by u32Mask parameter.
499 */
LPSPI_GetIntFlag(LPSPI_T * lpspi,uint32_t u32Mask)500 uint32_t LPSPI_GetIntFlag(LPSPI_T *lpspi, uint32_t u32Mask)
501 {
502 uint32_t u32IntFlag = 0U, u32TmpVal;
503
504 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_UNITIF_Msk;
505 /* Check unit transfer interrupt flag */
506 if((u32Mask & LPSPI_UNIT_INT_MASK) && (u32TmpVal))
507 {
508 u32IntFlag |= LPSPI_UNIT_INT_MASK;
509 }
510
511 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_SSACTIF_Msk;
512 /* Check slave selection signal active interrupt flag */
513 if((u32Mask & LPSPI_SSACT_INT_MASK) && (u32TmpVal))
514 {
515 u32IntFlag |= LPSPI_SSACT_INT_MASK;
516 }
517
518 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_SSINAIF_Msk;
519 /* Check slave selection signal inactive interrupt flag */
520 if((u32Mask & LPSPI_SSINACT_INT_MASK) && (u32TmpVal))
521 {
522 u32IntFlag |= LPSPI_SSINACT_INT_MASK;
523 }
524
525 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_SLVURIF_Msk;
526 /* Check slave TX under run interrupt flag */
527 if((u32Mask & LPSPI_SLVUR_INT_MASK) && (u32TmpVal))
528 {
529 u32IntFlag |= LPSPI_SLVUR_INT_MASK;
530 }
531
532 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_SLVBEIF_Msk;
533 /* Check slave bit count error interrupt flag */
534 if((u32Mask & LPSPI_SLVBE_INT_MASK) && (u32TmpVal))
535 {
536 u32IntFlag |= LPSPI_SLVBE_INT_MASK;
537 }
538
539 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_TXUFIF_Msk;
540 /* Check slave TX underflow interrupt flag */
541 if((u32Mask & LPSPI_TXUF_INT_MASK) && (u32TmpVal))
542 {
543 u32IntFlag |= LPSPI_TXUF_INT_MASK;
544 }
545
546 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_TXTHIF_Msk;
547 /* Check TX threshold interrupt flag */
548 if((u32Mask & LPSPI_FIFO_TXTH_INT_MASK) && (u32TmpVal))
549 {
550 u32IntFlag |= LPSPI_FIFO_TXTH_INT_MASK;
551 }
552
553 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_RXTHIF_Msk;
554 /* Check RX threshold interrupt flag */
555 if((u32Mask & LPSPI_FIFO_RXTH_INT_MASK) && (u32TmpVal))
556 {
557 u32IntFlag |= LPSPI_FIFO_RXTH_INT_MASK;
558 }
559
560 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_RXOVIF_Msk;
561 /* Check RX overrun interrupt flag */
562 if((u32Mask & LPSPI_FIFO_RXOV_INT_MASK) && (u32TmpVal))
563 {
564 u32IntFlag |= LPSPI_FIFO_RXOV_INT_MASK;
565 }
566
567 u32TmpVal = lpspi->STATUS & LPSPI_STATUS_RXTOIF_Msk;
568 /* Check RX time-out interrupt flag */
569 if((u32Mask & LPSPI_FIFO_RXTO_INT_MASK) && (u32TmpVal))
570 {
571 u32IntFlag |= LPSPI_FIFO_RXTO_INT_MASK;
572 }
573
574 return u32IntFlag;
575 }
576
577 /**
578 * @brief Clear interrupt flag.
579 * @param[in] lpspi The pointer of the specified LPSPI module.
580 * @param[in] u32Mask The combination of all related interrupt sources.
581 * Each bit corresponds to a interrupt source.
582 * This parameter decides which interrupt flags will be cleared. It could be the combination of:
583 * - \ref LPSPI_UNIT_INT_MASK
584 * - \ref LPSPI_SSACT_INT_MASK
585 * - \ref LPSPI_SSINACT_INT_MASK
586 * - \ref LPSPI_SLVUR_INT_MASK
587 * - \ref LPSPI_SLVBE_INT_MASK
588 * - \ref LPSPI_TXUF_INT_MASK
589 * - \ref LPSPI_FIFO_RXOV_INT_MASK
590 * - \ref LPSPI_FIFO_RXTO_INT_MASK
591 *
592 * @return None
593 * @details Clear LPSPI related interrupt flags specified by u32Mask parameter.
594 */
LPSPI_ClearIntFlag(LPSPI_T * lpspi,uint32_t u32Mask)595 void LPSPI_ClearIntFlag(LPSPI_T *lpspi, uint32_t u32Mask)
596 {
597 if(u32Mask & LPSPI_UNIT_INT_MASK)
598 {
599 lpspi->STATUS = LPSPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
600 }
601
602 if(u32Mask & LPSPI_SSACT_INT_MASK)
603 {
604 lpspi->STATUS = LPSPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
605 }
606
607 if(u32Mask & LPSPI_SSINACT_INT_MASK)
608 {
609 lpspi->STATUS = LPSPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
610 }
611
612 if(u32Mask & LPSPI_SLVUR_INT_MASK)
613 {
614 lpspi->STATUS = LPSPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
615 }
616
617 if(u32Mask & LPSPI_SLVBE_INT_MASK)
618 {
619 lpspi->STATUS = LPSPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
620 }
621
622 if(u32Mask & LPSPI_TXUF_INT_MASK)
623 {
624 lpspi->STATUS = LPSPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
625 }
626
627 if(u32Mask & LPSPI_FIFO_RXOV_INT_MASK)
628 {
629 lpspi->STATUS = LPSPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
630 }
631
632 if(u32Mask & LPSPI_FIFO_RXTO_INT_MASK)
633 {
634 lpspi->STATUS = LPSPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
635 }
636 }
637
638 /**
639 * @brief Get LPSPI status.
640 * @param[in] lpspi The pointer of the specified LPSPI module.
641 * @param[in] u32Mask The combination of all related sources.
642 * Each bit corresponds to a source.
643 * This parameter decides which flags will be read. It is combination of:
644 * - \ref LPSPI_BUSY_MASK
645 * - \ref LPSPI_RX_EMPTY_MASK
646 * - \ref LPSPI_RX_FULL_MASK
647 * - \ref LPSPI_TX_EMPTY_MASK
648 * - \ref LPSPI_TX_FULL_MASK
649 * - \ref LPSPI_TXRX_RESET_MASK
650 * - \ref LPSPI_SPIEN_STS_MASK
651 * - \ref LPSPI_SSLINE_STS_MASK
652 *
653 * @return Flags of selected sources.
654 * @details Get LPSPI related status specified by u32Mask parameter.
655 */
LPSPI_GetStatus(LPSPI_T * lpspi,uint32_t u32Mask)656 uint32_t LPSPI_GetStatus(LPSPI_T *lpspi, uint32_t u32Mask)
657 {
658 uint32_t u32Flag = 0U, u32TmpValue;
659
660 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_BUSY_Msk;
661 /* Check busy status */
662 if((u32Mask & LPSPI_BUSY_MASK) && (u32TmpValue))
663 {
664 u32Flag |= LPSPI_BUSY_MASK;
665 }
666
667 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_RXEMPTY_Msk;
668 /* Check RX empty flag */
669 if((u32Mask & LPSPI_RX_EMPTY_MASK) && (u32TmpValue))
670 {
671 u32Flag |= LPSPI_RX_EMPTY_MASK;
672 }
673
674 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_RXFULL_Msk;
675 /* Check RX full flag */
676 if((u32Mask & LPSPI_RX_FULL_MASK) && (u32TmpValue))
677 {
678 u32Flag |= LPSPI_RX_FULL_MASK;
679 }
680
681 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_TXEMPTY_Msk;
682 /* Check TX empty flag */
683 if((u32Mask & LPSPI_TX_EMPTY_MASK) && (u32TmpValue))
684 {
685 u32Flag |= LPSPI_TX_EMPTY_MASK;
686 }
687
688 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_TXFULL_Msk;
689 /* Check TX full flag */
690 if((u32Mask & LPSPI_TX_FULL_MASK) && (u32TmpValue))
691 {
692 u32Flag |= LPSPI_TX_FULL_MASK;
693 }
694
695 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_TXRXRST_Msk;
696 /* Check TX/RX reset flag */
697 if((u32Mask & LPSPI_TXRX_RESET_MASK) && (u32TmpValue))
698 {
699 u32Flag |= LPSPI_TXRX_RESET_MASK;
700 }
701
702 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_SPIENSTS_Msk;
703 /* Check SPIEN flag */
704 if((u32Mask & LPSPI_SPIEN_STS_MASK) && (u32TmpValue))
705 {
706 u32Flag |= LPSPI_SPIEN_STS_MASK;
707 }
708
709 u32TmpValue = lpspi->STATUS & LPSPI_STATUS_SSLINE_Msk;
710 /* Check SPIx_SS line status */
711 if((u32Mask & LPSPI_SSLINE_STS_MASK) && (u32TmpValue))
712 {
713 u32Flag |= LPSPI_SSLINE_STS_MASK;
714 }
715
716 return u32Flag;
717 }
718
719 /*@}*/ /* end of group LPSPI_EXPORTED_FUNCTIONS */
720
721 /*@}*/ /* end of group LPSPI_Driver */
722
723 /*@}*/ /* end of group Standard_Driver */
724
725 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
726