ssc_i2s.h File Reference


Detailed Description

SSC I2S example driver.

This file defines a useful set of functions for the SSC I2S interface on AVR32 devices. The driver handles normal polled usage and direct memory access (PDC) usage.

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

Definition in file ssc_i2s.h.

#include <avr32/io.h>

Go to the source code of this file.

Defines

#define SSC_I2S_TIMEOUT_VALUE   10000

Enumerations

enum  {
  SSC_I2S_ERROR = -1, SSC_I2S_OK = 0, SSC_I2S_TIMEOUT = 1, SSC_I2S_ERROR_ARGUMENT,
  SSC_I2S_ERROR_RX, SSC_I2S_ERROR_TX
}
 Error codes used by SSC I2S driver. More...
enum  {
  SSC_I2S_MODE_STEREO_OUT = 1, SSC_I2S_MODE_SLAVE_STEREO_OUT, SSC_I2S_MODE_STEREO_OUT_MONO_IN, SSC_I2S_MODE_RIGHT_IN,
  SSC_I2S_MODE_STEREO_IN, SSC_I2S_MODE_STEREO_OUT_STEREO_IN
}
 SSC I2S modes. More...

Functions

void ssc_i2s_disable_interrupts (volatile avr32_ssc_t *ssc, unsigned long int_mask)
 Disables the specified SSC interrupts.
void ssc_i2s_enable_interrupts (volatile avr32_ssc_t *ssc, unsigned long int_mask)
 Enables the specified SSC interrupts.
unsigned long ssc_i2s_get_status (volatile avr32_ssc_t *ssc)
 Returns the SSC status.
int ssc_i2s_init (volatile avr32_ssc_t *ssc, unsigned int sample_frequency, unsigned int data_bit_res, unsigned int frame_bit_res, unsigned char mode, unsigned int pba_hz)
 Sets up registers and intializes SSC for use as I2S.
void ssc_i2s_reset (volatile avr32_ssc_t *ssc)
 Resets the SSC module.
int ssc_i2s_transfer (volatile avr32_ssc_t *ssc, unsigned int data)
 Transfers a single message of data.


Define Documentation

#define SSC_I2S_TIMEOUT_VALUE   10000

Definition at line 53 of file ssc_i2s.h.

Referenced by ssc_i2s_transfer().


Enumeration Type Documentation

anonymous enum

Error codes used by SSC I2S driver.

Enumerator:
SSC_I2S_ERROR 
SSC_I2S_OK 
SSC_I2S_TIMEOUT 
SSC_I2S_ERROR_ARGUMENT 
SSC_I2S_ERROR_RX 
SSC_I2S_ERROR_TX 

Definition at line 57 of file ssc_i2s.h.

00058 {
00059   SSC_I2S_ERROR = -1,
00060   SSC_I2S_OK = 0,
00061   SSC_I2S_TIMEOUT = 1,
00062   SSC_I2S_ERROR_ARGUMENT,
00063   SSC_I2S_ERROR_RX,
00064   SSC_I2S_ERROR_TX
00065 };

anonymous enum

SSC I2S modes.

Enumerator:
SSC_I2S_MODE_STEREO_OUT 
SSC_I2S_MODE_SLAVE_STEREO_OUT 
SSC_I2S_MODE_STEREO_OUT_MONO_IN 
SSC_I2S_MODE_RIGHT_IN 
SSC_I2S_MODE_STEREO_IN 
SSC_I2S_MODE_STEREO_OUT_STEREO_IN 

Definition at line 68 of file ssc_i2s.h.


Function Documentation

void ssc_i2s_disable_interrupts ( volatile avr32_ssc_t *  ssc,
unsigned long  int_mask 
)

Disables the specified SSC interrupts.

Parameters:
ssc Base address of the SSC instance.
int_mask Bit-mask of SSC interrupts (AVR32_SSC_IDR_x_MASK).

Definition at line 309 of file ssc_i2s.c.

00310 {
00311   Bool global_interrupt_enabled = Is_global_interrupt_enabled();
00312 
00313   if (global_interrupt_enabled) Disable_global_interrupt();
00314   ssc->idr = int_mask;
00315   ssc->sr;
00316   if (global_interrupt_enabled) Enable_global_interrupt();
00317 }

void ssc_i2s_enable_interrupts ( volatile avr32_ssc_t *  ssc,
unsigned long  int_mask 
)

Enables the specified SSC interrupts.

Parameters:
ssc Base address of the SSC instance.
int_mask Bit-mask of SSC interrupts (AVR32_SSC_IER_x_MASK).

Definition at line 320 of file ssc_i2s.c.

