host_audio_task.c File Reference

#include "config.h"
#include "conf_usb.h"
#include "host_audio_task.h"
#include "modules/usb/host_chap9/usb_host_task.h"
#include "modules/usb/host_chap9/usb_host_enum.h"
#include "lib_mcu/usb/usb_drv.h"

Include dependency graph for host_audio_task.c:

Go to the source code of this file.

Defines

#define LOG_STR_CODE(str)
#define AUDIO_STREAM_SIZE   16

Functions

void host_audio_task_init (void)
 This function initializes the USB Host Audio application.
void host_audio_task (void)
void sof_action (void)
__interrupt void timer2_comp_interrupt ()
void DAC_SendPort (U8 data_dac)

Variables

volatile U8 audio_connected
volatile U8 audio_cpt_sof
U8 mute
U8 pipe_audio_in
U8 interf_audio_stream
volatile U8 audio_stream_in [16]
volatile U8 audio_stream_ptr_wr
volatile U8 audio_stream_ptr_rd
volatile U8 audio_stream_size
volatile bit audio_stream_empty


Detailed Description

This file manages the USB Host Audio control application.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file host_audio_task.c.


Define Documentation

#define LOG_STR_CODE ( str   ) 

Definition at line 53 of file host_audio_task.c.

Referenced by host_audio_task(), usb_general_interrupt(), and usb_host_task().

#define AUDIO_STREAM_SIZE   16

Definition at line 60 of file host_audio_task.c.

Referenced by host_audio_task().


Function Documentation

void host_audio_task_init ( void   ) 

This function initializes the USB Host Audio application.

Parameters:
none 
Returns:
none

Definition at line 85 of file host_audio_task.c.

00086 {
00087    Leds_init();
00088    audio_connected = 0;
00089    Joy_init();
00090    
00091    // D/A converter output rate management
00092    // At 8 kHz, output should be updated every 125µs. But real-time issues may occur between both USB devices :
00093    // The Host send a token to the Device every millisecond, to get back a new samples frame.
00094    // On the Device side, this frame is loaded into endpoint every millisecond. So some frames may be missed in
00095    // the case where the endpoint is not yet validated while the token has been sent.
00096    // To decrease error cases and probability, the device sample rate has been fixed to 120µs.
00097    // The Host ouput rate is also set to 120µs.
00098    TCCR2A=0x02;         // Prescaler div8
00099    OCR2A=120;           // Reload value to count 8x120=960 for FOSC 8MHz =>120µS refresh rate
00100    TCCR2B=0x02;         // Timer 2 mode CTC
00101    TIMSK2|=(1<<OCIE2A); // Enable compare interrupt
00102    
00103    // D/A converter hardware configuration
00104    // In this case, user is free to do what he wants
00105    Dac_output_init();
00106 }

void host_audio_task ( void   ) 

This function manages the USB Host Audio application

Parameters:
none 
Returns:
none

Definition at line 115 of file host_audio_task.c.

