uint32_t pdca_init_channel(uint8_t pdca_ch_number, const pdca_channel_options_t *opt) { /* get the correct channel pointer */ volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler( pdca_ch_number); pdca_disable_interrupt_transfer_complete(pdca_ch_number); pdca_disable_interrupt_reload_counter_zero(pdca_ch_number); irqflags_t flags = cpu_irq_save(); pdca_channel->mar = (uint32_t)opt->addr; pdca_channel->tcr = opt->size; pdca_channel->psr = opt->pid; pdca_channel->marr = (uint32_t)opt->r_addr; pdca_channel->tcrr = opt->r_size; pdca_channel->mr = #if (AVR32_PDCA_H_VERSION >= 120) opt->etrig << AVR32_PDCA_ETRIG_OFFSET | #endif opt->transfer_size << AVR32_PDCA_SIZE_OFFSET; pdca_channel->cr = AVR32_PDCA_ECLR_MASK; pdca_channel->isr; cpu_irq_restore(flags); return PDCA_SUCCESS; }
__interrupt #endif static void lin_pdca_int_rx_handler_node1(void) { U8 index = 0; U8 l_handle = 0xFF; // Check ID Value for the current message for(index = 0; index < NUMBER_OF_LIN_FRAMES_NODE1; index ++) { if(lin_descript_list_node1[index].l_id == usart_lin_get_id_char(usart_lin_node1)) { l_handle = index; break; } } // Check if the ID received is registered into the lin description list if (l_handle!=0xFF) { if (pdca_get_transfer_status(USART_LIN_NODE1_RX_PDCA_CHANNEL)&PDCA_TRANSFER_COMPLETE) { pdca_disable_interrupt_transfer_complete(USART_LIN_NODE1_RX_PDCA_CHANNEL); lin_get_response (1,lin_descript_list_node1[l_handle].l_pt_data); // Start of the associated task lin_descript_list_node1[l_handle].l_pt_function(lin_descript_list_node1[l_handle].l_pt_data); lin_handle_node1 = 0xFF; // End of communication } } }
void aic23b_dac_flush(void) { pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL); pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL); while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)); }
/*! \brief Flushes the sample buffer being output to the ABDAC. */ void tpa6130_dac_flush(void) { pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL); pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL); /*TODO Do we really want to wait here? Or do we just don't care when * the buffer is empty/flushed */ //while(!pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & // PDCA_TRANSFER_COMPLETE); pdca_disable (TPA6130_ABDAC_PDCA_CHANNEL ); pdca_load_channel (TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0); pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL,0x0, 0); pdca_enable (TPA6130_ABDAC_PDCA_CHANNEL ); }
ISR(tpa6130_abdac_tx_pdca_int_handler, TPA6130_ABDAC_PDCA_IRQ_GROUP, TPA6130_ABDAC_PDCA_INT_LEVEL) { if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE) { pdca_disable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL); if (tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB) tpa6130_output_param.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB); } if (pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO) { pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL); if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB) tpa6130_output_param.callback(AUDIO_DAC_RELOAD_CB); } }
static void pdca_int_handler_i2c0(void) { AVR32_TWIM0.cr = AVR32_TWIM_CR_MDIS_MASK; pdca_disable(TWI0_DMA_CH); pdca_disable_interrupt_transfer_complete(TWI0_DMA_CH); // call callback function to process data, at end of transfer // to process data, and maybe add some more data schedule[0][current_schedule_slot[0]].transfer_in_progress = 0; if (schedule[0][current_schedule_slot[0]].callback) { schedule[0][current_schedule_slot[0]].callback; } print_util_dbg_print( "!"); }
__interrupt #endif static void aic23b_ssc_rx_pdca_int_handler(void) { if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE) { pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL); if (aic23b_output_params.callback_opt & AUDIO_ADC_OUT_OF_SAMPLE_CB) aic23b_output_params.callback(AUDIO_ADC_OUT_OF_SAMPLE_CB); } if (pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO) { pdca_disable_interrupt_reload_counter_zero(AIC23B_SSC_RX_PDCA_CHANNEL); if (aic23b_output_params.callback_opt & AUDIO_ADC_RELOAD_CB) aic23b_output_params.callback(AUDIO_ADC_RELOAD_CB); } }
__interrupt #endif static void ms3_ssc_tx_pdca_int_handler(void) { if (pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE) { pdca_disable_interrupt_transfer_complete(MS3_SSC_TX_PDCA_CHANNEL); if (ms3_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB) ms3_output_params.callback(AUDIO_DAC_OUT_OF_SAMPLE_CB); } if (pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO) { pdca_disable_interrupt_reload_counter_zero(MS3_SSC_TX_PDCA_CHANNEL); if (ms3_output_params.callback_opt & AUDIO_DAC_RELOAD_CB) ms3_output_params.callback(AUDIO_DAC_RELOAD_CB); } }
__interrupt #endif static void pdca_int_handler(void) { // Disable all interrupts. Disable_global_interrupt(); // Disable interrupt channel. pdca_disable_interrupt_transfer_complete(AVR32_PDCA_CHANNEL_SPI_RX); sd_mmc_spi_read_close_PDCA();//unselects the SD/MMC memory. wait(); // Disable unnecessary channel pdca_disable(AVR32_PDCA_CHANNEL_SPI_TX); pdca_disable(AVR32_PDCA_CHANNEL_SPI_RX); // Enable all interrupts. Enable_global_interrupt(); end_of_transfer = true; }
static void irq_pdca(void) { // Disable all interrupts. // Disable_global_interrupt(); cpu_irq_disable(); // Disable interrupt channel. pdca_disable_interrupt_transfer_complete(AVR32_PDCA_CHANNEL_SPI_RX); //unselects the SD/MMC memory. sd_mmc_spi_read_close_PDCA(); //.... example has a 5000 clock gimpy delay here. // using delay_us instead delay_ms(10); // delay_ms(2); // Disable unnecessary channel pdca_disable(AVR32_PDCA_CHANNEL_SPI_TX); pdca_disable(AVR32_PDCA_CHANNEL_SPI_RX); // Enable all interrupts. cpu_irq_enable(); // Enable_global_interrupt(); // print_dbg("\r\n handled PDCA interrupt. \r\n"); fsEndTransfer = true; }
__interrupt #endif static void pdca_interrupt_handler(void) { pdca_disable_interrupt_transfer_complete(pdca_channel_usart); *((unsigned int *) pbuffer_w) = 1; // Point on the next buffer pbuffer_w += block_size; if (pbuffer_w + block_size >= buffer + BUFFER_SIZE) pbuffer_w = buffer; // If the next buffer is invalid, make an acquisition of the new data if (!*((unsigned int *) pbuffer_w)) { // If the buffer is invalidate, fill it with new data; get_new_block = 1; fill_activ = 1; } else { fill_activ = 0; } }
void aic23b_adc_start(uint32_t sample_rate_hz, uint8_t num_channels, uint8_t bits_per_sample, bool swap_channels, void (*callback)(uint32_t arg), uint32_t callback_opt, uint32_t pba_hz) { #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI static const spi_options_t AIC23B_SPI_OPTIONS = { .reg = AIC23B_SPI_NPCS, .baudrate = AIC23B_SPI_MASTER_SPEED, .bits = AIC23B_CTRL_SIZE, .spck_delay = 0, .trans_delay = 0, .stay_act = 0, .spi_mode = 3, .modfdis = 1 }; spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz); #endif aic23b_adc_stop(); gpio_enable_module(AIC23B_SSC_ADC_GPIO_MAP, sizeof(AIC23B_SSC_ADC_GPIO_MAP) / sizeof(AIC23B_SSC_ADC_GPIO_MAP[0])); aic23b_pdc_t pdc; pdc.data = AIC23B_DEFAULT(AIC23B_PDC); pdc.off = 0; pdc.clk = 0; pdc.osc = 0; pdc.out = 0; pdc.dac = 1; pdc.adc = 0; #if (AIC23B_INPUT==AIC23B_INPUT_LINE) pdc.mic = 1; pdc.line = 0; #elif (AIC23B_INPUT==AIC23B_INPUT_MIC) pdc.mic = 0; pdc.line = 1; #else #error No Input defined in file 'conf_tlv320aic23b.h' #endif aic23b_set_power_down_state(pdc); aic23b_adc_setup(sample_rate_hz, num_channels, bits_per_sample, swap_channels, callback, callback_opt, pba_hz); aic23b_aapc_t aapc; aapc.data = AIC23B_DEFAULT(AIC23B_AAPC); #if (AIC23B_INPUT==AIC23B_INPUT_LINE) aapc.ste = 0; aapc.dac = 0; aapc.byp = 0; aapc.insel = 0; aapc.micm = 0; aapc.micb = 0; #elif (AIC23B_INPUT==AIC23B_INPUT_MIC) aapc.ste = 0; aapc.dac = 0; aapc.byp = 0; aapc.insel = 1; aapc.micm = 0; aapc.micb = 0; #else #error No Input defined in file 'conf_tlv320aic23b.h' #endif aic23b_set_analog_audio_path(aapc); aic23b_dapc_t dapc; dapc.data = AIC23B_DEFAULT(AIC23B_DAPC); dapc.dacm = 0; dapc.deemp = AIC23B_DAPC_DEEMP_NONE; dapc.adchp = 0; aic23b_set_digital_audio_path(dapc); aic23b_llicvc_t llivc; llivc.data = AIC23B_DEFAULT(AIC23B_LLICVC); llivc.liv = 20; llivc.lim = 0; llivc.lrs = 1; aic23b_write_reg(AIC23B_LLICVC, llivc.data); aic23b_rlicvc_t rlivc; rlivc.data = AIC23B_DEFAULT(AIC23B_RLICVC); rlivc.riv = 20; rlivc.rim = 0; rlivc.rls = 1; aic23b_write_reg(AIC23B_RLICVC, rlivc.data); INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler, AIC23B_SSC_RX_PDCA_IRQ, AIC23B_SSC_RX_PDCA_INT_LEVEL); aic23b_activate_dig_audio(true); } void aic23b_adc_setup(uint32_t sample_rate_hz, uint8_t num_channels, uint8_t bits_per_sample, bool swap_channels, void (*callback)(uint32_t arg), callback_opt, uint32_t pba_hz) { ssc_i2s_init(AIC23B_SSC, sample_rate_hz, bits_per_sample, (bits_per_sample <= 16) ? 16 : (bits_per_sample <= 20) ? 20 : (bits_per_sample <= 24) ? 24 : 32, SSC_I2S_MODE_STEREO_IN, pba_hz); pdca_channel_options_t aic23b_ssc_pdca_options = { .addr = NULL, .size = 0, .r_addr = NULL, .r_size = 0, .pid = AIC23B_SSC_RX_PDCA_PID, .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE : (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD : PDCA_TRANSFER_SIZE_WORD }; pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options); pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL); // Set ADC frequency aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz); aic23b_daif_t daif; daif.data = AIC23B_DEFAULT(AIC23B_DAIF); daif.ms = AIC23B_DAIF_MS_SLAVE; daif.lrswap = swap_channels; daif.lrp = 0; daif.iwl = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 : (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 : (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 : AIC23B_DAIF_IWL_32; daif.fmt = AIC23B_DAIF_FMT_I2S; aic23b_write_reg(AIC23B_DAIF, daif.data); aic23b_output_params.num_channels = num_channels; aic23b_output_params.callback = callback; aic23b_output_params.callback_opt = callback_opt; } void aic23b_adc_flush(void) { pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL); while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)); }
void aic23b_codec_start(uint32_t sample_rate_hz, uint8_t num_channels, uint8_t bits_per_sample, bool swap_channels, void (*callback)(uint32_t arg), uint32_t callback_opt, uint32_t pba_hz) { #if AIC23B_CTRL_INTERFACE == AIC23B_CTRL_INTERFACE_SPI static const spi_options_t AIC23B_SPI_OPTIONS = { .reg = AIC23B_SPI_NPCS, .baudrate = AIC23B_SPI_MASTER_SPEED, .bits = AIC23B_CTRL_SIZE, .spck_delay = 0, .trans_delay = 0, .stay_act = 0, .spi_mode = 3, .modfdis = 1 }; spi_setupChipReg(AIC23B_SPI, &AIC23B_SPI_OPTIONS, pba_hz); #endif aic23b_codec_stop(); gpio_enable_module(AIC23B_SSC_CODEC_GPIO_MAP, sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0])); aic23b_pdc_t pdc; pdc.data = AIC23B_DEFAULT(AIC23B_PDC); pdc.off = 0; pdc.clk = 0; pdc.osc = 0; pdc.out = 0; pdc.dac = 0; pdc.adc = 0; #if (AIC23B_INPUT==AIC23B_INPUT_LINE) pdc.mic = 1; pdc.line = 0; #elif (AIC23B_INPUT==AIC23B_INPUT_MIC) pdc.mic = 0; pdc.line = 1; #else #error No Input defined in file 'conf_tlv320aic23b.h' #endif aic23b_set_power_down_state(pdc); aic23b_codec_setup(sample_rate_hz, num_channels, bits_per_sample, swap_channels, callback, callback_opt, pba_hz); aic23b_aapc_t aapc; aapc.data = AIC23B_DEFAULT(AIC23B_AAPC); #if (AIC23B_INPUT==AIC23B_INPUT_LINE) aapc.ste = 0; aapc.dac = 1; aapc.byp = 0; aapc.insel = 0; aapc.micm = 0; aapc.micb = 1; #elif (AIC23B_INPUT==AIC23B_INPUT_MIC) aapc.ste = 0; aapc.dac = 1; aapc.sta = 4; aapc.byp = 0; aapc.insel = 1; aapc.micm = 0; aapc.micb = 1; #else #error No Input defined in file 'conf_tlv320aic23b.h' #endif aic23b_set_analog_audio_path(aapc); aic23b_dapc_t dapc; dapc.data = AIC23B_DEFAULT(AIC23B_DAPC); dapc.dacm = 0; dapc.deemp = AIC23B_DAPC_DEEMP_NONE; dapc.adchp = 0; aic23b_set_digital_audio_path(dapc); aic23b_llicvc_t llivc; llivc.data = AIC23B_DEFAULT(AIC23B_LLICVC); llivc.liv = 20; llivc.lim = 0; llivc.lrs = 1; aic23b_write_reg(AIC23B_LLICVC, llivc.data); aic23b_rlicvc_t rlivc; rlivc.data = AIC23B_DEFAULT(AIC23B_RLICVC); rlivc.riv = 20; rlivc.rim = 0; rlivc.rls = 1; aic23b_write_reg(AIC23B_RLICVC, rlivc.data); INTC_register_interrupt(&aic23b_ssc_rx_pdca_int_handler, AIC23B_SSC_RX_PDCA_IRQ, AIC23B_SSC_RX_PDCA_INT_LEVEL); // set an acceptable start volume aic23b_set_headphone_volume(AIC23B_LEFT_CHANNEL | AIC23B_RIGHT_CHANNEL, -30, true); aic23b_activate_dig_audio(true); INTC_register_interrupt(&aic23b_ssc_tx_pdca_int_handler, AIC23B_SSC_TX_PDCA_IRQ, AIC23B_SSC_TX_PDCA_INT_LEVEL); } void aic23b_codec_setup(uint32_t sample_rate_hz, uint8_t num_channels, uint8_t bits_per_sample, bool swap_channels, void (*callback)(uint32_t opt), uint32_t callback_opt, uint32_t pba_hz) { uint32_t master_clock = AIC23B_MCLK_HZ; // default configuration // Change the CPU frequency // //Disable_global_interrupt(); // Switch to OSC0 during OSC1 transition //pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP); // Switch to PLL0 as the master clock //pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0); if (sample_rate_hz < (8000 + 8021) / 2) { // 8000 Hz } else if (sample_rate_hz < (8021 + 32000) / 2) { // 8021 Hz } else if (sample_rate_hz < (32000 + 44100) / 2) { // 32000 Hz master_clock = usb_stream_resync_frequency = 8192000; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, FOSC0)); pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(8192000); } else if (sample_rate_hz < (44100 + 48000) / 2) { // 44100 Hz master_clock = usb_stream_resync_frequency = 11289600; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, FOSC0)); pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(11289600); } else if (sample_rate_hz < (48000 + 88200) / 2) { // 48000 Hz master_clock = usb_stream_resync_frequency = 12288000; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, FOSC0)); pba_hz = FCPU_HZ = FHSB_HZ = FPBA_HZ = FPBB_HZ = FMCK_HZ(12288000); } else if (sample_rate_hz < (88200 + 96000) / 2) { // 88200 Hz } else { // 96000 Hz } //Enable_global_interrupt(); ssc_i2s_init(AIC23B_SSC, sample_rate_hz, bits_per_sample, (bits_per_sample <= 16) ? 16 : (bits_per_sample <= 20) ? 20 : (bits_per_sample <= 24) ? 24 : 32, SSC_I2S_MODE_STEREO_OUT_STEREO_IN, pba_hz); pdca_channel_options_t aic23b_ssc_pdca_options_rx = { .addr = NULL, .size = 0, .r_addr = NULL, .r_size = 0, .pid = AIC23B_SSC_RX_PDCA_PID, .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE : (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD : PDCA_TRANSFER_SIZE_WORD }; pdca_init_channel(AIC23B_SSC_RX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_rx); pdca_enable(AIC23B_SSC_RX_PDCA_CHANNEL); pdca_channel_options_t aic23b_ssc_pdca_options_tx = { .addr = NULL, .size = 0, .r_addr = NULL, .r_size = 0, .pid = AIC23B_SSC_TX_PDCA_PID, .transfer_size = (bits_per_sample <= 8) ? PDCA_TRANSFER_SIZE_BYTE : (bits_per_sample <= 16) ? PDCA_TRANSFER_SIZE_HALF_WORD : PDCA_TRANSFER_SIZE_WORD }; pdca_init_channel(AIC23B_SSC_TX_PDCA_CHANNEL, &aic23b_ssc_pdca_options_tx); pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL); // Set codec frequency aic23b_configure_freq(master_clock, sample_rate_hz); aic23b_daif_t daif; daif.data = AIC23B_DEFAULT(AIC23B_DAIF); daif.ms = AIC23B_DAIF_MS_SLAVE; daif.lrswap = swap_channels; daif.lrp = 0; daif.iwl = (bits_per_sample <= 16) ? AIC23B_DAIF_IWL_16 : (bits_per_sample <= 20) ? AIC23B_DAIF_IWL_20 : (bits_per_sample <= 24) ? AIC23B_DAIF_IWL_24 : AIC23B_DAIF_IWL_32; daif.fmt = AIC23B_DAIF_FMT_I2S; aic23b_write_reg(AIC23B_DAIF, daif.data); aic23b_output_params.num_channels = num_channels; aic23b_output_params.callback = callback; aic23b_output_params.callback_opt = callback_opt; } void aic23b_codec_flush(void) { pdca_disable_interrupt_transfer_complete(AIC23B_SSC_RX_PDCA_CHANNEL); while (!(pdca_get_transfer_status(AIC23B_SSC_RX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)); pdca_disable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL); while (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)); } void aic23b_codec_stop(void) { aic23b_codec_flush(); aic23b_reset(); aic23b_pdc_t pdc; pdc.data = AIC23B_DEFAULT(AIC23B_PDC); pdc.off = 1; pdc.clk = 1; pdc.osc = 1; pdc.out = 1; pdc.dac = 1; pdc.adc = 1; pdc.mic = 1; pdc.line = 1; aic23b_set_power_down_state(pdc); pdca_disable(AIC23B_SSC_RX_PDCA_CHANNEL); pdca_disable(AIC23B_SSC_TX_PDCA_CHANNEL); ssc_i2s_reset(AIC23B_SSC); gpio_enable_gpio(AIC23B_SSC_CODEC_GPIO_MAP, sizeof(AIC23B_SSC_CODEC_GPIO_MAP) / sizeof(AIC23B_SSC_CODEC_GPIO_MAP[0])); aic23b_output_params.num_channels = 0; aic23b_output_params.callback = NULL; aic23b_output_params.callback_opt = 0; }