00321 {
00322   ssc->ier = int_mask;
00323 }

unsigned long ssc_i2s_get_status ( volatile avr32_ssc_t *  ssc  ) 

Returns the SSC status.

Parameters:
ssc Base address of the SSC instance.
Returns:
The SSC Status Register.

Definition at line 326 of file ssc_i2s.c.

Referenced by main().

00327 {
00328   return ssc->sr;
00329 }

int ssc_i2s_init ( volatile avr32_ssc_t *  ssc,
unsigned int  sample_frequency,
unsigned int  data_bit_res,
unsigned int  frame_bit_res,
unsigned char  mode,
unsigned int  pba_hz 
)

Sets up registers and intializes SSC for use as I2S.

Parameters:
ssc Pointer to the correct volatile avr32_ssc_t struct
sample_frequency The sample frequency given in Hz
data_bit_res Number of significant data bits in an I2S channel frame
frame_bit_res Total number of bits in an I2S channel frame
mode I2S-mode
  • SSC_I2S_MODE_STEREO_OUT Two output channels.
  • SSC_I2S_MODE_SLAVE_STEREO_OUT Two output channels controlled by the DAC.
  • SSC_I2S_MODE_STEREO_OUT_MONO_IN Two output, one input channel.
  • SSC_I2S_MODE_RIGHT_IN. Right channel in. Used because one SSC only can manage one input channel at a time.
pba_hz The clock speed of the PBA bus in Hz.
Returns:
Status
Return values:
SSC_I2S_OK when no error occured.
SSC_I2S_ERROR_ARGUMENT when invalid arguments are passed

Todo:
check input values

Definition at line 86 of file ssc_i2s.c.

References set_clock_divider(), SSC_I2S_MODE_RIGHT_IN, SSC_I2S_MODE_SLAVE_STEREO_OUT, SSC_I2S_MODE_STEREO_OUT, SSC_I2S_MODE_STEREO_OUT_MONO_IN, SSC_I2S_OK, and ssc_i2s_reset().

Referenced by main().

