tlv320aic23b.c File Reference


Detailed Description

TLV320AIC23B stereo audio CODEC driver for AVR32.

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

Definition in file tlv320aic23b.c.

#include <stddef.h>
#include <string.h>
#include "compiler.h"
#include "audio.h"
#include "tlv320aic23b.h"
#include <avr32/io.h>
#include "intc.h"
#include "gpio.h"
#include "ssc_i2s.h"
#include "pdca.h"

Go to the source code of this file.

Defines

#define AIC23B_CTRL_RESET
 Default local image of the registers.
#define AIC23B_REG_COUNT   (sizeof(aic23b_ctrl) / sizeof(aic23b_ctrl[0]))
 Number of registers.

Functions

static void aic23b_ssc_rx_pdca_int_handler (void)
 SSC RX PDCA interrupt handler managing the out-of-samples condition.
static void aic23b_ssc_tx_pdca_int_handler (void)
 SSC TX PDCA interrupt handler managing the out-of-samples condition.
static void aic23b_write_control_word (aic23b_ctrl_t ctrl)
 Writes the ctrl control word.
Mid-Level Interface
void aic23b_activate_dig_audio (Bool act)
 Activates or deactivates the digital audio interface according to act.
U8 aic23b_dac_get_average_headphone_volume (void)
 Gets the average headphone volume.
Bool aic23b_dac_is_headphone_volume_boosted (void)
 Returns the state of the boost mode of the DAC.
Bool aic23b_dac_is_headphone_volume_muted (void)
 Returns the state of the mute mode of the DAC.
void aic23b_dac_set_average_headphone_volume (U8 volume)
 Sets the average headphone volume.
aic23b_aapc_t aic23b_get_analog_audio_path (void)
 Gets the analog audio path.
aic23b_dapc_t aic23b_get_digital_audio_path (void)
 Gets the digital audio path.
S8 aic23b_get_headphone_volume (U8 ch)
 Gets the ch channel headphone volume.
S8 aic23b_get_line_in_volume (U8 ch)
 Gets the ch line input channel volume.
aic23b_pdc_t aic23b_get_power_down_state (void)
 Gets the power down state.
Bool aic23b_is_dig_audio_activated (void)
 Tells whether the digital audio interface is activated.
void aic23b_reset (void)
 Resets the CODEC.
void aic23b_set_analog_audio_path (aic23b_aapc_t aapc)
 Sets the analog audio path to aapc.
void aic23b_set_digital_audio_path (aic23b_dapc_t dapc)
 Sets the digital audio path to dapc.
void aic23b_set_headphone_volume (U8 ch_mask, S8 vol, Bool z_cross)
 Sets the ch_mask channels headphone volume to vol, with zero-cross detect if z_cross is TRUE.
void aic23b_set_line_in_volume (U8 ch_mask, S8 vol)
 Sets the ch_mask line input channels volume to vol.
void aic23b_set_power_down_state (aic23b_pdc_t pdc)
 Sets the power down state to pdc.
High-Level Interface
Bool aic23b_adc_input (void *sample_buffer, size_t sample_length)
 Input a sample buffer from the ADC.
void aic23b_codec_flush (void)
 Flushes the sample buffers being input from the ADC and output to the DAC.
void aic23b_codec_setup (U32 sample_rate_hz, U8 num_channels, U8 bits_per_sample, Bool swap_channels, void(*callback)(U32 opt), U32 callback_opt, U32 pba_hz)
void aic23b_codec_start (U32 sample_rate_hz, U8 num_channels, U8 bits_per_sample, Bool swap_channels, void(*callback)(U32 arg), U32 callback_opt, U32 pba_hz)
 Starts the CODEC.
void aic23b_codec_stop (void)
 Stops the CODEC.
void aic23b_dac_decrease_volume (void)
 Decreases the output volume of the DAC.
void aic23b_dac_increase_volume (void)
 Increases the output volume of the DAC.
void aic23b_dac_mute (Bool mute)
 Mute audio if mute is set to true.
Bool aic23b_dac_output (void *sample_buffer, size_t sample_length)
 Outputs a sample buffer to the DAC.
Low-Level Interface
void aic23b_configure_freq (int master_clock_hz, int sample_rate_hz)
 Used to configure the codec frequency.
U16 aic23b_read_reg (U8 reg)
 Reads the reg register.
void aic23b_write_reg (U8 reg, U16 val)
 Writes val to the reg register.

Variables

static aic23b_ctrl_t aic23b_ctrl [] = AIC23B_CTRL_RESET
 Local image of the registers.
static const aic23b_ctrl_t aic23b_ctrl_reset [] = AIC23B_CTRL_RESET
 Default local image of the registers.
