LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
AudioOutput.c
Go to the documentation of this file.
1 /*
2  * @brief Make your board becomes a USB speaker
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * Copyright(C) Dean Camera, 2011, 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 "AudioOutput.h"
34 #if defined(USB_DEVICE_ROM_DRIVER)
35 #include ".\Lib\usbd_adcuser.h"
36 #endif
37 
42  .Config = {
44 
45  .DataOUTEndpointNumber = AUDIO_STREAM_EPNUM,
46  .DataOUTEndpointSize = AUDIO_STREAM_EPSIZE,
47  },
48 };
49 
51 #define AUDIO_MAX_SAMPLE_FREQ 48000
52 
54 
59 #define AUDIO_MAX_PC 10
61 uint8_t audio_buffer[2048] ATTR_ALIGNED(4);
67 {
71 }
72 
74 {
75  audio_buffer_wr_index += last_packet_size;
76  audio_buffer_count += last_packet_size;
79  }
82  }
83  return (uint32_t) &audio_buffer[audio_buffer_wr_index];
84 }
85 
86 void Audio_Init(uint32_t samplefreq)
87 {
88  Chip_I2S_Audio_Format_Type audio_Confg;
89  audio_Confg.SampleRate = samplefreq;
90  audio_Confg.ChannelNumber = 2; // 1 is mono, 2 is stereo
91  audio_Confg.WordWidth = 16; // 8, 16 or 32 bits
95  Chip_I2S_Config(LPC_I2S0, I2S_TX_MODE, &audio_Confg);
100  NVIC_EnableIRQ(I2S0_IRQn);
101 
103  switch (samplefreq) {
104  case 11025:
105  case 22050:
106  case 44100:
107  audio_buffer_size = 1764;
108  break;
109 
110  case 8000:
111  case 16000:
112  case 32000:
113  case 48000:
114  default:
115  audio_buffer_size = samplefreq * 4 * AUDIO_MAX_PC / 1000;
116  break;
117  }
118 }
119 
120 void Audio_DeInit(void)
121 {
124  NVIC_DisableIRQ(I2S0_IRQn);
125 }
126 
127 void I2S0_IRQHandler(void)
128 {
129  uint32_t txlevel, i;
131  if (txlevel <= 4) {
132  for (i = 0; i < 8 - txlevel; i++) {
133  if (audio_buffer_count >= 4) { /*has enough data */
134  audio_buffer_count -= 4;
135  Chip_I2S_Send(LPC_I2S0, *(uint32_t *) (audio_buffer + audio_buffer_rd_index));
139  }
140  }
141  else {
143  }
144 
145  /*Skip some samples if buffer run writting too fast. */
146  if ((audio_buffer_size != 0) && (audio_buffer_count >= (audio_buffer_size / 2))) {
147  audio_buffer_count -= 4;
151  }
152  }
153  }
154  }
155 }
156 
160 
161  /* Check if this is audio stream endpoint */
162  if (EPNum == AUDIO_STREAM_EPNUM) {
163  return Audio_Get_ISO_Buffer_Address(*last_packet_size);
164  }
165  else {return 0; }
166 }
167 
171 int main(void)
172 {
173  SetupHardware();
174 
175 #if defined(USB_DEVICE_ROM_DRIVER)
176  UsbdAdc_Init();
177 #endif
178 
179  for (;; ) {
180 #if !defined(USB_DEVICE_ROM_DRIVER)
181  Audio_Device_USBTask(&Speaker_Audio_Interface);
182  USB_USBTask();
183 #endif
184  }
185 }
186 
188 void SetupHardware(void)
189 {
190  Board_Init();
191  USB_Init();
192 }
193 
194 #if !defined(USB_DEVICE_ROM_DRIVER)
195 
197 {}
198 
201 {}
202 
205 {
206  bool ConfigSuccess = true;
207 
208  ConfigSuccess &= Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface);
209 
210  // LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
211 }
212 
215 {
216  Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
217 }
218 
220 {
221  /* reset audio buffer */
223 }
224 
229  const uint8_t EndpointProperty,
230  const uint8_t EndpointAddress,
231  const uint8_t EndpointControl,
232  uint16_t *const DataLength,
233  uint8_t *Data)
234 {
235  /* Check the requested endpoint to see if a supported endpoint is being manipulated */
236  if (EndpointAddress == (ENDPOINT_DIR_OUT | Speaker_Audio_Interface.Config.DataOUTEndpointNumber)) {
237  /* Check the requested control to see if a supported control is being manipulated */
238  if (EndpointControl == AUDIO_EPCONTROL_SamplingFreq) {
239  switch (EndpointProperty) {
241  /* Check if we are just testing for a valid property, or actually adjusting it */
242  if (DataLength != NULL) {
243  /* Set the new sampling frequency to the value given by the host */
245  (((uint32_t) Data[2] << 16) | ((uint32_t) Data[1] << 8) | (uint32_t) Data[0]);
247  return false;
248  }
249  Audio_DeInit();
251  }
252 
253  return true;
254 
256  /* Check if we are just testing for a valid property, or actually reading it */
257  if (DataLength != NULL) {
258  *DataLength = 3;
259 
260  Data[2] = (CurrentAudioSampleFrequency >> 16);
261  Data[1] = (CurrentAudioSampleFrequency >> 8);
262  Data[0] = (CurrentAudioSampleFrequency & 0xFF);
263  }
264 
265  return true;
266  }
267  }
268  }
269 
270  return false;
271 }
272 
273 #else
274 
275 #endif