Documentation improvements - put driver example code into its own section, fix incorr...
[pub/USBasp.git] / Demos / Device / ClassDriver / AudioOutput / AudioOutput.c
index 9d2232c..4650cd8 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
@@ -60,11 +60,9 @@ int main(void)
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        sei();
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
        sei();
-       
+
        for (;;)
        {
        for (;;)
        {
-               ProcessNextSample();
-
                Audio_Device_USBTask(&Speaker_Audio_Interface);
                USB_USBTask();
        }
                Audio_Device_USBTask(&Speaker_Audio_Interface);
                USB_USBTask();
        }
@@ -85,35 +83,31 @@ void SetupHardware(void)
        USB_Init();
 }
 
        USB_Init();
 }
 
-/** Processes the next audio sample by reading the last ADC conversion and writing it to the audio
- *  interface, each time the sample reload timer period elapses to give a constant sample rate.
- */
-void ProcessNextSample(void)
+/** ISR to handle the reloading of the PWM timer with the next sample. */
+ISR(TIMER0_COMPA_vect, ISR_BLOCK)
 {
 {
-       /* Check if the sample reload timer period has elapsed, and that the USB bus is ready for a new sample */
-       if ((TIFR0 & (1 << OCF0A)) && Audio_Device_IsSampleReceived(&Speaker_Audio_Interface))
-       {
-               /* Clear the sample reload timer compare flag, ready for the next interval */
-               TIFR0 |= (1 << OCF0A);
+       uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint();
 
 
+       if (Audio_Device_IsSampleReceived(&Speaker_Audio_Interface))
+       {
                /* Retrieve the signed 16-bit left and right audio samples, convert to 8-bit */
                /* Retrieve the signed 16-bit left and right audio samples, convert to 8-bit */
-               int8_t  LeftSample_8Bit   = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
-               int8_t  RightSample_8Bit  = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
+               int8_t LeftSample_8Bit  = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
+               int8_t RightSample_8Bit = (Audio_Device_ReadSample16(&Speaker_Audio_Interface) >> 8);
 
                /* Mix the two channels together to produce a mono, 8-bit sample */
 
                /* Mix the two channels together to produce a mono, 8-bit sample */
-               int8_t  MixedSample_8Bit  = (((int16_t)LeftSample_8Bit + (int16_t)RightSample_8Bit) >> 1);
+               int8_t MixedSample_8Bit = (((int16_t)LeftSample_8Bit + (int16_t)RightSample_8Bit) >> 1);
 
 
-#if defined(AUDIO_OUT_MONO)
+               #if defined(AUDIO_OUT_MONO)
                /* Load the sample into the PWM timer channel */
                OCR3A = (MixedSample_8Bit ^ (1 << 7));
                /* Load the sample into the PWM timer channel */
                OCR3A = (MixedSample_8Bit ^ (1 << 7));
-#elif defined(AUDIO_OUT_STEREO)
+               #elif defined(AUDIO_OUT_STEREO)
                /* Load the dual 8-bit samples into the PWM timer channels */
                OCR3A = (LeftSample_8Bit  ^ (1 << 7));
                OCR3B = (RightSample_8Bit ^ (1 << 7));
                /* Load the dual 8-bit samples into the PWM timer channels */
                OCR3A = (LeftSample_8Bit  ^ (1 << 7));
                OCR3B = (RightSample_8Bit ^ (1 << 7));
-#elif defined(AUDIO_OUT_PORTC)
+               #elif defined(AUDIO_OUT_PORTC)
                /* Load the 8-bit mixed sample into PORTC */
                PORTC = MixedSample_8Bit;
                /* Load the 8-bit mixed sample into PORTC */
                PORTC = MixedSample_8Bit;
-#endif
+               #endif
 
                uint8_t LEDMask = LEDS_NO_LEDS;
 
 
                uint8_t LEDMask = LEDS_NO_LEDS;
 
@@ -129,35 +123,38 @@ void ProcessNextSample(void)
 
                LEDs_SetAllLEDs(LEDMask);
        }
 
                LEDs_SetAllLEDs(LEDMask);
        }
+       
+       Endpoint_SelectEndpoint(PrevEndpoint);  
 }
 
 /** Event handler for the library USB Connection event. */
 void EVENT_USB_Device_Connect(void)
 {
        LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
 }
 
 /** Event handler for the library USB Connection event. */
 void EVENT_USB_Device_Connect(void)
 {
        LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
-       
+
        /* Sample reload timer initialization */
        /* 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
 
-#if defined(AUDIO_OUT_MONO)
+       #if defined(AUDIO_OUT_MONO)
        /* Set speaker as output */
        DDRC   |= (1 << 6);
        /* Set speaker as output */
        DDRC   |= (1 << 6);
-#elif defined(AUDIO_OUT_STEREO)
+       #elif defined(AUDIO_OUT_STEREO)
        /* Set speakers as outputs */
        DDRC   |= ((1 << 6) | (1 << 5));
        /* Set speakers as outputs */
        DDRC   |= ((1 << 6) | (1 << 5));
-#elif defined(AUDIO_OUT_PORTC)
+       #elif defined(AUDIO_OUT_PORTC)
        /* Set PORTC as outputs */
        DDRC   |= 0xFF;
        /* Set PORTC as outputs */
        DDRC   |= 0xFF;
-#endif
+       #endif
 
 
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
+       #if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
        /* PWM speaker timer initialization */
        TCCR3A  = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)
                | (1 << COM3B1) | (1 << COM3B0)); // Set on match, clear on TOP
        /* PWM speaker timer initialization */
        TCCR3A  = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)
                | (1 << COM3B1) | (1 << COM3B0)); // Set on match, clear on TOP