struct {
   void(*   callback )(U32 arg)
   U32   callback_opt
   U8   num_channels
aic23b_output_params
static const gpio_map_t AIC23B_SSC_CODEC_GPIO_MAP
 Map of the SSC pins used by the TLV320AIC23B.


Define Documentation

#define AIC23B_CTRL_RESET

Default local image of the registers.

Definition at line 75 of file tlv320aic23b.c.

#define AIC23B_REG_COUNT   (sizeof(aic23b_ctrl) / sizeof(aic23b_ctrl[0]))

Number of registers.

Definition at line 72 of file tlv320aic23b.c.

Referenced by aic23b_read_reg(), and aic23b_write_reg().


Function Documentation

void aic23b_activate_dig_audio ( Bool  act  ) 

Activates or deactivates the digital audio interface according to act.

Definition at line 560 of file tlv320aic23b.c.

Referenced by aic23b_codec_start().

00561 {
00562   aic23b_dia_t dia;
00563   dia.data = aic23b_read_reg(AIC23B_DIA);
00564   dia.act = act;
00565   aic23b_write_reg(AIC23B_DIA, dia.data);
00566 }

Bool aic23b_adc_input ( void *  sample_buffer,
size_t  sample_length 
)

Input a sample buffer from the ADC.

Note:
The ADC must have been started beforehand.

Definition at line 1081 of file tlv320aic23b.c.

Referenced by main().

01082 {
01083   if (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
01084         PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
01085     return FALSE;
01086 
01087   if (sample_length)
01088   {
01089     pdca_reload_channel(AIC23B_SSC_RX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
01090     pdca_get_reload_size(AIC23B_SSC_RX_PDCA_CHANNEL);
01091 
01092     if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB)
01093       pdca_enable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
01094     if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB)
01095       pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL);
01096   }
01097 
01098   return TRUE;
01099 }

void aic23b_codec_flush ( void   ) 

Flushes the sample buffers being input from the ADC and output to the DAC.

Definition at line 1285 of file tlv320aic23b.c.

Referenced by aic23b_codec_stop().

01286 {
01287   pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
01288   while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) &
01289            PDCA_TRANSFER_COMPLETE));
01290   pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
01291   while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
01292            PDCA_TRANSFER_COMPLETE));
01293 }

void aic23b_codec_setup ( U32  sample_rate_hz,
U8  num_channels,
U8  bits_per_sample,
Bool  swap_channels,
void(*)(U32 opt)  callback,
U32  callback_opt,
U32  pba_hz 
)

Definition at line 1218 of file tlv320aic23b.c.

References aic23b_configure_freq(), AIC23B_DAIF, AIC23B_DAIF_FMT_I2S, AIC23B_DAIF_IWL_16, AIC23B_DAIF_IWL_20, AIC23B_DAIF_IWL_24, AIC23B_DAIF_IWL_32, AIC23B_DAIF_MS_SLAVE, AIC23B_DEFAULT, AIC23B_MCLK_HZ, aic23b_output_params, AIC23B_SSC, AIC23B_SSC_RX_PDCA_CHANNEL, AIC23B_SSC_RX_PDCA_PID, AIC23B_SSC_TX_PDCA_CHANNEL, AIC23B_SSC_TX_PDCA_PID, aic23b_write_reg(), callback, aic23b_daif_t::data, aic23b_daif_t::fmt, aic23b_daif_t::iwl, aic23b_daif_t::lrp, aic23b_daif_t::lrswap, and aic23b_daif_t::ms.

Referenced by aic23b_codec_start().

