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