audio_task.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00013 
00014 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
00015  *
00016  * Redistribution and use in source and binary forms, with or without
00017  * modification, are permitted provided that the following conditions are met:
00018  *
00019  * 1. Redistributions of source code must retain the above copyright notice,
00020  * this list of conditions and the following disclaimer.
00021  *
00022  * 2. Redistributions in binary form must reproduce the above copyright notice,
00023  * this list of conditions and the following disclaimer in the documentation
00024  * and/or other materials provided with the distribution.
00025  *
00026  * 3. The name of ATMEL may not be used to endorse or promote products derived
00027  * from this software without specific prior written permission.
00028  *
00029  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00030  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00031  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
00032  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00033  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00034  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00035  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00036  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00038  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039  */
00040 
00041 //_____  I N C L U D E S ___________________________________________________
00042 
00043 #include "config.h"
00044 #include "conf_usb.h"
00045 #include "audio_task.h"
00046 #include "lib_board/stk_525/stk_525.h"
00047 #include "lib_mcu/usb/usb_drv.h"
00048 #include "lib_mcu/adc/adc_drv.h"
00049 #include "lib_mcu/timer/timer8_drv.h"
00050 #include "usb_descriptors.h"
00051 #include "modules/usb/device_chap9/usb_standard_request.h"
00052 #include "sound.h"
00053 
00054 //_____ M A C R O S ________________________________________________________
00055 
00056 
00057 //_____ D E F I N I T I O N S ______________________________________________
00058 
00059 
00060 //_____ D E C L A R A T I O N S ____________________________________________
00061 
00065 bit b_micro_mute;
00066 
00070 S16 s16_micro_volume;
00071 
00074 U16 g_u16_micro_sample_pos=0;
00075 
00076 
00079 void audio_task_init(void)
00080 {
00081    Leds_init();
00082    Joy_init();
00083    Hwb_button_init();
00084    init_adc();
00085    
00086    // Sample rate settings
00087    // At 8 kHz, signal is be sampled every 125µs. When endpoint is full (8 sample words), it is validated.
00088    // But periodically a real-time problem may occur, since the Host token is also sent approx. every 1ms : it can happen
00089    // that the token arrives while the Device endpoint has not been validated yet (the difference between these
00090    // two moments can be some µsecs), and the packet is not sent : 1 frame (1ms) is missed. So the sample rate has been
00091    // fixed every 120µs, to have a 40µs endpoint "free" delay to decrease error cases.
00092    Timer8_set_waveform_mode(TIMER8_WGM_CTC_OCR);   // Timer 2 mode CTC
00093    Timer8_set_compare(120);                        // (8MHz/8) * 120µs = 120ctn
00094    Timer8_set_clock(TIMER8_0_CLKIO_BY_8);          // Prescaler div8
00095    Timer8_compare_it_enable();                     // Enable compare interrupt
00096    
00097    b_micro_mute = FALSE;  // default state : enabled
00098 }
00099 
00100 
00103 void audio_task(void)
00104 {
00105    Leds_set_val(MSB(s16_micro_volume));
00106 }
00107 
00108 
00116 #ifdef __GNUC__
00117  ISR(TIMER2_COMPA_vect)
00118 #else
00119 #pragma vector = TIMER2_COMPA_vect
00120 __interrupt void timer2_comp_interrupt()
00121 #endif
00122 {
00123    S16 sample;
00124    U8 sav_ep;
00125       
00126    if(!Is_device_enumerated())
00127       return;                 // Device not ready
00128 
00129    sav_ep=Usb_get_selected_endpoint();       // save actually pipe
00130    Usb_select_endpoint(EP_AUDIO_IN);
00131    if(!Is_usb_write_enabled())
00132    {
00133       Usb_select_endpoint(sav_ep);           // restore pipe
00134       return;                                // Endpoint not free
00135    }
00136    
00137    if (b_micro_mute == FALSE)
00138    {
00139       //** Acquires new sample (from on-board micro, from external source, or from sample in flash raw )
00140       if( Is_btn_middle() || Is_joy_up() )
00141       {
00142          // Play flash raw sample
00143 #ifdef __GNUC__
00144          LSB(sample) = pgm_read_byte_near(&sample_sound[g_u16_micro_sample_pos++]);
00145          MSB(sample) = pgm_read_byte_near(&sample_sound[g_u16_micro_sample_pos++]);
00146 #else
00147          LSB(sample) = sample_sound[g_u16_micro_sample_pos++];
00148          MSB(sample) = sample_sound[g_u16_micro_sample_pos++];
00149 #endif
00150          if (g_u16_micro_sample_pos > SAMPLE_SOUND_LEN)
00151             g_u16_micro_sample_pos=0;  // end of sample sound, then run in a loop
00152       }
00153       else if (Is_joy_down())
00154       {
00155          // Get external input
00156          sample = (S32) (64*Get_adc_ext_val()-0x8000);  // EXTERNAL : joystick pushed DOWN
00157       }
00158       else
00159       {
00160          // All joystick directions released
00161          // Get micro input
00162          sample = (S32) (64*Get_adc_mic_val()-0x8000);
00163       }
00164       // Send new sample
00165       Usb_write_byte(LSB(sample));
00166       Usb_write_byte(MSB(sample));
00167    }
00168    else
00169    {
00170       //** Mute enable then send new sample null
00171       Usb_write_byte(0);
00172       Usb_write_byte(0);
00173    }
00174 
00175    // If pipe full then send it   
00176    if (Usb_byte_counter()==EP_SIZE_1)
00177    {
00178       Usb_send_in();
00179    }
00180    Usb_select_endpoint(sav_ep);              // restore pipe
00181 }
00182 
00183 
00192 U16 Get_adc_ext_val(void)
00193 {
00194    Start_conv_channel(3);
00195    while (!Is_adc_conv_finished());
00196    return (U16)(ADCL+((U16)(ADCH<<8)));
00197 }

Generated on Fri Oct 31 15:31:40 2008 for ATMEL by  doxygen 1.5.3