01225 {
01226   ssc_i2s_init(AIC23B_SSC,
01227                sample_rate_hz,
01228                bits_per_sample,
01229                (bits_per_sample <= 16) ? 16 :
01230                (bits_per_sample <= 20) ? 20 :
01231                (bits_per_sample <= 24) ? 24 :
01232                                          32,
01233                SSC_I2S_MODE_STEREO_OUT_STEREO_IN,
01234                pba_hz);
01235 
01236   pdca_channel_options_t aic23b_ssc_pdca_options_rx =
01237   {
01238     .addr           = NULL,
01239     .size           = 0,
01240     .r_addr         = NULL,
01241     .r_size         = 0,
01242     .pid            = AIC23B_SSC_RX_PDCA_PID,
01243     .transfer_size  = (bits_per_sample <=  8) ? PDCA_TRANSFER_SIZE_BYTE      :
01244                       (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
01245                                                 PDCA_TRANSFER_SIZE_WORD
01246 
01247   };
01248   pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_rx);
01249   pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL);
01250 
01251   pdca_channel_options_t aic23b_ssc_pdca_options_tx =
01252   {
01253     .addr           = NULL,
01254     .size           = 0,
01255     .r_addr         = NULL,
01256     .r_size         = 0,
01257     .pid            = AIC23B_SSC_TX_PDCA_PID,
01258     .transfer_size  = (bits_per_sample <=  8) ? PDCA_TRANSFER_SIZE_BYTE      :
01259                       (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD :
01260                                                 PDCA_TRANSFER_SIZE_WORD
01261   };
01262   pdca_init_channel(AIC23B_SSC_TX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_tx);
01263   pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);
01264 
01265   // Set codec frequency
01266   aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz);
01267 
01268   aic23b_daif_t daif;
01269   daif.data   = AIC23B_DEFAULT(AIC23B_DAIF);
01270   daif.ms     = AIC23B_DAIF_MS_SLAVE;
01271   daif.lrswap = swap_channels;
01272   daif.lrp    = 0;
01273   daif.iwl    = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 :
01274                 (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 :
01275                 (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 :
01276                                           AIC23B_DAIF_IWL_32;
01277   daif.fmt    = AIC23B_DAIF_FMT_I2S;
01278   aic23b_write_reg(AIC23B_DAIF, daif.data);
01279 
01280   aic23b_output_params.num_channels              = num_channels;
01281   aic23b_output_params.callback                  = callback;
01282   aic23b_output_params.callback_opt              = callback_opt;
01283 }

void aic23b_codec_start ( U32  sample_rate_hz,
U8  num_channels,
U8  bits_per_sample,
Bool  swap_channels,
void(*)(U32 arg)  callback,
U32  callback_opt,
U32  pba_hz 
)

Starts the CODEC.

Definition at line 1103 of file tlv320aic23b.c.

Referenced by main().

01110 {
01111 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
01112   static const spi_options_t AIC23B_SPI_OPTIONS =
01113   {
01114     .reg          = AIC23B_SPI_NPCS,
01115     .baudrate     = AIC23B_SPI_MASTER_SPEED,
01116     .bits         = AIC23B_CTRL_SIZE,
01117     .spck_delay   = 0,
01118     .trans_delay  = 0,
01119     .stay_act     = 0,
01120     .spi_mode     = 3,
01121     .modfdis      = 1
01122   };
01123   spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz);
01124 #endif
01125 
01126   aic23b_codec_stop();
01127 
01128   gpio_enable_module(AIC23B_SSC_CODEC_GPIO_MAP,
01129                      sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0]));
01130 
01131   aic23b_pdc_t pdc;
01132   pdc.data  = AIC23B_DEFAULT(AIC23B_PDC);
01133   pdc.off   = 0;
01134   pdc.clk   = 0;
01135   pdc.osc   = 0;
01136   pdc.out   = 0;
01137   pdc.dac   = 0;
01138   pdc.adc   = 0;
01139 #if (AIC23B_INPUT==AIC23B_INPUT_LINE)
01140   pdc.mic   = 1;
01141   pdc.line  = 0;
01142 #elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
01143   pdc.mic   = 0;
01144   pdc.line  = 1;
01145 #else
01146   #error No Input defined in file 'conf_tlv320aic23b.h'
01147 #endif
01148   aic23b_set_power_down_state(pdc);
01149 
01150   aic23b_codec_setup(sample_rate_hz,
01151                    num_channels,
01152                    bits_per_sample,
01153                    swap_channels,
01154                    callback,
01155                    callback_opt,
01156                    pba_hz);
01157 
01158   aic23b_aapc_t aapc;
01159   aapc.data  = AIC23B_DEFAULT(AIC23B_AAPC);
01160 #if (AIC23B_INPUT==AIC23B_INPUT_LINE)
01161   aapc.ste   = 0;
01162   aapc.dac   = 1;
01163   aapc.byp   = 0;
01164   aapc.insel = 0;
01165   aapc.micm  = 0;
01166   aapc.micb  = 1;
01167 #elif (AIC23B_INPUT==AIC23B_INPUT_MIC)
01168   aapc.ste   = 0;
01169   aapc.dac   = 1;
01170   aapc.sta   = 4;
01171   aapc.byp   = 0;
01172   aapc.insel = 1;
01173   aapc.micm  = 0;
01174   aapc.micb  = 1;
01175 #else
01176   #error No Input defined in file 'conf_tlv320aic23b.h'
01177 #endif
01178   aic23b_set_analog_audio_path(aapc);
01179 
01180   aic23b_dapc_t dapc;
01181   dapc.data   = AIC23B_DEFAULT(AIC23B_DAPC);
01182   dapc.dacm   = 0;
01183   dapc.deemp  = AIC23B_DAPC_DEEMP_NONE;
01184   dapc.adchp  = 0;
01185   aic23b_set_digital_audio_path(dapc);
01186 
01187 
01188   aic23b_llicvc_t llivc;
01189   llivc.data  = AIC23B_DEFAULT(AIC23B_LLICVC);
01190   llivc.liv   = 20;
01191   llivc.lim   = 0;
01192   llivc.lrs   = 1;
01193   aic23b_write_reg(AIC23B_LLICVC, llivc.data);
01194 
01195   aic23b_rlicvc_t rlivc;
01196   rlivc.data  = AIC23B_DEFAULT(AIC23B_RLICVC);
01197   rlivc.riv   = 20;
01198   rlivc.rim   = 0;
01199   rlivc.rls   = 1;
01200   aic23b_write_reg(AIC23B_RLICVC, rlivc.data);
01201 
01202   INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler,
01203                           AIC23B_SSC_RX_PDCA_IRQ,
01204                           AIC23B_SSC_RX_PDCA_INT_LEVEL);
01205 
01206   // set an acceptable start volume
01207   aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
01208                               -30,
01209                               TRUE);
01210 
01211   aic23b_activate_dig_audio(TRUE);
01212 
01213   INTC_register_interrupt(&aic23b_ssc_tx_pdca_int_handler,
01214                           AIC23B_SSC_TX_PDCA_IRQ,
01215                           AIC23B_SSC_TX_PDCA_INT_LEVEL);
01216 }

