1 /**************************************************************************//**
2  * @file     spi.c
3  * @version  V3.00
4  * @brief    SPI driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 #include "NuMicro.h"
10 
11 /** @addtogroup Standard_Driver Standard Driver
12   @{
13 */
14 
15 /** @addtogroup SPI_Driver SPI Driver
16   @{
17 */
18 
19 
20 /** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
21   @{
22 */
23 
24 static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s);
25 
26 /**
27   * @brief  This function make SPI module be ready to transfer.
28   * @param[in]  spi The pointer of the specified SPI module.
29   * @param[in]  u32MasterSlave Decides the SPI module is operating in master mode or in slave mode. (SPI_SLAVE, SPI_MASTER)
30   * @param[in]  u32SPIMode Decides the transfer timing. (SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3)
31   * @param[in]  u32DataWidth Decides the data width of a SPI transaction.
32   * @param[in]  u32BusClock The expected frequency of SPI bus clock in Hz.
33   * @return Actual frequency of SPI peripheral clock.
34   * @details By default, the SPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
35   *          slave selection function is disabled.
36   *          In Slave mode, the u32BusClock shall be NULL and the SPI clock divider setting will be 0.
37   *          The actual clock rate may be different from the target SPI clock rate.
38   *          For example, if the SPI source clock rate is 12 MHz and the target SPI bus clock rate is 7 MHz, the
39   *          actual SPI clock rate will be 6MHz.
40   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
41   * @note   If u32BusClock >= system clock frequency for Secure, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
42   * @note   If u32BusClock >= system clock frequency for Non-Secure, this function does not do anything to avoid the situation that the frequency of
43   *         SPI bus clock cannot be faster than the system clock rate. User should set up carefully.
44   * @note   If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
45   * @note   In slave mode for Secure, the SPI peripheral clock rate will equal to APB clock rate.
46   * @note   In slave mode for Non-Secure, the SPI peripheral clock rate will equal to the clock rate set in secure mode.
47   */
SPI_Open(SPI_T * spi,uint32_t u32MasterSlave,uint32_t u32SPIMode,uint32_t u32DataWidth,uint32_t u32BusClock)48 uint32_t SPI_Open(SPI_T *spi,
49                   uint32_t u32MasterSlave,
50                   uint32_t u32SPIMode,
51                   uint32_t u32DataWidth,
52                   uint32_t u32BusClock)
53 {
54     uint32_t u32ClkSrc = 0UL, u32Div, u32HCLKFreq, u32PCLK0Freq, u32PCLK1Freq, u32RetValue = 0UL;
55 
56     /* Disable I2S mode */
57     spi->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
58 
59     if(u32DataWidth == 32UL)
60     {
61         u32DataWidth = 0UL;
62     }
63 
64     /* Get system clock frequency */
65     u32HCLKFreq = CLK_GetHCLKFreq();
66     /* Get APB0 clock frequency */
67     u32PCLK0Freq = CLK_GetPCLK0Freq();
68     /* Get APB1 clock frequency */
69     u32PCLK1Freq = CLK_GetPCLK1Freq();
70 
71     if(u32MasterSlave == SPI_MASTER)
72     {
73         /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
74         spi->SSCTL = SPI_SS_ACTIVE_LOW;
75 
76         /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
77         spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
78 
79         if(u32BusClock >= u32HCLKFreq)
80         {
81             if(!(__PC() & NS_OFFSET))
82             {
83                 /* Select PCLK as the clock source of SPI */
84                 if((spi == SPI0) || (spi == SPI0_NS))
85                 {
86                     CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
87                 }
88                 else if((spi == SPI1) || (spi == SPI1_NS))
89                 {
90                     CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
91                 }
92                 else if((spi == SPI2) || (spi == SPI2_NS))
93                 {
94                     CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
95                 }
96                 else
97                 {
98                     CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
99                 }
100             }
101         }
102 
103         /* Check clock source of SPI */
104         if((spi == SPI0) || (spi == SPI0_NS))
105         {
106             if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
107             {
108                 u32ClkSrc = __HXT; /* Clock source is HXT */
109             }
110             else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
111             {
112                 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
113             }
114             else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
115             {
116                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
117             }
118             else
119             {
120                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
121             }
122         }
123         else if((spi == SPI1) || (spi == SPI1_NS))
124         {
125             if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
126             {
127                 u32ClkSrc = __HXT; /* Clock source is HXT */
128             }
129             else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
130             {
131                 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
132             }
133             else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
134             {
135                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
136             }
137             else
138             {
139                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
140             }
141         }
142         else if((spi == SPI2) || (spi == SPI2_NS))
143         {
144             if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
145             {
146                 u32ClkSrc = __HXT; /* Clock source is HXT */
147             }
148             else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
149             {
150                 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
151             }
152             else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
153             {
154                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
155             }
156             else
157             {
158                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
159             }
160         }
161         else
162         {
163             if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
164             {
165                 u32ClkSrc = __HXT; /* Clock source is HXT */
166             }
167             else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
168             {
169                 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
170             }
171             else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
172             {
173                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
174             }
175             else
176             {
177                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
178             }
179         }
180 
181         if(u32BusClock >= u32HCLKFreq)
182         {
183             /* Set DIVIDER = 0 */
184             spi->CLKDIV = 0UL;
185             /* Return master peripheral clock rate */
186             u32RetValue = u32ClkSrc;
187         }
188         else if(u32BusClock >= u32ClkSrc)
189         {
190             /* Set DIVIDER = 0 */
191             spi->CLKDIV = 0UL;
192             /* Return master peripheral clock rate */
193             u32RetValue = u32ClkSrc;
194         }
195         else if(u32BusClock == 0UL)
196         {
197             /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
198             spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
199             /* Return master peripheral clock rate */
200             u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
201         }
202         else
203         {
204             u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
205             if(u32Div > 0x1FFUL)
206             {
207                 u32Div = 0x1FFUL;
208                 spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
209                 /* Return master peripheral clock rate */
210                 u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
211             }
212             else
213             {
214                 spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
215                 /* Return master peripheral clock rate */
216                 u32RetValue = (u32ClkSrc / (u32Div + 1UL));
217             }
218         }
219     }
220     else     /* For slave mode, force the SPI peripheral clock rate to equal APB clock rate. */
221     {
222         /* Default setting: slave selection signal is low level active. */
223         spi->SSCTL = SPI_SS_ACTIVE_LOW;
224 
225         /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
226         spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
227 
228         /* Set DIVIDER = 0 */
229         spi->CLKDIV = 0UL;
230 
231         if(!(__PC() & NS_OFFSET))
232         {
233             /* Select PCLK as the clock source of SPI */
234             if((spi == SPI0) || (spi == SPI0_NS))
235             {
236                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
237                 /* Return slave peripheral clock rate */
238                 u32RetValue = u32PCLK1Freq;
239             }
240             else if((spi == SPI1) || (spi == SPI1_NS))
241             {
242                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
243                 /* Return slave peripheral clock rate */
244                 u32RetValue = u32PCLK0Freq;
245             }
246             else if((spi == SPI2) || (spi == SPI2_NS))
247             {
248                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
249                 /* Return slave peripheral clock rate */
250                 u32RetValue = u32PCLK1Freq;
251             }
252             else
253             {
254                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
255                 /* Return slave peripheral clock rate */
256                 u32RetValue = u32PCLK0Freq;
257             }
258         }
259         else
260         {
261             /* Check clock source of SPI */
262             if((spi == SPI0) || (spi == SPI0_NS))
263             {
264                 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
265                 {
266                     u32RetValue = __HXT; /* Clock source is HXT */
267                 }
268                 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
269                 {
270                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
271                 }
272                 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
273                 {
274                     u32RetValue = u32PCLK1Freq; /* Clock source is PCLK1 */
275                 }
276                 else
277                 {
278                     u32RetValue = __HIRC; /* Clock source is HIRC */
279                 }
280             }
281             else if((spi == SPI1) || (spi == SPI1_NS))
282             {
283                 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
284                 {
285                     u32RetValue = __HXT; /* Clock source is HXT */
286                 }
287                 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
288                 {
289                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
290                 }
291                 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
292                 {
293                     u32RetValue = u32PCLK0Freq; /* Clock source is PCLK0 */
294                 }
295                 else
296                 {
297                     u32RetValue = __HIRC; /* Clock source is HIRC */
298                 }
299             }
300             else if((spi == SPI2) || (spi == SPI2_NS))
301             {
302                 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
303                 {
304                     u32RetValue = __HXT; /* Clock source is HXT */
305                 }
306                 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
307                 {
308                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
309                 }
310                 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
311                 {
312                     u32RetValue = u32PCLK1Freq; /* Clock source is PCLK1 */
313                 }
314                 else
315                 {
316                     u32RetValue = __HIRC; /* Clock source is HIRC */
317                 }
318             }
319             else
320             {
321                 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
322                 {
323                     u32RetValue = __HXT; /* Clock source is HXT */
324                 }
325                 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
326                 {
327                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
328                 }
329                 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
330                 {
331                     u32RetValue = u32PCLK0Freq; /* Clock source is PCLK0 */
332                 }
333                 else
334                 {
335                     u32RetValue = __HIRC; /* Clock source is HIRC */
336                 }
337             }
338         }
339     }
340 
341     return u32RetValue;
342 }
343 
344 /**
345   * @brief  Disable SPI controller.
346   * @param[in]  spi The pointer of the specified SPI module.
347   * @return None
348   * @details Clear SPIEN bit of SPI_CTL register to disable SPI transfer control.
349   */
SPI_Close(SPI_T * spi)350 void SPI_Close(SPI_T *spi)
351 {
352     spi->CTL &= ~SPI_CTL_SPIEN_Msk;
353 }
354 
355 /**
356   * @brief  Clear RX FIFO buffer.
357   * @param[in]  spi The pointer of the specified SPI module.
358   * @return None
359   * @details This function will clear SPI RX FIFO buffer. The RXEMPTY (SPI_STATUS[8]) will be set to 1.
360   */
SPI_ClearRxFIFO(SPI_T * spi)361 void SPI_ClearRxFIFO(SPI_T *spi)
362 {
363     spi->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk;
364 }
365 
366 /**
367   * @brief  Clear TX FIFO buffer.
368   * @param[in]  spi The pointer of the specified SPI module.
369   * @return None
370   * @details This function will clear SPI TX FIFO buffer. The TXEMPTY (SPI_STATUS[16]) will be set to 1.
371   * @note The TX shift register will not be cleared.
372   */
SPI_ClearTxFIFO(SPI_T * spi)373 void SPI_ClearTxFIFO(SPI_T *spi)
374 {
375     spi->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk;
376 }
377 
378 /**
379   * @brief  Disable the automatic slave selection function.
380   * @param[in]  spi The pointer of the specified SPI module.
381   * @return None
382   * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
383   */
SPI_DisableAutoSS(SPI_T * spi)384 void SPI_DisableAutoSS(SPI_T *spi)
385 {
386     spi->SSCTL &= ~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SS_Msk);
387 }
388 
389 /**
390   * @brief  Enable the automatic slave selection function.
391   * @param[in]  spi The pointer of the specified SPI module.
392   * @param[in]  u32SSPinMask Specifies slave selection pins. (SPI_SS)
393   * @param[in]  u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW)
394   * @return None
395   * @details This function will enable the automatic slave selection function. Only available in Master mode.
396   *          The slave selection pin and the active level will be set in this function.
397   */
SPI_EnableAutoSS(SPI_T * spi,uint32_t u32SSPinMask,uint32_t u32ActiveLevel)398 void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
399 {
400     spi->SSCTL = (spi->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSCTL_AUTOSS_Msk);
401 }
402 
403 /**
404   * @brief  Set the SPI bus clock.
405   * @param[in]  spi The pointer of the specified SPI module.
406   * @param[in]  u32BusClock The expected frequency of SPI bus clock in Hz.
407   * @return Actual frequency of SPI bus clock.
408   * @details This function is only available in Master mode. The actual clock rate may be different from the target SPI bus clock rate.
409   *          For example, if the SPI source clock rate is 12 MHz and the target SPI bus clock rate is 7 MHz, the actual SPI bus clock
410   *          rate will be 6 MHz.
411   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
412   * @note   If u32BusClock >= system clock frequency for Secure, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
413   * @note   If u32BusClock >= system clock frequency for Non-Secure, this function does not do anything to avoid the situation that the frequency of
414   *         SPI bus clock cannot be faster than the system clock rate. User should set up carefully.
415   * @note   If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
416   */
SPI_SetBusClock(SPI_T * spi,uint32_t u32BusClock)417 uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
418 {
419     uint32_t u32ClkSrc, u32HCLKFreq;
420     uint32_t u32Div, u32RetValue;
421 
422     /* Get system clock frequency */
423     u32HCLKFreq = CLK_GetHCLKFreq();
424 
425     if(u32BusClock >= u32HCLKFreq)
426     {
427         if(!(__PC() & NS_OFFSET))
428         {
429             /* Select PCLK as the clock source of SPI */
430             if((spi == SPI0) || (spi == SPI0_NS))
431             {
432                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
433             }
434             else if((spi == SPI1) || (spi == SPI1_NS))
435             {
436                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
437             }
438             else if((spi == SPI2) || (spi == SPI2_NS))
439             {
440                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
441             }
442             else
443             {
444                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
445             }
446         }
447     }
448 
449     /* Check clock source of SPI */
450     if((spi == SPI0) || (spi == SPI0_NS))
451     {
452         if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
453         {
454             u32ClkSrc = __HXT; /* Clock source is HXT */
455         }
456         else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
457         {
458             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
459         }
460         else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
461         {
462             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
463         }
464         else
465         {
466             u32ClkSrc = __HIRC; /* Clock source is HIRC */
467         }
468     }
469     else if((spi == SPI1) || (spi == SPI1_NS))
470     {
471         if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
472         {
473             u32ClkSrc = __HXT; /* Clock source is HXT */
474         }
475         else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
476         {
477             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
478         }
479         else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
480         {
481             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
482         }
483         else
484         {
485             u32ClkSrc = __HIRC; /* Clock source is HIRC */
486         }
487     }
488     else if((spi == SPI2) || (spi == SPI2_NS))
489     {
490         if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
491         {
492             u32ClkSrc = __HXT; /* Clock source is HXT */
493         }
494         else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
495         {
496             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
497         }
498         else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
499         {
500             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
501         }
502         else
503         {
504             u32ClkSrc = __HIRC; /* Clock source is HIRC */
505         }
506     }
507     else
508     {
509         if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
510         {
511             u32ClkSrc = __HXT; /* Clock source is HXT */
512         }
513         else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
514         {
515             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
516         }
517         else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
518         {
519             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
520         }
521         else
522         {
523             u32ClkSrc = __HIRC; /* Clock source is HIRC */
524         }
525     }
526 
527     if(u32BusClock >= u32HCLKFreq)
528     {
529         /* Set DIVIDER = 0 */
530         spi->CLKDIV = 0UL;
531         /* Return master peripheral clock rate */
532         u32RetValue = u32ClkSrc;
533     }
534     else if(u32BusClock >= u32ClkSrc)
535     {
536         /* Set DIVIDER = 0 */
537         spi->CLKDIV = 0UL;
538         /* Return master peripheral clock rate */
539         u32RetValue = u32ClkSrc;
540     }
541     else if(u32BusClock == 0UL)
542     {
543         /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
544         spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
545         /* Return master peripheral clock rate */
546         u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
547     }
548     else
549     {
550         u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
551         if(u32Div > 0x1FFUL)
552         {
553             u32Div = 0x1FFUL;
554             spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
555             /* Return master peripheral clock rate */
556             u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
557         }
558         else
559         {
560             spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
561             /* Return master peripheral clock rate */
562             u32RetValue = (u32ClkSrc / (u32Div + 1UL));
563         }
564     }
565 
566     return u32RetValue;
567 }
568 
569 /**
570   * @brief  Configure FIFO threshold setting.
571   * @param[in]  spi The pointer of the specified SPI module.
572   * @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.
573   * @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.
574   * @return None
575   * @details Set TX FIFO threshold and RX FIFO threshold configurations.
576   */
SPI_SetFIFO(SPI_T * spi,uint32_t u32TxThreshold,uint32_t u32RxThreshold)577 void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
578 {
579     spi->FIFOCTL = (spi->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
580                    (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
581                    (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
582 }
583 
584 /**
585   * @brief  Get the actual frequency of SPI bus clock. Only available in Master mode.
586   * @param[in]  spi The pointer of the specified SPI module.
587   * @return Actual SPI bus clock frequency in Hz.
588   * @details This function will calculate the actual SPI bus clock rate according to the SPIxSEL and DIVIDER settings. Only available in Master mode.
589   */
SPI_GetBusClock(SPI_T * spi)590 uint32_t SPI_GetBusClock(SPI_T *spi)
591 {
592     uint32_t u32Div;
593     uint32_t u32ClkSrc;
594 
595     /* Get DIVIDER setting */
596     u32Div = (spi->CLKDIV & SPI_CLKDIV_DIVIDER_Msk) >> SPI_CLKDIV_DIVIDER_Pos;
597 
598     /* Check clock source of SPI */
599     if((spi == SPI0) || (spi == SPI0_NS))
600     {
601         if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
602         {
603             u32ClkSrc = __HXT; /* Clock source is HXT */
604         }
605         else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
606         {
607             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
608         }
609         else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
610         {
611             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
612         }
613         else
614         {
615             u32ClkSrc = __HIRC; /* Clock source is HIRC */
616         }
617     }
618     else if((spi == SPI1) || (spi == SPI1_NS))
619     {
620         if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
621         {
622             u32ClkSrc = __HXT; /* Clock source is HXT */
623         }
624         else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
625         {
626             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
627         }
628         else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
629         {
630             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
631         }
632         else
633         {
634             u32ClkSrc = __HIRC; /* Clock source is HIRC */
635         }
636     }
637     else if((spi == SPI2) || (spi == SPI2_NS))
638     {
639         if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
640         {
641             u32ClkSrc = __HXT; /* Clock source is HXT */
642         }
643         else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
644         {
645             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
646         }
647         else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
648         {
649             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
650         }
651         else
652         {
653             u32ClkSrc = __HIRC; /* Clock source is HIRC */
654         }
655     }
656     else
657     {
658         if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
659         {
660             u32ClkSrc = __HXT; /* Clock source is HXT */
661         }
662         else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
663         {
664             u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
665         }
666         else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
667         {
668             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
669         }
670         else
671         {
672             u32ClkSrc = __HIRC; /* Clock source is HIRC */
673         }
674     }
675 
676     /* Return SPI bus clock rate */
677     return (u32ClkSrc / (u32Div + 1UL));
678 }
679 
680 /**
681   * @brief  Enable interrupt function.
682   * @param[in]  spi The pointer of the specified SPI module.
683   * @param[in]  u32Mask The combination of all related interrupt enable bits.
684   *                     Each bit corresponds to a interrupt enable bit.
685   *                     This parameter decides which interrupts will be enabled. It is combination of:
686   *                       - \ref SPI_UNIT_INT_MASK
687   *                       - \ref SPI_SSACT_INT_MASK
688   *                       - \ref SPI_SSINACT_INT_MASK
689   *                       - \ref SPI_SLVUR_INT_MASK
690   *                       - \ref SPI_SLVBE_INT_MASK
691   *                       - \ref SPI_TXUF_INT_MASK
692   *                       - \ref SPI_FIFO_TXTH_INT_MASK
693   *                       - \ref SPI_FIFO_RXTH_INT_MASK
694   *                       - \ref SPI_FIFO_RXOV_INT_MASK
695   *                       - \ref SPI_FIFO_RXTO_INT_MASK
696   *
697   * @return None
698   * @details Enable SPI related interrupts specified by u32Mask parameter.
699   */
SPI_EnableInt(SPI_T * spi,uint32_t u32Mask)700 void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
701 {
702     /* Enable unit transfer interrupt flag */
703     if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
704     {
705         spi->CTL |= SPI_CTL_UNITIEN_Msk;
706     }
707 
708     /* Enable slave selection signal active interrupt flag */
709     if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
710     {
711         spi->SSCTL |= SPI_SSCTL_SSACTIEN_Msk;
712     }
713 
714     /* Enable slave selection signal inactive interrupt flag */
715     if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
716     {
717         spi->SSCTL |= SPI_SSCTL_SSINAIEN_Msk;
718     }
719 
720     /* Enable slave TX under run interrupt flag */
721     if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
722     {
723         spi->SSCTL |= SPI_SSCTL_SLVURIEN_Msk;
724     }
725 
726     /* Enable slave bit count error interrupt flag */
727     if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
728     {
729         spi->SSCTL |= SPI_SSCTL_SLVBEIEN_Msk;
730     }
731 
732     /* Enable slave TX underflow interrupt flag */
733     if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
734     {
735         spi->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
736     }
737 
738     /* Enable TX threshold interrupt flag */
739     if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
740     {
741         spi->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
742     }
743 
744     /* Enable RX threshold interrupt flag */
745     if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
746     {
747         spi->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
748     }
749 
750     /* Enable RX overrun interrupt flag */
751     if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
752     {
753         spi->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
754     }
755 
756     /* Enable RX time-out interrupt flag */
757     if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
758     {
759         spi->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
760     }
761 }
762 
763 /**
764   * @brief  Disable interrupt function.
765   * @param[in]  spi The pointer of the specified SPI module.
766   * @param[in]  u32Mask The combination of all related interrupt enable bits.
767   *                     Each bit corresponds to a interrupt bit.
768   *                     This parameter decides which interrupts will be disabled. It is combination of:
769   *                       - \ref SPI_UNIT_INT_MASK
770   *                       - \ref SPI_SSACT_INT_MASK
771   *                       - \ref SPI_SSINACT_INT_MASK
772   *                       - \ref SPI_SLVUR_INT_MASK
773   *                       - \ref SPI_SLVBE_INT_MASK
774   *                       - \ref SPI_TXUF_INT_MASK
775   *                       - \ref SPI_FIFO_TXTH_INT_MASK
776   *                       - \ref SPI_FIFO_RXTH_INT_MASK
777   *                       - \ref SPI_FIFO_RXOV_INT_MASK
778   *                       - \ref SPI_FIFO_RXTO_INT_MASK
779   *
780   * @return None
781   * @details Disable SPI related interrupts specified by u32Mask parameter.
782   */
SPI_DisableInt(SPI_T * spi,uint32_t u32Mask)783 void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
784 {
785     /* Disable unit transfer interrupt flag */
786     if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
787     {
788         spi->CTL &= ~SPI_CTL_UNITIEN_Msk;
789     }
790 
791     /* Disable slave selection signal active interrupt flag */
792     if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
793     {
794         spi->SSCTL &= ~SPI_SSCTL_SSACTIEN_Msk;
795     }
796 
797     /* Disable slave selection signal inactive interrupt flag */
798     if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
799     {
800         spi->SSCTL &= ~SPI_SSCTL_SSINAIEN_Msk;
801     }
802 
803     /* Disable slave TX under run interrupt flag */
804     if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
805     {
806         spi->SSCTL &= ~SPI_SSCTL_SLVURIEN_Msk;
807     }
808 
809     /* Disable slave bit count error interrupt flag */
810     if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
811     {
812         spi->SSCTL &= ~SPI_SSCTL_SLVBEIEN_Msk;
813     }
814 
815     /* Disable slave TX underflow interrupt flag */
816     if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
817     {
818         spi->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
819     }
820 
821     /* Disable TX threshold interrupt flag */
822     if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
823     {
824         spi->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
825     }
826 
827     /* Disable RX threshold interrupt flag */
828     if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
829     {
830         spi->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
831     }
832 
833     /* Disable RX overrun interrupt flag */
834     if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
835     {
836         spi->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
837     }
838 
839     /* Disable RX time-out interrupt flag */
840     if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
841     {
842         spi->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
843     }
844 }
845 
846 /**
847   * @brief  Get interrupt flag.
848   * @param[in]  spi The pointer of the specified SPI module.
849   * @param[in]  u32Mask The combination of all related interrupt sources.
850   *                     Each bit corresponds to a interrupt source.
851   *                     This parameter decides which interrupt flags will be read. It is combination of:
852   *                       - \ref SPI_UNIT_INT_MASK
853   *                       - \ref SPI_SSACT_INT_MASK
854   *                       - \ref SPI_SSINACT_INT_MASK
855   *                       - \ref SPI_SLVUR_INT_MASK
856   *                       - \ref SPI_SLVBE_INT_MASK
857   *                       - \ref SPI_TXUF_INT_MASK
858   *                       - \ref SPI_FIFO_TXTH_INT_MASK
859   *                       - \ref SPI_FIFO_RXTH_INT_MASK
860   *                       - \ref SPI_FIFO_RXOV_INT_MASK
861   *                       - \ref SPI_FIFO_RXTO_INT_MASK
862   *
863   * @return Interrupt flags of selected sources.
864   * @details Get SPI related interrupt flags specified by u32Mask parameter.
865   */
SPI_GetIntFlag(SPI_T * spi,uint32_t u32Mask)866 uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask)
867 {
868     uint32_t u32IntStatus;
869     uint32_t u32IntFlag = 0UL;
870 
871     u32IntStatus = spi->STATUS;
872 
873     /* Check unit transfer interrupt flag */
874     if((u32Mask & SPI_UNIT_INT_MASK) && (u32IntStatus & SPI_STATUS_UNITIF_Msk))
875     {
876         u32IntFlag |= SPI_UNIT_INT_MASK;
877     }
878 
879     /* Check slave selection signal active interrupt flag */
880     if((u32Mask & SPI_SSACT_INT_MASK) && (u32IntStatus & SPI_STATUS_SSACTIF_Msk))
881     {
882         u32IntFlag |= SPI_SSACT_INT_MASK;
883     }
884 
885     /* Check slave selection signal inactive interrupt flag */
886     if((u32Mask & SPI_SSINACT_INT_MASK) && (u32IntStatus & SPI_STATUS_SSINAIF_Msk))
887     {
888         u32IntFlag |= SPI_SSINACT_INT_MASK;
889     }
890 
891     /* Check slave TX under run interrupt flag */
892     if((u32Mask & SPI_SLVUR_INT_MASK) && (u32IntStatus & SPI_STATUS_SLVURIF_Msk))
893     {
894         u32IntFlag |= SPI_SLVUR_INT_MASK;
895     }
896 
897     /* Check slave bit count error interrupt flag */
898     if((u32Mask & SPI_SLVBE_INT_MASK) && (u32IntStatus & SPI_STATUS_SLVBEIF_Msk))
899     {
900         u32IntFlag |= SPI_SLVBE_INT_MASK;
901     }
902 
903     /* Check slave TX underflow interrupt flag */
904     if((u32Mask & SPI_TXUF_INT_MASK) && (u32IntStatus & SPI_STATUS_TXUFIF_Msk))
905     {
906         u32IntFlag |= SPI_TXUF_INT_MASK;
907     }
908 
909     /* Check TX threshold interrupt flag */
910     if((u32Mask & SPI_FIFO_TXTH_INT_MASK) && (u32IntStatus & SPI_STATUS_TXTHIF_Msk))
911     {
912         u32IntFlag |= SPI_FIFO_TXTH_INT_MASK;
913     }
914 
915     /* Check RX threshold interrupt flag */
916     if((u32Mask & SPI_FIFO_RXTH_INT_MASK) && (u32IntStatus & SPI_STATUS_RXTHIF_Msk))
917     {
918         u32IntFlag |= SPI_FIFO_RXTH_INT_MASK;
919     }
920 
921     /* Check RX overrun interrupt flag */
922     if((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (u32IntStatus & SPI_STATUS_RXOVIF_Msk))
923     {
924         u32IntFlag |= SPI_FIFO_RXOV_INT_MASK;
925     }
926 
927     /* Check RX time-out interrupt flag */
928     if((u32Mask & SPI_FIFO_RXTO_INT_MASK) && (u32IntStatus & SPI_STATUS_RXTOIF_Msk))
929     {
930         u32IntFlag |= SPI_FIFO_RXTO_INT_MASK;
931     }
932 
933     return u32IntFlag;
934 }
935 
936 /**
937   * @brief  Clear interrupt flag.
938   * @param[in]  spi The pointer of the specified SPI module.
939   * @param[in]  u32Mask The combination of all related interrupt sources.
940   *                     Each bit corresponds to a interrupt source.
941   *                     This parameter decides which interrupt flags will be cleared. It could be the combination of:
942   *                       - \ref SPI_UNIT_INT_MASK
943   *                       - \ref SPI_SSACT_INT_MASK
944   *                       - \ref SPI_SSINACT_INT_MASK
945   *                       - \ref SPI_SLVUR_INT_MASK
946   *                       - \ref SPI_SLVBE_INT_MASK
947   *                       - \ref SPI_TXUF_INT_MASK
948   *                       - \ref SPI_FIFO_RXOV_INT_MASK
949   *                       - \ref SPI_FIFO_RXTO_INT_MASK
950   *
951   * @return None
952   * @details Clear SPI related interrupt flags specified by u32Mask parameter.
953   */
SPI_ClearIntFlag(SPI_T * spi,uint32_t u32Mask)954 void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask)
955 {
956     if(u32Mask & SPI_UNIT_INT_MASK)
957     {
958         spi->STATUS = SPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
959     }
960 
961     if(u32Mask & SPI_SSACT_INT_MASK)
962     {
963         spi->STATUS = SPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
964     }
965 
966     if(u32Mask & SPI_SSINACT_INT_MASK)
967     {
968         spi->STATUS = SPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
969     }
970 
971     if(u32Mask & SPI_SLVUR_INT_MASK)
972     {
973         spi->STATUS = SPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
974     }
975 
976     if(u32Mask & SPI_SLVBE_INT_MASK)
977     {
978         spi->STATUS = SPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
979     }
980 
981     if(u32Mask & SPI_TXUF_INT_MASK)
982     {
983         spi->STATUS = SPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
984     }
985 
986     if(u32Mask & SPI_FIFO_RXOV_INT_MASK)
987     {
988         spi->STATUS = SPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
989     }
990 
991     if(u32Mask & SPI_FIFO_RXTO_INT_MASK)
992     {
993         spi->STATUS = SPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
994     }
995 }
996 
997 /**
998   * @brief  Get SPI status.
999   * @param[in]  spi The pointer of the specified SPI module.
1000   * @param[in]  u32Mask The combination of all related sources.
1001   *                     Each bit corresponds to a source.
1002   *                     This parameter decides which flags will be read. It is combination of:
1003   *                       - \ref SPI_BUSY_MASK
1004   *                       - \ref SPI_RX_EMPTY_MASK
1005   *                       - \ref SPI_RX_FULL_MASK
1006   *                       - \ref SPI_TX_EMPTY_MASK
1007   *                       - \ref SPI_TX_FULL_MASK
1008   *                       - \ref SPI_TXRX_RESET_MASK
1009   *                       - \ref SPI_SPIEN_STS_MASK
1010   *                       - \ref SPI_SSLINE_STS_MASK
1011   *
1012   * @return Flags of selected sources.
1013   * @details Get SPI related status specified by u32Mask parameter.
1014   */
SPI_GetStatus(SPI_T * spi,uint32_t u32Mask)1015 uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask)
1016 {
1017     uint32_t u32TmpStatus;
1018     uint32_t u32Flag = 0UL;
1019 
1020     u32TmpStatus = spi->STATUS;
1021 
1022     /* Check busy status */
1023     if((u32Mask & SPI_BUSY_MASK) && (u32TmpStatus & SPI_STATUS_BUSY_Msk))
1024     {
1025         u32Flag |= SPI_BUSY_MASK;
1026     }
1027 
1028     /* Check RX empty flag */
1029     if((u32Mask & SPI_RX_EMPTY_MASK) && (u32TmpStatus & SPI_STATUS_RXEMPTY_Msk))
1030     {
1031         u32Flag |= SPI_RX_EMPTY_MASK;
1032     }
1033 
1034     /* Check RX full flag */
1035     if((u32Mask & SPI_RX_FULL_MASK) && (u32TmpStatus & SPI_STATUS_RXFULL_Msk))
1036     {
1037         u32Flag |= SPI_RX_FULL_MASK;
1038     }
1039 
1040     /* Check TX empty flag */
1041     if((u32Mask & SPI_TX_EMPTY_MASK) && (u32TmpStatus & SPI_STATUS_TXEMPTY_Msk))
1042     {
1043         u32Flag |= SPI_TX_EMPTY_MASK;
1044     }
1045 
1046     /* Check TX full flag */
1047     if((u32Mask & SPI_TX_FULL_MASK) && (u32TmpStatus & SPI_STATUS_TXFULL_Msk))
1048     {
1049         u32Flag |= SPI_TX_FULL_MASK;
1050     }
1051 
1052     /* Check TX/RX reset flag */
1053     if((u32Mask & SPI_TXRX_RESET_MASK) && (u32TmpStatus & SPI_STATUS_TXRXRST_Msk))
1054     {
1055         u32Flag |= SPI_TXRX_RESET_MASK;
1056     }
1057 
1058     /* Check SPIEN flag */
1059     if((u32Mask & SPI_SPIEN_STS_MASK) && (u32TmpStatus & SPI_STATUS_SPIENSTS_Msk))
1060     {
1061         u32Flag |= SPI_SPIEN_STS_MASK;
1062     }
1063 
1064     /* Check SPIx_SS line status */
1065     if((u32Mask & SPI_SSLINE_STS_MASK) && (u32TmpStatus & SPI_STATUS_SSLINE_Msk))
1066     {
1067         u32Flag |= SPI_SSLINE_STS_MASK;
1068     }
1069 
1070     return u32Flag;
1071 }
1072 
1073 /**
1074   * @brief  Get SPI status2.
1075   * @param[in]  spi The pointer of the specified SPI module.
1076   * @param[in]  u32Mask The combination of all related sources.
1077   *                     Each bit corresponds to a source.
1078   *                     This parameter decides which flags will be read. It is combination of:
1079   *                       - \ref SPI_SLVBENUM_MASK
1080   *
1081   * @return Flags of selected sources.
1082   * @details Get SPI related status specified by u32Mask parameter.
1083   */
SPI_GetStatus2(SPI_T * spi,uint32_t u32Mask)1084 uint32_t SPI_GetStatus2(SPI_T *spi, uint32_t u32Mask)
1085 {
1086     uint32_t u32TmpStatus;
1087     uint32_t u32Number = 0UL;
1088 
1089     u32TmpStatus = spi->STATUS2;
1090 
1091     /* Check effective bit number of uncompleted RX data status */
1092     if(u32Mask & SPI_SLVBENUM_MASK)
1093     {
1094         u32Number = (u32TmpStatus & SPI_STATUS2_SLVBENUM_Msk) >> SPI_STATUS2_SLVBENUM_Pos;
1095     }
1096 
1097     return u32Number;
1098 }
1099 
1100 
1101 /**
1102   * @brief  This function is used to get I2S source clock frequency.
1103   * @param[in]  i2s The pointer of the specified I2S module.
1104   * @return I2S source clock frequency (Hz).
1105   * @details Return the source clock frequency according to the setting of SPI0SEL (CLK_CLKSEL2[5:4]) or SPI1SEL (CLK_CLKSEL2[7:6]) or SPI2SEL (CLK_CLKSEL2[11:10]) or SPI3SEL (CLK_CLKSEL2[13:12]).
1106   */
SPII2S_GetSourceClockFreq(SPI_T * i2s)1107 static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s)
1108 {
1109     uint32_t u32Freq;
1110 
1111     if((i2s == SPI0) || (i2s == SPI0_NS))
1112     {
1113         if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
1114         {
1115             u32Freq = __HXT; /* Clock source is HXT */
1116         }
1117         else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
1118         {
1119             u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1120         }
1121         else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
1122         {
1123             u32Freq = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1124         }
1125         else
1126         {
1127             u32Freq = __HIRC; /* Clock source is HIRC */
1128         }
1129     }
1130     else if((i2s == SPI1) || (i2s == SPI1_NS))
1131     {
1132         if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
1133         {
1134             u32Freq = __HXT; /* Clock source is HXT */
1135         }
1136         else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
1137         {
1138             u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1139         }
1140         else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
1141         {
1142             u32Freq = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1143         }
1144         else
1145         {
1146             u32Freq = __HIRC; /* Clock source is HIRC */
1147         }
1148     }
1149     else if((i2s == SPI2) || (i2s == SPI2_NS))
1150     {
1151         if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
1152         {
1153             u32Freq = __HXT; /* Clock source is HXT */
1154         }
1155         else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
1156         {
1157             u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1158         }
1159         else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
1160         {
1161             u32Freq = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1162         }
1163         else
1164         {
1165             u32Freq = __HIRC; /* Clock source is HIRC */
1166         }
1167     }
1168     else
1169     {
1170         if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
1171         {
1172             u32Freq = __HXT; /* Clock source is HXT */
1173         }
1174         else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
1175         {
1176             u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1177         }
1178         else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
1179         {
1180             u32Freq = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1181         }
1182         else
1183         {
1184             u32Freq = __HIRC; /* Clock source is HIRC */
1185         }
1186     }
1187 
1188     return u32Freq;
1189 }
1190 
1191 /**
1192   * @brief  This function configures some parameters of I2S interface for general purpose use.
1193   * @param[in] i2s The pointer of the specified I2S module.
1194   * @param[in] u32MasterSlave I2S operation mode. Valid values are listed below.
1195   *                                     - \ref SPII2S_MODE_MASTER
1196   *                                     - \ref SPII2S_MODE_SLAVE
1197   * @param[in] u32SampleRate Sample rate
1198   * @param[in] u32WordWidth Data length. Valid values are listed below.
1199   *                                     - \ref SPII2S_DATABIT_8
1200   *                                     - \ref SPII2S_DATABIT_16
1201   *                                     - \ref SPII2S_DATABIT_24
1202   *                                     - \ref SPII2S_DATABIT_32
1203   * @param[in] u32Channels Audio format. Valid values are listed below.
1204   *                                     - \ref SPII2S_MONO
1205   *                                     - \ref SPII2S_STEREO
1206   * @param[in] u32DataFormat Data format. Valid values are listed below.
1207   *                                     - \ref SPII2S_FORMAT_I2S
1208   *                                     - \ref SPII2S_FORMAT_MSB
1209   *                                     - \ref SPII2S_FORMAT_PCMA
1210   *                                     - \ref SPII2S_FORMAT_PCMB
1211   * @return Real sample rate of master mode or peripheral clock rate of slave mode.
1212   * @details This function will reset SPI/I2S controller and configure I2S controller according to the input parameters.
1213   *          Set TX FIFO threshold to 2 and RX FIFO threshold to 1. Both the TX and RX functions will be enabled.
1214   *          The actual sample rate may be different from the target sample rate. The real sample rate will be returned for reference.
1215   * @note   In slave mode for Secure, the SPI peripheral clock rate will equal to APB clock rate.
1216   * @note   In slave mode for Non-Secure, the SPI peripheral clock rate will equal to the clock rate set in secure mode.
1217   */
SPII2S_Open(SPI_T * i2s,uint32_t u32MasterSlave,uint32_t u32SampleRate,uint32_t u32WordWidth,uint32_t u32Channels,uint32_t u32DataFormat)1218 uint32_t SPII2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat)
1219 {
1220     uint32_t u32Divider;
1221     uint32_t u32BitRate, u32SrcClk, u32RetValue;
1222     uint32_t u32PCLK0Freq, u32PCLK1Freq;
1223 
1224     if(!(__PC() & NS_OFFSET))
1225     {
1226         /* Reset SPI/I2S */
1227         if((i2s == SPI0) || (i2s == SPI0_NS))
1228         {
1229             SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk;
1230             SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk;
1231         }
1232         else if((i2s == SPI1) || (i2s == SPI1_NS))
1233         {
1234             SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk;
1235             SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk;
1236         }
1237         else if((i2s == SPI2) || (i2s == SPI2_NS))
1238         {
1239             SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk;
1240             SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk;
1241         }
1242         else
1243         {
1244             SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
1245             SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
1246         }
1247     }
1248 
1249     /* Configure I2S controller */
1250     i2s->I2SCTL = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat;
1251     /* Set TX FIFO threshold to 2 and RX FIFO threshold to 1 */
1252     i2s->FIFOCTL = SPII2S_FIFO_TX_LEVEL_WORD_2 | SPII2S_FIFO_RX_LEVEL_WORD_2;
1253 
1254     if(u32MasterSlave == SPII2S_MODE_MASTER)
1255     {
1256         /* Get the source clock rate */
1257         u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
1258 
1259         /* Calculate the bit clock rate */
1260         u32BitRate = u32SampleRate * ((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1UL) * 16UL;
1261         u32Divider = (((((u32SrcClk * 10UL) / u32BitRate) >> 1UL) + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
1262         /* Set BCLKDIV setting */
1263         i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_BCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_BCLKDIV_Pos);
1264         /* Enable I2S mode for the frequency of peripheral clock. */
1265         i2s->I2SCLK |= SPI_I2SCLK_I2SMODE_Msk;
1266 
1267         /* Calculate bit clock rate */
1268         u32BitRate = u32SrcClk / ((u32Divider + 1UL) * 2UL);
1269         /* Calculate real sample rate */
1270         u32SampleRate = u32BitRate / (((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1UL) * 16UL);
1271 
1272         /* Enable TX function, RX function and I2S mode. */
1273         i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1274 
1275         /* Return the real sample rate */
1276         u32RetValue = u32SampleRate;
1277     }
1278     else
1279     {
1280         /* Set BCLKDIV = 0 */
1281         i2s->I2SCLK &= ~SPI_I2SCLK_BCLKDIV_Msk;
1282         /* Get APB0 clock frequency */
1283         u32PCLK0Freq = CLK_GetPCLK0Freq();
1284         /* Get APB1 clock frequency */
1285         u32PCLK1Freq = CLK_GetPCLK1Freq();
1286 
1287         if((i2s == SPI0) || (i2s == SPI0_NS))
1288         {
1289             if(!(__PC() & NS_OFFSET))
1290             {
1291                 /* Set the peripheral clock rate to equal APB clock rate */
1292                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
1293                 /* Return slave peripheral clock rate */
1294                 u32RetValue = u32PCLK1Freq;
1295             }
1296             else
1297             {
1298                 /* Check clock source of I2S */
1299                 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
1300                 {
1301                     u32RetValue = __HXT; /* Clock source is HXT */
1302                 }
1303                 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
1304                 {
1305                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1306                 }
1307                 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
1308                 {
1309                     u32RetValue = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1310                 }
1311                 else
1312                 {
1313                     u32RetValue = __HIRC; /* Clock source is HIRC */
1314                 }
1315             }
1316             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1317             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1318             /* Enable TX function, RX function and I2S mode. */
1319             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1320         }
1321         else if((i2s == SPI1) || (i2s == SPI1_NS))
1322         {
1323             if(!(__PC() & NS_OFFSET))
1324             {
1325                 /* Set the peripheral clock rate to equal APB clock rate */
1326                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
1327                 /* Return slave peripheral clock rate */
1328                 u32RetValue = u32PCLK0Freq;
1329             }
1330             else
1331             {
1332                 /* Check clock source of I2S */
1333                 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
1334                 {
1335                     u32RetValue = __HXT; /* Clock source is HXT */
1336                 }
1337                 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
1338                 {
1339                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1340                 }
1341                 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
1342                 {
1343                     u32RetValue = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1344                 }
1345                 else
1346                 {
1347                     u32RetValue = __HIRC; /* Clock source is HIRC */
1348                 }
1349             }
1350             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1351             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1352             /* Enable TX function, RX function and I2S mode. */
1353             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1354         }
1355         else if((i2s == SPI2) || (i2s == SPI2_NS))
1356         {
1357             if(!(__PC() & NS_OFFSET))
1358             {
1359                 /* Set the peripheral clock rate to equal APB clock rate */
1360                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
1361                 /* Return slave peripheral clock rate */
1362                 u32RetValue = u32PCLK1Freq;
1363             }
1364             else
1365             {
1366                 /* Check clock source of I2S */
1367                 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
1368                 {
1369                     u32RetValue = __HXT; /* Clock source is HXT */
1370                 }
1371                 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
1372                 {
1373                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1374                 }
1375                 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
1376                 {
1377                     u32RetValue = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1378                 }
1379                 else
1380                 {
1381                     u32RetValue = __HIRC; /* Clock source is HIRC */
1382                 }
1383             }
1384             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1385             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1386             /* Enable TX function, RX function and I2S mode. */
1387             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1388         }
1389         else
1390         {
1391             if(!(__PC() & NS_OFFSET))
1392             {
1393                 /* Set the peripheral clock rate to equal APB clock rate */
1394                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
1395                 /* Return slave peripheral clock rate */
1396                 u32RetValue = u32PCLK0Freq;
1397             }
1398             else
1399             {
1400                 /* Check clock source of I2S */
1401                 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
1402                 {
1403                     u32RetValue = __HXT; /* Clock source is HXT */
1404                 }
1405                 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
1406                 {
1407                     u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
1408                 }
1409                 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
1410                 {
1411                     u32RetValue = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1412                 }
1413                 else
1414                 {
1415                     u32RetValue = __HIRC; /* Clock source is HIRC */
1416                 }
1417             }
1418             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1419             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1420             /* Enable TX function, RX function and I2S mode. */
1421             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1422         }
1423     }
1424 
1425     return u32RetValue;
1426 }
1427 
1428 /**
1429   * @brief  Disable I2S function.
1430   * @param[in]  i2s The pointer of the specified I2S module.
1431   * @return None
1432   * @details Disable I2S function.
1433   */
SPII2S_Close(SPI_T * i2s)1434 void SPII2S_Close(SPI_T *i2s)
1435 {
1436     i2s->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
1437 }
1438 
1439 /**
1440   * @brief Enable interrupt function.
1441   * @param[in] i2s The pointer of the specified I2S module.
1442   * @param[in] u32Mask The combination of all related interrupt enable bits.
1443   *            Each bit corresponds to a interrupt source. Valid values are listed below.
1444   *            - \ref SPII2S_FIFO_TXTH_INT_MASK
1445   *            - \ref SPII2S_FIFO_RXTH_INT_MASK
1446   *            - \ref SPII2S_FIFO_RXOV_INT_MASK
1447   *            - \ref SPII2S_FIFO_RXTO_INT_MASK
1448   *            - \ref SPII2S_TXUF_INT_MASK
1449   *            - \ref SPII2S_RIGHT_ZC_INT_MASK
1450   *            - \ref SPII2S_LEFT_ZC_INT_MASK
1451   *            - \ref SPII2S_SLAVE_ERR_INT_MASK
1452   * @return None
1453   * @details This function enables the interrupt according to the u32Mask parameter.
1454   */
SPII2S_EnableInt(SPI_T * i2s,uint32_t u32Mask)1455 void SPII2S_EnableInt(SPI_T *i2s, uint32_t u32Mask)
1456 {
1457     /* Enable TX threshold interrupt flag */
1458     if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
1459     {
1460         i2s->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
1461     }
1462 
1463     /* Enable RX threshold interrupt flag */
1464     if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
1465     {
1466         i2s->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
1467     }
1468 
1469     /* Enable RX overrun interrupt flag */
1470     if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
1471     {
1472         i2s->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
1473     }
1474 
1475     /* Enable RX time-out interrupt flag */
1476     if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
1477     {
1478         i2s->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
1479     }
1480 
1481     /* Enable TX underflow interrupt flag */
1482     if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
1483     {
1484         i2s->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
1485     }
1486 
1487     /* Enable right channel zero cross interrupt flag */
1488     if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
1489     {
1490         i2s->I2SCTL |= SPI_I2SCTL_RZCIEN_Msk;
1491     }
1492 
1493     /* Enable left channel zero cross interrupt flag */
1494     if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
1495     {
1496         i2s->I2SCTL |= SPI_I2SCTL_LZCIEN_Msk;
1497     }
1498 
1499     /* Enable bit clock loss interrupt flag */
1500     if((u32Mask & SPII2S_SLAVE_ERR_INT_MASK) == SPII2S_SLAVE_ERR_INT_MASK)
1501     {
1502         i2s->I2SCTL |= SPI_I2SCTL_SLVERRIEN_Msk;
1503     }
1504 }
1505 
1506 /**
1507   * @brief Disable interrupt function.
1508   * @param[in] i2s The pointer of the specified I2S module.
1509   * @param[in] u32Mask The combination of all related interrupt enable bits.
1510   *            Each bit corresponds to a interrupt source. Valid values are listed below.
1511   *            - \ref SPII2S_FIFO_TXTH_INT_MASK
1512   *            - \ref SPII2S_FIFO_RXTH_INT_MASK
1513   *            - \ref SPII2S_FIFO_RXOV_INT_MASK
1514   *            - \ref SPII2S_FIFO_RXTO_INT_MASK
1515   *            - \ref SPII2S_TXUF_INT_MASK
1516   *            - \ref SPII2S_RIGHT_ZC_INT_MASK
1517   *            - \ref SPII2S_LEFT_ZC_INT_MASK
1518   *            - \ref SPII2S_SLAVE_ERR_INT_MASK
1519   * @return None
1520   * @details This function disables the interrupt according to the u32Mask parameter.
1521   */
SPII2S_DisableInt(SPI_T * i2s,uint32_t u32Mask)1522 void SPII2S_DisableInt(SPI_T *i2s, uint32_t u32Mask)
1523 {
1524     /* Disable TX threshold interrupt flag */
1525     if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
1526     {
1527         i2s->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
1528     }
1529 
1530     /* Disable RX threshold interrupt flag */
1531     if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
1532     {
1533         i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
1534     }
1535 
1536     /* Disable RX overrun interrupt flag */
1537     if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
1538     {
1539         i2s->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
1540     }
1541 
1542     /* Disable RX time-out interrupt flag */
1543     if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
1544     {
1545         i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
1546     }
1547 
1548     /* Disable TX underflow interrupt flag */
1549     if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
1550     {
1551         i2s->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
1552     }
1553 
1554     /* Disable right channel zero cross interrupt flag */
1555     if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
1556     {
1557         i2s->I2SCTL &= ~SPI_I2SCTL_RZCIEN_Msk;
1558     }
1559 
1560     /* Disable left channel zero cross interrupt flag */
1561     if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
1562     {
1563         i2s->I2SCTL &= ~SPI_I2SCTL_LZCIEN_Msk;
1564     }
1565 
1566     /* Disable bit clock loss interrupt flag */
1567     if((u32Mask & SPII2S_SLAVE_ERR_INT_MASK) == SPII2S_SLAVE_ERR_INT_MASK)
1568     {
1569         i2s->I2SCTL &= ~SPI_I2SCTL_SLVERRIEN_Msk;
1570     }
1571 }
1572 
1573 /**
1574   * @brief  Enable master clock (MCLK).
1575   * @param[in] i2s The pointer of the specified I2S module.
1576   * @param[in] u32BusClock The target MCLK clock rate.
1577   * @return Actual MCLK clock rate
1578   * @details Set the master clock rate according to u32BusClock parameter and enable master clock output.
1579   *          The actual master clock rate may be different from the target master clock rate. The real master clock rate will be returned for reference.
1580   */
SPII2S_EnableMCLK(SPI_T * i2s,uint32_t u32BusClock)1581 uint32_t SPII2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock)
1582 {
1583     uint32_t u32Divider;
1584     uint32_t u32SrcClk, u32RetValue;
1585 
1586     u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
1587     if(u32BusClock == u32SrcClk)
1588     {
1589         u32Divider = 0UL;
1590     }
1591     else
1592     {
1593         u32Divider = (u32SrcClk / u32BusClock) >> 1UL;
1594         /* MCLKDIV is a 7-bit width configuration. The maximum value is 0x7F. */
1595         if(u32Divider > 0x7FUL)
1596         {
1597             u32Divider = 0x7FUL;
1598         }
1599     }
1600 
1601     /* Write u32Divider to MCLKDIV (SPI_I2SCLK[6:0]) */
1602     i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_MCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_MCLKDIV_Pos);
1603 
1604     /* Enable MCLK output */
1605     i2s->I2SCTL |= SPI_I2SCTL_MCLKEN_Msk;
1606 
1607     if(u32Divider == 0UL)
1608     {
1609         u32RetValue = u32SrcClk; /* If MCLKDIV=0, master clock rate is equal to the source clock rate. */
1610     }
1611     else
1612     {
1613         u32RetValue = ((u32SrcClk >> 1UL) / u32Divider); /* If MCLKDIV>0, master clock rate = source clock rate / (MCLKDIV * 2) */
1614     }
1615 
1616     return u32RetValue;
1617 }
1618 
1619 /**
1620   * @brief  Disable master clock (MCLK).
1621   * @param[in] i2s The pointer of the specified I2S module.
1622   * @return None
1623   * @details Clear MCLKEN bit of SPI_I2SCTL register to disable master clock output.
1624   */
SPII2S_DisableMCLK(SPI_T * i2s)1625 void SPII2S_DisableMCLK(SPI_T *i2s)
1626 {
1627     i2s->I2SCTL &= ~SPI_I2SCTL_MCLKEN_Msk;
1628 }
1629 
1630 /**
1631   * @brief  Configure FIFO threshold setting.
1632   * @param[in]  i2s The pointer of the specified I2S module.
1633   * @param[in]  u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3.
1634   * @param[in]  u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3.
1635   * @return None
1636   * @details Set TX FIFO threshold and RX FIFO threshold configurations.
1637   */
SPII2S_SetFIFO(SPI_T * i2s,uint32_t u32TxThreshold,uint32_t u32RxThreshold)1638 void SPII2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
1639 {
1640     i2s->FIFOCTL = (i2s->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
1641                    (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
1642                    (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
1643 }
1644 
1645 /**@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
1646 
1647 /**@}*/ /* end of group SPI_Driver */
1648 
1649 /**@}*/ /* end of group Standard_Driver */
1650