00116 {
00117 U8 i, j;
00118 
00119    // Audio Device Management
00120    // *********************
00121    if(Is_host_ready())
00122    {
00123       if(Is_new_device_connection_event())   // Device connection
00124       {
00125          for(i=0;i<Get_nb_supported_interface();i++)
00126          {
00127             // Audio Streaming Interface
00128             // Select the audio streaming interface that has an IN PIPE
00129             if((Get_class(i)==AUDIO_AS_INTERFACE_CLASS) && (Get_subclass(i)==AUDIO_AS_INTERFACE_SUB_CLASS) && (Get_nb_ep(i) != 0))
00130             {
00131                for (j=0 ; j<Get_nb_ep(i) ; j++)
00132                {
00133                  if (Is_ep_addr_in(Get_ep_addr(i,j)))
00134                  {
00135                    // Log in device
00136                    audio_connected=1;
00137                    audio_stream_ptr_wr = 0;
00138                    audio_stream_ptr_rd = 0;
00139                    audio_stream_empty = TRUE;
00140                    Led0_on();
00141                    Host_enable_sof_interrupt();
00142                    LOG_STR_CODE(log_audio_connect);
00143                    
00144                    // Select and enable ISOCHRONOUS pipe
00145                    pipe_audio_in = host_get_hwd_pipe_nb(Get_ep_addr(i,j));
00146                    Host_select_pipe(PIPE_AUDIO_IN);
00147                    Host_continuous_in_mode();
00148                    Host_unfreeze_pipe();
00149                    
00150                    // Set the Device in Mute mode
00151                    mute = TRUE;
00152                    Led3_on();   // LED3 is ON when device muted
00153                    host_audio_set_cur(mute);        // set device default state : muted
00154                    
00155                    // Enable alternate streaming interface
00156                    interf_audio_stream = i;                     // store interface number
00157                    host_set_interface(interf_audio_stream,1);   // enable streaming interface with "alternate 1" on Device
00158                    break;
00159                  }
00160                }
00161             }
00162          }
00163       }
00164 
00165       if (audio_connected)
00166       {
00167          // Check in AUDIO_PIPE_IN for incoming stream
00168          // ******************************************
00169          Host_select_pipe(PIPE_AUDIO_IN);
00170          
00171          // Error management : clear any error (time-out, CRC, etc...) and unfreeze pipe if error flag rises
00172          // Error flag rises after three errors. Errors can be identified in UPERRX register.
00173          if (Is_host_pipe_error())
00174          {
00175            Host_ack_all_errors();
00176            Host_unfreeze_pipe();
00177          }
00178 
00179          // Stream management
00180          if (Is_host_in_received() && (Is_host_stall()==FALSE))
00181          {
00182            // Pipe has received a new frame !
00183            Disable_interrupt();   // to avoid interrupt access to audio_stream_in[] buffer
00184            while ((Host_data_length_U8() != 0) && (audio_stream_ptr_wr != AUDIO_STREAM_SIZE))
00185            {
00186               audio_stream_in[audio_stream_ptr_wr] = Host_read_byte();
00187               audio_stream_ptr_wr++;
00188            }
00189            audio_stream_size = audio_stream_ptr_wr;
00190            audio_stream_empty = FALSE;
00191            Host_ack_in_received();  // all the pipe data has been read
00192            Host_send_in();
00193            Enable_interrupt();
00194          }
00195          
00196          // Mute control : toggle MUTE state with Joystick DOWN direction
00197          if (Is_joy_down())
00198          {
00199            audio_cpt_sof = 0;
00200            while (audio_cpt_sof != 10); // debounce
00201            if (mute == TRUE)
00202            {
00203              mute=FALSE;
00204              Led3_off();
00205            }
00206            else
00207            {
00208              mute=TRUE;
00209              Led3_on();
00210            }
00211            host_audio_set_cur(mute);
00212            while (Is_joy_down());
00213            audio_cpt_sof = 0;           // debounce
00214            while (audio_cpt_sof != 10);
00215          }
00216       }
00217    }
00218 
00219    // Device disconnection...
00220    if(Is_device_disconnection_event())
00221    {
00222       Leds_off();
00223       audio_stream_empty = TRUE;
00224       audio_stream_ptr_rd = 0;
00225       audio_stream_ptr_wr = 0;
00226       audio_stream_size = 0;
00227       audio_connected = 0;
00228    }
00229 }

__interrupt void timer2_comp_interrupt (  ) 

Timer2 comparator interrupt routine service When in microphone mode, get adc microphone sample and load it to the Isochronous endpoint.

Note:
The dual bank endpoint usage allows to get ride of an extra synchonisation buffer
Parameters:
none 
Returns:
none

Definition at line 266 of file host_audio_task.c.

References audio_connected, audio_stream_empty, audio_stream_in, audio_stream_ptr_rd, audio_stream_ptr_wr, audio_stream_size, DAC_SendPort(), FALSE, and TRUE.