void aic23b_codec_stop ( void   ) 

Stops the CODEC.

Definition at line 1295 of file tlv320aic23b.c.

Referenced by aic23b_codec_start().

01296 {
01297   aic23b_codec_flush();
01298 
01299   aic23b_reset();
01300 
01301   aic23b_pdc_t pdc;
01302   pdc.data  = AIC23B_DEFAULT(AIC23B_PDC);
01303   pdc.off   = 1;
01304   pdc.clk   = 1;
01305   pdc.osc   = 1;
01306   pdc.out   = 1;
01307   pdc.dac   = 1;
01308   pdc.adc   = 1;
01309   pdc.mic   = 1;
01310   pdc.line  = 1;
01311   aic23b_set_power_down_state(pdc);
01312 
01313   pdca_disable(AIC23B_SSC_RX_PDCA_CHANNEL);
01314   pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL);
01315 
01316   ssc_i2s_reset(AIC23B_SSC);
01317 
01318   gpio_enable_gpio(AIC23B_SSC_CODEC_GPIO_MAP,
01319                    sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0]));
01320 
01321   aic23b_output_params.num_channels             = 0;
01322   aic23b_output_params.callback                 = NULL;
01323   aic23b_output_params.callback_opt             = 0;
01324 }

void aic23b_configure_freq ( int  master_clock_hz,
int  sample_rate_hz 
)

Used to configure the codec frequency.

Definition at line 259 of file tlv320aic23b.c.

Referenced by aic23b_codec_setup().

00260 {
00261   aic23b_src_t src;
00262 
00263   src.data    = AIC23B_DEFAULT(AIC23B_SRC);
00264   src.clkout  = 0;
00265   src.clkin   = 0;
00266 
00267   switch (master_clock_hz)
00268   {
00269    case 12000000:
00270     src.usb     = 1;
00271     if (sample_rate_hz < (8000 + 8021) / 2)
00272     { // 8000 Hz
00273       src.sr    = 0x3;
00274       src.bosr  = 0;
00275     }
00276     else if (sample_rate_hz < (8021 + 32000) / 2)
00277     { // 8021 Hz
00278       src.sr    = 0xB;
00279       src.bosr  = 1;
00280     }
00281     else if (sample_rate_hz < (32000 + 44100) / 2)
00282     { // 32000 Hz
00283       src.sr    = 0x6;
00284       src.bosr  = 0;
00285     }
00286     else if (sample_rate_hz < (44100 + 48000) / 2)
00287     { // 44100 Hz
00288       src.sr    = 0x8;
00289       src.bosr  = 1;
00290     }
00291     else if (sample_rate_hz < (48000 + 88200) / 2)
00292     { // 48000 Hz
00293       src.sr    = 0x0;
00294       src.bosr  = 0;
00295     }
00296     else if (sample_rate_hz < (88200 + 96000) / 2)
00297     { // 88200 Hz
00298       src.sr    = 0xF;
00299       src.bosr  = 1;
00300     }
00301     else
00302     { // 96000 Hz
00303       src.sr    = 0x7;
00304       src.bosr  = 0;
00305     }
00306     break;
00307   case 11289600:
00308     src.usb     = 0;
00309     if (sample_rate_hz < (8021 + 22050) / 2)
00310     { // 8021 Hz
00311       src.sr    = 0xB;
00312       src.bosr  = 0;
00313     }
00314     else if (sample_rate_hz < (22050 + 88200) / 2)
00315     { // 22050, 44100 and 48000 Hz
00316       src.sr    = 0x8;
00317       src.bosr  = 0;
00318     }
00319     else
00320     { // 88200 Hz
00321       src.sr    = 0xF;
00322       src.bosr  = 0;
00323     }
00324     break;
00325   case 18432000:
00326     src.usb   = 0;
00327     src.sr    = 0;
00328     src.bosr  = 1;
00329     break;
00330   default:
00331     //Not supported
00332     return;
00333   }
00334 
00335   aic23b_write_reg(AIC23B_SRC, src.data);
00336 }

