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 AIC23B_CTRL_RESET |
#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().
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.
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.
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.
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 | ) |
Bool aic23b_dac_is_headphone_volume_muted | ( | void | ) |
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.
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.
00444 { 00445 aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL,volume,TRUE); 00446 }
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 | ) |
Reads the reg register.
Definition at line 340 of file tlv320aic23b.c.
Referenced by aic23b_activate_dig_audio(), aic23b_dac_get_average_headphone_volume(), aic23b_get_analog_audio_path(), aic23b_get_digital_audio_path(), aic23b_get_headphone_volume(), aic23b_get_line_in_volume(), aic23b_get_power_down_state(), aic23b_is_dig_audio_activated(), aic23b_reset(), aic23b_set_headphone_volume(), and aic23b_set_line_in_volume().
00341 { 00342 if (reg >= AIC23B_REG_COUNT) return 0x0000; 00343 return aic23b_ctrl[reg].data; 00344 }
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 | |||
) |
Writes val to the reg register.
Definition at line 347 of file tlv320aic23b.c.
Referenced by aic23b_activate_dig_audio(), aic23b_codec_setup(), aic23b_codec_start(), aic23b_configure_freq(), aic23b_reset(), aic23b_set_analog_audio_path(), aic23b_set_digital_audio_path(), aic23b_set_headphone_volume(), aic23b_set_line_in_volume(), and aic23b_set_power_down_state().
00348 { 00349 if (reg >= AIC23B_REG_COUNT) return; 00350 aic23b_ctrl[reg].data = val; 00351 if (reg == AIC23B_RR && aic23b_ctrl[reg].data == AIC23B_DEFAULT(AIC23B_RR)) 00352 { 00353 memcpy(aic23b_ctrl, aic23b_ctrl_reset, sizeof(aic23b_ctrl)); 00354 } 00355 aic23b_write_control_word(aic23b_ctrl[reg]); 00356 }
aic23b_ctrl_t aic23b_ctrl[] = AIC23B_CTRL_RESET [static] |
const aic23b_ctrl_t aic23b_ctrl_reset[] = AIC23B_CTRL_RESET [static] |
struct { ... } aic23b_output_params [static] |
const gpio_map_t AIC23B_SSC_CODEC_GPIO_MAP [static] |
Initial value:
{ {AIC23B_SSC_TX_CLOCK_PIN, AIC23B_SSC_TX_CLOCK_FUNCTION }, {AIC23B_SSC_TX_DATA_PIN, AIC23B_SSC_TX_DATA_FUNCTION }, {AIC23B_SSC_TX_FRAME_SYNC_PIN, AIC23B_SSC_TX_FRAME_SYNC_FUNCTION }, {AIC23B_SSC_RX_DATA_PIN, AIC23B_SSC_RX_DATA_FUNCTION }, {AIC23B_SSC_RX_FRAME_SYNC_PIN, AIC23B_SSC_RX_FRAME_SYNC_FUNCTION } }
Definition at line 126 of file tlv320aic23b.c.
Referenced by aic23b_codec_start(), and aic23b_codec_stop().
void(* callback)(U32 arg) |
Referenced by aic23b_codec_setup(), and aic23b_codec_start().
U32 callback_opt |
Definition at line 166 of file tlv320aic23b.c.
U8 num_channels |
Definition at line 164 of file tlv320aic23b.c.