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