void aic23b_dac_decrease_volume ( void   ) 

Decreases the output volume of the DAC.

Note:
The DAC must have been started beforehand.

Definition at line 795 of file tlv320aic23b.c.

00796 {
00797   S8 volume = aic23b_get_headphone_volume(AIC23B_LEFT_CHANNEL);
00798   if( volume != AIC23B_MUTED )
00799     volume--;
00800   aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
00801                               volume,
00802                               TRUE);
00803 }

U8 aic23b_dac_get_average_headphone_volume ( void   ) 

Gets the average headphone volume.

Definition at line 423 of file tlv320aic23b.c.

00424 {
00425   S32 volume, volume_avg = 0;
00426   aic23b_lchvc_t lchvc;
00427   aic23b_rchvc_t rchvc;
00428 
00429   lchvc.data = aic23b_read_reg(AIC23B_LCHVC);
00430   rchvc.data = aic23b_read_reg(AIC23B_RCHVC);
00431   volume_avg = (lchvc.lhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00432                0 : lchvc.lhv - AIC23B_HP_VOL_OFFSET - AIC23B_HP_VOL_MIN;
00433   volume = (rchvc.rhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00434            0 : rchvc.rhv - AIC23B_HP_VOL_OFFSET - AIC23B_HP_VOL_MIN;
00435   // Get the volume average
00436   volume_avg = (volume_avg + volume) / 2;
00437   // Recenter the volume
00438   volume_avg = (volume_avg * 255) / (AIC23B_HP_VOL_MAX - AIC23B_HP_VOL_MIN);
00439 
00440   return (U8) volume_avg;
00441 }

void aic23b_dac_increase_volume ( void   ) 

Increases the output volume of the DAC.

Note:
The DAC must have been started beforehand.

Definition at line 784 of file tlv320aic23b.c.

00785 {
00786   S8 volume = aic23b_get_headphone_volume(AIC23B_LEFT_CHANNEL);
00787   if( volume < AIC23B_HP_VOL_MIN )
00788     volume = AIC23B_HP_VOL_MIN;
00789   aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,
00790                               volume + 1,
00791                               TRUE);
00792 }

Bool aic23b_dac_is_headphone_volume_boosted ( void   ) 

Returns the state of the boost mode of the DAC.

Definition at line 453 of file tlv320aic23b.c.

00454 {
00455   return FALSE;
00456 }

Bool aic23b_dac_is_headphone_volume_muted ( void   ) 

Returns the state of the mute mode of the DAC.

Definition at line 448 of file tlv320aic23b.c.

00449 {
00450   return FALSE;
00451 }

void aic23b_dac_mute ( Bool  mute  ) 

Mute audio if mute is set to true.

Definition at line 805 of file tlv320aic23b.c.

00806 {
00807 #if (AIC23B_MODE==AIC23B_MODE_DAC)
00808 /*  if(mute==TRUE) {
00809     pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL);
00810   }
00811   else {
00812        pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL);
00813   }
00814 */
00815   if (mute)
00816   {
00817     U32 save_dac_reload_callback_opt;
00818 
00819     // Disable the reload callback function
00820     save_dac_reload_callback_opt = aic23b_output_params.callback_opt;
00821     aic23b_output_params.callback_opt = 0;
00822     // Disable the transfer complete interruption and wait until the transfer is complete
00823     pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00824     while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE));
00825     // Re-enable the reload callback function
00826     aic23b_output_params.callback_opt = save_dac_reload_callback_opt;
00827   }
00828   else
00829   {
00830     // Re-enable the reload interrupt
00831     pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00832   }
00833 
00834 #endif
00835 }

Bool aic23b_dac_output ( void *  sample_buffer,
size_t  sample_length 
)

Outputs a sample buffer to the DAC.

Note:
The DAC must have been started beforehand.

