| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
i2s.c
Go to the documentation of this file.
1 /*
2 * @brief I2S example
3 * This example show how to use the I2S in 3 modes : Polling, Interrupt and DMA
4 *
5 * @note
6 * Copyright(C) NXP Semiconductors, 2012
7 * All rights reserved.
8 *
9 * @par
10 * Software that is described herein is for illustrative purposes only
11 * which provides customers with programming information regarding the
12 * LPC products. This software is supplied "AS IS" without any warranties of
13 * any kind, and NXP Semiconductors and its licensor disclaim any and
14 * all warranties, express or implied, including all implied warranties of
15 * merchantability, fitness for a particular purpose and non-infringement of
16 * intellectual property rights. NXP Semiconductors assumes no responsibility
17 * or liability for the use of the software, conveys no license or rights under any
18 * patent, copyright, mask work right, or any other intellectual property rights in
19 * or to any products. NXP Semiconductors reserves the right to make changes
20 * in the software without notification. NXP Semiconductors also makes no
21 * representation or warranty that such application will be suitable for the
22 * specified use without further testing or modification.
23 *
24 * @par
25 * Permission to use, copy, modify, and distribute this software and its
26 * documentation is hereby granted, under NXP Semiconductors' and its
27 * licensor's relevant copyrights in the software, without fee, provided that it
28 * is used in conjunction with NXP Semiconductors microcontrollers. This
29 * copyright, permission, and disclaimer notice must appear in all copies of
30 * this code.
31 */
32
33 #include "board.h"
34
71 /*****************************************************************************
72 * Private types/enumerations/variables
73 ****************************************************************************/
74
75 #define BUFFER_FULL 0
76 #define BUFFER_EMPTY 1
77 #define BUFFER_AVAILABLE 2
78
79 typedef struct ring_buff {
80 uint32_t buffer[256];
81 uint8_t read_index;
82 uint8_t write_index;
83 } Ring_Buffer_t;
84
85 static char WelcomeMenu[] = "\r\nHello NXP Semiconductors \r\n"
86 "I2S DEMO : Connect audio headphone out from computer to line-in on tested board to get audio signal\r\n"
87 "Please press \'1\' to test Polling mode\r\n"
88 "Please press \'2\' to test Interrupt mode\r\n"
89 "Please press \'3\' to test DMA mode\r\n"
90 "Please press \'x\' to exit test mode\r\n"
91 "Please press \'m\' to DISABLE/ENABLE mute\r\n";
92
93 static Ring_Buffer_t ring_buffer;
94
95 static uint8_t send_flag;
96 static uint8_t channelTC;
97 static uint8_t dmaChannelNum_I2S_Tx, dmaChannelNum_I2S_Rx;
98 static uint8_t dma_send_receive;
99
100 /*****************************************************************************
101 * Public types/enumerations/variables
102 ****************************************************************************/
103
104 /*****************************************************************************
105 * Private functions
106 ****************************************************************************/
107 uint8_t mute_status = 0;
108
109 /* Get input from console */
110 int Con_GetInput(void)
111 {
112 #ifdef DEBUG_ENABLE
113 return DEBUGIN();
114 #else
115 return '3';
116 #endif
117 }
118
119 static void mute_toggle()
120 {
121 mute_status = !mute_status;
122 if (mute_status) {
123 Chip_I2S_EnableMute(LPC_I2S0);
124 DEBUGOUT("MUTE ENABLE\n\r");
125 }
126 else {
127 Chip_I2S_DisableMute(LPC_I2S0);
128 DEBUGOUT("MUTE DISABLE\n\r");
129 }
130 }
131
132 /* Get status of the ring buffer */
133 static uint8_t ring_buff_get_status(Ring_Buffer_t *ring_buff)
134 {
135 if (ring_buff->read_index == ring_buff->write_index) {
136 return BUFFER_EMPTY;
137 }
138 else if (ring_buff->read_index == (ring_buff->write_index) + 1) {
139 return BUFFER_FULL;
140 }
141 else {return BUFFER_AVAILABLE; }
142 }
143
144 /* Interrupt routine for I2S example */
145 static void App_Interrupt_Test(void)
146 {
147 uint8_t bufferUART, continue_Flag = 1;
148 DEBUGOUT("I2S Interrupt mode\r\n");
149 Chip_I2S_Int_Cmd(LPC_I2S0, I2S_RX_MODE, ENABLE, 4);
150 Chip_I2S_Int_Cmd(LPC_I2S0, I2S_TX_MODE, ENABLE, 4);
151 NVIC_EnableIRQ(I2S0_IRQn);
152 while (continue_Flag) {
153 bufferUART = 0xFF;
154 bufferUART = Con_GetInput();
155 switch (bufferUART) {
156 case 'x':
157 continue_Flag = 0;
158 Chip_I2S_Int_Cmd(LPC_I2S0, I2S_RX_MODE, DISABLE, 4);
159 NVIC_DisableIRQ(I2S0_IRQn);
160 DEBUGOUT(WelcomeMenu);
161 break;
162
163 case 'm':
164 mute_toggle();
165 break;
166
167 default:
168 break;
169 }
170 }
171 }
172
173 /* Polling routine for I2S example */
174 static void App_Polling_Test(void)
175 {
176 uint32_t polling_data = 0;
177 uint8_t bufferUART, continue_Flag = 1;
178 DEBUGOUT("I2S Polling mode\r\n");
179 while (continue_Flag) {
180 bufferUART = 0xFF;
181 bufferUART = Con_GetInput();
182 switch (bufferUART) {
183 case 'x':
184 continue_Flag = 0;
185 DEBUGOUT(WelcomeMenu);
186 break;
187
188 case 'm':
189 mute_toggle();
190 break;
191
192 default:
193 break;
194 }
195
196 if (Chip_I2S_GetLevel(LPC_I2S0, I2S_RX_MODE) > 0) {
197 polling_data = Chip_I2S_Receive(LPC_I2S0);
198 send_flag = 1;
199 }
200 if ((Chip_I2S_GetLevel(LPC_I2S0, I2S_TX_MODE) < 4) && (send_flag == 1)) {
201 Chip_I2S_Send(LPC_I2S0, polling_data);
202 send_flag = 0;
203 }
204 }
205 }
206
207 /* DMA routine for I2S example */
208 static void App_DMA_Test(void)
209 {
210 uint8_t continue_Flag = 1, bufferUART = 0xFF;
211 Chip_I2S_DMA_Cmd(LPC_I2S0, I2S_TX_MODE, I2S_DMA_REQUEST_NUMBER_1, ENABLE, 4);
212 Chip_I2S_DMA_Cmd(LPC_I2S0, I2S_RX_MODE, I2S_DMA_REQUEST_NUMBER_2, ENABLE, 4);
213 /* Initialize GPDMA controller */
214 Chip_GPDMA_Init(LPC_GPDMA);
215 /* Setting GPDMA interrupt */
216 NVIC_DisableIRQ(DMA_IRQn);
217 NVIC_SetPriority(DMA_IRQn, ((0x01 << 3) | 0x01));
218 NVIC_EnableIRQ(DMA_IRQn);
219
220 dmaChannelNum_I2S_Rx = Chip_DMA_GetFreeChannel(LPC_GPDMA, GPDMA_CONN_I2S_Rx_Channel_1);
221
222 Chip_DMA_Transfer(LPC_GPDMA, dmaChannelNum_I2S_Rx,
223 GPDMA_CONN_I2S_Rx_Channel_1,
224 GPDMA_CONN_I2S_Tx_Channel_0,
225 GPDMA_TRANSFERTYPE_P2P_CONTROLLER_SrcPERIPHERAL,
226 1);
227
228 DEBUGOUT("I2S DMA mode\r\n");
229 while (continue_Flag) {
230 bufferUART = 0xFF;
231 bufferUART = Con_GetInput();
232 switch (bufferUART) {
233 case 'x':
234 continue_Flag = 0;
235 Chip_I2S_DMA_Cmd(LPC_I2S0, I2S_RX_MODE, 2, DISABLE, 1);
236 Chip_I2S_DMA_Cmd(LPC_I2S0, I2S_TX_MODE, 1, DISABLE, 1);
237
238 Chip_DMA_Stop(LPC_GPDMA, dmaChannelNum_I2S_Rx);
239 NVIC_DisableIRQ(DMA_IRQn);
240 DEBUGOUT(WelcomeMenu);
241 break;
242
243 case 'm':
244 mute_toggle();
245 break;
246
247 default:
248 break;
249 }
250 }
251 }
252
253 /*****************************************************************************
254 * Public functions
255 ****************************************************************************/
256
261 void DMA_IRQHandler(void)
262 {
263 if (dma_send_receive == 1) {
264 if (Chip_DMA_Interrupt(LPC_GPDMA, dmaChannelNum_I2S_Rx) == SUCCESS) {
265 channelTC++;
266 }
267 else {
268 /* Process error here */
269 }
270 }
271 else {
272 if (Chip_DMA_Interrupt(LPC_GPDMA, dmaChannelNum_I2S_Tx) == SUCCESS) {
273 channelTC++;
274 }
275 else {
276 /* Process error here */
277 }
278 }
279 }
280
285 void I2S0_IRQHandler(void)
286 {
287 while ((ring_buff_get_status(&ring_buffer) != BUFFER_FULL) && (Chip_I2S_GetLevel(LPC_I2S0, I2S_RX_MODE) > 0)) {
288 ring_buffer.buffer[ring_buffer.write_index++] = Chip_I2S_Receive(LPC_I2S0);
289 }
290 while ((ring_buff_get_status(&ring_buffer) != BUFFER_EMPTY) && (Chip_I2S_GetLevel(LPC_I2S0, I2S_TX_MODE) < 8)) {
291 Chip_I2S_Send(LPC_I2S0, ring_buffer.buffer[ring_buffer.read_index++]);
292 }
293 }
294
299 int main(void)
300 {
301
302 Chip_I2S_Audio_Format_T audio_Confg;
303 uint8_t bufferUART, continue_Flag = 1;
304 audio_Confg.SampleRate = 48000;
305 /* Select audio data is 2 channels (1 is mono, 2 is stereo) */
306 audio_Confg.ChannelNumber = 2;
307 /* Select audio data is 16 bits */
308 audio_Confg.WordWidth = 16;
309
310 Board_Init();
311 #if defined( __GNUC__ )
312 __sys_write(0, "", 0);
313 #endif
314
315 DEBUGOUT(WelcomeMenu);
316 Board_Audio_Init(LPC_I2S0, UDA1380_LINE_IN);
317
318 Chip_I2S_Init(LPC_I2S0);
319 Chip_I2S_Config(LPC_I2S0, I2S_RX_MODE, &audio_Confg);
320 Chip_I2S_Config(LPC_I2S0, I2S_TX_MODE, &audio_Confg);
321
322 Chip_I2S_Stop(LPC_I2S0, I2S_TX_MODE);
323 Chip_I2S_DisableMute(LPC_I2S0);
324 Chip_I2S_Start(LPC_I2S0, I2S_TX_MODE);
325 send_flag = 0;
326 while (continue_Flag) {
327 bufferUART = 0xFF;
328 bufferUART = Con_GetInput();
329 switch (bufferUART) {
330 case '1':
331 App_Polling_Test();
332 break;
333
334 case '2':
335 App_Interrupt_Test();
336 break;
337
338 case '3':
339 App_DMA_Test();
340 break;
341
342 case 'x':
343 continue_Flag = 0;
344 DEBUGOUT("Thanks for using\r\n");
345 break;
346
347 default:
348 break;
349 }
350 }
351 return 0;
352 }
353