LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2s_001.c
Go to the documentation of this file.
1 /*
2  * @brief I2S Registers and control functions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "i2s_001.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
37 
38 /*****************************************************************************
39  * Public types/enumerations/variables
40  ****************************************************************************/
41 
42 /*****************************************************************************
43  * Private functions
44  ****************************************************************************/
45 
46 /*****************************************************************************
47  * Public functions
48  ****************************************************************************/
49 
50 /* Initialize for I2S */
52 {}
53 
54 /* Shutdown I2S */
56 {
57  pI2S->DAI = 0x07E1;
58  pI2S->DAO = 0x87E1;
59  pI2S->IRQ = 0;
60  pI2S->TXMODE = 0;
61  pI2S->RXMODE = 0;
62  pI2S->DMA1 = 0;
63  pI2S->DMA2 = 0;
64 }
65 
66 /* I2S configuration functions --------*/
67 
68 /* Selects the number of bytes in data */
69 void IP_I2S_SetWordWidth(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t wordwidth)
70 {
71  uint32_t temp;
72  if (TRMode == I2S_TX_MODE) {
73  temp = pI2S->DAO & (~I2S_DAO_WORDWIDTH_MASK);
74  pI2S->DAO = temp | wordwidth;
75  }
76  else {
77  temp = pI2S->DAI & (~I2S_DAI_WORDWIDTH_MASK);
78  pI2S->DAI = temp | wordwidth;
79  }
80 }
81 
82 /* Set I2S data format is monaural or stereo */
83 void IP_I2S_SetMono(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t mono)
84 {
85  uint32_t temp;
86  if (TRMode == I2S_TX_MODE) {
87  temp = pI2S->DAO & (~I2S_DAO_MONO);
88  pI2S->DAO = temp | mono;
89  }
90  else {
91  temp = pI2S->DAI & (~I2S_DAI_MONO);
92  pI2S->DAI = temp | mono;
93  }
94 }
95 
96 /* Set I2S interface in master/slave mode */
97 void IP_I2S_SetMasterSlaveMode(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t mode)
98 {
99  uint32_t temp;
100  if (TRMode == I2S_TX_MODE) {
101  temp = pI2S->DAO & (~I2S_DAO_SLAVE);
102  pI2S->DAO = temp | mode;
103  }
104  else {
105  temp = pI2S->DAI & (~I2S_DAI_SLAVE);
106  pI2S->DAI = temp | mode;
107  }
108 }
109 
110 /* Set the clock frequency for I2S interface */
111 void IP_I2S_SetBitRate(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t mclk_divider)
112 {
113  if (TRMode == I2S_TX_MODE) {
114  pI2S->TXBITRATE = mclk_divider;
115  }
116  else {
117  pI2S->RXBITRATE = mclk_divider;
118  }
119 }
120 
121 /* Set the MCLK rate by using a fractional rate generator, dividing down the frequency of PCLK */
122 void IP_I2S_SetXYDivider(IP_I2S_001_T *pI2S, uint8_t TRMode, uint8_t x_divider, uint8_t y_divider)
123 {
124  if (TRMode == I2S_TX_MODE) {
125  pI2S->TXRATE = y_divider | (x_divider << 8);
126  }
127  else {
128  pI2S->RXRATE = y_divider | (x_divider << 8);
129  }
130 }
131 
132 /* Set word select (WS) half period */
133 void IP_I2S_SetWS_Halfperiod(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t ws_halfperiod)
134 {
135  uint32_t temp;
136  if (TRMode == I2S_TX_MODE) {
137  temp = pI2S->DAO & (~I2S_DAO_WS_HALFPERIOD_MASK);
138  pI2S->DAO = temp | (I2S_DAO_WS_HALFPERIOD(ws_halfperiod));
139  }
140  else {
141  temp = pI2S->DAI & (~I2S_DAI_WS_HALFPERIOD_MASK);
142  pI2S->DAI = temp | (I2S_DAI_WS_HALFPERIOD(ws_halfperiod));
143  }
144 }
145 
146 /* Set the I2S operating modes */
147 void IP_I2S_ModeConfig(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t clksel, uint32_t fpin, uint32_t mcena)
148 {
149  if (TRMode == I2S_TX_MODE) {
150  pI2S->TXMODE = clksel | fpin | mcena;
151  }
152  else {
153  pI2S->RXMODE = clksel | fpin | mcena;
154  }
155 }
156 
157 /* Get the current level of the Transmit/Receive FIFO */
158 uint8_t IP_I2S_GetLevel(IP_I2S_001_T *pI2S, uint8_t TRMode)
159 {
160  if (TRMode == I2S_TX_MODE) {
161  return (pI2S->STATE >> 16) & 0xF;
162  }
163  else {
164  return (pI2S->STATE >> 8) & 0xF;
165  }
166 }
167 
168 /* I2S operate functions -------------*/
169 
170 /* Send a 32-bit data to TXFIFO for transmition */
172 {
173  pI2S->TXFIFO = data;
174 }
175 
176 /* Get received data from RXFIFO */
178 {
179  return pI2S->RXFIFO;
180 }
181 
182 /* Start the I2S */
183 void IP_I2S_Start(IP_I2S_001_T *pI2S, uint8_t TRMode)
184 {
185  if (TRMode == I2S_TX_MODE) {
186  pI2S->DAO &= ~(I2S_DAO_RESET | I2S_DAO_STOP | I2S_DAO_MUTE);
187  }
188  else {
189  pI2S->DAI &= ~(I2S_DAI_RESET | I2S_DAI_STOP);
190  }
191 }
192 
193 /* Disables accesses on FIFOs, places the transmit channel in mute mode */
194 void IP_I2S_Pause(IP_I2S_001_T *pI2S, uint8_t TRMode)
195 {
196  if (TRMode == I2S_TX_MODE) {
197  pI2S->DAO |= I2S_DAO_STOP;
198  }
199  else {
200  pI2S->DAI |= I2S_DAI_STOP;
201  }
202 }
203 
204 /* Pause, resets the transmit channel and FIFO asynchronously */
205 void IP_I2S_Stop(IP_I2S_001_T *pI2S, uint8_t TRMode)
206 {
207  if (TRMode == I2S_TX_MODE) {
208  pI2S->DAO &= ~I2S_DAO_MUTE;
209  pI2S->DAO |= I2S_DAO_STOP | I2S_DAO_RESET;
210  }
211  else {
212  pI2S->DAI |= I2S_DAI_STOP | I2S_DAI_RESET;
213  }
214 }
215 
216 /* I2S DMA functions ----------------*/
217 
218 /* Set the FIFO level on which to create an DMA request */
219 void IP_I2S_DMACmd(IP_I2S_001_T *pI2S, IP_I2S_DMARequestNumber_T DMANum, uint8_t TRMode, FunctionalState NewState)
220 {
221  if (TRMode == I2S_RX_MODE) {
222  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
223  if (NewState == ENABLE) {
224  pI2S->DMA1 |= 0x01;
225  }
226  else {
227  pI2S->DMA1 &= ~0x01;
228  }
229  }
230  else {
231  if (NewState == ENABLE) {
232  pI2S->DMA2 |= 0x01;
233  }
234  else {
235  pI2S->DMA2 &= ~0x01;
236  }
237  }
238  }
239  else {
240  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
241  if (NewState == ENABLE) {
242  pI2S->DMA1 |= 0x02;
243  }
244  else {
245  pI2S->DMA1 &= ~0x02;
246  }
247  }
248  else {
249  if (NewState == ENABLE) {
250  pI2S->DMA2 |= 0x02;
251  }
252  else {
253  pI2S->DMA2 &= ~0x02;
254  }
255  }
256  }
257 }
258 
259 /* Enable/Disable DMA for the I2S */
260 void IP_I2S_SetFIFODepthDMA(IP_I2S_001_T *pI2S, uint8_t TRMode, IP_I2S_DMARequestNumber_T DMANum, uint32_t depth)
261 {
262  if (TRMode == I2S_RX_MODE) {
263  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
264  pI2S->DMA1 &= ~(0x0F << 8);
265  pI2S->DMA1 |= depth << 8;
266  }
267  else {
268  pI2S->DMA2 &= ~(0x0F << 8);
269  pI2S->DMA2 |= depth << 8;
270  }
271  }
272  else {
273  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
274  pI2S->DMA1 &= ~(0x0F << 16);
275  pI2S->DMA1 |= depth << 16;
276  }
277  else {
278  pI2S->DMA2 &= ~(0x0F << 16);
279  pI2S->DMA2 |= depth << 16;
280  }
281  }
282 }
283 
284 /* I2S IRQ functions ----------------*/
285 
286 /* Enable/Disable interrupt for the I2S */
287 void IP_I2S_InterruptCmd(IP_I2S_001_T *pI2S, uint8_t TRMode, FunctionalState NewState)
288 {
289  if (NewState == ENABLE) {
290  pI2S->IRQ |= (TRMode == I2S_RX_MODE) ? 0x01 : 0x02;
291  }
292  else {
293  pI2S->IRQ &= (TRMode == I2S_RX_MODE) ? (~0x01) : (~0x02);
294  }
295 }
296 
297 /* Set the FIFO level on which to create an irq request */
298 void IP_I2S_SetFIFODepthIRQ(IP_I2S_001_T *pI2S, uint8_t TRMode, uint32_t depth)
299 {
300  uint32_t temp;
301  depth &= 0x0F;
302  if (TRMode == I2S_RX_MODE) {
303  temp = pI2S->IRQ & (~I2S_IRQ_RX_DEPTH_MASK);
304  pI2S->IRQ = temp | (I2S_IRQ_RX_DEPTH(depth));
305  }
306  else {
307  temp = pI2S->IRQ & (~I2S_IRQ_TX_DEPTH_MASK);
308  pI2S->IRQ = temp | (I2S_IRQ_TX_DEPTH(depth));
309  }
310 }
311 
312 /* Get the status of I2S interrupt */
314 {
315  if (TRMode == I2S_TX_MODE) {
316  return (Status) (((pI2S->IRQ >> 1) & 0x01) & ((pI2S->STATE) & 0x01));
317  }
318  else {
319  return (Status) (((pI2S->IRQ) & 0x01) & ((pI2S->STATE) & 0x01));
320  }
321 }