1 /**************************************************************************//**
2  * @file     spi.c
3  * @version  V3.00
4  * @brief    M460 series SPI driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10 
11 /** @addtogroup Standard_Driver Standard Driver
12   @{
13 */
14 
15 /** @addtogroup SPI_Driver SPI Driver
16   @{
17 */
18 
19 
20 /** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
21   @{
22 */
23 static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s);
24 
25 /**
26   * @brief  This function make SPI module be ready to transfer.
27   * @param[in]  spi The pointer of the specified SPI module.
28   * @param[in]  u32MasterSlave Decides the SPI module is operating in master mode or in slave mode. (SPI_SLAVE, SPI_MASTER)
29   * @param[in]  u32SPIMode Decides the transfer timing. (SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3)
30   * @param[in]  u32DataWidth Decides the data width of a SPI transaction.
31   * @param[in]  u32BusClock The expected frequency of SPI bus clock in Hz.
32   * @return Actual frequency of SPI peripheral clock.
33   * @details By default, the SPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
34   *          slave selection function is disabled.
35   *          In Slave mode, the u32BusClock shall be NULL and the SPI clock divider setting will be 0.
36   *          The actual clock rate may be different from the target SPI clock rate.
37   *          For example, if the SPI source clock rate is 12 MHz and the target SPI bus clock rate is 7 MHz, the
38   *          actual SPI clock rate will be 6 MHz.
39   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
40   * @note   If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
41   * @note   If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
42   * @note   In slave mode, the SPI peripheral clock rate will be equal to APB clock rate.
43   */
SPI_Open(SPI_T * spi,uint32_t u32MasterSlave,uint32_t u32SPIMode,uint32_t u32DataWidth,uint32_t u32BusClock)44 uint32_t SPI_Open(SPI_T *spi,
45                   uint32_t u32MasterSlave,
46                   uint32_t u32SPIMode,
47                   uint32_t u32DataWidth,
48                   uint32_t u32BusClock)
49 {
50     uint32_t u32ClkSrc = 0U, u32Div, u32HCLKFreq, u32RetValue = 0U;
51 
52     /* Disable I2S mode */
53     spi->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
54 
55     if(u32DataWidth == 32U)
56     {
57         u32DataWidth = 0U;
58     }
59 
60     /* Get system clock frequency */
61     u32HCLKFreq = CLK_GetHCLKFreq();
62 
63     if(u32MasterSlave == SPI_MASTER)
64     {
65         /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
66         spi->SSCTL = SPI_SS_ACTIVE_LOW;
67 
68         /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
69         spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
70 
71         if(u32BusClock >= u32HCLKFreq)
72         {
73             /* Select PCLK as the clock source of SPI */
74             if(spi == SPI0)
75             {
76                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
77             }
78             else if(spi == SPI1)
79             {
80                 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
81             }
82             else if(spi == SPI2)
83             {
84                 CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI2SEL_Msk)) | CLK_CLKSEL3_SPI2SEL_PCLK1;
85             }
86             else if(spi == SPI3)
87             {
88                 CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI3SEL_Msk)) | CLK_CLKSEL3_SPI3SEL_PCLK0;
89             }
90             else if(spi == SPI4)
91             {
92                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI4SEL_Msk)) | CLK_CLKSEL4_SPI4SEL_PCLK1;
93             }
94             else if(spi == SPI5)
95             {
96                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI5SEL_Msk)) | CLK_CLKSEL4_SPI5SEL_PCLK0;
97             }
98             else if(spi == SPI6)
99             {
100                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI6SEL_Msk)) | CLK_CLKSEL4_SPI6SEL_PCLK1;
101             }
102             else if(spi == SPI7)
103             {
104                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI7SEL_Msk)) | CLK_CLKSEL4_SPI7SEL_PCLK0;
105             }
106             else if(spi == SPI8)
107             {
108                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI8SEL_Msk)) | CLK_CLKSEL4_SPI8SEL_PCLK1;
109             }
110             else if(spi == SPI9)
111             {
112                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI9SEL_Msk)) | CLK_CLKSEL4_SPI9SEL_PCLK0;
113             }
114             else
115             {
116                 CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI10SEL_Msk)) | CLK_CLKSEL4_SPI10SEL_PCLK1;
117             }
118         }
119 
120         /* Check clock source of SPI */
121         if(spi == SPI0)
122         {
123             if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
124             {
125                 u32ClkSrc = __HXT; /* Clock source is HXT */
126             }
127             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL_DIV2)
128             {
129                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
130             }
131             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
132             {
133                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
134             }
135             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC)
136             {
137                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
138             }
139             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC48M)
140             {
141                 u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
142             }
143             else
144             {
145                 u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
146             }
147         }
148         else if(spi == SPI1)
149         {
150             if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
151             {
152                 u32ClkSrc = __HXT; /* Clock source is HXT */
153             }
154             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL_DIV2)
155             {
156                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
157             }
158             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
159             {
160                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
161             }
162             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC)
163             {
164                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
165             }
166             else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC48M)
167             {
168                 u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
169             }
170             else
171             {
172                 u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
173             }
174         }
175         else if(spi == SPI2)
176         {
177             if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HXT)
178             {
179                 u32ClkSrc = __HXT; /* Clock source is HXT */
180             }
181             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PLL_DIV2)
182             {
183                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
184             }
185             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PCLK1)
186             {
187                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
188             }
189             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC)
190             {
191                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
192             }
193             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC48M)
194             {
195                 u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
196             }
197             else
198             {
199                 u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
200             }
201         }
202         else if(spi == SPI3)
203         {
204             if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HXT)
205             {
206                 u32ClkSrc = __HXT; /* Clock source is HXT */
207             }
208             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PLL_DIV2)
209             {
210                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
211             }
212             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PCLK0)
213             {
214                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
215             }
216             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC)
217             {
218                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
219             }
220             else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC48M)
221             {
222                 u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
223             }
224             else
225             {
226                 u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
227             }
228         }
229         else if(spi == SPI4)
230         {
231             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_HXT)
232             {
233                 u32ClkSrc = __HXT; /* Clock source is HXT */
234             }
235             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_PLL_DIV2)
236             {
237                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
238             }
239             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_PCLK1)
240             {
241                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
242             }
243             else
244             {
245                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
246             }
247         }
248         else if(spi == SPI5)
249         {
250             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_HXT)
251             {
252                 u32ClkSrc = __HXT; /* Clock source is HXT */
253             }
254             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_PLL_DIV2)
255             {
256                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
257             }
258             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_PCLK0)
259             {
260                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
261             }
262             else
263             {
264                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
265             }
266         }
267         else if(spi == SPI6)
268         {
269             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_HXT)
270             {
271                 u32ClkSrc = __HXT; /* Clock source is HXT */
272             }
273             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_PLL_DIV2)
274             {
275                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
276             }
277             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_PCLK1)
278             {
279                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
280             }
281             else
282             {
283                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
284             }
285         }
286         else if(spi == SPI7)
287         {
288             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_HXT)
289             {
290                 u32ClkSrc = __HXT; /* Clock source is HXT */
291             }
292             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_PLL_DIV2)
293             {
294                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
295             }
296             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_PCLK0)
297             {
298                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
299             }
300             else
301             {
302                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
303             }
304         }
305         else if(spi == SPI8)
306         {
307             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_HXT)
308             {
309                 u32ClkSrc = __HXT; /* Clock source is HXT */
310             }
311             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_PLL_DIV2)
312             {
313                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
314             }
315             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_PCLK1)
316             {
317                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
318             }
319             else
320             {
321                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
322             }
323         }
324         else if(spi == SPI9)
325         {
326             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_HXT)
327             {
328                 u32ClkSrc = __HXT; /* Clock source is HXT */
329             }
330             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_PLL_DIV2)
331             {
332                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
333             }
334             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_PCLK0)
335             {
336                 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
337             }
338             else
339             {
340                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
341             }
342         }
343         else
344         {
345             if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_HXT)
346             {
347                 u32ClkSrc = __HXT; /* Clock source is HXT */
348             }
349             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_PLL_DIV2)
350             {
351                 u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
352             }
353             else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_PCLK1)
354             {
355                 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
356             }
357             else
358             {
359                 u32ClkSrc = __HIRC; /* Clock source is HIRC */
360             }
361         }
362 
363         if(u32BusClock >= u32HCLKFreq)
364         {
365             /* Set DIVIDER = 0 */
366             spi->CLKDIV = 0U;
367             /* Return master peripheral clock rate */
368             u32RetValue = u32ClkSrc;
369         }
370         else if(u32BusClock >= u32ClkSrc)
371         {
372             /* Set DIVIDER = 0 */
373             spi->CLKDIV = 0U;
374             /* Return master peripheral clock rate */
375             u32RetValue = u32ClkSrc;
376         }
377         else if(u32BusClock == 0U)
378         {
379             /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
380             spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
381             /* Return master peripheral clock rate */
382             u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
383         }
384         else
385         {
386             u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
387             if(u32Div > 0x1FFU)
388             {
389                 u32Div = 0x1FFU;
390                 spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
391                 /* Return master peripheral clock rate */
392                 u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
393             }
394             else
395             {
396                 spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
397                 /* Return master peripheral clock rate */
398                 u32RetValue = (u32ClkSrc / (u32Div + 1U));
399             }
400         }
401     }
402     else     /* For slave mode, force the SPI peripheral clock rate to equal APB clock rate. */
403     {
404         /* Default setting: slave selection signal is low level active. */
405         spi->SSCTL = SPI_SS_ACTIVE_LOW;
406 
407         /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
408         spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
409 
410         /* Set DIVIDER = 0 */
411         spi->CLKDIV = 0U;
412 
413         /* Select PCLK as the clock source of SPI */
414         if(spi == SPI0)
415         {
416             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
417             /* Return slave peripheral clock rate */
418             u32RetValue = CLK_GetPCLK1Freq();
419         }
420         else if(spi == SPI1)
421         {
422             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
423             /* Return slave peripheral clock rate */
424             u32RetValue = CLK_GetPCLK0Freq();
425         }
426         else if(spi == SPI2)
427         {
428             CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI2SEL_Msk)) | CLK_CLKSEL3_SPI2SEL_PCLK1;
429             /* Return slave peripheral clock rate */
430             u32RetValue = CLK_GetPCLK1Freq();
431         }
432         else if(spi == SPI3)
433         {
434             CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI3SEL_Msk)) | CLK_CLKSEL3_SPI3SEL_PCLK0;
435             /* Return slave peripheral clock rate */
436             u32RetValue = CLK_GetPCLK0Freq();
437         }
438         else if(spi == SPI4)
439         {
440             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI4SEL_Msk)) | CLK_CLKSEL4_SPI4SEL_PCLK1;
441             /* Return slave peripheral clock rate */
442             u32RetValue = CLK_GetPCLK1Freq();
443         }
444         else if(spi == SPI5)
445         {
446             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI5SEL_Msk)) | CLK_CLKSEL4_SPI5SEL_PCLK0;
447             /* Return slave peripheral clock rate */
448             u32RetValue = CLK_GetPCLK0Freq();
449         }
450         else if(spi == SPI6)
451         {
452             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI6SEL_Msk)) | CLK_CLKSEL4_SPI6SEL_PCLK1;
453             /* Return slave peripheral clock rate */
454             u32RetValue = CLK_GetPCLK1Freq();
455         }
456         else if(spi == SPI7)
457         {
458             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI7SEL_Msk)) | CLK_CLKSEL4_SPI7SEL_PCLK0;
459             /* Return slave peripheral clock rate */
460             u32RetValue = CLK_GetPCLK0Freq();
461         }
462         else if(spi == SPI8)
463         {
464             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI8SEL_Msk)) | CLK_CLKSEL4_SPI8SEL_PCLK1;
465             /* Return slave peripheral clock rate */
466             u32RetValue = CLK_GetPCLK1Freq();
467         }
468         else if(spi == SPI9)
469         {
470             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI9SEL_Msk)) | CLK_CLKSEL4_SPI9SEL_PCLK0;
471             /* Return slave peripheral clock rate */
472             u32RetValue = CLK_GetPCLK0Freq();
473         }
474         else
475         {
476             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI10SEL_Msk)) | CLK_CLKSEL4_SPI10SEL_PCLK1;
477             /* Return slave peripheral clock rate */
478             u32RetValue = CLK_GetPCLK1Freq();
479         }
480     }
481 
482     return u32RetValue;
483 }
484 
485 /**
486   * @brief  Disable SPI controller.
487   * @param[in]  spi The pointer of the specified SPI module.
488   * @return None
489   * @details This function will reset SPI controller.
490   */
SPI_Close(SPI_T * spi)491 void SPI_Close(SPI_T *spi)
492 {
493     if(spi == SPI0)
494     {
495         /* Reset SPI */
496         SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk;
497         SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk;
498     }
499     else if(spi == SPI1)
500     {
501         /* Reset SPI */
502         SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk;
503         SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk;
504     }
505     else if(spi == SPI2)
506     {
507         /* Reset SPI */
508         SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk;
509         SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk;
510     }
511     else if(spi == SPI3)
512     {
513         /* Reset SPI */
514         SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
515         SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
516     }
517     else if(spi == SPI4)
518     {
519         /* Reset SPI */
520         SYS->IPRST2 |= SYS_IPRST2_SPI4RST_Msk;
521         SYS->IPRST2 &= ~SYS_IPRST2_SPI4RST_Msk;
522     }
523     else if(spi == SPI5)
524     {
525         /* Reset SPI */
526         SYS->IPRST3 |= SYS_IPRST3_SPI5RST_Msk;
527         SYS->IPRST3 &= ~SYS_IPRST3_SPI5RST_Msk;
528     }
529     else if(spi == SPI6)
530     {
531         /* Reset SPI */
532         SYS->IPRST3 |= SYS_IPRST3_SPI6RST_Msk;
533         SYS->IPRST3 &= ~SYS_IPRST3_SPI6RST_Msk;
534     }
535     else if(spi == SPI7)
536     {
537         /* Reset SPI */
538         SYS->IPRST3 |= SYS_IPRST3_SPI7RST_Msk;
539         SYS->IPRST3 &= ~SYS_IPRST3_SPI7RST_Msk;
540     }
541     else if(spi == SPI8)
542     {
543         /* Reset SPI */
544         SYS->IPRST3 |= SYS_IPRST3_SPI8RST_Msk;
545         SYS->IPRST3 &= ~SYS_IPRST3_SPI8RST_Msk;
546     }
547     else if(spi == SPI9)
548     {
549         /* Reset SPI */
550         SYS->IPRST3 |= SYS_IPRST3_SPI9RST_Msk;
551         SYS->IPRST3 &= ~SYS_IPRST3_SPI9RST_Msk;
552     }
553     else
554     {
555         /* Reset SPI */
556         SYS->IPRST3 |= SYS_IPRST3_SPI10RST_Msk;
557         SYS->IPRST3 &= ~SYS_IPRST3_SPI10RST_Msk;
558     }
559 }
560 
561 /**
562   * @brief  Clear RX FIFO buffer.
563   * @param[in]  spi The pointer of the specified SPI module.
564   * @return None
565   * @details This function will clear SPI RX FIFO buffer. The RXEMPTY (SPI_STATUS[8]) will be set to 1.
566   */
SPI_ClearRxFIFO(SPI_T * spi)567 void SPI_ClearRxFIFO(SPI_T *spi)
568 {
569     spi->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk;
570 }
571 
572 /**
573   * @brief  Clear TX FIFO buffer.
574   * @param[in]  spi The pointer of the specified SPI module.
575   * @return None
576   * @details This function will clear SPI TX FIFO buffer. The TXEMPTY (SPI_STATUS[16]) will be set to 1.
577   * @note The TX shift register will not be cleared.
578   */
SPI_ClearTxFIFO(SPI_T * spi)579 void SPI_ClearTxFIFO(SPI_T *spi)
580 {
581     spi->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk;
582 }
583 
584 /**
585   * @brief  Disable the automatic slave selection function.
586   * @param[in]  spi The pointer of the specified SPI module.
587   * @return None
588   * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
589   */
SPI_DisableAutoSS(SPI_T * spi)590 void SPI_DisableAutoSS(SPI_T *spi)
591 {
592     spi->SSCTL &= ~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SS_Msk);
593 }
594 
595 /**
596   * @brief  Enable the automatic slave selection function.
597   * @param[in]  spi The pointer of the specified SPI module.
598   * @param[in]  u32SSPinMask Specifies slave selection pins. (SPI_SS)
599   * @param[in]  u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW)
600   * @return None
601   * @details This function will enable the automatic slave selection function. Only available in Master mode.
602   *          The slave selection pin and the active level will be set in this function.
603   */
SPI_EnableAutoSS(SPI_T * spi,uint32_t u32SSPinMask,uint32_t u32ActiveLevel)604 void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
605 {
606     spi->SSCTL = (spi->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSCTL_AUTOSS_Msk);
607 }
608 
609 /**
610   * @brief  Set the SPI bus clock.
611   * @param[in]  spi The pointer of the specified SPI module.
612   * @param[in]  u32BusClock The expected frequency of SPI bus clock in Hz.
613   * @return Actual frequency of SPI bus clock.
614   * @details This function is only available in Master mode. The actual clock rate may be different from the target SPI bus clock rate.
615   *          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
616   *          rate will be 6 MHz.
617   * @note   If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
618   * @note   If u32BusClock >= system clock frequency, SPI peripheral clock source will be set to APB clock and DIVIDER will be set to 0.
619   * @note   If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
620   */
SPI_SetBusClock(SPI_T * spi,uint32_t u32BusClock)621 uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
622 {
623     uint32_t u32ClkSrc, u32HCLKFreq;
624     uint32_t u32Div, u32RetValue;
625 
626     /* Get system clock frequency */
627     u32HCLKFreq = CLK_GetHCLKFreq();
628 
629     if(u32BusClock >= u32HCLKFreq)
630     {
631         /* Select PCLK as the clock source of SPI */
632         if(spi == SPI0)
633             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
634         else if(spi == SPI1)
635             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
636         else if(spi == SPI2)
637             CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI2SEL_Msk)) | CLK_CLKSEL3_SPI2SEL_PCLK1;
638         else  if(spi == SPI3)
639             CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI3SEL_Msk)) | CLK_CLKSEL3_SPI3SEL_PCLK0;
640         else if(spi == SPI4)
641             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI4SEL_Msk)) | CLK_CLKSEL4_SPI4SEL_PCLK1;
642         else if(spi == SPI5)
643             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI5SEL_Msk)) | CLK_CLKSEL4_SPI5SEL_PCLK0;
644         else if(spi == SPI6)
645             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI6SEL_Msk)) | CLK_CLKSEL4_SPI6SEL_PCLK1;
646         else if(spi == SPI7)
647             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI7SEL_Msk)) | CLK_CLKSEL4_SPI7SEL_PCLK0;
648         else if(spi == SPI8)
649             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI8SEL_Msk)) | CLK_CLKSEL4_SPI8SEL_PCLK1;
650         else if(spi == SPI9)
651             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI9SEL_Msk)) | CLK_CLKSEL4_SPI9SEL_PCLK0;
652         else
653             CLK->CLKSEL4 = (CLK->CLKSEL4 & (~CLK_CLKSEL4_SPI10SEL_Msk)) | CLK_CLKSEL4_SPI10SEL_PCLK1;
654     }
655 
656     /* Check clock source of SPI */
657     if(spi == SPI0)
658     {
659         if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
660         {
661             u32ClkSrc = __HXT; /* Clock source is HXT */
662         }
663         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL_DIV2)
664         {
665             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
666         }
667         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
668         {
669             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
670         }
671         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC)
672         {
673             u32ClkSrc = __HIRC; /* Clock source is HIRC */
674         }
675         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC48M)
676         {
677             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
678         }
679         else
680         {
681             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
682         }
683     }
684     else if(spi == SPI1)
685     {
686         if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
687         {
688             u32ClkSrc = __HXT; /* Clock source is HXT */
689         }
690         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL_DIV2)
691         {
692             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
693         }
694         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
695         {
696             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
697         }
698         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC)
699         {
700             u32ClkSrc = __HIRC; /* Clock source is HIRC */
701         }
702         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC48M)
703         {
704             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
705         }
706         else
707         {
708             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
709         }
710     }
711     else if(spi == SPI2)
712     {
713         if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HXT)
714         {
715             u32ClkSrc = __HXT; /* Clock source is HXT */
716         }
717         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PLL_DIV2)
718         {
719             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
720         }
721         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PCLK1)
722         {
723             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
724         }
725         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC)
726         {
727             u32ClkSrc = __HIRC; /* Clock source is HIRC */
728         }
729         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC48M)
730         {
731             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
732         }
733         else
734         {
735             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
736         }
737     }
738     else if(spi == SPI3)
739     {
740         if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HXT)
741         {
742             u32ClkSrc = __HXT; /* Clock source is HXT */
743         }
744         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PLL_DIV2)
745         {
746             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
747         }
748         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PCLK0)
749         {
750             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
751         }
752         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC)
753         {
754             u32ClkSrc = __HIRC; /* Clock source is HIRC */
755         }
756         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC48M)
757         {
758             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
759         }
760         else
761         {
762             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
763         }
764     }
765     else if(spi == SPI4)
766     {
767         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_HXT)
768         {
769             u32ClkSrc = __HXT; /* Clock source is HXT */
770         }
771         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_PLL_DIV2)
772         {
773             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
774         }
775         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_PCLK1)
776         {
777             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
778         }
779         else
780         {
781             u32ClkSrc = __HIRC; /* Clock source is HIRC */
782         }
783     }
784     else if(spi == SPI5)
785     {
786         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_HXT)
787         {
788             u32ClkSrc = __HXT; /* Clock source is HXT */
789         }
790         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_PLL_DIV2)
791         {
792             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
793         }
794         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_PCLK0)
795         {
796             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
797         }
798         else
799         {
800             u32ClkSrc = __HIRC; /* Clock source is HIRC */
801         }
802     }
803     else if(spi == SPI6)
804     {
805         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_HXT)
806         {
807             u32ClkSrc = __HXT; /* Clock source is HXT */
808         }
809         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_PLL_DIV2)
810         {
811             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
812         }
813         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_PCLK1)
814         {
815             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
816         }
817         else
818         {
819             u32ClkSrc = __HIRC; /* Clock source is HIRC */
820         }
821     }
822     else if(spi == SPI7)
823     {
824         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_HXT)
825         {
826             u32ClkSrc = __HXT; /* Clock source is HXT */
827         }
828         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_PLL_DIV2)
829         {
830             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
831         }
832         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_PCLK0)
833         {
834             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
835         }
836         else
837         {
838             u32ClkSrc = __HIRC; /* Clock source is HIRC */
839         }
840     }
841     else if(spi == SPI8)
842     {
843         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_HXT)
844         {
845             u32ClkSrc = __HXT; /* Clock source is HXT */
846         }
847         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_PLL_DIV2)
848         {
849             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
850         }
851         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_PCLK1)
852         {
853             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
854         }
855         else
856         {
857             u32ClkSrc = __HIRC; /* Clock source is HIRC */
858         }
859     }
860     else if(spi == SPI9)
861     {
862         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_HXT)
863         {
864             u32ClkSrc = __HXT; /* Clock source is HXT */
865         }
866         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_PLL_DIV2)
867         {
868             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
869         }
870         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_PCLK0)
871         {
872             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
873         }
874         else
875         {
876             u32ClkSrc = __HIRC; /* Clock source is HIRC */
877         }
878     }
879     else
880     {
881         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_HXT)
882         {
883             u32ClkSrc = __HXT; /* Clock source is HXT */
884         }
885         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_PLL_DIV2)
886         {
887             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
888         }
889         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_PCLK1)
890         {
891             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
892         }
893         else
894         {
895             u32ClkSrc = __HIRC; /* Clock source is HIRC */
896         }
897     }
898 
899     if(u32BusClock >= u32HCLKFreq)
900     {
901         /* Set DIVIDER = 0 */
902         spi->CLKDIV = 0U;
903         /* Return master peripheral clock rate */
904         u32RetValue = u32ClkSrc;
905     }
906     else if(u32BusClock >= u32ClkSrc)
907     {
908         /* Set DIVIDER = 0 */
909         spi->CLKDIV = 0U;
910         /* Return master peripheral clock rate */
911         u32RetValue = u32ClkSrc;
912     }
913     else if(u32BusClock == 0U)
914     {
915         /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
916         spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
917         /* Return master peripheral clock rate */
918         u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
919     }
920     else
921     {
922         u32Div = (((u32ClkSrc * 10U) / u32BusClock + 5U) / 10U) - 1U; /* Round to the nearest integer */
923         if(u32Div > 0x1FFU)
924         {
925             u32Div = 0x1FFU;
926             spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
927             /* Return master peripheral clock rate */
928             u32RetValue = (u32ClkSrc / (0x1FFU + 1U));
929         }
930         else
931         {
932             spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
933             /* Return master peripheral clock rate */
934             u32RetValue = (u32ClkSrc / (u32Div + 1U));
935         }
936     }
937 
938     return u32RetValue;
939 }
940 
941 /**
942   * @brief  Configure FIFO threshold setting.
943   * @param[in]  spi The pointer of the specified SPI module.
944   * @param[in]  u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3. If data width is 4 ~ 16 bits, it could be 0 ~ 7.
945   * @param[in]  u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3. If data width is 4 ~ 16 bits, it could be 0 ~ 7.
946   * @return None
947   * @details Set TX FIFO threshold and RX FIFO threshold configurations.
948   */
SPI_SetFIFO(SPI_T * spi,uint32_t u32TxThreshold,uint32_t u32RxThreshold)949 void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
950 {
951     spi->FIFOCTL = (spi->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
952                    (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
953                    (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
954 }
955 
956 /**
957   * @brief  Get the actual frequency of SPI bus clock. Only available in Master mode.
958   * @param[in]  spi The pointer of the specified SPI module.
959   * @return Actual SPI bus clock frequency in Hz.
960   * @details This function will calculate the actual SPI bus clock rate according to the SPIxSEL and DIVIDER settings. Only available in Master mode.
961   */
SPI_GetBusClock(SPI_T * spi)962 uint32_t SPI_GetBusClock(SPI_T *spi)
963 {
964     uint32_t u32Div;
965     uint32_t u32ClkSrc;
966 
967     /* Get DIVIDER setting */
968     u32Div = (spi->CLKDIV & SPI_CLKDIV_DIVIDER_Msk) >> SPI_CLKDIV_DIVIDER_Pos;
969 
970     /* Check clock source of SPI */
971     if(spi == SPI0)
972     {
973         if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
974         {
975             u32ClkSrc = __HXT; /* Clock source is HXT */
976         }
977         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL_DIV2)
978         {
979             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
980         }
981         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
982         {
983             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
984         }
985         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC)
986         {
987             u32ClkSrc = __HIRC; /* Clock source is HIRC */
988         }
989         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC48M)
990         {
991             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
992         }
993         else
994         {
995             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
996         }
997     }
998     else if(spi == SPI1)
999     {
1000         if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
1001         {
1002             u32ClkSrc = __HXT; /* Clock source is HXT */
1003         }
1004         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL_DIV2)
1005         {
1006             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1007         }
1008         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
1009         {
1010             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1011         }
1012         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC)
1013         {
1014             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1015         }
1016         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC48M)
1017         {
1018             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
1019         }
1020         else
1021         {
1022             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1023         }
1024     }
1025     else if(spi == SPI2)
1026     {
1027         if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HXT)
1028         {
1029             u32ClkSrc = __HXT; /* Clock source is HXT */
1030         }
1031         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PLL_DIV2)
1032         {
1033             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1034         }
1035         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PCLK1)
1036         {
1037             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1038         }
1039         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC)
1040         {
1041             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1042         }
1043         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC48M)
1044         {
1045             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
1046         }
1047         else
1048         {
1049             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1050         }
1051     }
1052     else if(spi == SPI3)
1053     {
1054         if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HXT)
1055         {
1056             u32ClkSrc = __HXT; /* Clock source is HXT */
1057         }
1058         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PLL_DIV2)
1059         {
1060             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1061         }
1062         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PCLK0)
1063         {
1064             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1065         }
1066         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC)
1067         {
1068             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1069         }
1070         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC48M)
1071         {
1072             u32ClkSrc = __HIRC48M; /* Clock source is RC48M */
1073         }
1074         else
1075         {
1076             u32ClkSrc = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1077         }
1078     }
1079     else if(spi == SPI4)
1080     {
1081         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_HXT)
1082         {
1083             u32ClkSrc = __HXT; /* Clock source is HXT */
1084         }
1085         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_PLL_DIV2)
1086         {
1087             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1088         }
1089         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI4SEL_Msk) == CLK_CLKSEL4_SPI4SEL_PCLK1)
1090         {
1091             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1092         }
1093         else
1094         {
1095             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1096         }
1097     }
1098     else if(spi == SPI5)
1099     {
1100         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_HXT)
1101         {
1102             u32ClkSrc = __HXT; /* Clock source is HXT */
1103         }
1104         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_PLL_DIV2)
1105         {
1106             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1107         }
1108         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI5SEL_Msk) == CLK_CLKSEL4_SPI5SEL_PCLK0)
1109         {
1110             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1111         }
1112         else
1113         {
1114             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1115         }
1116     }
1117     else if(spi == SPI6)
1118     {
1119         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_HXT)
1120         {
1121             u32ClkSrc = __HXT; /* Clock source is HXT */
1122         }
1123         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_PLL_DIV2)
1124         {
1125             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1126         }
1127         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI6SEL_Msk) == CLK_CLKSEL4_SPI6SEL_PCLK1)
1128         {
1129             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1130         }
1131         else
1132         {
1133             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1134         }
1135     }
1136     else if(spi == SPI7)
1137     {
1138         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_HXT)
1139         {
1140             u32ClkSrc = __HXT; /* Clock source is HXT */
1141         }
1142         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_PLL_DIV2)
1143         {
1144             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1145         }
1146         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI7SEL_Msk) == CLK_CLKSEL4_SPI7SEL_PCLK0)
1147         {
1148             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1149         }
1150         else
1151         {
1152             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1153         }
1154     }
1155     else if(spi == SPI8)
1156     {
1157         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_HXT)
1158         {
1159             u32ClkSrc = __HXT; /* Clock source is HXT */
1160         }
1161         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_PLL_DIV2)
1162         {
1163             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1164         }
1165         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI8SEL_Msk) == CLK_CLKSEL4_SPI8SEL_PCLK1)
1166         {
1167             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1168         }
1169         else
1170         {
1171             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1172         }
1173     }
1174     else if(spi == SPI9)
1175     {
1176         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_HXT)
1177         {
1178             u32ClkSrc = __HXT; /* Clock source is HXT */
1179         }
1180         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_PLL_DIV2)
1181         {
1182             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1183         }
1184         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI9SEL_Msk) == CLK_CLKSEL4_SPI9SEL_PCLK0)
1185         {
1186             u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1187         }
1188         else
1189         {
1190             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1191         }
1192     }
1193     else
1194     {
1195         if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_HXT)
1196         {
1197             u32ClkSrc = __HXT; /* Clock source is HXT */
1198         }
1199         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_PLL_DIV2)
1200         {
1201             u32ClkSrc = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1202         }
1203         else if((CLK->CLKSEL4 & CLK_CLKSEL4_SPI10SEL_Msk) == CLK_CLKSEL4_SPI10SEL_PCLK1)
1204         {
1205             u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1206         }
1207         else
1208         {
1209             u32ClkSrc = __HIRC; /* Clock source is HIRC */
1210         }
1211     }
1212 
1213     /* Return SPI bus clock rate */
1214     return (u32ClkSrc / (u32Div + 1U));
1215 }
1216 
1217 /**
1218   * @brief  Enable interrupt function.
1219   * @param[in]  spi The pointer of the specified SPI module.
1220   * @param[in]  u32Mask The combination of all related interrupt enable bits.
1221   *                     Each bit corresponds to a interrupt enable bit.
1222   *                     This parameter decides which interrupts will be enabled. It is combination of:
1223   *                       - \ref SPI_UNIT_INT_MASK
1224   *                       - \ref SPI_SSACT_INT_MASK
1225   *                       - \ref SPI_SSINACT_INT_MASK
1226   *                       - \ref SPI_SLVUR_INT_MASK
1227   *                       - \ref SPI_SLVBE_INT_MASK
1228   *                       - \ref SPI_TXUF_INT_MASK
1229   *                       - \ref SPI_FIFO_TXTH_INT_MASK
1230   *                       - \ref SPI_FIFO_RXTH_INT_MASK
1231   *                       - \ref SPI_FIFO_RXOV_INT_MASK
1232   *                       - \ref SPI_FIFO_RXTO_INT_MASK
1233   *
1234   * @return None
1235   * @details Enable SPI related interrupts specified by u32Mask parameter.
1236   */
SPI_EnableInt(SPI_T * spi,uint32_t u32Mask)1237 void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
1238 {
1239     /* Enable unit transfer interrupt flag */
1240     if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
1241     {
1242         spi->CTL |= SPI_CTL_UNITIEN_Msk;
1243     }
1244 
1245     /* Enable slave selection signal active interrupt flag */
1246     if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
1247     {
1248         spi->SSCTL |= SPI_SSCTL_SSACTIEN_Msk;
1249     }
1250 
1251     /* Enable slave selection signal inactive interrupt flag */
1252     if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
1253     {
1254         spi->SSCTL |= SPI_SSCTL_SSINAIEN_Msk;
1255     }
1256 
1257     /* Enable slave TX under run interrupt flag */
1258     if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
1259     {
1260         spi->SSCTL |= SPI_SSCTL_SLVURIEN_Msk;
1261     }
1262 
1263     /* Enable slave bit count error interrupt flag */
1264     if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
1265     {
1266         spi->SSCTL |= SPI_SSCTL_SLVBEIEN_Msk;
1267     }
1268 
1269     /* Enable slave TX underflow interrupt flag */
1270     if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
1271     {
1272         spi->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
1273     }
1274 
1275     /* Enable TX threshold interrupt flag */
1276     if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
1277     {
1278         spi->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
1279     }
1280 
1281     /* Enable RX threshold interrupt flag */
1282     if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
1283     {
1284         spi->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
1285     }
1286 
1287     /* Enable RX overrun interrupt flag */
1288     if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
1289     {
1290         spi->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
1291     }
1292 
1293     /* Enable RX time-out interrupt flag */
1294     if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
1295     {
1296         spi->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
1297     }
1298 }
1299 
1300 /**
1301   * @brief  Disable interrupt function.
1302   * @param[in]  spi The pointer of the specified SPI module.
1303   * @param[in]  u32Mask The combination of all related interrupt enable bits.
1304   *                     Each bit corresponds to a interrupt bit.
1305   *                     This parameter decides which interrupts will be disabled. It is combination of:
1306   *                       - \ref SPI_UNIT_INT_MASK
1307   *                       - \ref SPI_SSACT_INT_MASK
1308   *                       - \ref SPI_SSINACT_INT_MASK
1309   *                       - \ref SPI_SLVUR_INT_MASK
1310   *                       - \ref SPI_SLVBE_INT_MASK
1311   *                       - \ref SPI_TXUF_INT_MASK
1312   *                       - \ref SPI_FIFO_TXTH_INT_MASK
1313   *                       - \ref SPI_FIFO_RXTH_INT_MASK
1314   *                       - \ref SPI_FIFO_RXOV_INT_MASK
1315   *                       - \ref SPI_FIFO_RXTO_INT_MASK
1316   *
1317   * @return None
1318   * @details Disable SPI related interrupts specified by u32Mask parameter.
1319   */
SPI_DisableInt(SPI_T * spi,uint32_t u32Mask)1320 void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
1321 {
1322     /* Disable unit transfer interrupt flag */
1323     if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
1324     {
1325         spi->CTL &= ~SPI_CTL_UNITIEN_Msk;
1326     }
1327 
1328     /* Disable slave selection signal active interrupt flag */
1329     if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
1330     {
1331         spi->SSCTL &= ~SPI_SSCTL_SSACTIEN_Msk;
1332     }
1333 
1334     /* Disable slave selection signal inactive interrupt flag */
1335     if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
1336     {
1337         spi->SSCTL &= ~SPI_SSCTL_SSINAIEN_Msk;
1338     }
1339 
1340     /* Disable slave TX under run interrupt flag */
1341     if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
1342     {
1343         spi->SSCTL &= ~SPI_SSCTL_SLVURIEN_Msk;
1344     }
1345 
1346     /* Disable slave bit count error interrupt flag */
1347     if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
1348     {
1349         spi->SSCTL &= ~SPI_SSCTL_SLVBEIEN_Msk;
1350     }
1351 
1352     /* Disable slave TX underflow interrupt flag */
1353     if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
1354     {
1355         spi->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
1356     }
1357 
1358     /* Disable TX threshold interrupt flag */
1359     if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
1360     {
1361         spi->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
1362     }
1363 
1364     /* Disable RX threshold interrupt flag */
1365     if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
1366     {
1367         spi->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
1368     }
1369 
1370     /* Disable RX overrun interrupt flag */
1371     if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
1372     {
1373         spi->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
1374     }
1375 
1376     /* Disable RX time-out interrupt flag */
1377     if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
1378     {
1379         spi->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
1380     }
1381 }
1382 
1383 /**
1384   * @brief  Get interrupt flag.
1385   * @param[in]  spi The pointer of the specified SPI module.
1386   * @param[in]  u32Mask The combination of all related interrupt sources.
1387   *                     Each bit corresponds to a interrupt source.
1388   *                     This parameter decides which interrupt flags will be read. It is combination of:
1389   *                       - \ref SPI_UNIT_INT_MASK
1390   *                       - \ref SPI_SSACT_INT_MASK
1391   *                       - \ref SPI_SSINACT_INT_MASK
1392   *                       - \ref SPI_SLVUR_INT_MASK
1393   *                       - \ref SPI_SLVBE_INT_MASK
1394   *                       - \ref SPI_TXUF_INT_MASK
1395   *                       - \ref SPI_FIFO_TXTH_INT_MASK
1396   *                       - \ref SPI_FIFO_RXTH_INT_MASK
1397   *                       - \ref SPI_FIFO_RXOV_INT_MASK
1398   *                       - \ref SPI_FIFO_RXTO_INT_MASK
1399   *
1400   * @return Interrupt flags of selected sources.
1401   * @details Get SPI related interrupt flags specified by u32Mask parameter.
1402   */
SPI_GetIntFlag(SPI_T * spi,uint32_t u32Mask)1403 uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask)
1404 {
1405     uint32_t u32IntFlag = 0U, u32TmpVal;
1406 
1407     u32TmpVal = spi->STATUS & SPI_STATUS_UNITIF_Msk;
1408     /* Check unit transfer interrupt flag */
1409     if((u32Mask & SPI_UNIT_INT_MASK) && (u32TmpVal))
1410     {
1411         u32IntFlag |= SPI_UNIT_INT_MASK;
1412     }
1413 
1414     u32TmpVal = spi->STATUS & SPI_STATUS_SSACTIF_Msk;
1415     /* Check slave selection signal active interrupt flag */
1416     if((u32Mask & SPI_SSACT_INT_MASK) && (u32TmpVal))
1417     {
1418         u32IntFlag |= SPI_SSACT_INT_MASK;
1419     }
1420 
1421     u32TmpVal = spi->STATUS & SPI_STATUS_SSINAIF_Msk;
1422     /* Check slave selection signal inactive interrupt flag */
1423     if((u32Mask & SPI_SSINACT_INT_MASK) && (u32TmpVal))
1424     {
1425         u32IntFlag |= SPI_SSINACT_INT_MASK;
1426     }
1427 
1428     u32TmpVal = spi->STATUS & SPI_STATUS_SLVURIF_Msk;
1429     /* Check slave TX under run interrupt flag */
1430     if((u32Mask & SPI_SLVUR_INT_MASK) && (u32TmpVal))
1431     {
1432         u32IntFlag |= SPI_SLVUR_INT_MASK;
1433     }
1434 
1435     u32TmpVal = spi->STATUS & SPI_STATUS_SLVBEIF_Msk;
1436     /* Check slave bit count error interrupt flag */
1437     if((u32Mask & SPI_SLVBE_INT_MASK) && (u32TmpVal))
1438     {
1439         u32IntFlag |= SPI_SLVBE_INT_MASK;
1440     }
1441 
1442     u32TmpVal = spi->STATUS & SPI_STATUS_TXUFIF_Msk;
1443     /* Check slave TX underflow interrupt flag */
1444     if((u32Mask & SPI_TXUF_INT_MASK) && (u32TmpVal))
1445     {
1446         u32IntFlag |= SPI_TXUF_INT_MASK;
1447     }
1448 
1449     u32TmpVal = spi->STATUS & SPI_STATUS_TXTHIF_Msk;
1450     /* Check TX threshold interrupt flag */
1451     if((u32Mask & SPI_FIFO_TXTH_INT_MASK) && (u32TmpVal))
1452     {
1453         u32IntFlag |= SPI_FIFO_TXTH_INT_MASK;
1454     }
1455 
1456     u32TmpVal = spi->STATUS & SPI_STATUS_RXTHIF_Msk;
1457     /* Check RX threshold interrupt flag */
1458     if((u32Mask & SPI_FIFO_RXTH_INT_MASK) && (u32TmpVal))
1459     {
1460         u32IntFlag |= SPI_FIFO_RXTH_INT_MASK;
1461     }
1462 
1463     u32TmpVal = spi->STATUS & SPI_STATUS_RXOVIF_Msk;
1464     /* Check RX overrun interrupt flag */
1465     if((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (u32TmpVal))
1466     {
1467         u32IntFlag |= SPI_FIFO_RXOV_INT_MASK;
1468     }
1469 
1470     u32TmpVal = spi->STATUS & SPI_STATUS_RXTOIF_Msk;
1471     /* Check RX time-out interrupt flag */
1472     if((u32Mask & SPI_FIFO_RXTO_INT_MASK) && (u32TmpVal))
1473     {
1474         u32IntFlag |= SPI_FIFO_RXTO_INT_MASK;
1475     }
1476 
1477     return u32IntFlag;
1478 }
1479 
1480 /**
1481   * @brief  Clear interrupt flag.
1482   * @param[in]  spi The pointer of the specified SPI module.
1483   * @param[in]  u32Mask The combination of all related interrupt sources.
1484   *                     Each bit corresponds to a interrupt source.
1485   *                     This parameter decides which interrupt flags will be cleared. It could be the combination of:
1486   *                       - \ref SPI_UNIT_INT_MASK
1487   *                       - \ref SPI_SSACT_INT_MASK
1488   *                       - \ref SPI_SSINACT_INT_MASK
1489   *                       - \ref SPI_SLVUR_INT_MASK
1490   *                       - \ref SPI_SLVBE_INT_MASK
1491   *                       - \ref SPI_TXUF_INT_MASK
1492   *                       - \ref SPI_FIFO_RXOV_INT_MASK
1493   *                       - \ref SPI_FIFO_RXTO_INT_MASK
1494   *
1495   * @return None
1496   * @details Clear SPI related interrupt flags specified by u32Mask parameter.
1497   */
SPI_ClearIntFlag(SPI_T * spi,uint32_t u32Mask)1498 void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask)
1499 {
1500     if(u32Mask & SPI_UNIT_INT_MASK)
1501     {
1502         spi->STATUS = SPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
1503     }
1504 
1505     if(u32Mask & SPI_SSACT_INT_MASK)
1506     {
1507         spi->STATUS = SPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
1508     }
1509 
1510     if(u32Mask & SPI_SSINACT_INT_MASK)
1511     {
1512         spi->STATUS = SPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
1513     }
1514 
1515     if(u32Mask & SPI_SLVUR_INT_MASK)
1516     {
1517         spi->STATUS = SPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
1518     }
1519 
1520     if(u32Mask & SPI_SLVBE_INT_MASK)
1521     {
1522         spi->STATUS = SPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
1523     }
1524 
1525     if(u32Mask & SPI_TXUF_INT_MASK)
1526     {
1527         spi->STATUS = SPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
1528     }
1529 
1530     if(u32Mask & SPI_FIFO_RXOV_INT_MASK)
1531     {
1532         spi->STATUS = SPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
1533     }
1534 
1535     if(u32Mask & SPI_FIFO_RXTO_INT_MASK)
1536     {
1537         spi->STATUS = SPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
1538     }
1539 }
1540 
1541 /**
1542   * @brief  Get SPI status.
1543   * @param[in]  spi The pointer of the specified SPI module.
1544   * @param[in]  u32Mask The combination of all related sources.
1545   *                     Each bit corresponds to a source.
1546   *                     This parameter decides which flags will be read. It is combination of:
1547   *                       - \ref SPI_BUSY_MASK
1548   *                       - \ref SPI_RX_EMPTY_MASK
1549   *                       - \ref SPI_RX_FULL_MASK
1550   *                       - \ref SPI_TX_EMPTY_MASK
1551   *                       - \ref SPI_TX_FULL_MASK
1552   *                       - \ref SPI_TXRX_RESET_MASK
1553   *                       - \ref SPI_SPIEN_STS_MASK
1554   *                       - \ref SPI_SSLINE_STS_MASK
1555   *
1556   * @return Flags of selected sources.
1557   * @details Get SPI related status specified by u32Mask parameter.
1558   */
SPI_GetStatus(SPI_T * spi,uint32_t u32Mask)1559 uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask)
1560 {
1561     uint32_t u32Flag = 0U, u32TmpValue;
1562 
1563     u32TmpValue = spi->STATUS & SPI_STATUS_BUSY_Msk;
1564     /* Check busy status */
1565     if((u32Mask & SPI_BUSY_MASK) && (u32TmpValue))
1566     {
1567         u32Flag |= SPI_BUSY_MASK;
1568     }
1569 
1570     u32TmpValue = spi->STATUS & SPI_STATUS_RXEMPTY_Msk;
1571     /* Check RX empty flag */
1572     if((u32Mask & SPI_RX_EMPTY_MASK) && (u32TmpValue))
1573     {
1574         u32Flag |= SPI_RX_EMPTY_MASK;
1575     }
1576 
1577     u32TmpValue = spi->STATUS & SPI_STATUS_RXFULL_Msk;
1578     /* Check RX full flag */
1579     if((u32Mask & SPI_RX_FULL_MASK) && (u32TmpValue))
1580     {
1581         u32Flag |= SPI_RX_FULL_MASK;
1582     }
1583 
1584     u32TmpValue = spi->STATUS & SPI_STATUS_TXEMPTY_Msk;
1585     /* Check TX empty flag */
1586     if((u32Mask & SPI_TX_EMPTY_MASK) && (u32TmpValue))
1587     {
1588         u32Flag |= SPI_TX_EMPTY_MASK;
1589     }
1590 
1591     u32TmpValue = spi->STATUS & SPI_STATUS_TXFULL_Msk;
1592     /* Check TX full flag */
1593     if((u32Mask & SPI_TX_FULL_MASK) && (u32TmpValue))
1594     {
1595         u32Flag |= SPI_TX_FULL_MASK;
1596     }
1597 
1598     u32TmpValue = spi->STATUS & SPI_STATUS_TXRXRST_Msk;
1599     /* Check TX/RX reset flag */
1600     if((u32Mask & SPI_TXRX_RESET_MASK) && (u32TmpValue))
1601     {
1602         u32Flag |= SPI_TXRX_RESET_MASK;
1603     }
1604 
1605     u32TmpValue = spi->STATUS & SPI_STATUS_SPIENSTS_Msk;
1606     /* Check SPIEN flag */
1607     if((u32Mask & SPI_SPIEN_STS_MASK) && (u32TmpValue))
1608     {
1609         u32Flag |= SPI_SPIEN_STS_MASK;
1610     }
1611 
1612     u32TmpValue = spi->STATUS & SPI_STATUS_SSLINE_Msk;
1613     /* Check SPIx_SS line status */
1614     if((u32Mask & SPI_SSLINE_STS_MASK) && (u32TmpValue))
1615     {
1616         u32Flag |= SPI_SSLINE_STS_MASK;
1617     }
1618 
1619     return u32Flag;
1620 }
1621 
1622 /**
1623   * @brief  Get SPI status2.
1624   * @param[in]  spi The pointer of the specified SPI module.
1625   * @param[in]  u32Mask The combination of all related sources.
1626   *                     Each bit corresponds to a source.
1627   *                     This parameter decides which flags will be read. It is combination of:
1628   *                       - \ref SPI_SLVBENUM_MASK
1629   *
1630   * @return Flags of selected sources.
1631   * @details Get SPI related status specified by u32Mask parameter.
1632   */
SPI_GetStatus2(SPI_T * spi,uint32_t u32Mask)1633 uint32_t SPI_GetStatus2(SPI_T *spi, uint32_t u32Mask)
1634 {
1635     uint32_t u32TmpStatus;
1636     uint32_t u32Number = 0U;
1637 
1638     u32TmpStatus = spi->STATUS2;
1639 
1640     /* Check effective bit number of uncompleted RX data status */
1641     if(u32Mask & SPI_SLVBENUM_MASK)
1642     {
1643         u32Number = (u32TmpStatus & SPI_STATUS2_SLVBENUM_Msk) >> SPI_STATUS2_SLVBENUM_Pos;
1644     }
1645 
1646     return u32Number;
1647 }
1648 
1649 
1650 /**
1651   * @brief  This function is used to get I2S source clock frequency.
1652   * @param[in]  i2s The pointer of the specified I2S module.
1653   * @return I2S source clock frequency (Hz).
1654   * @details Return the source clock frequency according to the setting of SPIxSEL.
1655   */
SPII2S_GetSourceClockFreq(SPI_T * i2s)1656 static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s)
1657 {
1658     uint32_t u32Freq;
1659 
1660     if(i2s == SPI0)
1661     {
1662         if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HXT)
1663         {
1664             u32Freq = __HXT; /* Clock source is HXT */
1665         }
1666         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PLL_DIV2)
1667         {
1668             u32Freq = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1669         }
1670         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_PCLK1)
1671         {
1672             u32Freq = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1673         }
1674         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC)
1675         {
1676             u32Freq = __HIRC; /* Clock source is HIRC */
1677         }
1678         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI0SEL_Msk) == CLK_CLKSEL2_SPI0SEL_HIRC48M)
1679         {
1680             u32Freq = __HIRC48M; /* Clock source is RC48M */
1681         }
1682         else
1683         {
1684             u32Freq = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1685         }
1686     }
1687     else if(i2s == SPI1)
1688     {
1689         if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HXT)
1690         {
1691             u32Freq = __HXT; /* Clock source is HXT */
1692         }
1693         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PLL_DIV2)
1694         {
1695             u32Freq = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1696         }
1697         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_PCLK0)
1698         {
1699             u32Freq = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1700         }
1701         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC)
1702         {
1703             u32Freq = __HIRC; /* Clock source is HIRC */
1704         }
1705         else if((CLK->CLKSEL2 & CLK_CLKSEL2_SPI1SEL_Msk) == CLK_CLKSEL2_SPI1SEL_HIRC48M)
1706         {
1707             u32Freq = __HIRC48M; /* Clock source is RC48M */
1708         }
1709         else
1710         {
1711             u32Freq = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1712         }
1713     }
1714     else if(i2s == SPI2)
1715     {
1716         if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HXT)
1717         {
1718             u32Freq = __HXT; /* Clock source is HXT */
1719         }
1720         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PLL_DIV2)
1721         {
1722             u32Freq = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1723         }
1724         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_PCLK1)
1725         {
1726             u32Freq = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
1727         }
1728         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC)
1729         {
1730             u32Freq = __HIRC; /* Clock source is HIRC */
1731         }
1732         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI2SEL_Msk) == CLK_CLKSEL3_SPI2SEL_HIRC48M)
1733         {
1734             u32Freq = __HIRC48M; /* Clock source is RC48M */
1735         }
1736         else
1737         {
1738             u32Freq = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1739         }
1740     }
1741     else
1742     {
1743         if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HXT)
1744         {
1745             u32Freq = __HXT; /* Clock source is HXT */
1746         }
1747         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PLL_DIV2)
1748         {
1749             u32Freq = (CLK_GetPLLClockFreq() >> 1); /* Clock source is PLL/2 */
1750         }
1751         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_PCLK0)
1752         {
1753             u32Freq = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
1754         }
1755         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC)
1756         {
1757             u32Freq = __HIRC; /* Clock source is HIRC */
1758         }
1759         else if((CLK->CLKSEL3 & CLK_CLKSEL3_SPI3SEL_Msk) == CLK_CLKSEL3_SPI3SEL_HIRC48M)
1760         {
1761             u32Freq = __HIRC48M; /* Clock source is RC48M */
1762         }
1763         else
1764         {
1765             u32Freq = (CLK_GetPLLFNClockFreq() >> 1); /* Clock source is PLLFN/2 */
1766         }
1767     }
1768 
1769     return u32Freq;
1770 }
1771 
1772 /**
1773   * @brief  This function configures some parameters of I2S interface for general purpose use.
1774   * @param[in] i2s The pointer of the specified I2S module.
1775   * @param[in] u32MasterSlave I2S operation mode. Valid values are listed below.
1776   *                                     - \ref SPII2S_MODE_MASTER
1777   *                                     - \ref SPII2S_MODE_SLAVE
1778   * @param[in] u32SampleRate Sample rate
1779   * @param[in] u32WordWidth Data length. Valid values are listed below.
1780   *                                     - \ref SPII2S_DATABIT_8
1781   *                                     - \ref SPII2S_DATABIT_16
1782   *                                     - \ref SPII2S_DATABIT_24
1783   *                                     - \ref SPII2S_DATABIT_32
1784   * @param[in] u32Channels Audio format. Valid values are listed below.
1785   *                                     - \ref SPII2S_MONO
1786   *                                     - \ref SPII2S_STEREO
1787   * @param[in] u32DataFormat Data format. Valid values are listed below.
1788   *                                     - \ref SPII2S_FORMAT_I2S
1789   *                                     - \ref SPII2S_FORMAT_MSB
1790   *                                     - \ref SPII2S_FORMAT_PCMA
1791   *                                     - \ref SPII2S_FORMAT_PCMB
1792   * @return Real sample rate of master mode or peripheral clock rate of slave mode.
1793   * @details This function will reset SPI/I2S controller and configure I2S controller according to the input parameters.
1794   *          Set TX FIFO threshold to 2 and RX FIFO threshold to 1. Both the TX and RX functions will be enabled.
1795   *          The actual sample rate may be different from the target sample rate. The real sample rate will be returned for reference.
1796   * @note   In slave mode, the SPI peripheral clock rate will be equal to APB clock rate.
1797   */
SPII2S_Open(SPI_T * i2s,uint32_t u32MasterSlave,uint32_t u32SampleRate,uint32_t u32WordWidth,uint32_t u32Channels,uint32_t u32DataFormat)1798 uint32_t SPII2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat)
1799 {
1800     uint32_t u32Divider;
1801     uint32_t u32BitRate, u32SrcClk, u32RetValue;
1802 
1803     /* Reset SPI/I2S */
1804     if(i2s == SPI0)
1805     {
1806         SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk;
1807         SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk;
1808     }
1809     else if(i2s == SPI1)
1810     {
1811         SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk;
1812         SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk;
1813     }
1814     else if(i2s == SPI2)
1815     {
1816         SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk;
1817         SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk;
1818     }
1819     else
1820     {
1821         SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
1822         SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
1823     }
1824 
1825     /* Configure I2S controller */
1826     i2s->I2SCTL = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat;
1827     /* Set TX FIFO threshold to 2 and RX FIFO threshold to 1 */
1828     SPII2S_SetFIFO(i2s, 2, 1);
1829 
1830     if(u32MasterSlave == SPII2S_MODE_MASTER)
1831     {
1832         /* Get the source clock rate */
1833         u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
1834 
1835         /* Calculate the bit clock rate */
1836         u32BitRate = u32SampleRate * ((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1U) * 16U;
1837         u32Divider = ((((u32SrcClk * 10UL / u32BitRate) >> 1U) + 5UL) / 10UL) - 1U; /* Round to the nearest integer */
1838         /* Set BCLKDIV setting */
1839         i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_BCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_BCLKDIV_Pos);
1840         /* Enable I2S mode for the frequency of peripheral clock. */
1841         i2s->I2SCLK |= SPI_I2SCLK_I2SMODE_Msk;
1842 
1843         /* Calculate bit clock rate */
1844         u32BitRate = u32SrcClk / ((u32Divider + 1U) * 2U);
1845         /* Calculate real sample rate */
1846         u32SampleRate = u32BitRate / (((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1U) * 16U);
1847 
1848         /* Enable TX function, RX function and I2S mode. */
1849         i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1850 
1851         /* Return the real sample rate */
1852         u32RetValue = u32SampleRate;
1853     }
1854     else
1855     {
1856         /* Set BCLKDIV = 0 */
1857         i2s->I2SCLK &= ~SPI_I2SCLK_BCLKDIV_Msk;
1858 
1859         if(i2s == SPI0)
1860         {
1861             /* Set the peripheral clock rate to equal APB clock rate */
1862             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
1863             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1864             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1865             /* Enable TX function, RX function and I2S mode. */
1866             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1867             /* Return slave peripheral clock rate */
1868             u32RetValue = CLK_GetPCLK1Freq();
1869         }
1870         else if(i2s == SPI1)
1871         {
1872             /* Set the peripheral clock rate to equal APB clock rate */
1873             CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
1874             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1875             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1876             /* Enable TX function, RX function and I2S mode. */
1877             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1878             /* Return slave peripheral clock rate */
1879             u32RetValue = CLK_GetPCLK0Freq();
1880         }
1881         else if(i2s == SPI2)
1882         {
1883             /* Set the peripheral clock rate to equal APB clock rate */
1884             CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI2SEL_Msk)) | CLK_CLKSEL3_SPI2SEL_PCLK1;
1885             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1886             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1887             /* Enable TX function, RX function and I2S mode. */
1888             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1889             /* Return slave peripheral clock rate */
1890             u32RetValue = CLK_GetPCLK1Freq();
1891         }
1892         else
1893         {
1894             /* Set the peripheral clock rate to equal APB clock rate */
1895             CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_SPI3SEL_Msk)) | CLK_CLKSEL3_SPI3SEL_PCLK0;
1896             /* Enable I2S slave mode and I2S mode for the frequency of peripheral clock. */
1897             i2s->I2SCLK |= (SPI_I2SCLK_I2SSLAVE_Msk | SPI_I2SCLK_I2SMODE_Msk);
1898             /* Enable TX function, RX function and I2S mode. */
1899             i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
1900             /* Return slave peripheral clock rate */
1901             u32RetValue = CLK_GetPCLK0Freq();
1902         }
1903     }
1904 
1905     return u32RetValue;
1906 }
1907 
1908 /**
1909   * @brief  Disable I2S function.
1910   * @param[in]  i2s The pointer of the specified I2S module.
1911   * @return None
1912   * @details Disable I2S function.
1913   */
SPII2S_Close(SPI_T * i2s)1914 void SPII2S_Close(SPI_T *i2s)
1915 {
1916     i2s->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
1917 }
1918 
1919 /**
1920   * @brief Enable interrupt function.
1921   * @param[in] i2s The pointer of the specified I2S module.
1922   * @param[in] u32Mask The combination of all related interrupt enable bits.
1923   *            Each bit corresponds to a interrupt source. Valid values are listed below.
1924   *            - \ref SPII2S_FIFO_TXTH_INT_MASK
1925   *            - \ref SPII2S_FIFO_RXTH_INT_MASK
1926   *            - \ref SPII2S_FIFO_RXOV_INT_MASK
1927   *            - \ref SPII2S_FIFO_RXTO_INT_MASK
1928   *            - \ref SPII2S_TXUF_INT_MASK
1929   *            - \ref SPII2S_RIGHT_ZC_INT_MASK
1930   *            - \ref SPII2S_LEFT_ZC_INT_MASK
1931   *            - \ref SPII2S_SLAVE_ERR_INT_MASK
1932   * @return None
1933   * @details This function enables the interrupt according to the u32Mask parameter.
1934   */
SPII2S_EnableInt(SPI_T * i2s,uint32_t u32Mask)1935 void SPII2S_EnableInt(SPI_T *i2s, uint32_t u32Mask)
1936 {
1937     /* Enable TX threshold interrupt flag */
1938     if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
1939     {
1940         i2s->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
1941     }
1942 
1943     /* Enable RX threshold interrupt flag */
1944     if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
1945     {
1946         i2s->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
1947     }
1948 
1949     /* Enable RX overrun interrupt flag */
1950     if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
1951     {
1952         i2s->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
1953     }
1954 
1955     /* Enable RX time-out interrupt flag */
1956     if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
1957     {
1958         i2s->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
1959     }
1960 
1961     /* Enable TX underflow interrupt flag */
1962     if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
1963     {
1964         i2s->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
1965     }
1966 
1967     /* Enable right channel zero cross interrupt flag */
1968     if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
1969     {
1970         i2s->I2SCTL |= SPI_I2SCTL_RZCIEN_Msk;
1971     }
1972 
1973     /* Enable left channel zero cross interrupt flag */
1974     if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
1975     {
1976         i2s->I2SCTL |= SPI_I2SCTL_LZCIEN_Msk;
1977     }
1978     /* Enable bit clock loss interrupt flag */
1979     if((u32Mask & SPII2S_SLAVE_ERR_INT_MASK) == SPII2S_SLAVE_ERR_INT_MASK)
1980     {
1981         i2s->I2SCTL |= SPI_I2SCTL_SLVERRIEN_Msk;
1982     }
1983 }
1984 
1985 /**
1986   * @brief Disable interrupt function.
1987   * @param[in] i2s The pointer of the specified I2S module.
1988   * @param[in] u32Mask The combination of all related interrupt enable bits.
1989   *            Each bit corresponds to a interrupt source. Valid values are listed below.
1990   *            - \ref SPII2S_FIFO_TXTH_INT_MASK
1991   *            - \ref SPII2S_FIFO_RXTH_INT_MASK
1992   *            - \ref SPII2S_FIFO_RXOV_INT_MASK
1993   *            - \ref SPII2S_FIFO_RXTO_INT_MASK
1994   *            - \ref SPII2S_TXUF_INT_MASK
1995   *            - \ref SPII2S_RIGHT_ZC_INT_MASK
1996   *            - \ref SPII2S_LEFT_ZC_INT_MASK
1997   *            - \ref SPII2S_SLAVE_ERR_INT_MASK
1998   * @return None
1999   * @details This function disables the interrupt according to the u32Mask parameter.
2000   */
SPII2S_DisableInt(SPI_T * i2s,uint32_t u32Mask)2001 void SPII2S_DisableInt(SPI_T *i2s, uint32_t u32Mask)
2002 {
2003     /* Disable TX threshold interrupt flag */
2004     if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
2005     {
2006         i2s->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
2007     }
2008 
2009     /* Disable RX threshold interrupt flag */
2010     if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
2011     {
2012         i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
2013     }
2014 
2015     /* Disable RX overrun interrupt flag */
2016     if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
2017     {
2018         i2s->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
2019     }
2020 
2021     /* Disable RX time-out interrupt flag */
2022     if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
2023     {
2024         i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
2025     }
2026 
2027     /* Disable TX underflow interrupt flag */
2028     if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
2029     {
2030         i2s->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
2031     }
2032 
2033     /* Disable right channel zero cross interrupt flag */
2034     if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
2035     {
2036         i2s->I2SCTL &= ~SPI_I2SCTL_RZCIEN_Msk;
2037     }
2038 
2039     /* Disable left channel zero cross interrupt flag */
2040     if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
2041     {
2042         i2s->I2SCTL &= ~SPI_I2SCTL_LZCIEN_Msk;
2043     }
2044     /* Disable bit clock loss interrupt flag */
2045     if((u32Mask & SPII2S_SLAVE_ERR_INT_MASK) == SPII2S_SLAVE_ERR_INT_MASK)
2046     {
2047         i2s->I2SCTL &= ~SPI_I2SCTL_SLVERRIEN_Msk;
2048     }
2049 }
2050 
2051 /**
2052   * @brief  Enable master clock (MCLK).
2053   * @param[in] i2s The pointer of the specified I2S module.
2054   * @param[in] u32BusClock The target MCLK clock rate.
2055   * @return Actual MCLK clock rate
2056   * @details Set the master clock rate according to u32BusClock parameter and enable master clock output.
2057   *          The actual master clock rate may be different from the target master clock rate. The real master clock rate will be returned for reference.
2058   */
SPII2S_EnableMCLK(SPI_T * i2s,uint32_t u32BusClock)2059 uint32_t SPII2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock)
2060 {
2061     uint32_t u32Divider;
2062     uint32_t u32SrcClk, u32RetValue;
2063 
2064     u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
2065     if(u32BusClock == u32SrcClk)
2066     {
2067         u32Divider = 0U;
2068     }
2069     else
2070     {
2071         u32Divider = (u32SrcClk / u32BusClock) >> 1U;
2072         /* MCLKDIV is a 7-bit width configuration. The maximum value is 0x7F. */
2073         if(u32Divider > 0x7FU)
2074         {
2075             u32Divider = 0x7FU;
2076         }
2077     }
2078 
2079     /* Write u32Divider to MCLKDIV (SPI_I2SCLK[6:0]) */
2080     i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_MCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_MCLKDIV_Pos);
2081 
2082     /* Enable MCLK output */
2083     i2s->I2SCTL |= SPI_I2SCTL_MCLKEN_Msk;
2084 
2085     if(u32Divider == 0U)
2086     {
2087         u32RetValue = u32SrcClk; /* If MCLKDIV=0, master clock rate is equal to the source clock rate. */
2088     }
2089     else
2090     {
2091         u32RetValue = ((u32SrcClk >> 1U) / u32Divider); /* If MCLKDIV>0, master clock rate = source clock rate / (MCLKDIV * 2) */
2092     }
2093 
2094     return u32RetValue;
2095 }
2096 
2097 /**
2098   * @brief  Disable master clock (MCLK).
2099   * @param[in] i2s The pointer of the specified I2S module.
2100   * @return None
2101   * @details Clear MCLKEN bit of SPI_I2SCTL register to disable master clock output.
2102   */
SPII2S_DisableMCLK(SPI_T * i2s)2103 void SPII2S_DisableMCLK(SPI_T *i2s)
2104 {
2105     i2s->I2SCTL &= ~SPI_I2SCTL_MCLKEN_Msk;
2106 }
2107 
2108 /**
2109   * @brief  Configure FIFO threshold setting.
2110   * @param[in]  i2s The pointer of the specified I2S module.
2111   * @param[in]  u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 3.
2112   * @param[in]  u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 3.
2113   * @return None
2114   * @details Set TX FIFO threshold and RX FIFO threshold configurations.
2115   */
SPII2S_SetFIFO(SPI_T * i2s,uint32_t u32TxThreshold,uint32_t u32RxThreshold)2116 void SPII2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
2117 {
2118     i2s->FIFOCTL = (i2s->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
2119                    (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
2120                    (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
2121 }
2122 
2123 /*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
2124 
2125 /*@}*/ /* end of group SPI_Driver */
2126 
2127 /*@}*/ /* end of group Standard_Driver */
2128