AudioInput.c 11 KB
 Dean Camera committed May 08, 2010 1 2 /* LUFA Library  Dean Camera committed Feb 04, 2012 3  Copyright (C) Dean Camera, 2012.  4   Dean Camera committed May 08, 2010 5  dean [at] fourwalledcubicle [dot] com  Dean Camera committed Oct 28, 2010 6  www.lufa-lib.org  Dean Camera committed May 08, 2010 7 8 9 */ /*  Dean Camera committed Jan 01, 2011 10  Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)  Dean Camera committed May 08, 2010 11   12  Permission to use, copy, modify, distribute, and sell this  Dean Camera committed May 08, 2010 13  software and its documentation for any purpose is hereby granted  14  without fee, provided that the above copyright notice appear in  Dean Camera committed May 08, 2010 15  all copies and that both that the copyright notice and this  16 17 18  permission notice and warranty disclaimer appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the  Dean Camera committed May 08, 2010 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53  software without specific, written prior permission. The author disclaim all warranties with regard to this software, including all implied warranties of merchantability and fitness. In no event shall the author be liable for any special, indirect or consequential damages or any damages whatsoever resulting from loss of use, data or profits, whether in an action of contract, negligence or other tortious action, arising out of or in connection with the use or performance of this software. */ /** \file * * Main source file for the AudioInput demo. This file contains the main tasks of * the demo and is responsible for the initial application hardware configuration. */ #include "AudioInput.h" /** LUFA Audio Class driver interface configuration and state information. This structure is * passed to all Audio Class driver functions, so that multiple instances of the same class * within a device can be differentiated from one another. */ USB_ClassInfo_Audio_Device_t Microphone_Audio_Interface = { .Config = { .StreamingInterfaceNumber = 1, .DataINEndpointNumber = AUDIO_STREAM_EPNUM, .DataINEndpointSize = AUDIO_STREAM_EPSIZE, }, };  Dean Camera committed Jun 03, 2011 54 /** Current audio sampling frequency of the streaming audio endpoint. */  55 static uint32_t CurrentAudioSampleFrequency = 48000;  Dean Camera committed Jun 03, 2011 56   Dean Camera committed Feb 10, 2011 57   Dean Camera committed May 08, 2010 58 59 60 61 62 63 64 65 66 /** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. */ int main(void) { SetupHardware(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei();  67   Dean Camera committed May 08, 2010 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83  for (;;) { Audio_Device_USBTask(&Microphone_Audio_Interface); USB_USBTask(); } } /** Configures the board hardware and chip peripherals for the demo's functionality. */ void SetupHardware(void) { /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); /* Disable clock division */ clock_prescale_set(clock_div_1);  84   Dean Camera committed May 08, 2010 85 86  /* Hardware Initialization */ LEDs_Init();  Dean Camera committed Oct 20, 2010 87  Buttons_Init();  Dean Camera committed May 08, 2010 88 89  ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32); ADC_SetupChannel(MIC_IN_ADC_CHANNEL);  Dean Camera committed Oct 20, 2010 90  USB_Init();  91   Dean Camera committed May 08, 2010 92 93 94 95  /* Start the ADC conversion in free running mode */ ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_MUX_MASK); }  Dean Camera committed Oct 26, 2010 96 97 /** ISR to handle the reloading of the data endpoint with the next sample. */ ISR(TIMER0_COMPA_vect, ISR_BLOCK)  Dean Camera committed May 08, 2010 98 {  Dean Camera committed Oct 26, 2010 99 100  uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();  Dean Camera committed Jun 09, 2011 101  /* Check that the USB bus is ready for the next sample to write */  Dean Camera committed Oct 26, 2010 102  if (Audio_Device_IsReadyForNextSample(&Microphone_Audio_Interface))  Dean Camera committed May 08, 2010 103  {  Dean Camera committed Oct 20, 2010 104 105 106 107 108  int16_t AudioSample; #if defined(USE_TEST_TONE) static uint8_t SquareWaveSampleCount; static int16_t CurrentWaveValue;  Dean Camera committed Dec 23, 2011 109   Dean Camera committed Oct 20, 2010 110 111 112  /* In test tone mode, generate a square wave at 1/256 of the sample rate */ if (SquareWaveSampleCount++ == 0xFF) CurrentWaveValue ^= 0x8000;  Dean Camera committed Dec 23, 2011 113   Dean Camera committed Oct 20, 2010 114 115 116 117 118 119 120 121 122 123  /* Only generate audio if the board button is being pressed */ AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0; #else /* Audio sample is ADC value scaled to fit the entire range */ AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult()); #if defined(MICROPHONE_BIASED_TO_HALF_RAIL) /* Microphone is biased to half rail voltage, subtract the bias from the sample value */ AudioSample -= (SAMPLE_MAX_RANGE / 2); #endif  Dean Camera committed May 08, 2010 124  #endif  Dean Camera committed Dec 23, 2011 125   Dean Camera committed May 08, 2010 126 127  Audio_Device_WriteSample16(&Microphone_Audio_Interface, AudioSample); }  Dean Camera committed Oct 26, 2010 128 129  Endpoint_SelectEndpoint(PrevEndpoint);  Dean Camera committed May 08, 2010 130 131 132 133 134 135 136 137 } /** Event handler for the library USB Connection event. */ void EVENT_USB_Device_Connect(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); /* Sample reload timer initialization */  Dean Camera committed Oct 26, 2010 138  TIMSK0 = (1 << OCIE0A);  Dean Camera committed Jun 03, 2011 139  OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);  Dean Camera committed May 08, 2010 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155  TCCR0A = (1 << WGM01); // CTC mode TCCR0B = (1 << CS01); // Fcpu/8 speed } /** Event handler for the library USB Disconnection event. */ void EVENT_USB_Device_Disconnect(void) { /* Stop the sample reload timer */ TCCR0B = 0; LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); } /** Event handler for the library USB Configuration Changed event. */ void EVENT_USB_Device_ConfigurationChanged(void) {  Dean Camera committed Aug 09, 2010 156 157 158 159 160  bool ConfigSuccess = true; ConfigSuccess &= Audio_Device_ConfigureEndpoints(&Microphone_Audio_Interface); LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);  Dean Camera committed May 08, 2010 161 162 }  Dean Camera committed Nov 05, 2010 163 164 /** Event handler for the library USB Control Request reception event. */ void EVENT_USB_Device_ControlRequest(void)  Dean Camera committed May 08, 2010 165 166 167 { Audio_Device_ProcessControlRequest(&Microphone_Audio_Interface); }  168   Dean Camera committed Jun 03, 2011 169 170 171 172 173 174 175 176 177 178 179 180 /** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented * in the user application to handle property manipulations on streaming audio endpoints. * * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations * to indicate the size of the retreived data. * * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value * of the \c DataLength parameter. * * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. * \param[in] EndpointProperty Property of the endpoint to get or set, a value from Audio_ClassRequests_t.  Dean Camera committed Jun 14, 2011 181  * \param[in] EndpointAddress Address of the streaming endpoint whose property is being referenced.  Dean Camera committed Jun 03, 2011 182 183 184 185 186 187 188  * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from Audio_EndpointControls_t. * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum * length of the retrieved data. When NULL, the function should return whether the given property * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where * the retrieved data is to be stored for GET operations. *  Dean Camera committed Jan 28, 2012 189  * \return Boolean \c true if the property get/set was successful, \c false otherwise  Dean Camera committed Jun 03, 2011 190  */  Dean Camera committed Jun 16, 2011 191 192 193 194 195 196 bool CALLBACK_Audio_Device_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const uint8_t EndpointProperty, const uint8_t EndpointAddress, const uint8_t EndpointControl, uint16_t* const DataLength, uint8_t* Data)  Dean Camera committed Jun 03, 2011 197 198 { /* Check the requested endpoint to see if a supported endpoint is being manipulated */  Dean Camera committed Jul 19, 2011 199  if (EndpointAddress == (ENDPOINT_DIR_IN | Microphone_Audio_Interface.Config.DataINEndpointNumber))  Dean Camera committed Jun 03, 2011 200 201 202 203  { /* Check the requested control to see if a supported control is being manipulated */ if (EndpointControl == AUDIO_EPCONTROL_SamplingFreq) {  Dean Camera committed Jun 29, 2011 204  switch (EndpointProperty)  Dean Camera committed Jun 03, 2011 205  {  Dean Camera committed Jun 29, 2011 206 207 208 209 210 211 212 213  case AUDIO_REQ_SetCurrent: /* Check if we are just testing for a valid property, or actually adjusting it */ if (DataLength != NULL) { /* Set the new sampling frequency to the value given by the host */ CurrentAudioSampleFrequency = (((uint32_t)Data[2] << 16) | ((uint32_t)Data[1] << 8) | (uint32_t)Data[0]); /* Adjust sample reload timer to the new frequency */  Dean Camera committed Dec 23, 2011 214  OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);  Dean Camera committed Jun 29, 2011 215  }  Dean Camera committed Dec 23, 2011 216 217  return true;  Dean Camera committed Jun 29, 2011 218 219 220 221 222 223 224 225  case AUDIO_REQ_GetCurrent: /* Check if we are just testing for a valid property, or actually reading it */ if (DataLength != NULL) { *DataLength = 3; Data[2] = (CurrentAudioSampleFrequency >> 16); Data[1] = (CurrentAudioSampleFrequency >> 8);  Dean Camera committed Dec 23, 2011 226  Data[0] = (CurrentAudioSampleFrequency & 0xFF);  Dean Camera committed Jun 29, 2011 227  }  Dean Camera committed Dec 23, 2011 228   Dean Camera committed Jun 29, 2011 229  return true;  Dean Camera committed Jun 03, 2011 230 231 232  } } }  Dean Camera committed Dec 23, 2011 233   Dean Camera committed Jun 03, 2011 234 235  return false; }  Dean Camera committed Dec 23, 2011 236   Dean Camera committed Jan 28, 2012 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 /** Audio class driver callback for the setting and retrieval of streaming interface properties. This callback must be implemented * in the user application to handle property manipulations on streaming audio interfaces. * * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for * the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations * to indicate the size of the retreived data. * * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value * of the \c DataLength parameter. * * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. * \param[in] Property Property of the interface to get or set, a value from \ref Audio_ClassRequests_t. * \param[in] EntityAddress Address of the audio entity whose property is being referenced. * \param[in] Parameter Parameter of the entity to get or set, specific to each type of entity (see USB Audio specification). * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum * length of the retrieved data. When NULL, the function should return whether the given property * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where * the retrieved data is to be stored for GET operations. * * \return Boolean \c true if the property GET/SET was successful, \c false otherwise */ bool CALLBACK_Audio_Device_GetSetInterfaceProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, const uint8_t Property, const uint8_t EntityAddress, const uint16_t Parameter, uint16_t* const DataLength, uint8_t* Data) { /* No audio interface entities in the device descriptor, thus no properties to get or set. */ return false; }