00092 {
00095   /* Reset */
00096   ssc_i2s_reset(ssc);
00097 
00098   if (mode == SSC_I2S_MODE_SLAVE_STEREO_OUT)
00099   {
00100     ssc->cmr = AVR32_SSC_CMR_DIV_NOT_ACTIVE << AVR32_SSC_CMR_DIV_OFFSET;
00101 
00102     ssc->tcmr = AVR32_SSC_TCMR_CKS_TK_PIN               << AVR32_SSC_TCMR_CKS_OFFSET    |
00103                 AVR32_SSC_TCMR_CKO_INPUT_ONLY           << AVR32_SSC_TCMR_CKO_OFFSET    |
00104                 0                                       << AVR32_SSC_TCMR_CKI_OFFSET    |
00105                 AVR32_SSC_TCMR_CKG_NONE                 << AVR32_SSC_TCMR_CKG_OFFSET    |
00106                 AVR32_SSC_TCMR_START_DETECT_ANY_EDGE_TF << AVR32_SSC_TCMR_START_OFFSET  |
00107                 1                                       << AVR32_SSC_TCMR_STTDLY_OFFSET |
00108                 0                                       << AVR32_SSC_TCMR_PERIOD_OFFSET;
00109 #ifdef AVR32_SSC_220_H_INCLUDED
00110     ssc->tfmr = (data_bit_res - 1)             << AVR32_SSC_TFMR_DATLEN_OFFSET  |
00111                 0                              << AVR32_SSC_TFMR_DATDEF_OFFSET  |
00112                 1                              << AVR32_SSC_TFMR_MSBF_OFFSET    |
00113                 (1 - 1)                        << AVR32_SSC_TFMR_DATNB_OFFSET   |
00114                 0                              << AVR32_SSC_TFMR_FSLEN_OFFSET   |
00115                 AVR32_SSC_TFMR_FSOS_INPUT_ONLY << AVR32_SSC_TFMR_FSOS_OFFSET    |
00116                 0                              << AVR32_SSC_TFMR_FSDEN_OFFSET   |
00117                 0                              << AVR32_SSC_TFMR_FSEDGE_OFFSET;
00118 #else
00119     ssc->tfmr = (data_bit_res - 1)             << AVR32_SSC_TFMR_DATLEN_OFFSET  |
00120                 0                              << AVR32_SSC_TFMR_DATDEF_OFFSET  |
00121                 1                              << AVR32_SSC_TFMR_MSBF_OFFSET    |
00122                 (1 - 1)                        << AVR32_SSC_TFMR_DATNB_OFFSET   |
00123                 0                              << AVR32_SSC_TFMR_FSLEN_OFFSET   |
00124                 AVR32_SSC_TFMR_FSOS_INPUT_ONLY << AVR32_SSC_TFMR_FSOS_OFFSET    |
00125                 0                              << AVR32_SSC_TFMR_FSDEN_OFFSET   |
00126                 0                              << AVR32_SSC_TFMR_FSEDGE_OFFSET  |
00127                 0                              << AVR32_SSC_TFMR_FSLENHI_OFFSET;
00128 #endif
00129     ssc->cr = AVR32_SSC_CR_TXEN_MASK;
00130   }
00131   else
00132   {
00133     unsigned long txen_mask = 0x00000000,
00134                   rxen_mask = 0x00000000;
00135 
00136     /* Set clock divider */
00137     set_clock_divider(ssc, 2 * sample_frequency * frame_bit_res, pba_hz);
00138 
00139     /* SSC can only receive one channel of audio input.  In order
00140      * to use two inputs, two SSC's must be used. The first (master)
00141      * deals with both output channels and the left input, and should
00142      * be set to mode=I2S_STEREO_OUT_MONO_IN, and the second to
00143      * mode=I2S_RIGHT_IN. The second SSC should be connected to the
00144      * first SSC's in the following way:
00145      * master-ssc:TF -> slave-ssc:RF,
00146      * master-ssc:TK -> slave-ssc:RK
00147      */
00148 
00149     /* If only slave I2S SSC, do not set transmit registers */
00150     if (mode != SSC_I2S_MODE_RIGHT_IN)
00151     {
00152       
00153       /* Set transmit clock mode:
00154        *   CKS - use divided clock,
00155        *   CKO - transmit continous clock on TK
00156        *   CKI - shift data on falling clock
00157        *   CKG - transmit continous clock on TK
00158        *   START - on falling TF(WS) edge
00159        *   STTDLY - TF toggles before last bit of last word, not before
00160        *            first bit on next word. Therefore: delay one cycle.
00161        *   PERIOD - generate framesync for each sample (FS is generated
00162        *            every (PERIOD + 1) * 2 clock)
00163        */
00164       ssc->tcmr = AVR32_SSC_TCMR_CKS_DIV_CLOCK              << AVR32_SSC_TCMR_CKS_OFFSET    |
00165                   AVR32_SSC_TCMR_CKO_CONTINOUS_CLOCK_OUTPUT << AVR32_SSC_TCMR_CKO_OFFSET    |
00166                   0                                         << AVR32_SSC_TCMR_CKI_OFFSET    |
00167                   AVR32_SSC_TCMR_CKG_NONE                   << AVR32_SSC_TCMR_CKG_OFFSET    |
00168                   AVR32_SSC_TCMR_START_DETECT_ANY_EDGE_TF   << AVR32_SSC_TCMR_START_OFFSET  |
00169                   1                                         << AVR32_SSC_TCMR_STTDLY_OFFSET |
00170                   (frame_bit_res - 1)                       << AVR32_SSC_TCMR_PERIOD_OFFSET;
00171 
00172       /* Set transmit frame mode:
00173        *  DATLEN - one sample for one channel
00174        *  DATDEF - Default to zero,
00175        *  MSBF - transmit msb first,
00176        *  DATNB - Transfer two words (left+right),
00177        *  FSLEN - Frame sync is entire left channel
00178        *  FSOS - transmit negative pulse on WS (start sync on left channel)
00179        *  FSDEN - Do not use transmit frame sync data
00180        *  FSEDGE - detect frame sync positive edge
00181        */
00182 #ifdef AVR32_SSC_220_H_INCLUDED
00183       ssc->tfmr = (data_bit_res - 1)                                 << AVR32_SSC_TFMR_DATLEN_OFFSET                              |
00184                   0                                                  << AVR32_SSC_TFMR_DATDEF_OFFSET                              |
00185                   1                                                  << AVR32_SSC_TFMR_MSBF_OFFSET                                |
00186                   (1 - 1)                                            << AVR32_SSC_TFMR_DATNB_OFFSET                               |
00187                   (((frame_bit_res - 1)                              << AVR32_SSC_TFMR_FSLEN_OFFSET) & AVR32_SSC_TFMR_FSLEN_MASK) |
00188                   AVR32_SSC_TFMR_FSOS_NEG_PULSE                      << AVR32_SSC_TFMR_FSOS_OFFSET                                |
00189                   0                                                  << AVR32_SSC_TFMR_FSDEN_OFFSET                               |
00190                   1                                                  << AVR32_SSC_TFMR_FSEDGE_OFFSET;
00191 #else
00192       ssc->tfmr = (data_bit_res - 1)                                 << AVR32_SSC_TFMR_DATLEN_OFFSET                              |
00193                   0                                                  << AVR32_SSC_TFMR_DATDEF_OFFSET                              |
00194                   1                                                  << AVR32_SSC_TFMR_MSBF_OFFSET                                |
00195                   (1 - 1)                                            << AVR32_SSC_TFMR_DATNB_OFFSET                               |
00196                   (((frame_bit_res - 1)                              << AVR32_SSC_TFMR_FSLEN_OFFSET) & AVR32_SSC_TFMR_FSLEN_MASK) |
00197                   AVR32_SSC_TFMR_FSOS_NEG_PULSE                      << AVR32_SSC_TFMR_FSOS_OFFSET                                |
00198                   0                                                  << AVR32_SSC_TFMR_FSDEN_OFFSET                               |
00199                   1                                                  << AVR32_SSC_TFMR_FSEDGE_OFFSET                              |
00200                   ((frame_bit_res - 1) >> AVR32_SSC_TFMR_FSLEN_SIZE) << AVR32_SSC_TFMR_FSLENHI_OFFSET;
00201 #endif
00202       txen_mask = AVR32_SSC_CR_TXEN_MASK;
00203     }
00204 
00205     /* If receiving data, set receiving clock register */
00206     if (mode != SSC_I2S_MODE_STEREO_OUT)
00207     {
00208       if ( (mode == SSC_I2S_MODE_STEREO_OUT_MONO_IN) || (mode == SSC_I2S_MODE_RIGHT_IN) )
00209       {
00210           /* Set receive clock mode:
00211            *  CKS - left ch uses TK, right (slave) uses RK pin
00212            *  CKO - No clock output,
00213            *  CKI - shift data on rising edge,
00214            *  CKG - No clock output,
00215            *  START - left ch starts when transmit starts, right starts on
00216            *          word-select (RF) rising edge
00217            *  STTDLY - RF toggles before last bit of last word, not before
00218            *           first bit on next word. Therefore, delay one cycle.
00219            *  PERIOD - No FS generation
00220            */
00221           ssc->rcmr =
00222             (( mode == SSC_I2S_MODE_RIGHT_IN ? AVR32_SSC_RCMR_CKS_RK_PIN : AVR32_SSC_RCMR_CKS_TK_CLOCK )
00223                                            << AVR32_SSC_RCMR_CKS_OFFSET)|
00224             (AVR32_SSC_RCMR_CKO_INPUT_ONLY << AVR32_SSC_RCMR_CKO_OFFSET)|
00225             (1                             << AVR32_SSC_RCMR_CKI_OFFSET)|
00226             (AVR32_SSC_RCMR_CKG_NONE       << AVR32_SSC_RCMR_CKG_OFFSET)|
00227             (( mode == SSC_I2S_MODE_RIGHT_IN ? AVR32_SSC_RCMR_START_DETECT_RISING_RF : AVR32_SSC_RCMR_START_TRANSMIT_START )
00228                                            << AVR32_SSC_RCMR_START_OFFSET)|
00229             (1                             << AVR32_SSC_RCMR_STTDLY_OFFSET)|
00230             (0                             << AVR32_SSC_RCMR_PERIOD_OFFSET);
00231     
00232           /* Set receive frame mode:
00233            *  DATLEN - bits per sample
00234            *  LOOP - no loopback
00235            *  MSBF - msb first
00236            *  DATNB - transmit one per sync
00237            *  FSLEN - no generate framesync
00238            *  FSOS - do not generate framesync
00239            *  FSEDGE - detect frame sync positive edge
00240            */
00241           ssc->rfmr =
00242             ((data_bit_res-1)               << AVR32_SSC_RFMR_DATLEN_OFFSET)|
00243             (0                              << AVR32_SSC_RFMR_LOOP_OFFSET)|
00244             (1                              << AVR32_SSC_RFMR_MSBF_OFFSET)|
00245             (0                              << AVR32_SSC_RFMR_DATNB_OFFSET)|
00246             (0                              << AVR32_SSC_RFMR_FSLEN_OFFSET)|
00247             (AVR32_SSC_RFMR_FSOS_INPUT_ONLY << AVR32_SSC_RFMR_FSOS_OFFSET)|
00248             (0                              << AVR32_SSC_RFMR_FSEDGE_OFFSET);
00249           
00250             rxen_mask = AVR32_SSC_CR_RXEN_MASK;
00251         }
00252         else
00253         {
00254             ssc->rcmr = AVR32_SSC_RCMR_CKS_TK_CLOCK               << AVR32_SSC_RCMR_CKS_OFFSET    |
00255                         AVR32_SSC_RCMR_CKO_CONTINOUS_CLOCK_OUTPUT << AVR32_SSC_RCMR_CKO_OFFSET    |
00256                         0                                         << AVR32_SSC_RCMR_CKI_OFFSET    |
00257                         AVR32_SSC_RCMR_CKG_NONE                   << AVR32_SSC_RCMR_CKG_OFFSET    |
00258                         AVR32_SSC_RCMR_START_DETECT_ANY_EDGE_RF   << AVR32_SSC_RCMR_START_OFFSET  |
00259                         1                                         << AVR32_SSC_RCMR_STTDLY_OFFSET |
00260                         (frame_bit_res - 1)                       << AVR32_SSC_RCMR_PERIOD_OFFSET;
00261 
00262 #ifdef AVR32_SSC_220_H_INCLUDED
00263             ssc->rfmr = (data_bit_res - 1)                                 << AVR32_SSC_RFMR_DATLEN_OFFSET                              |
00264                         1                                                  << AVR32_SSC_RFMR_MSBF_OFFSET                                |
00265                         (1 - 1)                                            << AVR32_SSC_RFMR_DATNB_OFFSET                               |
00266                         (((frame_bit_res - 1)                              << AVR32_SSC_RFMR_FSLEN_OFFSET) & AVR32_SSC_TFMR_FSLEN_MASK) |
00267                         AVR32_SSC_RFMR_FSOS_NEG_PULSE                      << AVR32_SSC_RFMR_FSOS_OFFSET                                |
00268                         1                                                  << AVR32_SSC_RFMR_FSEDGE_OFFSET;                                          
00269 #else            
00270             ssc->rfmr = (data_bit_res - 1)                                 << AVR32_SSC_RFMR_DATLEN_OFFSET                              |
00271                         1                                                  << AVR32_SSC_RFMR_MSBF_OFFSET                                |
00272                         (1 - 1)                                            << AVR32_SSC_RFMR_DATNB_OFFSET                               |
00273                         (((frame_bit_res - 1)                              << AVR32_SSC_RFMR_FSLEN_OFFSET) & AVR32_SSC_TFMR_FSLEN_MASK) |
00274                         AVR32_SSC_RFMR_FSOS_NEG_PULSE                      << AVR32_SSC_RFMR_FSOS_OFFSET                                |
00275                         1                                                  << AVR32_SSC_RFMR_FSEDGE_OFFSET                              |
00276                         ((frame_bit_res - 1) >> AVR32_SSC_RFMR_FSLEN_SIZE) << AVR32_SSC_RFMR_FSLENHI_OFFSET;
00277 #endif              
00278             rxen_mask = AVR32_SSC_CR_RXEN_MASK;
00279         }
00280         
00281       }      
00282     /* Enable transceiver and/or receiver */
00283     ssc->cr = txen_mask | rxen_mask;
00284   }
00285 
00286   return SSC_I2S_OK;
00287 }

