1 /**************************************************************************//**
\r
4 * @brief M2351 series SPI driver source file
\r
6 * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
\r
7 *****************************************************************************/
\r
10 /** @addtogroup Standard_Driver Standard Driver
\r
14 /** @addtogroup SPI_Driver SPI Driver
\r
19 /** @addtogroup SPI_EXPORTED_FUNCTIONS SPI Exported Functions
\r
23 static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s);
\r
26 * @brief This function make SPI module be ready to transfer.
\r
27 * @param[in] spi The pointer of the specified SPI module.
\r
28 * @param[in] u32MasterSlave Decides the SPI module is operating in master mode or in slave mode. (SPI_SLAVE, SPI_MASTER)
\r
29 * @param[in] u32SPIMode Decides the transfer timing. (SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3)
\r
30 * @param[in] u32DataWidth Decides the data width of a SPI transaction.
\r
31 * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
\r
32 * @return Actual frequency of SPI peripheral clock.
\r
33 * @details By default, the SPI transfer sequence is MSB first, the slave selection signal is active low and the automatic
\r
34 * slave selection function is disabled.
\r
35 * In Slave mode, the u32BusClock shall be NULL and the SPI clock divider setting will be 0.
\r
36 * The actual clock rate may be different from the target SPI clock rate.
\r
37 * For example, if the SPI source clock rate is 12 MHz and the target SPI bus clock rate is 7 MHz, the
\r
38 * actual SPI clock rate will be 6MHz.
\r
39 * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
\r
40 * @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.
\r
41 * @note If u32BusClock >= system clock frequency for Non-Secure, this function does not do anything to avoid the situation that the frequency of
\r
42 * SPI bus clock cannot be faster than the system clock rate. User should set up carefully.
\r
43 * @note If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
\r
44 * @note In slave mode for Secure, the SPI peripheral clock rate will equal to APB clock rate.
\r
45 * @note In slave mode for Non-Secure, the SPI peripheral clock rate will equal to the clock rate set in secure mode.
\r
47 uint32_t SPI_Open(SPI_T *spi,
\r
48 uint32_t u32MasterSlave,
\r
49 uint32_t u32SPIMode,
\r
50 uint32_t u32DataWidth,
\r
51 uint32_t u32BusClock)
\r
53 uint32_t u32ClkSrc = 0UL, u32Div, u32HCLKFreq, u32PCLK0Freq, u32PCLK1Freq, u32RetValue = 0UL;
\r
55 /* Disable I2S mode */
\r
56 spi->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
\r
58 if(u32DataWidth == 32UL)
\r
63 /* Get system clock frequency */
\r
64 u32HCLKFreq = CLK_GetHCLKFreq();
\r
65 /* Get APB0 clock frequency */
\r
66 u32PCLK0Freq = CLK_GetPCLK0Freq();
\r
67 /* Get APB1 clock frequency */
\r
68 u32PCLK1Freq = CLK_GetPCLK1Freq();
\r
70 if(u32MasterSlave == SPI_MASTER)
\r
72 /* Default setting: slave selection signal is active low; disable automatic slave selection function. */
\r
73 spi->SSCTL = SPI_SS_ACTIVE_LOW;
\r
75 /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
\r
76 spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
\r
78 if(u32BusClock >= u32HCLKFreq)
\r
80 if(!(__PC() & (1UL << 28UL)))
\r
82 /* Select PCLK as the clock source of SPI */
\r
83 if((spi == SPI0) || (spi == SPI0_NS))
\r
85 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
\r
87 else if((spi == SPI1) || (spi == SPI1_NS))
\r
89 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
\r
91 else if((spi == SPI2) || (spi == SPI2_NS))
\r
93 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
\r
97 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
\r
102 /* Check clock source of SPI */
\r
103 if((spi == SPI0) || (spi == SPI0_NS))
\r
105 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
\r
107 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
109 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
\r
111 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
113 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
\r
115 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
119 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
122 else if((spi == SPI1) || (spi == SPI1_NS))
\r
124 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
\r
126 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
128 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
\r
130 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
132 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
\r
134 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
138 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
141 else if((spi == SPI2) || (spi == SPI2_NS))
\r
143 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
\r
145 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
147 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
\r
149 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
151 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
\r
153 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
157 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
162 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
\r
164 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
166 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
\r
168 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
170 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
\r
172 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
176 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
180 if(u32BusClock >= u32HCLKFreq)
\r
182 /* Set DIVIDER = 0 */
\r
184 /* Return master peripheral clock rate */
\r
185 u32RetValue = u32ClkSrc;
\r
187 else if(u32BusClock >= u32ClkSrc)
\r
189 /* Set DIVIDER = 0 */
\r
191 /* Return master peripheral clock rate */
\r
192 u32RetValue = u32ClkSrc;
\r
194 else if(u32BusClock == 0UL)
\r
196 /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
\r
197 spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
\r
198 /* Return master peripheral clock rate */
\r
199 u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
\r
203 u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
\r
204 if(u32Div > 0x1FFUL)
\r
207 spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
\r
208 /* Return master peripheral clock rate */
\r
209 u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
\r
213 spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
\r
214 /* Return master peripheral clock rate */
\r
215 u32RetValue = (u32ClkSrc / (u32Div + 1UL));
\r
219 else /* For slave mode, force the SPI peripheral clock rate to equal APB clock rate. */
\r
221 /* Default setting: slave selection signal is low level active. */
\r
222 spi->SSCTL = SPI_SS_ACTIVE_LOW;
\r
224 /* Default setting: MSB first, disable unit transfer interrupt, SP_CYCLE = 0. */
\r
225 spi->CTL = u32MasterSlave | (u32DataWidth << SPI_CTL_DWIDTH_Pos) | (u32SPIMode) | SPI_CTL_SPIEN_Msk;
\r
227 /* Set DIVIDER = 0 */
\r
230 if(!(__PC() & (1UL << 28UL)))
\r
232 /* Select PCLK as the clock source of SPI */
\r
233 if((spi == SPI0) || (spi == SPI0_NS))
\r
235 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
\r
236 /* Return slave peripheral clock rate */
\r
237 u32RetValue = u32PCLK1Freq;
\r
239 else if((spi == SPI1) || (spi == SPI1_NS))
\r
241 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
\r
242 /* Return slave peripheral clock rate */
\r
243 u32RetValue = u32PCLK0Freq;
\r
245 else if((spi == SPI2) || (spi == SPI2_NS))
\r
247 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
\r
248 /* Return slave peripheral clock rate */
\r
249 u32RetValue = u32PCLK1Freq;
\r
253 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
\r
254 /* Return slave peripheral clock rate */
\r
255 u32RetValue = u32PCLK0Freq;
\r
260 /* Check clock source of SPI */
\r
261 if((spi == SPI0) || (spi == SPI0_NS))
\r
263 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
\r
265 u32RetValue = __HXT; /* Clock source is HXT */
\r
267 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
\r
269 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
271 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
\r
273 u32RetValue = u32PCLK1Freq; /* Clock source is PCLK1 */
\r
277 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
280 else if((spi == SPI1) || (spi == SPI1_NS))
\r
282 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
\r
284 u32RetValue = __HXT; /* Clock source is HXT */
\r
286 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
\r
288 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
290 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
\r
292 u32RetValue = u32PCLK0Freq; /* Clock source is PCLK0 */
\r
296 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
299 else if((spi == SPI2) || (spi == SPI2_NS))
\r
301 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
\r
303 u32RetValue = __HXT; /* Clock source is HXT */
\r
305 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
\r
307 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
309 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
\r
311 u32RetValue = u32PCLK1Freq; /* Clock source is PCLK1 */
\r
315 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
320 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
\r
322 u32RetValue = __HXT; /* Clock source is HXT */
\r
324 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
\r
326 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
328 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
\r
330 u32RetValue = u32PCLK0Freq; /* Clock source is PCLK0 */
\r
334 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
340 return u32RetValue;
\r
344 * @brief Disable SPI controller.
\r
345 * @param[in] spi The pointer of the specified SPI module.
\r
347 * @details Clear SPIEN bit of SPI_CTL register to disable SPI transfer control.
\r
349 void SPI_Close(SPI_T *spi)
\r
351 spi->CTL &= ~SPI_CTL_SPIEN_Msk;
\r
355 * @brief Clear RX FIFO buffer.
\r
356 * @param[in] spi The pointer of the specified SPI module.
\r
358 * @details This function will clear SPI RX FIFO buffer. The RXEMPTY (SPI_STATUS[8]) will be set to 1.
\r
360 void SPI_ClearRxFIFO(SPI_T *spi)
\r
362 spi->FIFOCTL |= SPI_FIFOCTL_RXFBCLR_Msk;
\r
366 * @brief Clear TX FIFO buffer.
\r
367 * @param[in] spi The pointer of the specified SPI module.
\r
369 * @details This function will clear SPI TX FIFO buffer. The TXEMPTY (SPI_STATUS[16]) will be set to 1.
\r
370 * @note The TX shift register will not be cleared.
\r
372 void SPI_ClearTxFIFO(SPI_T *spi)
\r
374 spi->FIFOCTL |= SPI_FIFOCTL_TXFBCLR_Msk;
\r
378 * @brief Disable the automatic slave selection function.
\r
379 * @param[in] spi The pointer of the specified SPI module.
\r
381 * @details This function will disable the automatic slave selection function and set slave selection signal to inactive state.
\r
383 void SPI_DisableAutoSS(SPI_T *spi)
\r
385 spi->SSCTL &= ~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SS_Msk);
\r
389 * @brief Enable the automatic slave selection function.
\r
390 * @param[in] spi The pointer of the specified SPI module.
\r
391 * @param[in] u32SSPinMask Specifies slave selection pins. (SPI_SS)
\r
392 * @param[in] u32ActiveLevel Specifies the active level of slave selection signal. (SPI_SS_ACTIVE_HIGH, SPI_SS_ACTIVE_LOW)
\r
394 * @details This function will enable the automatic slave selection function. Only available in Master mode.
\r
395 * The slave selection pin and the active level will be set in this function.
\r
397 void SPI_EnableAutoSS(SPI_T *spi, uint32_t u32SSPinMask, uint32_t u32ActiveLevel)
\r
399 spi->SSCTL = (spi->SSCTL & (~(SPI_SSCTL_AUTOSS_Msk | SPI_SSCTL_SSACTPOL_Msk | SPI_SSCTL_SS_Msk))) | (u32SSPinMask | u32ActiveLevel | SPI_SSCTL_AUTOSS_Msk);
\r
403 * @brief Set the SPI bus clock.
\r
404 * @param[in] spi The pointer of the specified SPI module.
\r
405 * @param[in] u32BusClock The expected frequency of SPI bus clock in Hz.
\r
406 * @return Actual frequency of SPI bus clock.
\r
407 * @details This function is only available in Master mode. The actual clock rate may be different from the target SPI bus clock rate.
\r
408 * 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
\r
409 * rate will be 6 MHz.
\r
410 * @note If u32BusClock = 0, DIVIDER setting will be set to the maximum value.
\r
411 * @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.
\r
412 * @note If u32BusClock >= system clock frequency for Non-Secure, this function does not do anything to avoid the situation that the frequency of
\r
413 * SPI bus clock cannot be faster than the system clock rate. User should set up carefully.
\r
414 * @note If u32BusClock >= SPI peripheral clock source, DIVIDER will be set to 0.
\r
416 uint32_t SPI_SetBusClock(SPI_T *spi, uint32_t u32BusClock)
\r
418 uint32_t u32ClkSrc, u32HCLKFreq;
\r
419 uint32_t u32Div, u32RetValue;
\r
421 /* Get system clock frequency */
\r
422 u32HCLKFreq = CLK_GetHCLKFreq();
\r
424 if(u32BusClock >= u32HCLKFreq)
\r
426 if(!(__PC() & (1UL << 28UL)))
\r
428 /* Select PCLK as the clock source of SPI */
\r
429 if((spi == SPI0) || (spi == SPI0_NS))
\r
431 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
\r
433 else if((spi == SPI1) || (spi == SPI1_NS))
\r
435 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
\r
437 else if((spi == SPI2) || (spi == SPI2_NS))
\r
439 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
\r
443 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
\r
448 /* Check clock source of SPI */
\r
449 if((spi == SPI0) || (spi == SPI0_NS))
\r
451 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
\r
453 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
455 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
\r
457 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
459 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
\r
461 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
465 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
468 else if((spi == SPI1) || (spi == SPI1_NS))
\r
470 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
\r
472 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
474 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
\r
476 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
478 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
\r
480 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
484 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
487 else if((spi == SPI2) || (spi == SPI2_NS))
\r
489 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
\r
491 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
493 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
\r
495 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
497 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
\r
499 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
503 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
508 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
\r
510 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
512 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
\r
514 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
516 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
\r
518 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
522 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
526 if(u32BusClock >= u32HCLKFreq)
\r
528 /* Set DIVIDER = 0 */
\r
530 /* Return master peripheral clock rate */
\r
531 u32RetValue = u32ClkSrc;
\r
533 else if(u32BusClock >= u32ClkSrc)
\r
535 /* Set DIVIDER = 0 */
\r
537 /* Return master peripheral clock rate */
\r
538 u32RetValue = u32ClkSrc;
\r
540 else if(u32BusClock == 0UL)
\r
542 /* Set DIVIDER to the maximum value 0x1FF. f_spi = f_spi_clk_src / (DIVIDER + 1) */
\r
543 spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
\r
544 /* Return master peripheral clock rate */
\r
545 u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
\r
549 u32Div = (((u32ClkSrc * 10UL) / u32BusClock + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
\r
550 if(u32Div > 0x1FFUL)
\r
553 spi->CLKDIV |= SPI_CLKDIV_DIVIDER_Msk;
\r
554 /* Return master peripheral clock rate */
\r
555 u32RetValue = (u32ClkSrc / (0x1FFUL + 1UL));
\r
559 spi->CLKDIV = (spi->CLKDIV & (~SPI_CLKDIV_DIVIDER_Msk)) | (u32Div << SPI_CLKDIV_DIVIDER_Pos);
\r
560 /* Return master peripheral clock rate */
\r
561 u32RetValue = (u32ClkSrc / (u32Div + 1UL));
\r
565 return u32RetValue;
\r
569 * @brief Configure FIFO threshold setting.
\r
570 * @param[in] spi The pointer of the specified SPI module.
\r
571 * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 7.
\r
572 * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 7.
\r
574 * @details Set TX FIFO threshold and RX FIFO threshold configurations.
\r
576 void SPI_SetFIFO(SPI_T *spi, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
\r
578 spi->FIFOCTL = (spi->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
\r
579 (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
\r
580 (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
\r
584 * @brief Get the actual frequency of SPI bus clock. Only available in Master mode.
\r
585 * @param[in] spi The pointer of the specified SPI module.
\r
586 * @return Actual SPI bus clock frequency in Hz.
\r
587 * @details This function will calculate the actual SPI bus clock rate according to the SPIxSEL and DIVIDER settings. Only available in Master mode.
\r
589 uint32_t SPI_GetBusClock(SPI_T *spi)
\r
592 uint32_t u32ClkSrc;
\r
594 /* Get DIVIDER setting */
\r
595 u32Div = (spi->CLKDIV & SPI_CLKDIV_DIVIDER_Msk) >> SPI_CLKDIV_DIVIDER_Pos;
\r
597 /* Check clock source of SPI */
\r
598 if((spi == SPI0) || (spi == SPI0_NS))
\r
600 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
\r
602 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
604 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
\r
606 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
608 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
\r
610 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
614 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
617 else if((spi == SPI1) || (spi == SPI1_NS))
\r
619 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
\r
621 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
623 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
\r
625 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
627 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
\r
629 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
633 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
636 else if((spi == SPI2) || (spi == SPI2_NS))
\r
638 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
\r
640 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
642 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
\r
644 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
646 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
\r
648 u32ClkSrc = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
652 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
657 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
\r
659 u32ClkSrc = __HXT; /* Clock source is HXT */
\r
661 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
\r
663 u32ClkSrc = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
665 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
\r
667 u32ClkSrc = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
671 u32ClkSrc = __HIRC; /* Clock source is HIRC */
\r
675 /* Return SPI bus clock rate */
\r
676 return (u32ClkSrc / (u32Div + 1UL));
\r
680 * @brief Enable interrupt function.
\r
681 * @param[in] spi The pointer of the specified SPI module.
\r
682 * @param[in] u32Mask The combination of all related interrupt enable bits.
\r
683 * Each bit corresponds to a interrupt enable bit.
\r
684 * This parameter decides which interrupts will be enabled. It is combination of:
\r
685 * - \ref SPI_UNIT_INT_MASK
\r
686 * - \ref SPI_SSACT_INT_MASK
\r
687 * - \ref SPI_SSINACT_INT_MASK
\r
688 * - \ref SPI_SLVUR_INT_MASK
\r
689 * - \ref SPI_SLVBE_INT_MASK
\r
690 * - \ref SPI_TXUF_INT_MASK
\r
691 * - \ref SPI_FIFO_TXTH_INT_MASK
\r
692 * - \ref SPI_FIFO_RXTH_INT_MASK
\r
693 * - \ref SPI_FIFO_RXOV_INT_MASK
\r
694 * - \ref SPI_FIFO_RXTO_INT_MASK
\r
697 * @details Enable SPI related interrupts specified by u32Mask parameter.
\r
699 void SPI_EnableInt(SPI_T *spi, uint32_t u32Mask)
\r
701 /* Enable unit transfer interrupt flag */
\r
702 if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
\r
704 spi->CTL |= SPI_CTL_UNITIEN_Msk;
\r
707 /* Enable slave selection signal active interrupt flag */
\r
708 if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
\r
710 spi->SSCTL |= SPI_SSCTL_SSACTIEN_Msk;
\r
713 /* Enable slave selection signal inactive interrupt flag */
\r
714 if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
\r
716 spi->SSCTL |= SPI_SSCTL_SSINAIEN_Msk;
\r
719 /* Enable slave TX under run interrupt flag */
\r
720 if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
\r
722 spi->SSCTL |= SPI_SSCTL_SLVURIEN_Msk;
\r
725 /* Enable slave bit count error interrupt flag */
\r
726 if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
\r
728 spi->SSCTL |= SPI_SSCTL_SLVBEIEN_Msk;
\r
731 /* Enable slave TX underflow interrupt flag */
\r
732 if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
\r
734 spi->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
\r
737 /* Enable TX threshold interrupt flag */
\r
738 if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
\r
740 spi->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
\r
743 /* Enable RX threshold interrupt flag */
\r
744 if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
\r
746 spi->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
\r
749 /* Enable RX overrun interrupt flag */
\r
750 if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
\r
752 spi->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
\r
755 /* Enable RX time-out interrupt flag */
\r
756 if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
\r
758 spi->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
\r
763 * @brief Disable interrupt function.
\r
764 * @param[in] spi The pointer of the specified SPI module.
\r
765 * @param[in] u32Mask The combination of all related interrupt enable bits.
\r
766 * Each bit corresponds to a interrupt bit.
\r
767 * This parameter decides which interrupts will be disabled. It is combination of:
\r
768 * - \ref SPI_UNIT_INT_MASK
\r
769 * - \ref SPI_SSACT_INT_MASK
\r
770 * - \ref SPI_SSINACT_INT_MASK
\r
771 * - \ref SPI_SLVUR_INT_MASK
\r
772 * - \ref SPI_SLVBE_INT_MASK
\r
773 * - \ref SPI_TXUF_INT_MASK
\r
774 * - \ref SPI_FIFO_TXTH_INT_MASK
\r
775 * - \ref SPI_FIFO_RXTH_INT_MASK
\r
776 * - \ref SPI_FIFO_RXOV_INT_MASK
\r
777 * - \ref SPI_FIFO_RXTO_INT_MASK
\r
780 * @details Disable SPI related interrupts specified by u32Mask parameter.
\r
782 void SPI_DisableInt(SPI_T *spi, uint32_t u32Mask)
\r
784 /* Disable unit transfer interrupt flag */
\r
785 if((u32Mask & SPI_UNIT_INT_MASK) == SPI_UNIT_INT_MASK)
\r
787 spi->CTL &= ~SPI_CTL_UNITIEN_Msk;
\r
790 /* Disable slave selection signal active interrupt flag */
\r
791 if((u32Mask & SPI_SSACT_INT_MASK) == SPI_SSACT_INT_MASK)
\r
793 spi->SSCTL &= ~SPI_SSCTL_SSACTIEN_Msk;
\r
796 /* Disable slave selection signal inactive interrupt flag */
\r
797 if((u32Mask & SPI_SSINACT_INT_MASK) == SPI_SSINACT_INT_MASK)
\r
799 spi->SSCTL &= ~SPI_SSCTL_SSINAIEN_Msk;
\r
802 /* Disable slave TX under run interrupt flag */
\r
803 if((u32Mask & SPI_SLVUR_INT_MASK) == SPI_SLVUR_INT_MASK)
\r
805 spi->SSCTL &= ~SPI_SSCTL_SLVURIEN_Msk;
\r
808 /* Disable slave bit count error interrupt flag */
\r
809 if((u32Mask & SPI_SLVBE_INT_MASK) == SPI_SLVBE_INT_MASK)
\r
811 spi->SSCTL &= ~SPI_SSCTL_SLVBEIEN_Msk;
\r
814 /* Disable slave TX underflow interrupt flag */
\r
815 if((u32Mask & SPI_TXUF_INT_MASK) == SPI_TXUF_INT_MASK)
\r
817 spi->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
\r
820 /* Disable TX threshold interrupt flag */
\r
821 if((u32Mask & SPI_FIFO_TXTH_INT_MASK) == SPI_FIFO_TXTH_INT_MASK)
\r
823 spi->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
\r
826 /* Disable RX threshold interrupt flag */
\r
827 if((u32Mask & SPI_FIFO_RXTH_INT_MASK) == SPI_FIFO_RXTH_INT_MASK)
\r
829 spi->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
\r
832 /* Disable RX overrun interrupt flag */
\r
833 if((u32Mask & SPI_FIFO_RXOV_INT_MASK) == SPI_FIFO_RXOV_INT_MASK)
\r
835 spi->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
\r
838 /* Disable RX time-out interrupt flag */
\r
839 if((u32Mask & SPI_FIFO_RXTO_INT_MASK) == SPI_FIFO_RXTO_INT_MASK)
\r
841 spi->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
\r
846 * @brief Get interrupt flag.
\r
847 * @param[in] spi The pointer of the specified SPI module.
\r
848 * @param[in] u32Mask The combination of all related interrupt sources.
\r
849 * Each bit corresponds to a interrupt source.
\r
850 * This parameter decides which interrupt flags will be read. It is combination of:
\r
851 * - \ref SPI_UNIT_INT_MASK
\r
852 * - \ref SPI_SSACT_INT_MASK
\r
853 * - \ref SPI_SSINACT_INT_MASK
\r
854 * - \ref SPI_SLVUR_INT_MASK
\r
855 * - \ref SPI_SLVBE_INT_MASK
\r
856 * - \ref SPI_TXUF_INT_MASK
\r
857 * - \ref SPI_FIFO_TXTH_INT_MASK
\r
858 * - \ref SPI_FIFO_RXTH_INT_MASK
\r
859 * - \ref SPI_FIFO_RXOV_INT_MASK
\r
860 * - \ref SPI_FIFO_RXTO_INT_MASK
\r
862 * @return Interrupt flags of selected sources.
\r
863 * @details Get SPI related interrupt flags specified by u32Mask parameter.
\r
865 uint32_t SPI_GetIntFlag(SPI_T *spi, uint32_t u32Mask)
\r
867 uint32_t u32IntStatus;
\r
868 uint32_t u32IntFlag = 0UL;
\r
870 u32IntStatus = spi->STATUS;
\r
872 /* Check unit transfer interrupt flag */
\r
873 if((u32Mask & SPI_UNIT_INT_MASK) && (u32IntStatus & SPI_STATUS_UNITIF_Msk))
\r
875 u32IntFlag |= SPI_UNIT_INT_MASK;
\r
878 /* Check slave selection signal active interrupt flag */
\r
879 if((u32Mask & SPI_SSACT_INT_MASK) && (u32IntStatus & SPI_STATUS_SSACTIF_Msk))
\r
881 u32IntFlag |= SPI_SSACT_INT_MASK;
\r
884 /* Check slave selection signal inactive interrupt flag */
\r
885 if((u32Mask & SPI_SSINACT_INT_MASK) && (u32IntStatus & SPI_STATUS_SSINAIF_Msk))
\r
887 u32IntFlag |= SPI_SSINACT_INT_MASK;
\r
890 /* Check slave TX under run interrupt flag */
\r
891 if((u32Mask & SPI_SLVUR_INT_MASK) && (u32IntStatus & SPI_STATUS_SLVURIF_Msk))
\r
893 u32IntFlag |= SPI_SLVUR_INT_MASK;
\r
896 /* Check slave bit count error interrupt flag */
\r
897 if((u32Mask & SPI_SLVBE_INT_MASK) && (u32IntStatus & SPI_STATUS_SLVBEIF_Msk))
\r
899 u32IntFlag |= SPI_SLVBE_INT_MASK;
\r
902 /* Check slave TX underflow interrupt flag */
\r
903 if((u32Mask & SPI_TXUF_INT_MASK) && (u32IntStatus & SPI_STATUS_TXUFIF_Msk))
\r
905 u32IntFlag |= SPI_TXUF_INT_MASK;
\r
908 /* Check TX threshold interrupt flag */
\r
909 if((u32Mask & SPI_FIFO_TXTH_INT_MASK) && (u32IntStatus & SPI_STATUS_TXTHIF_Msk))
\r
911 u32IntFlag |= SPI_FIFO_TXTH_INT_MASK;
\r
914 /* Check RX threshold interrupt flag */
\r
915 if((u32Mask & SPI_FIFO_RXTH_INT_MASK) && (u32IntStatus & SPI_STATUS_RXTHIF_Msk))
\r
917 u32IntFlag |= SPI_FIFO_RXTH_INT_MASK;
\r
920 /* Check RX overrun interrupt flag */
\r
921 if((u32Mask & SPI_FIFO_RXOV_INT_MASK) && (u32IntStatus & SPI_STATUS_RXOVIF_Msk))
\r
923 u32IntFlag |= SPI_FIFO_RXOV_INT_MASK;
\r
926 /* Check RX time-out interrupt flag */
\r
927 if((u32Mask & SPI_FIFO_RXTO_INT_MASK) && (u32IntStatus & SPI_STATUS_RXTOIF_Msk))
\r
929 u32IntFlag |= SPI_FIFO_RXTO_INT_MASK;
\r
936 * @brief Clear interrupt flag.
\r
937 * @param[in] spi The pointer of the specified SPI module.
\r
938 * @param[in] u32Mask The combination of all related interrupt sources.
\r
939 * Each bit corresponds to a interrupt source.
\r
940 * This parameter decides which interrupt flags will be cleared. It could be the combination of:
\r
941 * - \ref SPI_UNIT_INT_MASK
\r
942 * - \ref SPI_SSACT_INT_MASK
\r
943 * - \ref SPI_SSINACT_INT_MASK
\r
944 * - \ref SPI_SLVUR_INT_MASK
\r
945 * - \ref SPI_SLVBE_INT_MASK
\r
946 * - \ref SPI_TXUF_INT_MASK
\r
947 * - \ref SPI_FIFO_RXOV_INT_MASK
\r
948 * - \ref SPI_FIFO_RXTO_INT_MASK
\r
951 * @details Clear SPI related interrupt flags specified by u32Mask parameter.
\r
953 void SPI_ClearIntFlag(SPI_T *spi, uint32_t u32Mask)
\r
955 if(u32Mask & SPI_UNIT_INT_MASK)
\r
957 spi->STATUS = SPI_STATUS_UNITIF_Msk; /* Clear unit transfer interrupt flag */
\r
960 if(u32Mask & SPI_SSACT_INT_MASK)
\r
962 spi->STATUS = SPI_STATUS_SSACTIF_Msk; /* Clear slave selection signal active interrupt flag */
\r
965 if(u32Mask & SPI_SSINACT_INT_MASK)
\r
967 spi->STATUS = SPI_STATUS_SSINAIF_Msk; /* Clear slave selection signal inactive interrupt flag */
\r
970 if(u32Mask & SPI_SLVUR_INT_MASK)
\r
972 spi->STATUS = SPI_STATUS_SLVURIF_Msk; /* Clear slave TX under run interrupt flag */
\r
975 if(u32Mask & SPI_SLVBE_INT_MASK)
\r
977 spi->STATUS = SPI_STATUS_SLVBEIF_Msk; /* Clear slave bit count error interrupt flag */
\r
980 if(u32Mask & SPI_TXUF_INT_MASK)
\r
982 spi->STATUS = SPI_STATUS_TXUFIF_Msk; /* Clear slave TX underflow interrupt flag */
\r
985 if(u32Mask & SPI_FIFO_RXOV_INT_MASK)
\r
987 spi->STATUS = SPI_STATUS_RXOVIF_Msk; /* Clear RX overrun interrupt flag */
\r
990 if(u32Mask & SPI_FIFO_RXTO_INT_MASK)
\r
992 spi->STATUS = SPI_STATUS_RXTOIF_Msk; /* Clear RX time-out interrupt flag */
\r
997 * @brief Get SPI status.
\r
998 * @param[in] spi The pointer of the specified SPI module.
\r
999 * @param[in] u32Mask The combination of all related sources.
\r
1000 * Each bit corresponds to a source.
\r
1001 * This parameter decides which flags will be read. It is combination of:
\r
1002 * - \ref SPI_BUSY_MASK
\r
1003 * - \ref SPI_RX_EMPTY_MASK
\r
1004 * - \ref SPI_RX_FULL_MASK
\r
1005 * - \ref SPI_TX_EMPTY_MASK
\r
1006 * - \ref SPI_TX_FULL_MASK
\r
1007 * - \ref SPI_TXRX_RESET_MASK
\r
1008 * - \ref SPI_SPIEN_STS_MASK
\r
1009 * - \ref SPI_SSLINE_STS_MASK
\r
1011 * @return Flags of selected sources.
\r
1012 * @details Get SPI related status specified by u32Mask parameter.
\r
1014 uint32_t SPI_GetStatus(SPI_T *spi, uint32_t u32Mask)
\r
1016 uint32_t u32TmpStatus;
\r
1017 uint32_t u32Flag = 0UL;
\r
1019 u32TmpStatus = spi->STATUS;
\r
1021 /* Check busy status */
\r
1022 if((u32Mask & SPI_BUSY_MASK) && (u32TmpStatus & SPI_STATUS_BUSY_Msk))
\r
1024 u32Flag |= SPI_BUSY_MASK;
\r
1027 /* Check RX empty flag */
\r
1028 if((u32Mask & SPI_RX_EMPTY_MASK) && (u32TmpStatus & SPI_STATUS_RXEMPTY_Msk))
\r
1030 u32Flag |= SPI_RX_EMPTY_MASK;
\r
1033 /* Check RX full flag */
\r
1034 if((u32Mask & SPI_RX_FULL_MASK) && (u32TmpStatus & SPI_STATUS_RXFULL_Msk))
\r
1036 u32Flag |= SPI_RX_FULL_MASK;
\r
1039 /* Check TX empty flag */
\r
1040 if((u32Mask & SPI_TX_EMPTY_MASK) && (u32TmpStatus & SPI_STATUS_TXEMPTY_Msk))
\r
1042 u32Flag |= SPI_TX_EMPTY_MASK;
\r
1045 /* Check TX full flag */
\r
1046 if((u32Mask & SPI_TX_FULL_MASK) && (u32TmpStatus & SPI_STATUS_TXFULL_Msk))
\r
1048 u32Flag |= SPI_TX_FULL_MASK;
\r
1051 /* Check TX/RX reset flag */
\r
1052 if((u32Mask & SPI_TXRX_RESET_MASK) && (u32TmpStatus & SPI_STATUS_TXRXRST_Msk))
\r
1054 u32Flag |= SPI_TXRX_RESET_MASK;
\r
1057 /* Check SPIEN flag */
\r
1058 if((u32Mask & SPI_SPIEN_STS_MASK) && (u32TmpStatus & SPI_STATUS_SPIENSTS_Msk))
\r
1060 u32Flag |= SPI_SPIEN_STS_MASK;
\r
1063 /* Check SPIx_SS line status */
\r
1064 if((u32Mask & SPI_SSLINE_STS_MASK) && (u32TmpStatus & SPI_STATUS_SSLINE_Msk))
\r
1066 u32Flag |= SPI_SSLINE_STS_MASK;
\r
1074 * @brief This function is used to get I2S source clock frequency.
\r
1075 * @param[in] i2s The pointer of the specified I2S module.
\r
1076 * @return I2S source clock frequency (Hz).
\r
1077 * @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]).
\r
1079 static uint32_t SPII2S_GetSourceClockFreq(SPI_T *i2s)
\r
1083 if((i2s == SPI0) || (i2s == SPI0_NS))
\r
1085 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
\r
1087 u32Freq = __HXT; /* Clock source is HXT */
\r
1089 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
\r
1091 u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1093 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
\r
1095 u32Freq = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
1099 u32Freq = __HIRC; /* Clock source is HIRC */
\r
1102 else if((i2s == SPI1) || (i2s == SPI1_NS))
\r
1104 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
\r
1106 u32Freq = __HXT; /* Clock source is HXT */
\r
1108 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
\r
1110 u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1112 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
\r
1114 u32Freq = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
1118 u32Freq = __HIRC; /* Clock source is HIRC */
\r
1121 else if((i2s == SPI2) || (i2s == SPI2_NS))
\r
1123 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
\r
1125 u32Freq = __HXT; /* Clock source is HXT */
\r
1127 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
\r
1129 u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1131 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
\r
1133 u32Freq = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
1137 u32Freq = __HIRC; /* Clock source is HIRC */
\r
1142 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
\r
1144 u32Freq = __HXT; /* Clock source is HXT */
\r
1146 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
\r
1148 u32Freq = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1150 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
\r
1152 u32Freq = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
1156 u32Freq = __HIRC; /* Clock source is HIRC */
\r
1164 * @brief This function configures some parameters of I2S interface for general purpose use.
\r
1165 * @param[in] i2s The pointer of the specified I2S module.
\r
1166 * @param[in] u32MasterSlave I2S operation mode. Valid values are listed below.
\r
1167 * - \ref SPII2S_MODE_MASTER
\r
1168 * - \ref SPII2S_MODE_SLAVE
\r
1169 * @param[in] u32SampleRate Sample rate
\r
1170 * @param[in] u32WordWidth Data length. Valid values are listed below.
\r
1171 * - \ref SPII2S_DATABIT_8
\r
1172 * - \ref SPII2S_DATABIT_16
\r
1173 * - \ref SPII2S_DATABIT_24
\r
1174 * - \ref SPII2S_DATABIT_32
\r
1175 * @param[in] u32Channels Audio format. Valid values are listed below.
\r
1176 * - \ref SPII2S_MONO
\r
1177 * - \ref SPII2S_STEREO
\r
1178 * @param[in] u32DataFormat Data format. Valid values are listed below.
\r
1179 * - \ref SPII2S_FORMAT_I2S
\r
1180 * - \ref SPII2S_FORMAT_MSB
\r
1181 * - \ref SPII2S_FORMAT_PCMA
\r
1182 * - \ref SPII2S_FORMAT_PCMB
\r
1183 * @return Real sample rate of master mode or peripheral clock rate of slave mode.
\r
1184 * @details This function will reset SPI/I2S controller and configure I2S controller according to the input parameters.
\r
1185 * Set TX FIFO threshold to 2 and RX FIFO threshold to 1. Both the TX and RX functions will be enabled.
\r
1186 * The actual sample rate may be different from the target sample rate. The real sample rate will be returned for reference.
\r
1187 * @note In slave mode for Secure, the SPI peripheral clock rate will equal to APB clock rate.
\r
1188 * @note In slave mode for Non-Secure, the SPI peripheral clock rate will equal to the clock rate set in secure mode.
\r
1190 uint32_t SPII2S_Open(SPI_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32Channels, uint32_t u32DataFormat)
\r
1192 uint32_t u32Divider;
\r
1193 uint32_t u32BitRate, u32SrcClk, u32RetValue;
\r
1194 uint32_t u32PCLK0Freq, u32PCLK1Freq;
\r
1196 if(!(__PC() & (1UL << 28UL)))
\r
1198 /* Reset SPI/I2S */
\r
1199 if((i2s == SPI0) || (i2s == SPI0_NS))
\r
1201 SYS->IPRST1 |= SYS_IPRST1_SPI0RST_Msk;
\r
1202 SYS->IPRST1 &= ~SYS_IPRST1_SPI0RST_Msk;
\r
1204 else if((i2s == SPI1) || (i2s == SPI1_NS))
\r
1206 SYS->IPRST1 |= SYS_IPRST1_SPI1RST_Msk;
\r
1207 SYS->IPRST1 &= ~SYS_IPRST1_SPI1RST_Msk;
\r
1209 else if((i2s == SPI2) || (i2s == SPI2_NS))
\r
1211 SYS->IPRST1 |= SYS_IPRST1_SPI2RST_Msk;
\r
1212 SYS->IPRST1 &= ~SYS_IPRST1_SPI2RST_Msk;
\r
1216 SYS->IPRST2 |= SYS_IPRST2_SPI3RST_Msk;
\r
1217 SYS->IPRST2 &= ~SYS_IPRST2_SPI3RST_Msk;
\r
1221 /* Configure I2S controller */
\r
1222 i2s->I2SCTL = u32MasterSlave | u32WordWidth | u32Channels | u32DataFormat;
\r
1223 /* Set TX FIFO threshold to 2 and RX FIFO threshold to 1 */
\r
1224 i2s->FIFOCTL = SPII2S_FIFO_TX_LEVEL_WORD_2 | SPII2S_FIFO_RX_LEVEL_WORD_2;
\r
1226 if(u32MasterSlave == SPI_MASTER)
\r
1228 /* Get the source clock rate */
\r
1229 u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
\r
1231 /* Calculate the bit clock rate */
\r
1232 u32BitRate = u32SampleRate * ((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1UL) * 16UL;
\r
1233 u32Divider = (((((u32SrcClk * 10UL) / u32BitRate) >> 1UL) + 5UL) / 10UL) - 1UL; /* Round to the nearest integer */
\r
1234 /* Set BCLKDIV setting */
\r
1235 i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_BCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_BCLKDIV_Pos);
\r
1237 /* Calculate bit clock rate */
\r
1238 u32BitRate = u32SrcClk / ((u32Divider + 1UL) * 2UL);
\r
1239 /* Calculate real sample rate */
\r
1240 u32SampleRate = u32BitRate / (((u32WordWidth >> SPI_I2SCTL_WDWIDTH_Pos) + 1UL) * 16UL);
\r
1242 /* Enable TX function, RX function and I2S mode. */
\r
1243 i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
\r
1245 /* Return the real sample rate */
\r
1246 u32RetValue = u32SampleRate;
\r
1250 /* Set BCLKDIV = 0 */
\r
1251 i2s->I2SCLK &= ~SPI_I2SCLK_BCLKDIV_Msk;
\r
1252 /* Get APB0 clock frequency */
\r
1253 u32PCLK0Freq = CLK_GetPCLK0Freq();
\r
1254 /* Get APB1 clock frequency */
\r
1255 u32PCLK1Freq = CLK_GetPCLK1Freq();
\r
1257 if((i2s == SPI0) || (i2s == SPI0_NS))
\r
1259 if(!(__PC() & (1UL << 28UL)))
\r
1261 /* Set the peripheral clock rate to equal APB clock rate */
\r
1262 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI0SEL_Msk)) | CLK_CLKSEL2_SPI0SEL_PCLK1;
\r
1263 /* Return slave peripheral clock rate */
\r
1264 u32RetValue = u32PCLK1Freq;
\r
1268 /* Check clock source of I2S */
\r
1269 if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_HXT)
\r
1271 u32RetValue = __HXT; /* Clock source is HXT */
\r
1273 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PLL)
\r
1275 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1277 else if((CLK_GetModuleClockSource(SPI0_MODULE) << CLK_CLKSEL2_SPI0SEL_Pos) == CLK_CLKSEL2_SPI0SEL_PCLK1)
\r
1279 u32RetValue = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
1283 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
1286 /* Enable TX function, RX function and I2S mode. */
\r
1287 i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
\r
1289 else if((i2s == SPI1) || (i2s == SPI1_NS))
\r
1291 if(!(__PC() & (1UL << 28UL)))
\r
1293 /* Set the peripheral clock rate to equal APB clock rate */
\r
1294 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI1SEL_Msk)) | CLK_CLKSEL2_SPI1SEL_PCLK0;
\r
1295 /* Return slave peripheral clock rate */
\r
1296 u32RetValue = u32PCLK0Freq;
\r
1300 /* Check clock source of I2S */
\r
1301 if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_HXT)
\r
1303 u32RetValue = __HXT; /* Clock source is HXT */
\r
1305 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PLL)
\r
1307 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1309 else if((CLK_GetModuleClockSource(SPI1_MODULE) << CLK_CLKSEL2_SPI1SEL_Pos) == CLK_CLKSEL2_SPI1SEL_PCLK0)
\r
1311 u32RetValue = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
1315 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
1318 /* Enable TX function, RX function and I2S mode. */
\r
1319 i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
\r
1321 else if((i2s == SPI2) || (i2s == SPI2_NS))
\r
1323 if(!(__PC() & (1UL << 28UL)))
\r
1325 /* Set the peripheral clock rate to equal APB clock rate */
\r
1326 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI2SEL_Msk)) | CLK_CLKSEL2_SPI2SEL_PCLK1;
\r
1327 /* Return slave peripheral clock rate */
\r
1328 u32RetValue = u32PCLK1Freq;
\r
1332 /* Check clock source of I2S */
\r
1333 if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_HXT)
\r
1335 u32RetValue = __HXT; /* Clock source is HXT */
\r
1337 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PLL)
\r
1339 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1341 else if((CLK_GetModuleClockSource(SPI2_MODULE) << CLK_CLKSEL2_SPI2SEL_Pos) == CLK_CLKSEL2_SPI2SEL_PCLK1)
\r
1343 u32RetValue = CLK_GetPCLK1Freq(); /* Clock source is PCLK1 */
\r
1347 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
1350 /* Enable TX function, RX function and I2S mode. */
\r
1351 i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
\r
1355 if(!(__PC() & (1UL << 28UL)))
\r
1357 /* Set the peripheral clock rate to equal APB clock rate */
\r
1358 CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_SPI3SEL_Msk)) | CLK_CLKSEL2_SPI3SEL_PCLK0;
\r
1359 /* Return slave peripheral clock rate */
\r
1360 u32RetValue = u32PCLK0Freq;
\r
1364 /* Check clock source of I2S */
\r
1365 if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_HXT)
\r
1367 u32RetValue = __HXT; /* Clock source is HXT */
\r
1369 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PLL)
\r
1371 u32RetValue = CLK_GetPLLClockFreq(); /* Clock source is PLL */
\r
1373 else if((CLK_GetModuleClockSource(SPI3_MODULE) << CLK_CLKSEL2_SPI3SEL_Pos) == CLK_CLKSEL2_SPI3SEL_PCLK0)
\r
1375 u32RetValue = CLK_GetPCLK0Freq(); /* Clock source is PCLK0 */
\r
1379 u32RetValue = __HIRC; /* Clock source is HIRC */
\r
1382 /* Enable TX function, RX function and I2S mode. */
\r
1383 i2s->I2SCTL |= (SPI_I2SCTL_RXEN_Msk | SPI_I2SCTL_TXEN_Msk | SPI_I2SCTL_I2SEN_Msk);
\r
1387 return u32RetValue;
\r
1391 * @brief Disable I2S function.
\r
1392 * @param[in] i2s The pointer of the specified I2S module.
\r
1394 * @details Disable I2S function.
\r
1396 void SPII2S_Close(SPI_T *i2s)
\r
1398 i2s->I2SCTL &= ~SPI_I2SCTL_I2SEN_Msk;
\r
1402 * @brief Enable interrupt function.
\r
1403 * @param[in] i2s The pointer of the specified I2S module.
\r
1404 * @param[in] u32Mask The combination of all related interrupt enable bits.
\r
1405 * Each bit corresponds to a interrupt source. Valid values are listed below.
\r
1406 * - \ref SPII2S_FIFO_TXTH_INT_MASK
\r
1407 * - \ref SPII2S_FIFO_RXTH_INT_MASK
\r
1408 * - \ref SPII2S_FIFO_RXOV_INT_MASK
\r
1409 * - \ref SPII2S_FIFO_RXTO_INT_MASK
\r
1410 * - \ref SPII2S_TXUF_INT_MASK
\r
1411 * - \ref SPII2S_RIGHT_ZC_INT_MASK
\r
1412 * - \ref SPII2S_LEFT_ZC_INT_MASK
\r
1414 * @details This function enables the interrupt according to the u32Mask parameter.
\r
1416 void SPII2S_EnableInt(SPI_T *i2s, uint32_t u32Mask)
\r
1418 /* Enable TX threshold interrupt flag */
\r
1419 if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
\r
1421 i2s->FIFOCTL |= SPI_FIFOCTL_TXTHIEN_Msk;
\r
1424 /* Enable RX threshold interrupt flag */
\r
1425 if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
\r
1427 i2s->FIFOCTL |= SPI_FIFOCTL_RXTHIEN_Msk;
\r
1430 /* Enable RX overrun interrupt flag */
\r
1431 if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
\r
1433 i2s->FIFOCTL |= SPI_FIFOCTL_RXOVIEN_Msk;
\r
1436 /* Enable RX time-out interrupt flag */
\r
1437 if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
\r
1439 i2s->FIFOCTL |= SPI_FIFOCTL_RXTOIEN_Msk;
\r
1442 /* Enable TX underflow interrupt flag */
\r
1443 if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
\r
1445 i2s->FIFOCTL |= SPI_FIFOCTL_TXUFIEN_Msk;
\r
1448 /* Enable right channel zero cross interrupt flag */
\r
1449 if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
\r
1451 i2s->I2SCTL |= SPI_I2SCTL_RZCIEN_Msk;
\r
1454 /* Enable left channel zero cross interrupt flag */
\r
1455 if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
\r
1457 i2s->I2SCTL |= SPI_I2SCTL_LZCIEN_Msk;
\r
1462 * @brief Disable interrupt function.
\r
1463 * @param[in] i2s The pointer of the specified I2S module.
\r
1464 * @param[in] u32Mask The combination of all related interrupt enable bits.
\r
1465 * Each bit corresponds to a interrupt source. Valid values are listed below.
\r
1466 * - \ref SPII2S_FIFO_TXTH_INT_MASK
\r
1467 * - \ref SPII2S_FIFO_RXTH_INT_MASK
\r
1468 * - \ref SPII2S_FIFO_RXOV_INT_MASK
\r
1469 * - \ref SPII2S_FIFO_RXTO_INT_MASK
\r
1470 * - \ref SPII2S_TXUF_INT_MASK
\r
1471 * - \ref SPII2S_RIGHT_ZC_INT_MASK
\r
1472 * - \ref SPII2S_LEFT_ZC_INT_MASK
\r
1474 * @details This function disables the interrupt according to the u32Mask parameter.
\r
1476 void SPII2S_DisableInt(SPI_T *i2s, uint32_t u32Mask)
\r
1478 /* Disable TX threshold interrupt flag */
\r
1479 if((u32Mask & SPII2S_FIFO_TXTH_INT_MASK) == SPII2S_FIFO_TXTH_INT_MASK)
\r
1481 i2s->FIFOCTL &= ~SPI_FIFOCTL_TXTHIEN_Msk;
\r
1484 /* Disable RX threshold interrupt flag */
\r
1485 if((u32Mask & SPII2S_FIFO_RXTH_INT_MASK) == SPII2S_FIFO_RXTH_INT_MASK)
\r
1487 i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTHIEN_Msk;
\r
1490 /* Disable RX overrun interrupt flag */
\r
1491 if((u32Mask & SPII2S_FIFO_RXOV_INT_MASK) == SPII2S_FIFO_RXOV_INT_MASK)
\r
1493 i2s->FIFOCTL &= ~SPI_FIFOCTL_RXOVIEN_Msk;
\r
1496 /* Disable RX time-out interrupt flag */
\r
1497 if((u32Mask & SPII2S_FIFO_RXTO_INT_MASK) == SPII2S_FIFO_RXTO_INT_MASK)
\r
1499 i2s->FIFOCTL &= ~SPI_FIFOCTL_RXTOIEN_Msk;
\r
1502 /* Disable TX underflow interrupt flag */
\r
1503 if((u32Mask & SPII2S_TXUF_INT_MASK) == SPII2S_TXUF_INT_MASK)
\r
1505 i2s->FIFOCTL &= ~SPI_FIFOCTL_TXUFIEN_Msk;
\r
1508 /* Disable right channel zero cross interrupt flag */
\r
1509 if((u32Mask & SPII2S_RIGHT_ZC_INT_MASK) == SPII2S_RIGHT_ZC_INT_MASK)
\r
1511 i2s->I2SCTL &= ~SPI_I2SCTL_RZCIEN_Msk;
\r
1514 /* Disable left channel zero cross interrupt flag */
\r
1515 if((u32Mask & SPII2S_LEFT_ZC_INT_MASK) == SPII2S_LEFT_ZC_INT_MASK)
\r
1517 i2s->I2SCTL &= ~SPI_I2SCTL_LZCIEN_Msk;
\r
1522 * @brief Enable master clock (MCLK).
\r
1523 * @param[in] i2s The pointer of the specified I2S module.
\r
1524 * @param[in] u32BusClock The target MCLK clock rate.
\r
1525 * @return Actual MCLK clock rate
\r
1526 * @details Set the master clock rate according to u32BusClock parameter and enable master clock output.
\r
1527 * The actual master clock rate may be different from the target master clock rate. The real master clock rate will be returned for reference.
\r
1529 uint32_t SPII2S_EnableMCLK(SPI_T *i2s, uint32_t u32BusClock)
\r
1531 uint32_t u32Divider;
\r
1532 uint32_t u32SrcClk, u32RetValue;
\r
1534 u32SrcClk = SPII2S_GetSourceClockFreq(i2s);
\r
1535 if(u32BusClock == u32SrcClk)
\r
1541 u32Divider = (u32SrcClk / u32BusClock) >> 1UL;
\r
1542 /* MCLKDIV is a 7-bit width configuration. The maximum value is 0x7F. */
\r
1543 if(u32Divider > 0x7FUL)
\r
1545 u32Divider = 0x7FUL;
\r
1549 /* Write u32Divider to MCLKDIV (SPI_I2SCLK[6:0]) */
\r
1550 i2s->I2SCLK = (i2s->I2SCLK & ~SPI_I2SCLK_MCLKDIV_Msk) | (u32Divider << SPI_I2SCLK_MCLKDIV_Pos);
\r
1552 /* Enable MCLK output */
\r
1553 i2s->I2SCTL |= SPI_I2SCTL_MCLKEN_Msk;
\r
1555 if(u32Divider == 0UL)
\r
1557 u32RetValue = u32SrcClk; /* If MCLKDIV=0, master clock rate is equal to the source clock rate. */
\r
1561 u32RetValue = ((u32SrcClk >> 1UL) / u32Divider); /* If MCLKDIV>0, master clock rate = source clock rate / (MCLKDIV * 2) */
\r
1564 return u32RetValue;
\r
1568 * @brief Disable master clock (MCLK).
\r
1569 * @param[in] i2s The pointer of the specified I2S module.
\r
1571 * @details Clear MCLKEN bit of SPI_I2SCTL register to disable master clock output.
\r
1573 void SPII2S_DisableMCLK(SPI_T *i2s)
\r
1575 i2s->I2SCTL &= ~SPI_I2SCTL_MCLKEN_Msk;
\r
1579 * @brief Configure FIFO threshold setting.
\r
1580 * @param[in] i2s The pointer of the specified I2S module.
\r
1581 * @param[in] u32TxThreshold Decides the TX FIFO threshold. It could be 0 ~ 7.
\r
1582 * @param[in] u32RxThreshold Decides the RX FIFO threshold. It could be 0 ~ 7.
\r
1584 * @details Set TX FIFO threshold and RX FIFO threshold configurations.
\r
1586 void SPII2S_SetFIFO(SPI_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
\r
1588 i2s->FIFOCTL = (i2s->FIFOCTL & ~(SPI_FIFOCTL_TXTH_Msk | SPI_FIFOCTL_RXTH_Msk)) |
\r
1589 (u32TxThreshold << SPI_FIFOCTL_TXTH_Pos) |
\r
1590 (u32RxThreshold << SPI_FIFOCTL_RXTH_Pos);
\r
1593 /*@}*/ /* end of group SPI_EXPORTED_FUNCTIONS */
\r
1595 /*@}*/ /* end of group SPI_Driver */
\r
1597 /*@}*/ /* end of group Standard_Driver */
\r
1599 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
\r