LPCOpen Platform
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_Type *pI2S, uint8_t TRMode, uint32_t wordwidth)
70 {
71  if (TRMode == I2S_TX_MODE) {
72  pI2S->DAO &= ~I2S_DAO_WORDWIDTH_MASK;
73  pI2S->DAO |= wordwidth;
74  }
75  else {
76  pI2S->DAI &= ~I2S_DAI_WORDWIDTH_MASK;
77  pI2S->DAI |= wordwidth;
78  }
79 }
80 
81 /* Set I2S data format is monaural or stereo */
82 void IP_I2S_SetMono(IP_I2S_001_Type *pI2S, uint8_t TRMode, uint32_t mono)
83 {
84  if (TRMode == I2S_TX_MODE) {
85  pI2S->DAO &= ~I2S_DAO_MONO;
86  pI2S->DAO |= mono;
87  }
88  else {
89  pI2S->DAI &= ~I2S_DAI_MONO;
90  pI2S->DAI |= mono;
91  }
92 }
93 
94 /* Set I2S interface in master/slave mode */
96 {
97  if (TRMode == I2S_TX_MODE) {
98  pI2S->DAO &= ~I2S_DAO_SLAVE;
99  pI2S->DAO |= mode;
100  }
101  else {
102  pI2S->DAI &= ~I2S_DAI_SLAVE;
103  pI2S->DAI |= mode;
104  }
105 }
106 
107 /* Set the clock frequency for I2S interface */
108 void IP_I2S_SetBitRate(IP_I2S_001_Type *pI2S, uint8_t TRMode, uint32_t mclk_divider)
109 {
110  if (TRMode == I2S_TX_MODE) {
111  pI2S->TXBITRATE = mclk_divider;
112  }
113  else {
114  pI2S->RXBITRATE = mclk_divider;
115  }
116 }
117 
118 /* Set the MCLK rate by using a fractional rate generator, dividing down the frequency of PCLK */
119 void IP_I2S_SetXYDivider(IP_I2S_001_Type *pI2S, uint8_t TRMode, uint8_t x_divider, uint8_t y_divider)
120 {
121  if (TRMode == I2S_TX_MODE) {
122  pI2S->TXRATE = y_divider | (x_divider << 8);
123  }
124  else {
125  pI2S->RXRATE = y_divider | (x_divider << 8);
126  }
127 }
128 
129 /* Set word select (WS) half period */
130 void IP_I2S_SetWS_Halfperiod(IP_I2S_001_Type *pI2S, uint8_t TRMode, uint32_t ws_halfperiod)
131 {
132  if (TRMode == I2S_TX_MODE) {
134  pI2S->DAO |= I2S_DAO_WS_HALFPERIOD(ws_halfperiod);
135  }
136  else {
138  pI2S->DAI |= I2S_DAI_WS_HALFPERIOD(ws_halfperiod);
139  }
140 }
141 
142 /* Set the I2S operating modes */
143 void IP_I2S_ModeConfig(IP_I2S_001_Type *pI2S, uint8_t TRMode, uint32_t clksel, uint32_t fpin, uint32_t mcena)
144 {
145  if (TRMode == I2S_TX_MODE) {
146  pI2S->TXMODE = clksel | fpin | mcena;
147  }
148  else {
149  pI2S->RXMODE = clksel | fpin | mcena;
150  }
151 }
152 
153 /* Get the current level of the Transmit/Receive FIFO */
154 uint8_t IP_I2S_GetLevel(IP_I2S_001_Type *pI2S, uint8_t TRMode)
155 {
156  if (TRMode == I2S_TX_MODE) {
157  return (pI2S->STATE >> 16) & 0xF;
158  }
159  else {
160  return (pI2S->STATE >> 8) & 0xF;
161  }
162 }
163 
164 /* I2S operate functions -------------*/
165 
166 /* Send a 32-bit data to TXFIFO for transmition */
168 {
169  pI2S->TXFIFO = data;
170 }
171 
172 /* Get received data from RXFIFO */
174 {
175  return pI2S->RXFIFO;
176 }
177 
178 /* Start the I2S */
179 void IP_I2S_Start(IP_I2S_001_Type *pI2S, uint8_t TRMode)
180 {
181  if (TRMode == I2S_TX_MODE) {
182  pI2S->DAO &= ~(I2S_DAO_RESET | I2S_DAO_STOP | I2S_DAO_MUTE);
183  }
184  else {
185  pI2S->DAI &= ~(I2S_DAI_RESET | I2S_DAI_STOP);
186  }
187 }
188 
189 /* Disables accesses on FIFOs, places the transmit channel in mute mode */
190 void IP_I2S_Pause(IP_I2S_001_Type *pI2S, uint8_t TRMode)
191 {
192  if (TRMode == I2S_TX_MODE) {
193  pI2S->DAO |= I2S_DAO_STOP;
194  }
195  else {
196  pI2S->DAI |= I2S_DAI_STOP;
197  }
198 }
199 
200 /* Transmit channel sends only zeroes */
202 {
203  if (NewState == ENABLE) {
204  pI2S->DAO |= I2S_DAO_MUTE;
205  }
206  else {
207  pI2S->DAO &= ~I2S_DAO_MUTE;
208  }
209 }
210 
211 /* Pause, resets the transmit channel and FIFO asynchronously */
212 void IP_I2S_Stop(IP_I2S_001_Type *pI2S, uint8_t TRMode)
213 {
214  if (TRMode == I2S_TX_MODE) {
215  pI2S->DAO &= ~I2S_DAO_MUTE;
216  pI2S->DAO |= I2S_DAO_STOP | I2S_DAO_RESET;
217  }
218  else {
219  pI2S->DAI |= I2S_DAI_STOP | I2S_DAI_RESET;
220  }
221 }
222 
223 /* I2S DMA functions ----------------*/
224 
225 /* Set the FIFO level on which to create an DMA request */
226 void IP_I2S_DMACmd(IP_I2S_001_Type *pI2S, IP_I2S_DMARequestNumber_Type DMANum, uint8_t TRMode, FunctionalState NewState)
227 {
228  if (TRMode == I2S_RX_MODE) {
229  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
230  if (NewState == ENABLE) {
231  pI2S->DMA1 |= 0x01;
232  }
233  else {
234  pI2S->DMA1 &= ~0x01;
235  }
236  }
237  else {
238  if (NewState == ENABLE) {
239  pI2S->DMA2 |= 0x01;
240  }
241  else {
242  pI2S->DMA2 &= ~0x01;
243  }
244  }
245  }
246  else {
247  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
248  if (NewState == ENABLE) {
249  pI2S->DMA1 |= 0x02;
250  }
251  else {
252  pI2S->DMA1 &= ~0x02;
253  }
254  }
255  else {
256  if (NewState == ENABLE) {
257  pI2S->DMA2 |= 0x02;
258  }
259  else {
260  pI2S->DMA2 &= ~0x02;
261  }
262  }
263  }
264 }
265 
266 /* Enable/Disable DMA for the I2S */
268 {
269  if (TRMode == I2S_RX_MODE) {
270  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
271  pI2S->DMA1 &= ~(0x0F << 8);
272  pI2S->DMA1 |= depth << 8;
273  }
274  else {
275  pI2S->DMA2 &= ~(0x0F << 8);
276  pI2S->DMA2 |= depth << 8;
277  }
278  }
279  else {
280  if (DMANum == IP_I2S_DMA_REQUEST_NUMBER_1) {
281  pI2S->DMA1 &= ~(0x0F << 16);
282  pI2S->DMA1 |= depth << 16;
283  }
284  else {
285  pI2S->DMA2 &= ~(0x0F << 16);
286  pI2S->DMA2 |= depth << 16;
287  }
288  }
289 }
290 
291 /* I2S IRQ functions ----------------*/
292 
293 /* Enable/Disable interrupt for the I2S */
294 void IP_I2S_InterruptCmd(IP_I2S_001_Type *pI2S, uint8_t TRMode, FunctionalState NewState)
295 {
296  if (NewState == ENABLE) {
297  pI2S->IRQ |= (TRMode == I2S_RX_MODE) ? 0x01 : 0x02;
298  }
299  else {
300  pI2S->IRQ &= (TRMode == I2S_RX_MODE) ? (~0x01) : (~0x02);
301  }
302 }
303 
304 /* Set the FIFO level on which to create an irq request */
305 void IP_I2S_SetFIFODepthIRQ(IP_I2S_001_Type *pI2S, uint8_t TRMode, uint32_t depth)
306 {
307  depth &= 0x0F;
308  if (TRMode == I2S_RX_MODE) {
309  pI2S->IRQ &= ~I2S_IRQ_RX_DEPTH_MASK;
310  pI2S->IRQ |= I2S_IRQ_RX_DEPTH(depth);
311  }
312  else {
313  pI2S->IRQ &= ~I2S_IRQ_TX_DEPTH_MASK;
314  pI2S->IRQ |= I2S_IRQ_TX_DEPTH(depth);
315  }
316 }
317 
318 /* Get the status of I2S interrupt */
320 {
321  if (TRMode == I2S_TX_MODE) {
322  return (Status) (((pI2S->IRQ >> 1) & 0x01) & ((pI2S->STATE) & 0x01));
323  }
324  else {
325  return (Status) (((pI2S->IRQ) & 0x01) & ((pI2S->STATE) & 0x01));
326  }
327 }