Documentation improvements - put driver example code into its own section, fix incorr...
[pub/USBasp.git] / Demos / Device / LowLevel / AudioInput / AudioInput.c
index 6655a27..16ac90e 100644 (file)
@@ -1,21 +1,21 @@
 /*
              LUFA Library
      Copyright (C) Dean Camera, 2010.
 /*
              LUFA Library
      Copyright (C) Dean Camera, 2010.
-              
+
   dean [at] fourwalledcubicle [dot] com
   dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.com
+           www.lufa-lib.org
 */
 
 /*
   Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
 */
 
 /*
   Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)
 
-  Permission to use, copy, modify, distribute, and sell this 
+  Permission to use, copy, modify, distribute, and sell this
   software and its documentation for any purpose is hereby granted
   software and its documentation for any purpose is hereby granted
-  without fee, provided that the above copyright notice appear in 
+  without fee, provided that the above copyright notice appear in
   all copies and that both that the copyright notice and this
   all copies and that both that the copyright notice and this
-  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 
+  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
   software without specific, written prior permission.
 
   The author disclaim all warranties with regard to this
   software without specific, written prior permission.
 
   The author disclaim all warranties with regard to this
@@ -48,10 +48,9 @@ int main(void)
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        sei();
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        sei();
-       
+
        for (;;)
        {
        for (;;)
        {
-               USB_Audio_Task();
                USB_USBTask();
        }
 }
                USB_USBTask();
        }
 }
@@ -65,13 +64,14 @@ void SetupHardware(void)
 
        /* Disable clock division */
        clock_prescale_set(clock_div_1);
 
        /* Disable clock division */
        clock_prescale_set(clock_div_1);
-       
+
        /* Hardware Initialization */
        LEDs_Init();
        /* Hardware Initialization */
        LEDs_Init();
+       Buttons_Init();
        ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
        ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
        USB_Init();
        ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32);
        ADC_SetupChannel(MIC_IN_ADC_CHANNEL);
        USB_Init();
-       
+
        /* Start the ADC conversion in free running mode */
        ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_MUX_MASK);
 }
        /* Start the ADC conversion in free running mode */
        ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | MIC_IN_ADC_MUX_MASK);
 }
@@ -85,7 +85,8 @@ void EVENT_USB_Device_Connect(void)
        LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 
        /* Sample reload timer initialization */
        LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 
        /* Sample reload timer initialization */
-       OCR0A   = (F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1;
+       TIMSK0  = (1 << OCIE0A);
+       OCR0A   = ((F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1);
        TCCR0A  = (1 << WGM01);  // CTC mode
        TCCR0B  = (1 << CS01);   // Fcpu/8 speed
 }
        TCCR0A  = (1 << WGM01);  // CTC mode
        TCCR0B  = (1 << CS01);   // Fcpu/8 speed
 }
@@ -110,23 +111,21 @@ void EVENT_USB_Device_Disconnect(void)
  */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
  */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
-       /* Indicate USB connected and ready */
-       LEDs_SetAllLEDs(LEDMASK_USB_READY);
+       bool ConfigSuccess = true;
 
 
-       /* Setup audio stream endpoint */
-       if (!(Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS,
-                                            ENDPOINT_DIR_IN, AUDIO_STREAM_EPSIZE,
-                                        ENDPOINT_BANK_DOUBLE)))
-       {
-               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
-       }
+       /* Setup Audio Stream Endpoint */
+       ConfigSuccess &= Endpoint_ConfigureEndpoint(AUDIO_STREAM_EPNUM, EP_TYPE_ISOCHRONOUS, ENDPOINT_DIR_IN,
+                                                   AUDIO_STREAM_EPSIZE, ENDPOINT_BANK_DOUBLE);
+
+       /* Indicate endpoint configuration success or failure */
+       LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
 }
 
 }
 
-/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific
- *  control requests that are not handled internally by the USB library (including the Audio class-specific
- *  requests) so that they can be handled appropriately for the application.
+/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
+ *  the device from the USB host before passing along unhandled control requests to the library for processing
+ *  internally.
  */
  */
-void EVENT_USB_Device_UnhandledControlRequest(void)
+void EVENT_USB_Device_ControlRequest(void)
 {
        /* Process General and Audio specific control requests */
        switch (USB_ControlRequest.bRequest)
 {
        /* Process General and Audio specific control requests */
        switch (USB_ControlRequest.bRequest)
@@ -136,43 +135,47 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
                        {
                                Endpoint_ClearSETUP();
                        if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
                        {
                                Endpoint_ClearSETUP();
-                               
+                               Endpoint_ClearStatusStage();
+
                                /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
                                StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
                                /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
                                StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
-                               
-                               Endpoint_ClearStatusStage();
                        }
 
                        break;
        }
 }
 
                        }
 
                        break;
        }
 }
 
-/** Task to manage the Audio interface, reading in ADC samples from the microphone, and them to the host. */
-void USB_Audio_Task(void)
+/** ISR to handle the reloading of the data endpoint with the next sample. */
+ISR(TIMER0_COMPA_vect, ISR_BLOCK)
 {
 {
-       /* Device must be connected and configured for the task to run */
-       if (USB_DeviceState != DEVICE_STATE_Configured)
-         return;
-
-       /* Check to see if the streaming interface is selected, if not the host is not receiving audio */
-       if (!(StreamingAudioInterfaceSelected))
-         return;
+       uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
 
        /* Select the audio stream endpoint */
        Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
 
        /* Select the audio stream endpoint */
        Endpoint_SelectEndpoint(AUDIO_STREAM_EPNUM);
-       
-       /* Check if the current endpoint can be written to and that the next sample should be stored */
-       if (Endpoint_IsINReady() && (TIFR0 & (1 << OCF0A)))
+
+       /* Check if the current endpoint can be written to and that the audio interface is enabled */
+       if (Endpoint_IsINReady() && StreamingAudioInterfaceSelected)
        {
        {
-               /* Clear the sample reload timer */
-               TIFR0 |= (1 << OCF0A);
-
-               /* Audio sample is ADC value scaled to fit the entire range */
-               int16_t 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);
+               int16_t AudioSample;
+
+               #if defined(USE_TEST_TONE)
+                       static uint8_t SquareWaveSampleCount;
+                       static int16_t CurrentWaveValue;
+                       
+                       /* In test tone mode, generate a square wave at 1/256 of the sample rate */
+                       if (SquareWaveSampleCount++ == 0xFF)
+                         CurrentWaveValue ^= 0x8000;
+                       
+                       /* 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          
                #endif
 
                /* Write the sample to the buffer */
                #endif
 
                /* Write the sample to the buffer */
@@ -185,4 +188,7 @@ void USB_Audio_Task(void)
                        Endpoint_ClearIN();
                }
        }
                        Endpoint_ClearIN();
                }
        }
+
+       Endpoint_SelectEndpoint(PrevEndpoint);
 }
 }
+