void ssc_i2s_reset ( volatile avr32_ssc_t *  ssc  ) 

Resets the SSC module.

Parameters:
ssc pointer to the correct volatile avr32_ssc_t struct

Definition at line 79 of file ssc_i2s.c.

Referenced by ssc_i2s_init().

00080 {
00081   /* Software reset SSC */
00082   ssc->cr = AVR32_SSC_CR_SWRST_MASK;
00083 }

int ssc_i2s_transfer ( volatile avr32_ssc_t *  ssc,
unsigned int  data 
)

Transfers a single message of data.

Parameters:
ssc Pointer to the correct volatile avr32_ssc_t struct
data The data to transfer
Returns:
Status
Return values:
SSC_I2S_OK when no error occured.
SSC_I2S_TIMEOUT when a timeout occured while trying to transfer

Definition at line 290 of file ssc_i2s.c.

References SSC_I2S_OK, SSC_I2S_TIMEOUT, and SSC_I2S_TIMEOUT_VALUE.

Referenced by main().

00291 {
00292   unsigned int timeout = SSC_I2S_TIMEOUT_VALUE;
00293 
00294   while( ( ssc->sr & (1<<AVR32_SSC_SR_TXRDY_OFFSET) ) == 0 &&
00295       timeout > 0 ) {
00296     timeout--;
00297   }
00298 
00299   if( timeout <= 0 ) {
00300     return SSC_I2S_TIMEOUT;
00301   }
00302 
00303   ssc->thr = data;
00304 
00305   return SSC_I2S_OK;
00306 }


Generated on Tue Nov 25 11:16:35 2008 for AVR32 AP7 - SSC Driver for I2S by  doxygen 1.5.6