-       TCCR3B  = ((1 << WGM32) | (1 << CS30));  // Fast 8-Bit PWM, Fcpu speed
-#endif
+       TCCR3B  = ((1 << WGM32) | (1 << CS30));  // Fast 8-Bit PWM, F_CPU speed
+       #endif
 }
 
 /** Event handler for the library USB Disconnection event. */
 }
 
 /** Event handler for the library USB Disconnection event. */
@@ -168,34 +165,36 @@ void EVENT_USB_Device_Disconnect(void)
        /* Stop the sample reload timer */
        TCCR0B = 0;
 
        /* Stop the sample reload timer */
        TCCR0B = 0;
 
-#if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
+       #if (defined(AUDIO_OUT_MONO) || defined(AUDIO_OUT_STEREO))
        /* Stop the PWM generation timer */
        TCCR3B = 0;
        /* Stop the PWM generation timer */
        TCCR3B = 0;
-#endif
+       #endif
 
 
-#if defined(AUDIO_OUT_MONO)
+       #if defined(AUDIO_OUT_MONO)
        /* Set speaker as input to reduce current draw */
        /* Set speaker as input to reduce current draw */
-       DDRC   &= ~(1 << 6);
-#elif defined(AUDIO_OUT_STEREO)
+       DDRC  &= ~(1 << 6);
+       #elif defined(AUDIO_OUT_STEREO)
        /* Set speakers as inputs to reduce current draw */
        /* Set speakers as inputs to reduce current draw */
-       DDRC   &= ~((1 << 6) | (1 << 5));
-#elif defined(AUDIO_OUT_PORTC)
+       DDRC  &= ~((1 << 6) | (1 << 5));
+       #elif defined(AUDIO_OUT_PORTC)
        /* Set PORTC low */
        /* Set PORTC low */
-       PORTC  = 0x00;
-#endif
+       PORTC = 0x00;
+       #endif
 }
 
 /** Event handler for the library USB Configuration Changed event. */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
 }
 
 /** Event handler for the library USB Configuration Changed event. */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
-       LEDs_SetAllLEDs(LEDMASK_USB_READY);
-       
-       if (!(Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface)))
-         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
+       bool ConfigSuccess = true;
+
+       ConfigSuccess &= Audio_Device_ConfigureEndpoints(&Speaker_Audio_Interface);
+
+       LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
 }
 
 }
 
-/** Event handler for the library USB Unhandled Control Request event. */
-void EVENT_USB_Device_UnhandledControlRequest(void)
+/** Event handler for the library USB Control Request reception event. */
+void EVENT_USB_Device_ControlRequest(void)
 {
        Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
 }
 {
        Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
 }
+