00268 {
00269    U8   data_dac;
00270    U16  data_16b;
00271 
00272    if (audio_connected)
00273    {
00274       if (audio_stream_empty == FALSE)
00275       {
00276         // Get the sample word (16 bits)
00277         data_16b = audio_stream_in[audio_stream_ptr_rd];
00278         audio_stream_ptr_rd++;
00279         data_16b |= ((U16) (audio_stream_in[audio_stream_ptr_rd])) << 8;
00280         audio_stream_ptr_rd++;
00281         
00282         // Decode PCM 16 bits word to 8 bits unsigned
00283         data_16b ^= 0x8000; // complement MSB
00284         data_dac = (U8)(data_16b>>8);
00285         
00286         // Drives R-2R ladder (uses a complete PORT ; PORTA is free on STK525)
00287         DAC_SendPort(data_dac);
00288         
00289         // Check if end of buffer reached
00290         if (audio_stream_ptr_rd == audio_stream_size) // no more data to read
00291         {
00292           audio_stream_ptr_rd = 0;
00293           audio_stream_ptr_wr = 0;
00294           audio_stream_size = 0;
00295           audio_stream_empty = TRUE;
00296         }
00297       }
00298    }
00299 }

Here is the call graph for this function:

void DAC_SendPort ( U8  data_dac  ) 

Function that ouputs the 8-bits value to the R-2R ladder (2 configurations possibles) Refer to the "fig" folder that contains the schematics of the two R-2R ladder configurations

Note:
This function can also be modified to transmit the 8-bit sound sample to an external DAC (external peripheral, PWM, etc..)
Parameters:
none 
Returns:
none

Definition at line 311 of file host_audio_task.c.

Referenced by timer2_comp_interrupt().

00312 {
00313   U8   port_value;
00314   
00315   // DAC_OUT value must be set to the value specified by your external DAC ladder configuration
00316 #if   (DAC_OUT==PORT_A_RIGHT)
00317   // In this configuration, see the R-2R ladder configuration on the "R2R_LADDER_RIGHT" schematic
00318   PORTA = data_dac;
00319 #elif (DAC_OUT==PORT_A_CPLX)
00320   // In this configuration (easier to mount directly on EXPAND0 connector...), the connexions of the PORTA signals are not
00321   // the same that for the R2R_LADDER_RIGHT schematic. The resistor structure is the same, but the port connexions are differents :
00322   // see R2R_LADDER_CPLX schematic.
00323   port_value  = (data_dac&0x01);          // bit 0 : portA,0
00324   port_value |= (data_dac&0x02)<<(2-1);   // bit 1 : portA,2
00325   port_value |= (data_dac&0x04)<<(4-2);   // bit 2 : portA,4
00326   port_value |= (data_dac&0x08)<<(6-3);   // bit 3 : portA,6
00327   port_value |= (data_dac&0x10)<<(7-4);   // bit 4 : portA,7
00328   port_value |= (data_dac&0x20);          // bit 5 : portA,5
00329   port_value |= (data_dac&0x40)>>(6-3);   // bit 6 : portA,3
00330   port_value |= (data_dac&0x80)>>(7-1);   // bit 7 : portA,1
00331   PORTA = port_value;
00332 #endif
00333 }

Here is the caller graph for this function:


Variable Documentation

volatile U8 audio_connected

Definition at line 65 of file host_audio_task.c.

Referenced by host_audio_task(), host_audio_task_init(), and timer2_comp_interrupt().

volatile U8 audio_cpt_sof

Definition at line 66 of file host_audio_task.c.

Referenced by host_audio_task(), and sof_action().

U8 mute

Definition at line 67 of file host_audio_task.c.

Referenced by host_audio_task().

U8 interf_audio_stream

Definition at line 70 of file host_audio_task.c.

Referenced by host_audio_task().

volatile U8 audio_stream_in[16]

Definition at line 72 of file host_audio_task.c.

Referenced by host_audio_task(), and timer2_comp_interrupt().

volatile U8 audio_stream_ptr_wr

Definition at line 73 of file host_audio_task.c.

Referenced by host_audio_task(), and timer2_comp_interrupt().

volatile U8 audio_stream_ptr_rd

Definition at line 74 of file host_audio_task.c.

Referenced by host_audio_task(), and timer2_comp_interrupt().

volatile U8 audio_stream_size

Definition at line 75 of file host_audio_task.c.

Referenced by host_audio_task(), and timer2_comp_interrupt().

volatile bit audio_stream_empty

Definition at line 76 of file host_audio_task.c.

Referenced by host_audio_task(), and timer2_comp_interrupt().


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