M480 BSP  V3.05.001
The Board Support Package for M480 Series
i2s.c
Go to the documentation of this file.
1 /**************************************************************************/
10 #include <stdio.h>
11 #include "NuMicro.h"
12 
25 static uint32_t I2S_GetSourceClockFreq(I2S_T *i2s);
26 
32 static uint32_t I2S_GetSourceClockFreq(I2S_T *i2s)
33 {
34  uint32_t u32Freq, u32ClkSrcSel;
35 
36  /* get I2S selection clock source */
37  u32ClkSrcSel = CLK->CLKSEL3 & CLK_CLKSEL3_I2S0SEL_Msk;
38 
39  switch (u32ClkSrcSel)
40  {
42  u32Freq = __HXT;
43  break;
44 
46  u32Freq = CLK_GetPLLClockFreq();
47  break;
48 
50  u32Freq = __HIRC;
51  break;
52 
54  u32Freq = (uint32_t)CLK_GetPCLK0Freq();
55  break;
56 
57  default:
58  u32Freq = __HIRC;
59  break;
60  }
61 
62  return u32Freq;
63 }
64 
91 uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32MonoData, uint32_t u32DataFormat)
92 {
93  uint16_t u16Divider;
94  uint32_t u32BitRate, u32SrcClk;
95 
96  SYS->IPRST1 |= SYS_IPRST1_I2S0RST_Msk;
97  SYS->IPRST1 &= ~SYS_IPRST1_I2S0RST_Msk;
98 
99  i2s->CTL0 = u32MasterSlave | u32WordWidth | u32MonoData | u32DataFormat;
101 
102  u32SrcClk = I2S_GetSourceClockFreq(i2s);
103 
104  u32BitRate = u32SampleRate * (((u32WordWidth>>4U) & 0x3U) + 1U) * 16U;
105  //u16Divider = (uint16_t)((u32SrcClk/u32BitRate) >> 1U) - 1U;
106  u16Divider = (uint16_t)((((u32SrcClk * 10UL / u32BitRate) >> 1U) + 5UL) / 10UL) - 1U;
107  i2s->CLKDIV = (i2s->CLKDIV & ~I2S_CLKDIV_BCLKDIV_Msk) | ((uint32_t)u16Divider << 8U);
108 
109  /* calculate real sample rate */
110  u32BitRate = u32SrcClk / (2U*((uint32_t)u16Divider+1U));
111  u32SampleRate = u32BitRate / ((((u32WordWidth>>4U) & 0x3U) + 1U) * 16U);
112 
113  i2s->CTL0 |= I2S_CTL0_I2SEN_Msk;
114 
115  return u32SampleRate;
116 }
117 
123 void I2S_Close(I2S_T *i2s)
124 {
125  i2s->CTL0 &= ~I2S_CTL0_I2SEN_Msk;
126 }
127 
135 void I2S_EnableInt(I2S_T *i2s, uint32_t u32Mask)
136 {
137  i2s->IEN |= u32Mask;
138 }
139 
147 void I2S_DisableInt(I2S_T *i2s, uint32_t u32Mask)
148 {
149  i2s->IEN &= ~u32Mask;
150 }
151 
158 uint32_t I2S_EnableMCLK(I2S_T *i2s, uint32_t u32BusClock)
159 {
160  uint8_t u8Divider;
161  uint32_t u32SrcClk, u32Reg, u32Clock;
162 
163  u32SrcClk = I2S_GetSourceClockFreq(i2s);
164  if (u32BusClock == u32SrcClk)
165  {
166  u8Divider = 0U;
167  }
168  else
169  {
170  u8Divider = (uint8_t)(u32SrcClk/u32BusClock) >> 1U;
171  }
172 
173  i2s->CLKDIV = (i2s->CLKDIV & ~I2S_CLKDIV_MCLKDIV_Msk) | u8Divider;
174 
175  i2s->CTL0 |= I2S_CTL0_MCLKEN_Msk;
176 
177  u32Reg = i2s->CLKDIV & I2S_CLKDIV_MCLKDIV_Msk;
178 
179  if (u32Reg == 0U)
180  {
181  u32Clock = u32SrcClk;
182  }
183  else
184  {
185  u32Clock = ((u32SrcClk >> 1U) / u32Reg);
186  }
187 
188  return u32Clock;
189 }
190 
197 {
198  i2s->CTL0 &= ~I2S_CTL0_MCLKEN_Msk;
199 }
200 
209 void I2S_SetFIFO(I2S_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
210 {
211  i2s->CTL1 = ((i2s->CTL1 & ~(I2S_CTL1_TXTH_Msk | I2S_CTL1_RXTH_Msk)) |
212  (u32TxThreshold << I2S_CTL1_TXTH_Pos) |
213  (u32RxThreshold << I2S_CTL1_RXTH_Pos));
214 }
215 
216 
236 void I2S_ConfigureTDM(I2S_T *i2s, uint32_t u32ChannelWidth, uint32_t u32ChannelNum, uint32_t u32SyncWidth)
237 {
239  (u32ChannelWidth << I2S_CTL0_CHWIDTH_Pos) |
240  (u32ChannelNum << I2S_CTL0_TDMCHNUM_Pos) |
241  (u32SyncWidth << I2S_CTL0_PCMSYNC_Pos));
242 }
243  /* end of group I2S_EXPORTED_FUNCTIONS */
245  /* end of group I2S_Driver */
247  /* end of group Standard_Driver */
249 
250 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
#define I2S_CLKDIV_BCLKDIV_Msk
Definition: i2s_reg.h:1065
#define CLK
Definition: M480.h:368
#define CLK_CLKSEL3_I2S0SEL_PCLK0
Definition: clk.h:215
#define I2S_FIFO_RX_LEVEL_WORD_8
Definition: i2s.h:94
#define CLK_CLKSEL3_I2S0SEL_HIRC
Definition: clk.h:214
__IO uint32_t CTL1
Definition: i2s_reg.h:997
#define I2S_CTL0_CHWIDTH_Pos
Definition: i2s_reg.h:1055
void I2S_EnableInt(I2S_T *i2s, uint32_t u32Mask)
This function enables the interrupt according to the mask parameter.
Definition: i2s.c:135
void I2S_DisableInt(I2S_T *i2s, uint32_t u32Mask)
This function disables the interrupt according to the mask parameter.
Definition: i2s.c:147
uint32_t I2S_EnableMCLK(I2S_T *i2s, uint32_t u32BusClock)
Enable MCLK .
Definition: i2s.c:158
NuMicro peripheral access layer header file.
#define I2S_CTL1_RXTH_Msk
Definition: i2s_reg.h:1188
#define SYS
Definition: M480.h:367
#define CLK_CLKSEL3_I2S0SEL_HXT
Definition: clk.h:212
#define SYS_IPRST1_I2S0RST_Msk
Definition: sys_reg.h:4972
#define I2S_CTL0_PCMSYNC_Pos
Definition: i2s_reg.h:1052
#define I2S_CLKDIV_MCLKDIV_Msk
Definition: i2s_reg.h:1062
uint32_t CLK_GetPCLK0Freq(void)
Get PCLK0 frequency.
Definition: clk.c:164
#define I2S_FIFO_TX_LEVEL_WORD_8
Definition: i2s.h:78
Definition: i2s_reg.h:26
uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
Definition: clk.c:1188
#define I2S_CTL0_TDMCHNUM_Pos
Definition: i2s_reg.h:1058
#define I2S_CTL0_MCLKEN_Msk
Definition: i2s_reg.h:1032
__IO uint32_t CLKDIV
Definition: i2s_reg.h:989
#define I2S_CTL0_I2SEN_Msk
Definition: i2s_reg.h:1008
#define I2S_CTL1_TXTH_Msk
Definition: i2s_reg.h:1185
#define I2S_CTL1_TXTH_Pos
Definition: i2s_reg.h:1184
void I2S_ConfigureTDM(I2S_T *i2s, uint32_t u32ChannelWidth, uint32_t u32ChannelNum, uint32_t u32SyncWidth)
Configure PCM(TDM) function parameters, such as channel width, channel number and sync pulse width.
Definition: i2s.c:236
uint32_t I2S_Open(I2S_T *i2s, uint32_t u32MasterSlave, uint32_t u32SampleRate, uint32_t u32WordWidth, uint32_t u32MonoData, uint32_t u32DataFormat)
This function configures some parameters of I2S interface for general purpose use....
Definition: i2s.c:91
#define __HIRC
Definition: system_M480.h:36
#define CLK_CLKSEL3_I2S0SEL_Msk
Definition: clk_reg.h:2595
#define I2S_CTL1_RXTH_Pos
Definition: i2s_reg.h:1187
void I2S_Close(I2S_T *i2s)
Disable I2S function and I2S clock.
Definition: i2s.c:123
void I2S_DisableMCLK(I2S_T *i2s)
Disable MCLK .
Definition: i2s.c:196
__IO uint32_t CTL0
Definition: i2s_reg.h:988
#define CLK_CLKSEL3_I2S0SEL_PLL
Definition: clk.h:213
#define I2S_CTL0_CHWIDTH_Msk
Definition: i2s_reg.h:1056
void I2S_SetFIFO(I2S_T *i2s, uint32_t u32TxThreshold, uint32_t u32RxThreshold)
Configure FIFO threshold setting.
Definition: i2s.c:209
#define __HXT
Definition: system_M480.h:29
static uint32_t I2S_GetSourceClockFreq(I2S_T *i2s)
This function is used to get I2S source clock frequency.
Definition: i2s.c:32
__IO uint32_t IEN
Definition: i2s_reg.h:990
#define I2S_CTL0_PCMSYNC_Msk
Definition: i2s_reg.h:1053
#define I2S_CTL0_TDMCHNUM_Msk
Definition: i2s_reg.h:1059