Definition at line 737 of file tlv320aic23b.c.

Referenced by main().

00738 {
00739   Bool global_interrupt_enabled;
00740 
00741   if (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
00742         PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO))
00743     return FALSE;
00744 
00745   if (sample_length)
00746   {
00747     if (aic23b_output_params.num_channels == 1)
00748     {
00749       S16 *s16_sample_buffer = sample_buffer;
00750       int i;
00751 
00752       for (i = sample_length - 1; i >= 0; i--)
00753       {
00754         s16_sample_buffer[2 * i + 1] =
00755         s16_sample_buffer[2 * i]     = s16_sample_buffer[i];
00756       }
00757     }
00758 
00759     // The PDCA is not able to synchronize its start of transfer with the SSC
00760     // start of period, so this has to be done by polling the TF pin.
00761     // Not doing so may result in channels being swapped randomly.
00762     if ((global_interrupt_enabled = Is_global_interrupt_enabled()))
00763       Disable_global_interrupt();
00764     if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) &
00765         PDCA_TRANSFER_COMPLETE)
00766     {
00767       while (gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN));
00768       while (!gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN));
00769     }
00770     pdca_reload_channel(AIC23B_SSC_TX_PDCA_CHANNEL, sample_buffer, sample_length * 2);
00771     pdca_get_reload_size(AIC23B_SSC_TX_PDCA_CHANNEL);
00772     if (global_interrupt_enabled)
00773       Enable_global_interrupt();
00774 
00775     if (aic23b_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00776       pdca_enable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
00777     if (aic23b_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
00778       pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00779   }
00780   return TRUE;
00781 }

void aic23b_dac_set_average_headphone_volume ( U8  volume  ) 

Sets the average headphone volume.

Definition at line 443 of file tlv320aic23b.c.

aic23b_aapc_t aic23b_get_analog_audio_path ( void   ) 

Gets the analog audio path.

Definition at line 510 of file tlv320aic23b.c.

00511 {
00512   aic23b_aapc_t aapc;
00513   aapc.data = aic23b_read_reg(AIC23B_AAPC);
00514   return aapc;
00515 }

aic23b_dapc_t aic23b_get_digital_audio_path ( void   ) 

Gets the digital audio path.

Definition at line 524 of file tlv320aic23b.c.

00525 {
00526   aic23b_dapc_t dapc;
00527   dapc.data = aic23b_read_reg(AIC23B_DAPC);
00528   return dapc;
00529 }

S8 aic23b_get_headphone_volume ( U8  ch  ) 

Gets the ch channel headphone volume.

Definition at line 458 of file tlv320aic23b.c.

Referenced by aic23b_dac_decrease_volume(), and aic23b_dac_increase_volume().

