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