00459 {
00460   switch (ch)
00461   {
00462   case AIC23B_LEFT_CHANNEL:
00463     {
00464       aic23b_lchvc_t lchvc;
00465       lchvc.data = aic23b_read_reg(AIC23B_LCHVC);
00466       return (lchvc.lhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00467              AIC23B_MUTED :
00468              lchvc.lhv - AIC23B_HP_VOL_OFFSET;
00469     }
00470   case AIC23B_RIGHT_CHANNEL:
00471     {
00472       aic23b_rchvc_t rchvc;
00473       rchvc.data = aic23b_read_reg(AIC23B_RCHVC);
00474       return (rchvc.rhv < AIC23B_HP_VOL_MIN + AIC23B_HP_VOL_OFFSET) ?
00475              AIC23B_MUTED :
00476              rchvc.rhv - AIC23B_HP_VOL_OFFSET;
00477     }
00478   default:
00479     return AIC23B_MUTED;
00480   }
00481 }

S8 aic23b_get_line_in_volume ( U8  ch  ) 

Gets the ch line input channel volume.

Definition at line 367 of file tlv320aic23b.c.

00368 {
00369   switch (ch)
00370   {
00371   case AIC23B_LEFT_CHANNEL:
00372     {
00373       aic23b_llicvc_t llicvc;
00374       llicvc.data = aic23b_read_reg(AIC23B_LLICVC);
00375       return (llicvc.lim) ?
00376              AIC23B_MUTED :
00377              llicvc.liv - AIC23B_LIN_VOL_OFFSET;
00378     }
00379   case AIC23B_RIGHT_CHANNEL:
00380     {
00381       aic23b_rlicvc_t rlicvc;
00382       rlicvc.data = aic23b_read_reg(AIC23B_RLICVC);
00383       return (rlicvc.rim) ?
00384              AIC23B_MUTED :
00385              rlicvc.riv - AIC23B_LIN_VOL_OFFSET;
00386     }
00387   default:
00388     return AIC23B_MUTED;
00389   }
00390 }

aic23b_pdc_t aic23b_get_power_down_state ( void   ) 

Gets the power down state.

Definition at line 538 of file tlv320aic23b.c.

00539 {
00540   aic23b_pdc_t pdc;
00541   pdc.data = aic23b_read_reg(AIC23B_PDC);
00542   return pdc;
00543 }

Bool aic23b_is_dig_audio_activated ( void   ) 

Tells whether the digital audio interface is activated.

Definition at line 552 of file tlv320aic23b.c.

00553 {
00554   aic23b_dia_t dia;
00555   dia.data = aic23b_read_reg(AIC23B_DIA);
00556   return dia.act;
00557 }

U16 aic23b_read_reg ( U8  reg  ) 

void aic23b_reset ( void   ) 

Resets the CODEC.

Definition at line 569 of file tlv320aic23b.c.

Referenced by aic23b_codec_stop().

00570 {
00571   aic23b_rr_t rr;
00572   rr.data = aic23b_read_reg(AIC23B_RR);
00573   rr.res = AIC23B_DEFAULT(AIC23B_RR) >> AIC23B_OFFSET(AIC23B_RR, RES);
00574   aic23b_write_reg(AIC23B_RR, rr.data);
00575 }

void aic23b_set_analog_audio_path ( aic23b_aapc_t  aapc  ) 

Sets the analog audio path to aapc.

Definition at line 518 of file tlv320aic23b.c.

Referenced by aic23b_codec_start().

00519 {
00520   aic23b_write_reg(AIC23B_AAPC, aapc.data);
00521 }

void aic23b_set_digital_audio_path ( aic23b_dapc_t  dapc  ) 

Sets the digital audio path to dapc.

Definition at line 532 of file tlv320aic23b.c.

Referenced by aic23b_codec_start().

00533 {
00534   aic23b_write_reg(AIC23B_DAPC, dapc.data);
00535 }

void aic23b_set_headphone_volume ( U8  ch_mask,
S8  vol,
Bool  z_cross 
)

Sets the ch_mask channels headphone volume to vol, with zero-cross detect if z_cross is TRUE.

Definition at line 483 of file tlv320aic23b.c.

Referenced by aic23b_codec_start(), aic23b_dac_decrease_volume(), aic23b_dac_increase_volume(), and aic23b_dac_set_average_headphone_volume().

00484 {
00485   if (ch_mask & AIC23B_LEFT_CHANNEL)
00486   {
00487     aic23b_lchvc_t lchvc;
00488     lchvc.data = aic23b_read_reg(AIC23B_LCHVC);
00489     lchvc.lrs = ((ch_mask & AIC23B_RIGHT_CHANNEL) != 0);
00490     lchvc.lzc = z_cross;
00491     lchvc.lhv = (vol < AIC23B_HP_VOL_MIN) ?
00492                 0 :
00493                 min(vol, AIC23B_HP_VOL_MAX) + AIC23B_HP_VOL_OFFSET;
00494     aic23b_write_reg(AIC23B_LCHVC, lchvc.data);
00495   }
00496   if (ch_mask & AIC23B_RIGHT_CHANNEL)
00497   {
00498     aic23b_rchvc_t rchvc;
00499     rchvc.data = aic23b_read_reg(AIC23B_RCHVC);
00500     rchvc.rls = 0;
00501     rchvc.rzc = z_cross;
00502     rchvc.rhv = (vol < AIC23B_HP_VOL_MIN) ?
00503                 0 :
00504                 min(vol, AIC23B_HP_VOL_MAX) + AIC23B_HP_VOL_OFFSET;
00505     aic23b_write_reg(AIC23B_RCHVC, rchvc.data);
00506   }
00507 }

void aic23b_set_line_in_volume ( U8  ch_mask,
S8  vol 
)

Sets the ch_mask line input channels volume to vol.

Definition at line 393 of file tlv320aic23b.c.

00394 {
00395   if (ch_mask & AIC23B_LEFT_CHANNEL)
00396   {
00397     aic23b_llicvc_t llicvc;
00398     llicvc.data = aic23b_read_reg(AIC23B_LLICVC);
00399     llicvc.lrs = ((ch_mask & AIC23B_RIGHT_CHANNEL) != 0);
00400     if (vol < AIC23B_LIN_VOL_MIN) llicvc.lim = 1;
00401     else
00402     {
00403       llicvc.lim = 0;
00404       llicvc.liv = min(vol, AIC23B_LIN_VOL_MAX) + AIC23B_LIN_VOL_OFFSET;
00405     }
00406     aic23b_write_reg(AIC23B_LLICVC, llicvc.data);
00407   }
00408   else if (ch_mask & AIC23B_RIGHT_CHANNEL)
00409   {
00410     aic23b_rlicvc_t rlicvc;
00411     rlicvc.data = aic23b_read_reg(AIC23B_RLICVC);
00412     rlicvc.rls = 0;
00413     if (vol < AIC23B_LIN_VOL_MIN) rlicvc.rim = 1;
00414     else
00415     {
00416       rlicvc.rim = 0;
00417       rlicvc.riv = min(vol, AIC23B_LIN_VOL_MAX) + AIC23B_LIN_VOL_OFFSET;
00418     }
00419     aic23b_write_reg(AIC23B_RLICVC, rlicvc.data);
00420   }
00421 }

void aic23b_set_power_down_state ( aic23b_pdc_t  pdc  ) 

Sets the power down state to pdc.

Definition at line 546 of file tlv320aic23b.c.

Referenced by aic23b_codec_start(), and aic23b_codec_stop().

00547 {
00548   aic23b_write_reg(AIC23B_PDC, pdc.data);
00549 }

static void aic23b_ssc_rx_pdca_int_handler ( void   )  [static]

SSC RX PDCA interrupt handler managing the out-of-samples condition.

Definition at line 210 of file tlv320aic23b.c.

References aic23b_output_params, and AIC23B_SSC_RX_PDCA_CHANNEL.

Referenced by aic23b_codec_start().

00211 {
00212   if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00213   {
00214     pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL);
00215     if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB)
00216       aic23b_output_params.callback(AUDIO_ADC_OUT_OF_SAMPLE_CB);
00217   }
00218 
00219   if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00220   {
00221     pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL);
00222     if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB)
00223       aic23b_output_params.callback(AUDIO_ADC_RELOAD_CB);
00224   }
00225 }

static void aic23b_ssc_tx_pdca_int_handler ( void   )  [static]

SSC TX PDCA interrupt handler managing the out-of-samples condition.

Definition at line 183 of file tlv320aic23b.c.

References aic23b_output_params, and AIC23B_SSC_TX_PDCA_CHANNEL.

Referenced by aic23b_codec_start().

00184 {
00185   if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)
00186   {
00187     pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL);
00188     if (aic23b_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB)
00189       aic23b_output_params.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB);
00190   }
00191 
00192   if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)
00193   {
00194     pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL);
00195     if (aic23b_output_params.callback_opt & AUDIO_DAC_RELOAD_CB)
00196       aic23b_output_params.callback(AUDIO_DAC_RELOAD_CB);
00197   }
00198 }

static void aic23b_write_control_word ( aic23b_ctrl_t  ctrl  )  [static]

Writes the ctrl control word.

Definition at line 230 of file tlv320aic23b.c.

Referenced by aic23b_write_reg().

00231 {
00232 #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_TWI
00233   int twi_status;
00234   aic23b_ctrl_t my_ctrl = ctrl;
00235   twi_package_t twi_package =
00236   {
00237     .chip         = AIC23B_TWI_ADDRESS,
00238     .addr_length  = AVR32_TWI_MMR_IADRSZ_NO_ADDR,
00239     .buffer       = &my_ctrl,
00240     .length       = sizeof(my_ctrl)
00241   };
00242   do
00243   {
00244      twi_status=twi_master_write(AIC23B_TWI, &twi_package);
00245   }
00246   while( twi_status != TWI_SUCCESS );
00247 #elif AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI
00248   spi_selectChip(AIC23B_SPI, AIC23B_SPI_NPCS);
00249   spi_write(AIC23B_SPI, *(U16 *)&ctrl);
00250   spi_unselectChip(AIC23B_SPI, AIC23B_SPI_NPCS);
00251 #endif
00252 }

void aic23b_write_reg ( U8  reg,
U16  val 
)


Variable Documentation

aic23b_ctrl_t aic23b_ctrl[] = AIC23B_CTRL_RESET [static]

Local image of the registers.

Definition at line 159 of file tlv320aic23b.c.

const aic23b_ctrl_t aic23b_ctrl_reset[] = AIC23B_CTRL_RESET [static]

Default local image of the registers.

Definition at line 156 of file tlv320aic23b.c.

struct { ... } aic23b_output_params [static]

const gpio_map_t AIC23B_SSC_CODEC_GPIO_MAP [static]

void(* callback)(U32 arg)

Definition at line 166 of file tlv320aic23b.c.

Definition at line 164 of file tlv320aic23b.c.


Generated on Fri Nov 27 14:08:35 2009 for AVR32 UC3 - Example of using an external Audio Codec TLV320AIC23B by  doxygen 1.5.5