//this gets an experiment, plus additional data, from the host //A full cluster will be transferred void get_experiment_from_host_to_SD(void) { USB_USART->rtor=0; //going to use PDCA for receiving data, so disable receive timeout pdca_disable(USB_USART_RX_PDCA_CHANNEL); my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&bank0[0]),samplebuffer_size, USB_USART_RX_PDCA_PID, 0, 0, PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_RX_PDCA_CHANNEL); while(!(pdca_get_transfer_status(USB_USART_RX_PDCA_CHANNEL) & AVR32_PDCA_TRC_MASK)); //wait until transfer is done pdca_disable(USB_USART_RX_PDCA_CHANNEL); //reset USART RX channel to receive host commands USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //changing back to receiving command mode USB_USART->rtor=15000; //so reenable timeout pdca_load_channel(USB_USART_RX_PDCA_CHANNEL, (&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer))); pdca_enable(USB_USART_RX_PDCA_CHANNEL); spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); while(check_busy_fast()!=0xFF); spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); my_SD_SPI_block_write_multi(bank0,experiment_base_address,blocks_per_cluster); //write data to SD spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); while(check_busy_fast()!=0xFF); spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); }
char* get_LCD_cmd(void) { if((LCD_USART->csr & AVR32_USART_CSR_TIMEOUT_MASK) != 0) {//timeout detected LCD_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set to not start counting again until after new character is received LCD_USART->rtor=230; cmd_ptr=(char *)(AVR32_PDCA.channel[LCD_USART_RX_PDCA_CHANNEL].mar-1); if((*(cmd_ptr)==0x0D) && ((cmd_ptr)!=(&LCD_USART_buffer[0]))) { pdca_disable(LCD_USART_RX_PDCA_CHANNEL); pdca_load_channel(LCD_USART_RX_PDCA_CHANNEL, (&LCD_USART_buffer),(uint32_t)(sizeof(LCD_USART_buffer))); *(cmd_ptr+1)=0x00; cmd_ptr--; while((*(cmd_ptr-1)!=0x0D) && ((cmd_ptr)!=(&LCD_USART_buffer[0]))) { cmd_ptr--; } pdca_enable(LCD_USART_RX_PDCA_CHANNEL); return cmd_ptr; } pdca_disable(LCD_USART_RX_PDCA_CHANNEL); pdca_load_channel(LCD_USART_RX_PDCA_CHANNEL, (&LCD_USART_buffer),(uint32_t)(sizeof(LCD_USART_buffer))); pdca_enable(LCD_USART_RX_PDCA_CHANNEL); return "false"; } return "false"; }
/** * \brief Application entry point for pdca_usart example. * * \return Unused (ANSI-C compatibility). */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the UART console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Enable PDCA module clock */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PDCA_TX_CHANNEL, &pdca_tx_configs); /* Enable PDCA channel */ pdca_channel_enable(PDCA_TX_CHANNEL); pdca_channel_set_callback(PDCA_TX_CHANNEL, pdca_tranfer_done, PDCA_0_IRQn, 1, PDCA_IER_RCZ); while (1) { } }
/*! \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 ); }
bool wait_for_CR(void) { if((LCD_USART->csr & AVR32_USART_CSR_TIMEOUT_MASK) != 0) {//timeout detected LCD_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set to not start counting again until after new character is received LCD_USART->rtor=230; pdca_disable(LCD_USART_RX_PDCA_CHANNEL); pdca_load_channel(LCD_USART_RX_PDCA_CHANNEL, (&LCD_USART_buffer),(uint32_t)(sizeof(LCD_USART_buffer))); pdca_enable(LCD_USART_RX_PDCA_CHANNEL); return true; } return false; }
char* get_HOST_cmd(void) { if((USB_USART->csr & AVR32_USART_CSR_TIMEOUT_MASK) != 0) {//timeout detected USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set to not start counting again until after new character is received USB_USART->rtor=15000; //baud rate is 3mbaud, so 15000 gives 5ms timeout pdca_disable(USB_USART_RX_PDCA_CHANNEL); cmd_ptr=(char *)(AVR32_PDCA.channel[USB_USART_RX_PDCA_CHANNEL].mar); *(cmd_ptr)=0x00; //make sure command string is null terminated cmd_ptr=&host_USART_buffer[0]; pdca_load_channel(USB_USART_RX_PDCA_CHANNEL, (&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer))); pdca_enable(USB_USART_RX_PDCA_CHANNEL); return cmd_ptr; } return "false"; }
__interrupt #endif static void int_usart_handler(void) { unsigned char c; if( USART->csr & AVR32_USART_RXRDY_MASK ) { c = (USART->rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET; if(MessageReady == true) { //Do not update message will old message has not been read return; } SERIAL_RX_Buffer[SERIAL_RX_index++]=c; // resynchronize until we get MESSAGE_START if(SERIAL_RX_Buffer[0]!=MESSAGE_START) { SERIAL_RX_index=0; } if(SERIAL_RX_index == 3u) { rx_size = ((SERIAL_RX_Buffer[1]<<8) | SERIAL_RX_Buffer[2]); } // If SERIAL_RX_index==3 run PDCA to received rest of the message if(SERIAL_RX_index == 3u) { // Disable RXRDY interrupt before switch to PDCA MODE USART->idr = AVR32_USART_IDR_RXRDY_MASK; rx_size = ((SERIAL_RX_Buffer[1]<<8) | SERIAL_RX_Buffer[2]); pdca_load_channel(PDCA_CHANNEL_RX_USART, (void *)&(SERIAL_RX_Buffer[3]),rx_size-2 ); pdca_enable(PDCA_CHANNEL_RX_USART); pdca_enable_interrupt_transfer_complete(PDCA_CHANNEL_RX_USART); } if(SERIAL_RX_index > 3) { // Must not occurred, require a sync SERIAL_RX_index=0; } }
/** * Initialize the PDCA transfer for the example. */ static void init_pdca(void) { /* PDCA channel options */ static const pdca_channel_config_t pdca_tx_configs = { .addr = (void *)event_string, .pid = PDCA_PID_USART_TX, .size = sizeof(event_string), .r_addr = 0, .r_size = 0, .ring = false, .etrig = true, .transfer_size = PDCA_MR_SIZE_BYTE }; /* Enable PDCA module clock */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PEVC_ID_USER_PDCA_0, &pdca_tx_configs); /* Set callback for PDCA channel */ pdca_channel_set_callback(PEVC_ID_USER_PDCA_0, pdca_tranfer_done, PDCA_0_IRQn, 1, PDCA_IER_TRC | PDCA_IER_TERR); /* Enable PDCA channel */ pdca_channel_enable(PEVC_ID_USER_PDCA_0); } /** * Push button 0 interrupt callback. */ //! [example_pb0_callback] static void pb0_callback(void) { /* Handle pin interrupt here e.g. toggle an LED */ LED_Toggle(LED0); }
/** * \brief Application entry point for usart_serial example. * * \return Unused (ANSI-C compatibility). */ int main(void) { /* Initialize the SAM system. */ sysclk_init(); board_init(); /* Configure UART for debug message output. */ configure_console(); /* Output example information. */ puts(STRING_HEADER); puts("-- Start to echo serial inputs with PDCA -- \r\n\r"); /* Configure TC. */ configure_tc(); /* Enable PDCA module clock */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PDCA_RX_CHANNEL, &pdca_rx_options); pdca_channel_set_config(PDCA_TX_CHANNEL, &pdca_tx_options); /* Enable PDCA channel, start receiving data. */ pdca_channel_enable(PDCA_RX_CHANNEL); pdca_channel_enable(PDCA_TX_CHANNEL); /* Enable USART RXBUFF interrupt */ usart_enable_interrupt(BOARD_USART, US_IER_RXBUFF); /* Configure and enable interrupt of USART. */ NVIC_EnableIRQ(USART_IRQn); /* Start timer. */ tc_start(TC0, 0); while (1) { } }
/*! \brief Sets the DACs up with new settings. * * \note The DACs must have been started beforehand. */ void tpa6130_dac_setup(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) { // save input parameters to local driver data tpa6130_output_param.num_channels = num_channels; tpa6130_output_param.callback = callback; tpa6130_output_param.callback_opt = callback_opt; /* Probe for amplifier and initialize it */ tpa6130_init(); #if defined(TPA6130_DAC_CLOCK_SET_CALLBACK) TPA6130_DAC_CLOCK_SET_CALLBACK(sample_rate_hz); #else /* ABDAC configuration * The ABDAC needs the input frequency of its generic clock (bus_hz) * Here we use the configuration value from the conf_tpa6130.h file * (TPA6130_ABDAC_GCLK_INPUT_HZ). * The sample rate specifies the desired sample rate for the ABDAC. * The generic clock input must be greater than 256*sample_rate_hz * or the setup of the ABDAC will fail silently here. * TODO we could add asserts here to detect wrong settings during * compile time. */ if(!abdac_set_dac_sample_rate(sample_rate_hz)) { // if it is not possible to set correctly the sample rate // Use default set function abdac_set_dac_hz(TPA6130_ABDAC, TPA6130_ABDAC_GCLK_INPUT_HZ,sample_rate_hz); } #endif if(swap_channels) { abdac_swap_channels(TPA6130_ABDAC); } abdac_enable(TPA6130_ABDAC); /* PDCA setup */ /*FIXME we use only word as transfer size for now. * half-word transfer size will only write to channel0 * of the ABDAC, this can be used to implement mono */ pdca_channel_options_t tpa6130_abdac_pdca_options = { .addr = NULL, .size = 0, .r_addr = 0, .r_size = 0, .pid = TPA6130_ABDAC_PDCA_PID, .transfer_size = PDCA_TRANSFER_SIZE_WORD }; /* Initialize the PCDA for the ABDAC * The channel number can be set in the configuration file * with the define TPA6130_ABDAC_PDCA_CHANNEL. */ pdca_init_channel(TPA6130_ABDAC_PDCA_CHANNEL, &tpa6130_abdac_pdca_options); /* Enable the PDCA channel. Since we did not provide any data * yet the channel is in idle mode */ pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL); } /*! \brief Outputs a sample buffer to the DACs. * The input requires a sample buffer that consists of words (32-bit) * which contain two (16-bit) samples, one for each channel. * * \note The DACs must have been started beforehand. */ bool tpa6130_dac_output(void *sample_buffer, size_t sample_length) { //int global_interrupt_enabled; /*Wait until the PDCA loads the reload value to its transfer * counter register(TCRR=0). Then we are ready to set up a new * transfer */ if(!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)) { return false; } /* Nothing to do if we get no data. */ if(sample_length) { /*TODO Do we really need to adjust the buffer for mono*/ /* While reloading the PDC we do not need any active interrupt*/ //if((global_interrupt_enabled = cpu_irq_is_enabled())) // cpu_irq_disable(); /*FIXME This assumes a stereo 16-bit sample size */ // one sample here consists of 2x16-bit (16-bit stereo) pdca_reload_channel(TPA6130_ABDAC_PDCA_CHANNEL, sample_buffer, sample_length); //if(global_interrupt_enabled) // cpu_irq_enable(); /*TODO enable transfer complete interrupt * Is it possible to move this to setup or other places?*/ if(tpa6130_output_param.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB) pdca_enable_interrupt_transfer_complete(TPA6130_ABDAC_PDCA_CHANNEL); if (tpa6130_output_param.callback_opt & AUDIO_DAC_RELOAD_CB) pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL); } return true; } bool tpa6130_dac_is_volume_muted(void) { return false; } void tpa6130_dac_mute(bool mute) { // //1st Version Mute Audio for Play/Pause /* int volume=tpa6130_get_volume(); if(mute==true) { //Mute volume volume= volume|MUTE_L|MUTE_R; } else { //Unmute volume volume= volume&(~(MUTE_L|MUTE_R)); } tpa6130_write_data(TPA6130_VOLUME_AND_MUTE,volume); */ //2n Version Stop PDCA >> No lost of audio when pause /* if(mute==true) { pdca_disable(TPA6130_ABDAC_PDCA_CHANNEL); } else { pdca_enable(TPA6130_ABDAC_PDCA_CHANNEL); } */ // 3rd Version wait until the current buffers are empty and disable the interrupts int8_t volume = tpa6130_get_volume(); if (mute) { uint32_t save_dac_reload_callback_opt; // Mute the audio stream volume = volume | MUTE_L | MUTE_R; tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume); // Disable the reload channel of the interrupt save_dac_reload_callback_opt = tpa6130_output_param.callback_opt; tpa6130_output_param.callback_opt = 0; // Disable the reload interruption and wait until the transfer is complete pdca_disable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL); while (!(pdca_get_transfer_status(TPA6130_ABDAC_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE)); // Restore the reload callback function tpa6130_output_param.callback_opt = save_dac_reload_callback_opt; } else { // Re-enable the interrupts pdca_enable_interrupt_reload_counter_zero(TPA6130_ABDAC_PDCA_CHANNEL); // Un-mute the audio stream volume = volume & (~(MUTE_L | MUTE_R)); tpa6130_write_data(TPA6130_VOLUME_AND_MUTE, volume); } }
/** * \brief Configure ADC sequencer support multi-channel mode. * * \param cfg Pointer to ADC multi-channel mode configuration. */ void adc_pdca_set_config(struct adc_pdca_config *cfg) { /* Enable PDCA module clock */ pdca_enable(PDCA); /* PDCA channel options */ pdca_channel_config_t PDCA_TX_CONFIGS = { /* memory address */ .addr = (void *)cfg->cdma_cfg, /* select peripheral */ .pid = ADCIFE_PDCA_ID_TX, /* transfer counter */ .size = cfg->wm == true ? (cfg->nb_channels)*2 : cfg->nb_channels, /* next memory address */ .r_addr = NULL, /* next transfer counter */ .r_size = 0, /* select size of the transfer */ .transfer_size = PDCA_MR_SIZE_WORD }; pdca_channel_config_t PDCA_RX_CONFIGS = { /* memory address */ .addr = (void *)cfg->buffer, /* select peripheral */ .pid = ADCIFE_PDCA_ID_RX, /* transfer counter */ .size = cfg->nb_channels, /* next memory address */ .r_addr = NULL, /* next transfer counter */ .r_size = 0, /* select size of the transfer */ .transfer_size = PDCA_MR_SIZE_HALF_WORD }; /* Init PDCA channel with the pdca_options. */ pdca_channel_set_config(cfg->pdc_tx_channel, &PDCA_TX_CONFIGS); pdca_channel_set_config(cfg->pdc_rx_channel, &PDCA_RX_CONFIGS); /* Enable PDCA channel */ pdca_channel_enable(cfg->pdc_tx_channel); pdca_channel_enable(cfg->pdc_rx_channel); } /** * \brief Enable ADC module. * * \param dev_inst Device structure pointer. * */ status_code_t adc_enable(struct adc_dev_inst *const dev_inst) { uint32_t timeout = ADC_NUM_OF_ATTEMPTS; sysclk_enable_peripheral_clock(dev_inst->hw_dev); sleepmgr_lock_mode(SLEEPMGR_SLEEP_1); dev_inst->hw_dev->ADCIFE_CR = ADCIFE_CR_EN; while (!(dev_inst->hw_dev->ADCIFE_SR & ADCIFE_SR_EN)) { if (!timeout--) { return ERR_TIMEOUT; } } dev_inst->hw_dev->ADCIFE_CR = ADCIFE_CR_REFBUFEN | ADCIFE_CR_BGREQEN; return STATUS_OK; } /** * \brief Disable ADC module. * * \param dev_inst Device structure pointer. * */ void adc_disable(struct adc_dev_inst *const dev_inst) { dev_inst->hw_dev->ADCIFE_CR = ADCIFE_CR_DIS | ADCIFE_CR_REFBUFDIS | ADCIFE_CR_BGREQDIS; sysclk_disable_peripheral_clock(dev_inst->hw_dev); sleepmgr_unlock_mode(SLEEPMGR_SLEEP_1); }
uint8_t check_SD(void) { if(SD_card_inserted()==false) { return SD_card_not_inserted; } spi_options_t SD_spiOptions = { .reg = SD_MMC_SPI_NPCS, .baudrate = SD_SPI_SPEED, // Defined in conf_sd_mmc_spi.h. .bits = 8, // Defined in conf_sd_mmc_spi.h. .spck_delay = 0, .trans_delay = 0, .stay_act = 1, .spi_mode = 0, .modfdis = 1 }; if(sd_mmc_spi_init(SD_spiOptions, PBA_SPEED)==false) { return SD_card_init_failed; } if(card_type!=SD_CARD_2_SDHC) { return SD_card_invalid; } return SD_card_valid; } bool SD_card_inserted(void) { if(gpio_get_pin_value(SD_detect_pin)==0) { return true; } else { return false; } } uint8_t hostmode_run(void) { //first receive and verify full experiment //set USB PDCA to store experiment USB_USART->rtor=0; //disable timeout pdca_disable(USB_USART_RX_PDCA_CHANNEL); my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&experiment.MODE),(uint32_t)(sizeof(experiment)), USB_USART_RX_PDCA_PID, 0, 0, PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_RX_PDCA_CHANNEL); while(!(pdca_get_transfer_status(USB_USART_RX_PDCA_CHANNEL) & AVR32_PDCA_TRC_MASK)); //wait until transfer is done if(validate_sequences()==false) { usart_write_line(USB_USART, "badexp\n"); usart_putchar(USB_USART,(uint8_t)(get_experiment_problem())); my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_RX_PDCA_CHANNEL); USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received USB_USART->rtor=15000; //set to timeout in 1ms return 0; } usart_write_line(USB_USART, "goodexp\n"); pdca_disable(USB_USART_TX_PDCA_CHANNEL); gettruesequence(); my_pdca_init_channel(USB_USART_TX_PDCA_CHANNEL, (uint32_t)(&experiment.MODE),(uint32_t)(sizeof(experiment)), USB_USART_TX_PDCA_PID, 0, 0, PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_TX_PDCA_CHANNEL); while(!(pdca_get_transfer_status(USB_USART_TX_PDCA_CHANNEL) & AVR32_PDCA_TRC_MASK)); //wait until transfer is done pdca_disable(USB_USART_TX_PDCA_CHANNEL); //change back USB USART to accept command tokens my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_RX_PDCA_CHANNEL); for(uint8_t i=0;i<Nsequences_max;i++) { usart_putchar(USB_USART,(uint8_t)(t_experiment.t_sequence[i].clusters_per_sequence)); } USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received USB_USART->rtor=15000; //set to timeout in 1ms reset_SD_sink_ptr(); uint32_t SD_read_ptr=data_base_address; DAC1->dr0=t_experiment.t_Vgain; //set gain of RF amp while(1) //once in host mode, this will run until a restart command is received { char *HOSTCMD="false"; while(strcmp(HOSTCMD,"false")==0) { HOSTCMD=get_HOST_cmd(); if(strcmp((HOSTCMD+1),"sequencetoken")==0) { uint8_t sequenceindex=*HOSTCMD; t_currentsequence=t_experiment.t_sequence[sequenceindex]; executesequence_SDstorage_multiprep_combined(); if(did_data_fail()) { usart_write_line(USB_USART, "fail\n"); usart_putchar(USB_USART,(uint8_t)(get_failure_cause())); usart_putchar(USB_USART,(uint8_t)(get_saved_r1())); } else { usart_write_line(USB_USART, "good\n"); send_data_to_host(SD_read_ptr,t_currentsequence.clusters_per_sequence); } SD_read_ptr+=t_currentsequence.clusters_per_sequence*blocks_per_cluster*bytes_per_block; //set back to command mode pdca_disable(USB_USART_RX_PDCA_CHANNEL); my_pdca_init_channel(USB_USART_RX_PDCA_CHANNEL, (uint32_t)(&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer)),USB_USART_RX_PDCA_PID,0,0, PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_RX_PDCA_CHANNEL); USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set timeout to stop until new character is received USB_USART->rtor=15000; //set to timeout in 1ms } else if(strcmp((HOSTCMD),"RESTART\n")==0) { //want to handle start of new host mode experiment return 1; } } } return 1; }
void idle(void) { while(1) { uint8_t tempmode=0; while(tempmode==0) //wait until a command has been received { if(lcdinit==false) //check for LCD { if(detect_lcd()==true) { usart_write_line(LCD_USART, "play modesel\r\n"); lcdinit=true; } } tempmode=idle_getmode(); } uint8_t tempsd=check_SD(); switch(tempmode) { case start_hostmode: if(tempsd!=SD_card_valid) { usart_write_line(USB_USART, "bad SD card\n"); } else { usart_write_line(USB_USART, "good SD card\n"); hostmode_run(); //go to host execution } break; case select_standalone: if(tempsd==SD_card_valid) { //valid SD card detected //retrieve experiment from SD card my_SD_read_experiment_PDCA(experiment_base_address,(uint32_t)(&experiment.MODE), (uint32_t)(&bank0[0]), sizeof(experiment), blocks_per_cluster); if(validate_sequences()==false) { //sequence was not valid usart_write_line(LCD_USART, "play badexp\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); } else { //sequence was valid usart_write_line(LCD_USART, "play goodexp\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); standalone_mode_run(); //re-enable USB USART to receive commands from host pdca_load_channel(USB_USART_RX_PDCA_CHANNEL, (&host_USART_buffer),(uint32_t)(sizeof(host_USART_buffer))); pdca_enable(USB_USART_RX_PDCA_CHANNEL); USB_USART->cr|=AVR32_USART_CR_STTTO_MASK; //set to not start counting again until after new character is received USB_USART->rtor=15000; //baud rate is 3mbaud, so 15000 gives 5ms timeout usart_write_line(LCD_USART, "play modesel\r\n"); //will eventually have branch here to cancel, examine experiment, or proceed } } else if(tempsd==SD_card_not_inserted) { //no SD card inserted usart_write_line(LCD_USART, "play noSD\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); } else if(tempsd==SD_card_init_failed) { //SD card failed to init usart_write_line(LCD_USART, "play SDerr\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); } else if(tempsd==SD_card_invalid) { //SD card init but not valid usart_write_line(LCD_USART, "play badSD\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); } break; case select_checkSD: switch (tempsd) { case SD_card_valid: usart_write_line(LCD_USART, "play goodSD\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); break; case SD_card_not_inserted: usart_write_line(LCD_USART, "play noSD\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); break; case SD_card_init_failed: usart_write_line(LCD_USART, "play SDerr\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); break; case SD_card_invalid: usart_write_line(LCD_USART, "play badSD\r\n"); while(strcmp(get_LCD_cmd(),"BR2\r")!=0); usart_write_line(LCD_USART, "play modesel\r\n"); break; } break; case program_experiment: if(tempsd!=SD_card_valid) { usart_write_line(USB_USART, "bad SD card\n"); } else { usart_write_line(USB_USART, "good SD card\n"); get_experiment_from_host_to_SD(); my_SD_read_experiment_PDCA(experiment_base_address,(uint32_t)(&experiment.MODE), (uint32_t)(&bank1[0]), sizeof(experiment), blocks_per_cluster); if(validate_sequences()==true) { usart_write_line(USB_USART, "goodexp\n"); } else { usart_write_line(USB_USART, "badexp\n"); } } break; case get_data: if(tempsd!=SD_card_valid) { usart_write_line(USB_USART, "bad SD card\n"); //if SD card is bad, say so and return } else {//if SD card is good, say so. Then read the experiment and validate it usart_write_line(USB_USART, "good SD card\n"); //this will read in entire first cluster of SD my_SD_read_experiment_PDCA(experiment_base_address,(uint32_t)(&experiment.MODE), (uint32_t)(&bank1[0]), sizeof(experiment), blocks_per_cluster); if(validate_sequences()==true) { //if experiment is valid, say so, then get true experiment usart_write_line(USB_USART, "goodexperiment\n"); gettruesequence(); //send entire cluster's worth of data to host. this will start with experiment and also include other "stuff" in the first cluster pdca_disable(USB_USART_TX_PDCA_CHANNEL);//goin to set up PDCA to send all of experiment, then start reading out bank1 until an entire cluster has been written my_pdca_init_channel(USB_USART_TX_PDCA_CHANNEL, (uint32_t)(&experiment.MODE),(uint32_t)(sizeof(experiment)), USB_USART_TX_PDCA_PID, (uint32_t)(&bank1[0]), (blocks_per_cluster*512-(uint32_t)(sizeof(experiment))), PDCA_TRANSFER_SIZE_BYTE); pdca_enable(USB_USART_TX_PDCA_CHANNEL); while(!(pdca_get_transfer_status(USB_USART_TX_PDCA_CHANNEL) & AVR32_PDCA_TRC_MASK)); //wait until transfer is done pdca_disable(USB_USART_TX_PDCA_CHANNEL); for(uint8_t i=0;i<Nsequences_max;i++) { usart_putchar(USB_USART,(uint8_t)(t_experiment.t_sequence[i].clusters_per_sequence)); } uint32_t SD_read_ptr=data_base_address; //now need to send actual data for(uint8_t i=0;i<t_experiment.N_experiments;i++) { for(uint8_t j=0;j<t_experiment.N_sequences;j++) { while(strcmp(get_HOST_cmd(),"SEND SEQUENCE\n")!=0); //wait for host to ask for each sequence send_data_to_host(SD_read_ptr,t_experiment.t_sequence[j].clusters_per_sequence); SD_read_ptr+=t_experiment.t_sequence[j].clusters_per_sequence*blocks_per_cluster*bytes_per_block; } } } else { usart_write_line(USB_USART, "badexperiment\n"); } } break; } } }
/** * \brief Application entry point for ABDAC example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint8_t key; uint32_t i, count; status_code_t status; /* Initialize the SAM system. */ sysclk_init(); board_init(); /* Initialize the UART console. */ configure_console(); /* Output example information */ printf("-- ABDAC Example --\r\n"); printf("-- %s\r\n", BOARD_NAME); printf("-- Compiled: %s %s --\r\n", __DATE__, __TIME__); /* Config the push button. */ config_buttons(); /* Config the ABDAC. */ abdac_get_config_defaults(&g_abdac_cfg); g_abdac_cfg.sample_rate_hz = ABDAC_SAMPLE_RATE_11025; g_abdac_cfg.data_word_format = ABDAC_DATE_16BIT; g_abdac_cfg.mono = false; g_abdac_cfg.cmoc = false; status = abdac_init(&g_abdac_inst, ABDACB, &g_abdac_cfg); if (status != STATUS_OK) { printf("-- Initialization fails! --\r\n"); while (1) { } } abdac_enable(&g_abdac_inst); abdac_clear_interrupt_flag(&g_abdac_inst, ABDAC_INTERRUPT_TXRDY); abdac_clear_interrupt_flag(&g_abdac_inst, ABDAC_INTERRUPT_TXUR); /* Config PDCA module */ pdca_enable(PDCA); pdca_channel_set_config(PDCA_ABDAC_CHANNEL0, &pdca_abdac_config0); pdca_channel_enable(PDCA_ABDAC_CHANNEL0); pdca_channel_set_config(PDCA_ABDAC_CHANNEL1, &pdca_abdac_config1); pdca_channel_enable(PDCA_ABDAC_CHANNEL1); /* Display menu. */ display_menu(); while (1) { scanf("%c", (char *)&key); switch (key) { case 'h': display_menu(); break; case 's': printf("--Looped output audio, use push button to exit--\r\n"); abdac_set_volume0(&g_abdac_inst, false, 0x7FFF); abdac_set_volume1(&g_abdac_inst, false, 0x7FFF); i = 0; /* output sample from the sound_table array */ while(!exit_flag) { count = 0; // Store sample from the sound_table array while(count < (SOUND_SAMPLES)){ samples_left[count] = ((uint8_t)sound_table[i]) << 8; samples_right[count] = ((uint8_t)sound_table[i]) << 8; i++; count++; if (i >= sizeof(sound_table)) i = 0; } pdca_channel_write_reload(PDCA_ABDAC_CHANNEL0, (void *)samples_left, SOUND_SAMPLES); pdca_channel_write_reload(PDCA_ABDAC_CHANNEL1, (void *)samples_right, SOUND_SAMPLES); /** * Wait until the reload register is empty. This means that * one transmission is still ongoing but we are already able * to set up the next transmission. */ while(!(pdca_get_channel_status(PDCA_ABDAC_CHANNEL1) == PDCA_CH_COUNTER_RELOAD_IS_ZERO)); } exit_flag = false; printf("--Exit the audio output--\r\n\r\n"); /* Mute the volume */ abdac_set_volume0(&g_abdac_inst, true, 0x7FFF); abdac_set_volume1(&g_abdac_inst, true, 0x7FFF); break; default: break; } } }
/** * \brief usart_rs485 Application entry point. * * Configure USART in RS485 mode. If the application starts earlier, it acts * as a receiver. Otherwise, it should be a transmitter. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint8_t uc_receive, uc_send = SYNC_CHAR; uint32_t time_elapsed = 0; uint32_t i; /* Initialize the SAM system. */ sysclk_init(); board_init(); /* Configure UART for debug message output. */ configure_console(); /* Output example information. */ puts(STRING_HEADER); /* 1ms tick. */ configure_systick(); /* Configure USART. */ configure_usart(); /* Initialize receiving buffer to distinguish with the sent frame. */ memset(g_uc_receive_buffer, 0x0, BUFFER_SIZE); /* * Enable transmitter here, and disable receiver first, to avoid receiving * characters sent by itself. It's necessary for half duplex RS485. */ usart_enable_tx(BOARD_USART); usart_disable_rx(BOARD_USART); /* Enable PDCA module clock */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PDCA_RX_CHANNEL, &PDCA_RX_OPTIONS); pdca_channel_set_config(PDCA_TX_CHANNEL, &PDCA_TX_OPTIONS); /* Send a sync character XON (0x11). */ pdca_channel_write_load(PDCA_TX_CHANNEL, &uc_send, 1); /* Enable transfer PDCA channel */ pdca_channel_enable(PDCA_TX_CHANNEL); /* Delay until the line is cleared, an estimated time used. */ wait(50); /* Then enable receiver. */ usart_enable_rx(BOARD_USART); /* Read the acknowledgement. */ pdca_channel_write_load(PDCA_RX_CHANNEL, &uc_receive, 1); /* Enable PDCA channel */ pdca_channel_enable(PDCA_RX_CHANNEL); /* Wait until time out or acknowledgement is received. */ time_elapsed = get_tick_count(); while (pdca_get_channel_status(PDCA_RX_CHANNEL) != PDCA_CH_TRANSFER_COMPLETED) { if (get_tick_count() - time_elapsed > TIMEOUT) { break; } } /* If acknowledgement received in a short time. */ if (pdca_get_channel_status(PDCA_RX_CHANNEL) == PDCA_CH_TRANSFER_COMPLETED) { /* Acknowledgement. */ if (uc_receive == ACK_CHAR) { /* Act as transmitter, start transmitting. */ puts("-I- Act as transmitter.\r"); g_state = TRANSMITTING; puts("-I- Start transmitting!\r"); pdca_channel_write_load(PDCA_TX_CHANNEL, g_uc_transmit_buffer, BUFFER_SIZE); /* Enable PDCA interrupt */ pdca_channel_set_callback(PDCA_TX_CHANNEL, PDCA_TX_Handler, PDCA_1_IRQn, 1, PDCA_IER_TRC); while (g_state != TRANSMITTED) { } puts("-I- Transmit done!\r"); while (1) { } } } else { /* Start receiving, act as receiver. */ puts("-I- Act as receiver.\r"); puts("-I- Receiving sync character.\r"); while (pdca_get_channel_status(PDCA_RX_CHANNEL) != PDCA_CH_TRANSFER_COMPLETED) { } /* Sync character is received. */ if (uc_receive == SYNC_CHAR) { puts("-I- Received sync character.\r"); /* SEND XOff as acknowledgement. */ uc_send = ACK_CHAR; /* * Delay to prevent the character from being discarded by * transmitter due to responding too soon. */ wait(100); ioport_set_pin_level(RS485_USART_CTS_PIN, 1); pdca_channel_write_load(PDCA_TX_CHANNEL, &uc_send, 1); g_state = RECEIVING; puts("-I- Start receiving buffer!\r"); pdca_channel_write_load(PDCA_RX_CHANNEL, g_uc_receive_buffer, BUFFER_SIZE); /* Enable PDCA interrupt */ pdca_channel_set_callback(PDCA_RX_CHANNEL, PDCA_RX_Handler, PDCA_0_IRQn, 1, PDCA_IER_TRC); ioport_set_pin_level(RS485_USART_CTS_PIN, 0); while (g_state != RECEIVED) { } } } i = 0; /* Check received frame. */ while (i < BUFFER_SIZE) { if (g_uc_transmit_buffer[i] != g_uc_receive_buffer[i]) { puts("-E- Error occurred while receiving!\r"); /* Infinite loop here. */ while (1) { } } i++; } puts("-I- Received buffer successfully!\r"); while (1) { } }
/** * \brief Set a given number of pixels to the same color * * Use this function to write a certain number of pixels to the same color * within a set limit. * * Limits have to be set prior to calling this function, e.g.: * \code * ili9341_set_top_left_limit(0, 0); * ili9341_set_bottom_right_limit(320, 240); * ... * \endcode * * \param color The color to write to the display * \param count The number of pixels to write with this color */ void ili9341_duplicate_pixel(const ili9341_color_t color, uint32_t count) { /* Sanity check to make sure that the pixel count is not zero */ Assert(count > 0); ili9341_send_command(ILI9341_CMD_MEMORY_WRITE); #if defined(ILI9341_DMA_ENABLED) ili9341_color_t chunk_buf[ILI9341_DMA_CHUNK_SIZE]; uint32_t chunk_len; # if SAM Pdc *SPI_DMA = spi_get_pdc_base(CONF_ILI9341_SPI); pdc_packet_t spi_pdc_data; pdc_enable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); spi_pdc_data.ul_addr = (uint32_t)chunk_buf; # elif UC3 pdca_set_transfer_size(CONF_ILI9341_PDCA_CHANNEL, PDCA_TRANSFER_SIZE_BYTE); pdca_set_peripheral_select(CONF_ILI9341_PDCA_CHANNEL, CONF_ILI9341_PDCA_PID); # endif for (uint32_t i = 0; i < ILI9341_DMA_CHUNK_SIZE; i++) { chunk_buf[i] = le16_to_cpu(color); } while (count) { chunk_len = min(ILI9341_DMA_CHUNK_SIZE, count); ili9341_wait_for_send_done(); # if SAM spi_pdc_data.ul_size = (uint32_t)sizeof(ili9341_color_t) * chunk_len; pdc_tx_init(SPI_DMA, NULL, &spi_pdc_data); # elif UC3 pdca_reload_channel(CONF_ILI9341_PDCA_CHANNEL, chunk_buf, (uint32_t)sizeof(ili9341_color_t) * chunk_len); pdca_enable(CONF_ILI9341_PDCA_CHANNEL); # endif count -= chunk_len; } ili9341_wait_for_send_done(); ili9341_deselect_chip(); # if SAM pdc_disable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); # elif UC3 pdca_disable(CONF_ILI9341_PDCA_CHANNEL); # endif #else while (count--) { ili9341_send_byte(color); ili9341_send_byte(color >> 8); } ili9341_wait_for_send_done(); ili9341_deselect_chip(); #endif }
/** * Initialize the PDCA transfer for the example. */ static void init_pdca(void) { /* PDCA channel options */ static const pdca_channel_config_t pdca_tx_configs = { .addr = (void *)event_string, .pid = PDCA_PID_USART2_TX, .size = sizeof(event_string), .r_addr = 0, .r_size = 0, .ring = false, .etrig = true, .transfer_size = PDCA_MR_SIZE_BYTE }; /* Enable PDCA module */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PEVC_ID_USER_PDCA_0, &pdca_tx_configs); /* Set callback for PDCA channel */ pdca_channel_set_callback(PEVC_ID_USER_PDCA_0, pdca_tranfer_done, PDCA_0_IRQn, 1, PDCA_IER_TRC | PDCA_IER_TERR); /* Enable PDCA channel */ pdca_channel_enable(PEVC_ID_USER_PDCA_0); } /** * Configure serial console. */ static void configure_console(void) { const usart_serial_options_t uart_serial_options = { .baudrate = CONF_UART_BAUDRATE, #ifdef CONF_UART_CHAR_LENGTH .charlength = CONF_UART_CHAR_LENGTH, #endif .paritytype = CONF_UART_PARITY, #ifdef CONF_UART_STOP_BITS .stopbits = CONF_UART_STOP_BITS, #endif }; /* Configure console. */ stdio_serial_init(CONF_UART, &uart_serial_options); } /** * \brief Main entry point for event example. */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ printf("\r\n\r\n-- Events example 2 --\r\n"); printf("-- %s\r\n", BOARD_NAME); printf("-- Compiled: %s %s --\r\n", __DATE__, __TIME__); /* Configure pin to trigger an enent on falling edge */ ioport_set_pin_mode(CONF_EXAMPLE_PIN_EVENT, IOPORT_MODE_PULLUP | IOPORT_MODE_MUX_C); ioport_disable_pin(CONF_EXAMPLE_PIN_EVENT); ioport_set_pin_sense_mode(CONF_EXAMPLE_PIN_EVENT, IOPORT_SENSE_FALLING); gpio_enable_pin_periph_event(CONF_EXAMPLE_PIN_EVENT); printf(CONF_EXAMPLE_EVENT_MSG); init_events(); init_pdca(); while (1) { /* Toggle LED0 every 500 ms */ LED_Toggle(LED0); delay_ms(500); } }
void aic23b_dac_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_dac_stop(); gpio_enable_module(AIC23B_SSC_DAC_GPIO_MAP, sizeof(AIC23B_SSC_DAC_GPIO_MAP) / sizeof(AIC23B_SSC_DAC_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 = 1; pdc.mic = 1; pdc.line = 1; aic23b_set_power_down_state(pdc); aic23b_dac_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); aapc.ste = 0; aapc.dac = 1; aapc.byp = 0; aapc.micm = 1; aapc.micb = 0; 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 = 1; aic23b_set_digital_audio_path(dapc); // 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_dac_setup(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 defined(AIC23B_DAC_USE_RX_CLOCK) && AIC23B_DAC_USE_RX_CLOCK == true #if defined(AIC23B_DAC_RX_CLOCK_SET_CALLBACK) AIC23B_DAC_RX_CLOCK_SET_CALLBACK(2 * sample_rate_hz * ((bits_per_sample <= 16) ? 16 : (bits_per_sample <= 20) ? 20 : (bits_per_sample <= 24) ? 24 : 32)); #endif 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_EXT_CLK, pba_hz); #else 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, pba_hz); #endif pdca_channel_options_t aic23b_ssc_pdca_options = { .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); pdca_enable(AIC23B_SSC_TX_PDCA_CHANNEL); #if !defined(AIC23B_DAC_USE_RX_CLOCK) || AIC23B_DAC_USE_RX_CLOCK == false || \ !defined(AIC23B_DAC_RX_CLOCK_SET_CALLBACK) // Set DAC frequency aic23b_configure_freq(AIC23B_MCLK_HZ, sample_rate_hz); #endif 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; } #endif bool aic23b_dac_output(void *sample_buffer, size_t sample_length) { bool global_interrupt_enabled; if (!(pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)) return false; if (sample_length) { if (aic23b_output_params.num_channels == 1) { int16_t *s16_sample_buffer = sample_buffer; int i; for (i = sample_length - 1; i >= 0; i--) { s16_sample_buffer[2 * i + 1] = s16_sample_buffer[2 * i] = s16_sample_buffer[i]; } } // The PDCA is not able to synchronize its start of transfer with the SSC // start of period, so this has to be done by polling the TF pin. // Not doing so may result in channels being swapped randomly. if ((global_interrupt_enabled = Is_global_interrupt_enabled())) Disable_global_interrupt(); if (pdca_get_transfer_status(AIC23B_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE) { while (gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN)); while (!gpio_get_pin_value(AIC23B_SSC_TX_FRAME_SYNC_PIN)); } pdca_reload_channel(AIC23B_SSC_TX_PDCA_CHANNEL, sample_buffer, sample_length * 2); pdca_get_reload_size(AIC23B_SSC_TX_PDCA_CHANNEL); if (global_interrupt_enabled) Enable_global_interrupt(); if (aic23b_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB) pdca_enable_interrupt_transfer_complete(AIC23B_SSC_TX_PDCA_CHANNEL); if (aic23b_output_params.callback_opt & AUDIO_DAC_RELOAD_CB) pdca_enable_interrupt_reload_counter_zero(AIC23B_SSC_TX_PDCA_CHANNEL); } return true; }
void ms3_dac_setup(U32 sample_rate_hz, U8 num_channels, U8 bits_per_sample, bool swap_channels, void (*callback)(U32 arg), U32 callback_opt, U32 pba_hz) { //configure clock if (sample_rate_hz < (8000 + 8021) / 2) { usb_stream_resync_frequency = 4096000; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF)); } else if (sample_rate_hz < (8021 + 22050) / 2) { usb_stream_resync_frequency = 4106752; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF)); } else if (sample_rate_hz < (22050 + 32000) / 2) { usb_stream_resync_frequency = 11289600; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF)); } else if (sample_rate_hz < (32000 + 44100) / 2) { usb_stream_resync_frequency = 16384000; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF)); } else if (sample_rate_hz < (44100 + 48000) / 2) { usb_stream_resync_frequency = 22579200; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF)); } else if (sample_rate_hz < (48000 + 88200) / 2) { usb_stream_resync_frequency = 24576000; cs2200_freq_clk_out(_32_BITS_RATIO(usb_stream_resync_frequency, CS2200_FREF)); } //configure ssc to use clock on TX_CLOCK pin AVR32_SSC.tcmr = (0 << AVR32_SSC_TCMR_CKO_OFFSET) | (1 << AVR32_SSC_TCMR_STTDLY_OFFSET) | (2 << AVR32_SSC_TCMR_CKS_OFFSET) | (7 << AVR32_SSC_TCMR_START_OFFSET) | (0x1f << AVR32_SSC_TCMR_PERIOD_OFFSET); AVR32_SSC.tfmr = (0xf << AVR32_SSC_TFMR_DATLEN_OFFSET) | (1 << AVR32_SSC_TFMR_MSBF_OFFSET) | (1 << AVR32_SSC_TFMR_FSOS_OFFSET) | (1 << AVR32_SSC_TFMR_FSLENHI_OFFSET) | (0xf << AVR32_SSC_TFMR_FSLEN_OFFSET); AVR32_SSC.cr = AVR32_SSC_CR_TXEN_MASK; //configure DMA pdca_channel_options_t ms3_ssc_pdca_options = { .addr = NULL, .size = 0, .r_addr = NULL, .r_size = 0, .pid = AVR32_PDCA_PID_SSC_TX, .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(MS3_SSC_TX_PDCA_CHANNEL, &ms3_ssc_pdca_options); pdca_enable(MS3_SSC_TX_PDCA_CHANNEL); //configure audio parameters ms3_output_params.num_channels = num_channels; ms3_output_params.callback = callback; ms3_output_params.callback_opt = callback_opt; } bool ms3_dac_output(void *sample_buffer, size_t sample_length) { bool global_interrupt_enabled; if (!(pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COUNTER_RELOAD_IS_ZERO)) return false; if (sample_length) { if (ms3_output_params.num_channels == 1) { S16 *s16_sample_buffer = sample_buffer; int i; for (i = sample_length - 1; i >= 0; i--) { s16_sample_buffer[2 * i + 1] = s16_sample_buffer[2 * i] = s16_sample_buffer[i]; } } // The PDCA is not able to synchronize its start of transfer with the SSC // start of period, so this has to be done by polling the TF pin. // Not doing so may result in channels being swapped randomly. if ((global_interrupt_enabled = Is_global_interrupt_enabled())) Disable_global_interrupt(); if (pdca_get_transfer_status(MS3_SSC_TX_PDCA_CHANNEL) & PDCA_TRANSFER_COMPLETE) { while (gpio_get_pin_value(MS3_SSC_TX_FRAME_SYNC_PIN)); while (!gpio_get_pin_value(MS3_SSC_TX_FRAME_SYNC_PIN)); } pdca_reload_channel(MS3_SSC_TX_PDCA_CHANNEL, sample_buffer, sample_length * 2); pdca_get_reload_size(MS3_SSC_TX_PDCA_CHANNEL); if (global_interrupt_enabled) Enable_global_interrupt(); if (ms3_output_params.callback_opt & AUDIO_DAC_OUT_OF_SAMPLE_CB) pdca_enable_interrupt_transfer_complete(MS3_SSC_TX_PDCA_CHANNEL); if (ms3_output_params.callback_opt & AUDIO_DAC_RELOAD_CB) pdca_enable_interrupt_reload_counter_zero(MS3_SSC_TX_PDCA_CHANNEL); } return true; }
/*! \brief This function commands the sending of a LIN header and response, MASTER task only * * \param l_node Node Value * \param l_handle Handle on the descriptor list * \param l_len Message length corresponding to the message pointed by the handle in the descriptor list * * \return Status PASS / FAIL * */ static U8 lin_tx_header_and_response( U8 l_node, U8 l_handle, U8 l_len ) { if (l_node == 0) { //! Enable Interrupt for Error flags and end ID Reception #if ( defined (AVR32_USART_400_H_INCLUDED) || \ defined (AVR32_USART_410_H_INCLUDED) || \ defined (AVR32_USART_420_H_INCLUDED) ) // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_tx_buffer_node0, // memory address .pid = USART_LIN_NODE0_PDCA_PID_TX, // select peripheral - data are transmit on USART TX line. .size = (l_len+1), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE0_TX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); // Copy data of the data contained in the descriptor list into the tx buffer of the PDCA memcpy(&lin_tx_buffer_node0[1],lin_descript_list_node0[l_handle].l_pt_data,l_len); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE0_TX_PDCA_CHANNEL); // Set the ID First lin_tx_buffer_node0[0] = lin_descript_list_node0[l_handle].l_id; // Start PDCA transfer ID + Data pdca_enable(USART_LIN_NODE0_TX_PDCA_CHANNEL); usart_lin_set_id_char(usart_lin_node0,lin_descript_list_node0[l_handle].l_id); #else // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_tx_buffer_node0, // memory address .pid = USART_LIN_NODE0_PDCA_PID_TX, // select peripheral - data are transmit on USART TX line. .size = (l_len+1), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE0_TX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); // Copy data of the data contained in the descriptor list into the tx buffer of the PDCA memcpy(&lin_tx_buffer_node0[1],lin_descript_list_node0[l_handle].l_pt_data,l_len); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE0_TX_PDCA_CHANNEL); // Set the ID First lin_tx_buffer_node0[0] = lin_descript_list_node0[l_handle].l_id; // Start PDCA transfer ID + Data pdca_enable(USART_LIN_NODE0_TX_PDCA_CHANNEL); #endif return PASS; } #ifdef USART_LIN_NODE1_INSTANCE else { //! Enable Interrupt for Error flags and end ID Reception #if ( defined (AVR32_USART_400_H_INCLUDED) || \ defined (AVR32_USART_410_H_INCLUDED) || \ defined (AVR32_USART_420_H_INCLUDED) ) // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_tx_buffer_node1, // memory address .pid = USART_LIN_NODE1_PDCA_PID_TX, // select peripheral - data are transmit on USART TX line. .size = (l_len+1), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE1_TX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); // Copy data of the data contained in the descriptor list into the tx buffer of the PDCA memcpy(&lin_tx_buffer_node1[1],lin_descript_list_node1[l_handle].l_pt_data,l_len); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE1_TX_PDCA_CHANNEL); // Set the ID First lin_tx_buffer_node1[0] = lin_descript_list_node1[l_handle].l_id; // Start PDCA transfer ID + Data pdca_enable(USART_LIN_NODE1_TX_PDCA_CHANNEL); usart_lin_set_id_char(usart_lin_node1,lin_descript_list_node1[l_handle].l_id); #else // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_tx_buffer_node1, // memory address .pid = USART_LIN_NODE1_PDCA_PID_TX, // select peripheral - data are transmit on USART TX line. .size = (l_len+1), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE1_TX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); // Copy data of the data contained in the descriptor list into the tx buffer of the PDCA memcpy(&lin_tx_buffer_node1[1],lin_descript_list_node1[l_handle].l_pt_data,l_len); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE1_TX_PDCA_CHANNEL); // Set the ID First lin_tx_buffer_node1[0] = lin_descript_list_node1[l_handle].l_id; // Start PDCA transfer ID + Data pdca_enable(USART_LIN_NODE1_TX_PDCA_CHANNEL); #endif return PASS; } #endif } /*! \brief This function commands the sending of a LIN response, SLAVE task of MASTER or SLAVE node. * * \param l_node Node Value * \param l_handle Handle on the descriptor list * \param l_data Pointer on the data corresponding to the message pointed by the handle in the descriptor list * \param l_len Message length corresponding to the message pointed by the handle in the descriptor list * * \return Status PASS / FAIL * */ static U8 lin_tx_response ( U8 l_node, U8 l_handle, U8 *l_data, U8 l_len ) { if (l_node == 0) { // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_tx_buffer_node0, // memory address .pid = USART_LIN_NODE0_PDCA_PID_TX, // select peripheral - data are transmit on USART TX line. .size = (l_len), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE0_TX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); // Copy data of the data contained in the descriptor list into the tx buffer of the PDCA memcpy(&lin_tx_buffer_node0[0],lin_descript_list_node0[l_handle].l_pt_data,l_len+1); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE0_TX_PDCA_CHANNEL); // Start PDCA transfer Data pdca_enable(USART_LIN_NODE0_TX_PDCA_CHANNEL); return 1; } #ifdef USART_LIN_NODE1_INSTANCE else { // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_tx_buffer_node1, // memory address .pid = USART_LIN_NODE1_PDCA_PID_TX, // select peripheral - data are transmit on USART TX line. .size = (l_len), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE1_TX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); // Copy data of the data contained in the descriptor list into the tx buffer of the PDCA memcpy(&lin_tx_buffer_node1[0],lin_descript_list_node1[l_handle].l_pt_data,l_len+1); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE1_TX_PDCA_CHANNEL); // Start PDCA transfer Data pdca_enable(USART_LIN_NODE1_TX_PDCA_CHANNEL); return 1; } #endif } /*! \brief This function commands the reception of a LIN response, SLAVE task of MASTER or SLAVE node. * * \param l_node Node Value * \param l_handle Handle on the descriptor list * \param l_len Message length corresponding to the message pointed by the handle in the descriptor list * * \return Status PASS / FAIL * */ static U8 lin_rx_response ( U8 l_node, U8 l_handle, U8 l_len ) { if (l_node == 0) { // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_rx_buffer_node0, // memory address .pid = USART_LIN_NODE0_PDCA_PID_RX, // select peripheral - data are transmit on USART TX line. .size = (l_len), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE0_RX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE0_RX_PDCA_CHANNEL); // Start PDCA transfer Data pdca_enable(USART_LIN_NODE0_RX_PDCA_CHANNEL); return 1; } #ifdef USART_LIN_NODE1_INSTANCE else { // PDCA channel options pdca_channel_options_t USART_LIN_PDCA_OPTIONS = { .addr = (void *)lin_rx_buffer_node1, // memory address .pid = USART_LIN_NODE1_PDCA_PID_RX, // select peripheral - data are transmit on USART TX line. .size = (l_len), // transfer counter .r_addr = NULL, // next memory address .r_size = 0, // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE // select size of the transfer }; pdca_init_channel(USART_LIN_NODE1_RX_PDCA_CHANNEL, &USART_LIN_PDCA_OPTIONS); pdca_enable_interrupt_transfer_complete(USART_LIN_NODE1_RX_PDCA_CHANNEL); // Start PDCA transfer Data pdca_enable(USART_LIN_NODE1_RX_PDCA_CHANNEL); return 1; } #endif } /*! \brief This function reads (empties) the reception data buffer when a LIN response * had been received. This function is additional of the `lin_rx_response()' * function. * * \param l_node Node Value * \param l_data Pointer on the data corresponding to the message pointed by the handle in the descriptor list * * \return Status PASS / FAIL * */ static void lin_get_response (U8 l_node, U8 *l_data) { U8 i, l_len; if (l_node == 0) { l_len = usart_lin_get_data_length(usart_lin_node0); for (i = 0; i < l_len; i++) { (*l_data++) = lin_rx_buffer_node0[i]; } } #ifdef USART_LIN_NODE1_INSTANCE else { l_len = usart_lin_get_data_length(usart_lin_node1); for (i = 0; i < l_len; i++) { (*l_data++) = lin_rx_buffer_node1[i]; } } #endif }
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; }
/** ** PDCA Init. **/ void init_pdca(void) { // PDCA channel 0/1 options static const pdca_channel_options_t PDCA_CH_OPTIONS = { .addr = (void *)aDataTransfered, // memory address .pid = AVR32_PDCA_PID_USART2_TX, // select peripheral - data are transmit on USART TX line. .size = 0, // transfer counter .r_addr = (void *)aDataTransfered, // next memory address .r_size = sizeof(aDataTransfered), // next transfer counter .transfer_size = PDCA_TRANSFER_SIZE_BYTE, // select size of one data packet .etrig = true // Trigger transfer on event. }; Disable_global_interrupt(); // Initialize interrupt vectors. INTC_init_interrupts(); // Register the PDCA interrupt handler to the interrupt controller. INTC_register_interrupt(&pdca_int_handler, PDCA_CHANNEL_IRQ, AVR32_INTC_INT0); Enable_global_interrupt(); // Init PDCA channel with the pdca_options. pdca_init_channel(PDCA_CHANNEL_USART, &PDCA_CH_OPTIONS); pdca_channel = pdca_get_handler(PDCA_CHANNEL_USART); // For use in the pdca interrupt handler. // Enable pdca transfer error interrupt & transfer complete interrupt. pdca_enable_interrupt_transfer_error(PDCA_CHANNEL_USART); pdca_enable_interrupt_transfer_complete(PDCA_CHANNEL_USART); // Enable the PEVC channel "PDCA CHANNEL 0/1 ONE-ITEM-TRANSFER" PEVC_CHANNELS_ENABLE(ppevc, 1<<PEVC_PDCA_SOT_USER); // Enable the PDCA. pdca_enable(PDCA_CHANNEL_USART); } /** ** AST Init. **/ void init_ast(void) { avr32_ast_pir0_t pir = { .insel = 14 // Set a event every second }; ast_calendar_t ast_calendar; ast_calendar.FIELD.sec = 30; ast_calendar.FIELD.min = 45; ast_calendar.FIELD.hour = 12; ast_calendar.FIELD.day = 7; ast_calendar.FIELD.month= 10; ast_calendar.FIELD.year = 9; scif_osc32_opt_t opt; opt.mode = SCIF_OSC_MODE_2PIN_CRYSTAL; opt.startup = AVR32_SCIF_OSCCTRL32_STARTUP_0_RCOSC; // Start OSC_32KHZ scif_start_osc32(&opt,true); // Initialize the AST if (!ast_init_calendar(&AVR32_AST, AST_OSC_32KHZ, AST_PSEL_32KHZ_1HZ, ast_calendar)) { print_dbg("Error initializing the AST\r\n"); while(1); } ast_set_periodic0_value(&AVR32_AST,pir); ast_enable_periodic0(&AVR32_AST); // Clear All Interrupt AVR32_AST.scr=0xFFFFFFFF; // Enable the AST ast_enable(&AVR32_AST); } /*! \brief Initializes the MCU system clocks. */ static void init_sys_clocks(void) { /*! \name System Clock Frequencies */ //! @{ static pcl_freq_param_t pcl_freq_param = { .cpu_f = FCPU_HZ, .pba_f = FPBA_HZ, .osc0_f = FOSC0, .osc0_startup = OSC0_STARTUP }; //! @} // Configure system clocks. if (pcl_configure_clocks(&pcl_freq_param) != PASS) { while(1); } } /*! \brief This example show a DMA transfer to USART controlled by the AST periodic alarm using the PEVC. */ int main(void) { int i; // Init the string with a simple recognizable pattern. for(i=0;i<sizeof(aDataTransfered);i++) aDataTransfered[i] = '0' + (i%36); init_sys_clocks(); init_usart(); gpio_clr_gpio_pin(LED0_GPIO); init_pevc(); init_ast(); init_pdca(); while(1) { gpio_tgl_gpio_pin(LED1_GPIO); delay_ms(500); //Wait 500ms } }
//! //! @brief This function initializes the hardware/software resources //! required for device CDC task. //! void AK5394A_task_init(void) { // Set up CS4344 // Set up GLCK1 to provide master clock for CS4344 gpio_enable_module_pin(GCLK1, GCLK1_FUNCTION); // for DA_SCLK // LRCK is SCLK / 64 generated by TX_SSC // so SCLK of 6.144Mhz ===> 96khz pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 1, // diven - enabled 0); // divided by 2. Therefore GCLK1 = 6.144Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_enable_osc1_ext_clock(&AVR32_PM); // OSC1 is clocked by 12.288Mhz Osc // from AK5394A Xtal Oscillator pm_enable_clk1(&AVR32_PM, OSC1_STARTUP); // Set up AK5394A gpio_clr_gpio_pin(AK5394_RSTN); // put AK5394A in reset gpio_clr_gpio_pin(AK5394_DFS0); // L L -> 48khz gpio_clr_gpio_pin(AK5394_DFS1); gpio_set_gpio_pin(AK5394_HPFE); // enable HP filter gpio_clr_gpio_pin(AK5394_ZCAL); // use VCOML and VCOMR to cal gpio_set_gpio_pin(AK5394_SMODE1); // SMODE1 = H for Master i2s gpio_set_gpio_pin(AK5394_SMODE2); // SMODE2 = H for Master/Slave i2s gpio_set_gpio_pin(AK5394_RSTN); // start AK5394A while (gpio_get_pin_value(AK5394_CAL)); // wait till CAL goes low // Assign GPIO to SSC. gpio_enable_module(SSC_GPIO_MAP, sizeof(SSC_GPIO_MAP) / sizeof(SSC_GPIO_MAP[0])); gpio_enable_pin_glitch_filter(SSC_RX_CLOCK); gpio_enable_pin_glitch_filter(SSC_RX_DATA); gpio_enable_pin_glitch_filter(SSC_RX_FRAME_SYNC); gpio_enable_pin_glitch_filter(SSC_TX_CLOCK); gpio_enable_pin_glitch_filter(SSC_TX_DATA); gpio_enable_pin_glitch_filter(SSC_TX_FRAME_SYNC); current_freq.frequency = 96000; // set up SSC ssc_i2s_init(ssc, 96000, 24, 32, SSC_I2S_MODE_STEREO_OUT_STEREO_IN, FPBA_HZ); // set up PDCA // In order to avoid long slave handling during undefined length bursts (INCR), the Bus Matrix // provides specific logic in order to re-arbitrate before the end of the INCR transfer. // // HSB Bus Matrix: By default the HSB bus matrix mode is in Undefined length burst type (INCR). // Here we have to put in single access (the undefined length burst is treated as a succession of single // accesses, allowing re-arbitration at each beat of the INCR burst. // Refer to the HSB bus matrix section of the datasheet for more details. // // HSB Bus matrix register MCFG1 is associated with the CPU instruction master interface. AVR32_HMATRIX.mcfg[AVR32_HMATRIX_MASTER_CPU_INSN] = 0x1; audio_buffer_in = 0; spk_buffer_out = 0; // Register PDCA IRQ interrupt. pdca_set_irq(); // Init PDCA channel with the pdca_options. pdca_init_channel(PDCA_CHANNEL_SSC_RX, &PDCA_OPTIONS); // init PDCA channel with options. pdca_enable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_init_channel(PDCA_CHANNEL_SSC_TX, &SPK_PDCA_OPTIONS); // init PDCA channel with options. pdca_enable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_TX); ////////////////////////////////////////////// // Enable now the transfer. pdca_enable(PDCA_CHANNEL_SSC_TX); xTaskCreate(AK5394A_task, configTSK_AK5394A_NAME, configTSK_AK5394A_STACK_SIZE, NULL, configTSK_AK5394A_PRIORITY, NULL); }
/** * \brief Copy pixels from SRAM to the screen * * Used to copy a large quantitative of data to the screen in one go. * * Limits have to be set prior to calling this function, e.g.: * \code * ili9341_set_top_left_limit(0, 0); * ili9341_set_bottom_right_limit(320, 240); * ... * \endcode * * \param pixels Pointer to the pixel data * \param count Number of pixels to copy to the screen */ void ili9341_copy_pixels_to_screen(const ili9341_color_t *pixels, uint32_t count) { const ili9341_color_t *pixel = pixels; /* Sanity check to make sure that the pixel count is not zero */ Assert(count > 0); ili9341_send_command(ILI9341_CMD_MEMORY_WRITE); #if defined(ILI9341_DMA_ENABLED) ili9341_color_t chunk_buf[ILI9341_DMA_CHUNK_SIZE]; uint32_t chunk_len; # if SAM Pdc *SPI_DMA = spi_get_pdc_base(CONF_ILI9341_SPI); pdc_packet_t spi_pdc_data; pdc_enable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); spi_pdc_data.ul_addr = (uint32_t)chunk_buf; # elif UC3 pdca_set_transfer_size(CONF_ILI9341_PDCA_CHANNEL, PDCA_TRANSFER_SIZE_BYTE); pdca_set_peripheral_select(CONF_ILI9341_PDCA_CHANNEL, CONF_ILI9341_PDCA_PID); # endif while (count) { /* We need to copy out the data to send in chunks into RAM, as the PDC * does not allow FLASH->Peripheral transfers */ chunk_len = min(ILI9341_DMA_CHUNK_SIZE, count); /* Wait for pending transfer to complete */ ili9341_wait_for_send_done(); for (uint32_t i = 0; i < chunk_len; i++) { chunk_buf[i] = le16_to_cpu(pixel[i]); } # if SAM spi_pdc_data.ul_size = (uint32_t)sizeof(ili9341_color_t) * chunk_len; pdc_tx_init(SPI_DMA, NULL, &spi_pdc_data); # elif UC3 pdca_reload_channel(CONF_ILI9341_PDCA_CHANNEL, chunk_buf, (uint32_t)sizeof(ili9341_color_t) * chunk_len); pdca_enable(CONF_ILI9341_PDCA_CHANNEL); # endif pixel += chunk_len; count -= chunk_len; } ili9341_wait_for_send_done(); ili9341_deselect_chip(); # if SAM pdc_disable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN); # elif UC3 pdca_disable(CONF_ILI9341_PDCA_CHANNEL); # endif #else while (count--) { ili9341_send_byte(*pixel); ili9341_send_byte(*pixel >> 8); pixel++; } ili9341_wait_for_send_done(); ili9341_deselect_chip(); #endif }
//! //! @brief Entry point of the AK5394A task management //! void AK5394A_task(void *pvParameters) { portTickType xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); int i; while (TRUE) { // All the hardwork is done by the pdca and the interrupt handler. // Just check whether sampling freq is changed, to do rate change etc. vTaskDelayUntil(&xLastWakeTime, configTSK_AK5394A_PERIOD); if (freq_changed){ if (current_freq.frequency == 96000){ pdca_disable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_disable(PDCA_CHANNEL_SSC_RX); gpio_set_gpio_pin(AK5394_DFS0); // L H -> 96khz gpio_clr_gpio_pin(AK5394_DFS1); pm_gc_disable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 1, // diven - enabled 0); // divided by 2. Therefore GCLK1 = 6.144Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); if (Is_usb_full_speed_mode()) FB_rate = 96 << 14; else FB_rate = (96) << 13; } else if (current_freq.frequency == 192000) { pdca_disable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_disable(PDCA_CHANNEL_SSC_RX); gpio_clr_gpio_pin(AK5394_DFS0); // H L -> 192khz gpio_set_gpio_pin(AK5394_DFS1); pm_gc_disable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 0, // diven - disabled 0); // GCLK1 = 12.288Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); if (Is_usb_full_speed_mode()) FB_rate = 192 << 14; else FB_rate = (192) << 13; } else if (current_freq.frequency == 48000) // 48khz { pdca_disable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); pdca_disable(PDCA_CHANNEL_SSC_RX); gpio_clr_gpio_pin(AK5394_DFS0); // L L -> 48khz gpio_clr_gpio_pin(AK5394_DFS1); pm_gc_disable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_GCLK1, // gc 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 1, // diven - enabled 1); // divided by 4. Therefore GCLK1 = 3.072Mhz pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_GCLK1); if (Is_usb_full_speed_mode()) FB_rate = 48 << 14; else FB_rate = (48) << 13; } // re-sync SSC to LRCK // Wait for the next frame synchronization event // to avoid channel inversion. Start with left channel - FS goes low // However, the channels are reversed at 192khz if (current_freq.frequency == 192000) { while (gpio_get_pin_value(AK5394_LRCK)); while (!gpio_get_pin_value(AK5394_LRCK)); // exit when FS goes high } else { while (!gpio_get_pin_value(AK5394_LRCK)); while (gpio_get_pin_value(AK5394_LRCK)); // exit when FS goes low } // Enable now the transfer. pdca_enable(PDCA_CHANNEL_SSC_RX); // Init PDCA channel with the pdca_options. pdca_init_channel(PDCA_CHANNEL_SSC_RX, &PDCA_OPTIONS); // init PDCA channel with options. pdca_enable_interrupt_reload_counter_zero(PDCA_CHANNEL_SSC_RX); // reset freq_changed flag freq_changed = FALSE; } if (usb_alternate_setting_out_changed){ if (usb_alternate_setting_out != 1){ for (i = 0; i < SPK_BUFFER_SIZE; i++){ spk_buffer_0[i] = 0; spk_buffer_1[i] = 0; } }; usb_alternate_setting_out_changed = FALSE; } } }
/** * \brief Test audio data transfer and receive. * * \param test Current test case. */ static void run_iis_test(const struct test_case *test) { uint32_t i; struct iis_config config; struct iis_dev_inst dev_inst; struct genclk_config gencfg; struct pll_config pcfg; /* Set the GCLK according to the sample rate */ genclk_config_defaults(&gencfg, IISC_GCLK_NUM); /* CPUCLK 48M */ pll_config_init(&pcfg, PLL_SRC_OSC0, 2, 96000000 / BOARD_OSC0_HZ); pll_enable(&pcfg, 0); sysclk_set_prescalers(0, 0, 0, 0, 0); pll_wait_for_lock(0); sysclk_set_source(SYSCLK_SRC_PLL0); /* GCLK according fs ratio */ genclk_enable_source(GENCLK_SRC_CLK_CPU); genclk_config_set_source(&gencfg, GENCLK_SRC_CLK_CPU); genclk_config_set_divider(&gencfg, 4); genclk_enable(&gencfg, IISC_GCLK_NUM); /* Set the configuration */ iis_get_config_defaults(&config); config.data_format = IIS_DATE_16BIT_COMPACT; config.slot_length = IIS_SLOT_LENGTH_16BIT; config.fs_ratio = IIS_FS_RATE_256; config.tx_channels = IIS_CHANNEL_STEREO; config.rx_channels = IIS_CHANNEL_STEREO; config.tx_dma = IIS_ONE_DMA_CHANNEL_FOR_BOTH_CHANNELS; config.rx_dma = IIS_ONE_DMA_CHANNEL_FOR_BOTH_CHANNELS; config.loopback = true; iis_init(&dev_inst, IISC, &config); /* Enable the IIS module. */ iis_enable(&dev_inst); /* Config PDCA module */ pdca_enable(PDCA); pdca_channel_set_config(PDCA_IISC_CHANNEL0, &pdca_iisc_config_tx); pdca_channel_set_config(PDCA_IISC_CHANNEL1, &pdca_iisc_config_rx); pdca_channel_write_load(PDCA_IISC_CHANNEL0, (void *)output_samples, SOUND_SAMPLES / 2); pdca_channel_write_load(PDCA_IISC_CHANNEL1, (void *)input_samples, SOUND_SAMPLES / 2); pdca_channel_enable(PDCA_IISC_CHANNEL0); pdca_channel_enable(PDCA_IISC_CHANNEL1); /* Enable the functions */ iis_enable_transmission(&dev_inst); iis_enable_clocks(&dev_inst); /** * Since the transfer and receive timing is not under control, we * need adjust here the enable sequence and add some delay * functions if it's needed. */ delay_us(20); iis_enable_reception(&dev_inst); while (!(pdca_get_channel_status(PDCA_IISC_CHANNEL1) == PDCA_CH_TRANSFER_COMPLETED)) { } /* Disable the PDCA module. */ pdca_channel_disable(PDCA_IISC_CHANNEL0); pdca_channel_disable(PDCA_IISC_CHANNEL1); pdca_disable(PDCA); /* Disable the IISC module. */ iis_disable(&dev_inst); for (i = 0; i < SOUND_SAMPLES; i++) { if (input_samples[i] != output_samples[i]) { flag = false; } } test_assert_true(test, flag == true, "Audio data did not match!"); }
/** * \brief Test ECB mode encryption and decryption with PDCA. * * \param test Current test case. */ static void run_ecb_mode_test_pdca(const struct test_case *test) { /* Change the AES interrupt callback function. */ aes_set_callback(&g_aes_inst, AES_INTERRUPT_INPUT_BUFFER_READY, aes_callback_pdca, 1); /* Enable PDCA module clock */ pdca_enable(PDCA); state = false; /* Configure the AES. */ g_aes_inst.aes_cfg->encrypt_mode = AES_ENCRYPTION; g_aes_inst.aes_cfg->key_size = AES_KEY_SIZE_128; g_aes_inst.aes_cfg->dma_mode = AES_DMA_MODE; g_aes_inst.aes_cfg->opmode = AES_ECB_MODE; g_aes_inst.aes_cfg->cfb_size = AES_CFB_SIZE_128; g_aes_inst.aes_cfg->countermeasure_mask = AES_COUNTERMEASURE_TYPE_ALL; aes_set_config(&g_aes_inst); /* Beginning of a new message. */ aes_set_new_message(&g_aes_inst); /* Set the cryptographic key. */ aes_write_key(&g_aes_inst, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be ciphered to the input data registers. */ /* Init PDCA channel with the pdca_options.*/ PDCA_TX_OPTIONS.addr = (void *)ref_plain_text; /* memory address */ PDCA_TX_OPTIONS.pid = AESA_PDCA_ID_TX; /* select peripheral - AESA TX.*/ PDCA_TX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_TX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_TX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_TX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_TX_CHANNEL, &PDCA_TX_OPTIONS); PDCA_RX_OPTIONS.addr = (void *)output_data; /* memory address */ PDCA_RX_OPTIONS.pid = AESA_PDCA_ID_RX; /* select peripheral - AESA RX.*/ PDCA_RX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_RX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_RX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_RX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_RX_CHANNEL, &PDCA_RX_OPTIONS); /* Enable PDCA channel, start transfer data. */ pdca_channel_enable(PDCA_TX_CHANNEL); /* Wait for the end of the encryption process. */ delay_ms(30); /* Disable PDCA channel. */ pdca_channel_disable(PDCA_RX_CHANNEL); pdca_channel_disable(PDCA_TX_CHANNEL); if ((ref_cipher_text_ecb[0] != output_data[0]) || (ref_cipher_text_ecb[1] != output_data[1]) || (ref_cipher_text_ecb[2] != output_data[2]) || (ref_cipher_text_ecb[3] != output_data[3])) { flag = false; } else { flag = true; } test_assert_true(test, flag == true, "ECB mode encryption not work!"); state = false; /* Configure the AES. */ g_aes_inst.aes_cfg->encrypt_mode = AES_DECRYPTION; g_aes_inst.aes_cfg->key_size = AES_KEY_SIZE_128; g_aes_inst.aes_cfg->dma_mode = AES_DMA_MODE; g_aes_inst.aes_cfg->opmode = AES_ECB_MODE; g_aes_inst.aes_cfg->cfb_size = AES_CFB_SIZE_128; g_aes_inst.aes_cfg->countermeasure_mask = AES_COUNTERMEASURE_TYPE_ALL; aes_set_config(&g_aes_inst); /* Beginning of a new message. */ aes_set_new_message(&g_aes_inst); /* Set the cryptographic key. */ aes_write_key(&g_aes_inst, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be deciphered to the input data registers. */ /* Init PDCA channel with the pdca_options.*/ PDCA_TX_OPTIONS.addr = (void *)ref_cipher_text_ecb; /* memory address */ PDCA_TX_OPTIONS.pid = AESA_PDCA_ID_TX; /* select peripheral - AESA TX.*/ PDCA_TX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_TX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_TX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_TX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_TX_CHANNEL, &PDCA_TX_OPTIONS); PDCA_RX_OPTIONS.addr = (void *)output_data; /* memory address */ PDCA_RX_OPTIONS.pid = AESA_PDCA_ID_RX; /* select peripheral - AESA RX.*/ PDCA_RX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_RX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_RX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_RX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_RX_CHANNEL, &PDCA_RX_OPTIONS); /* Enable PDCA channel, start transfer data. */ pdca_channel_enable(PDCA_TX_CHANNEL); /* Wait for the end of the decryption process. */ delay_ms(30); /* Disable PDCA channel. */ pdca_channel_disable(PDCA_RX_CHANNEL); pdca_channel_disable(PDCA_TX_CHANNEL); /* check the result. */ if ((ref_plain_text[0] != output_data[0]) || (ref_plain_text[1] != output_data[1]) || (ref_plain_text[2] != output_data[2]) || (ref_plain_text[3] != output_data[3])) { flag = false; } else { flag = true; } test_assert_true(test, flag == true, "ECB mode decryption not work!"); /* Disable PDCA module clock */ pdca_disable(PDCA); /* Change back the AES interrupt callback function. */ aes_set_callback(&g_aes_inst, AES_INTERRUPT_INPUT_BUFFER_READY, aes_callback, 1); }
/** * \brief Application entry point for PARC example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t uc_key; /* Initialize the SAM system. */ sysclk_init(); board_init(); /* Configure UART for debug message output. */ configure_console(); parc_port_source_simulation_config(); //! [parc_variables] struct parc_module module_inst; struct parc_config config; //! [parc_variables] /* Output example information. */ puts(STRING_HEADER); /* Configure TC. */ configure_tc(); /* Start timer. */ tc_start(TC0, 0); //! [parc_get_defaults] // Get default configuration parc_get_config_defaults(&config); //! [parc_get_defaults] printf("Press y to sample the data when both data enable pins are enabled.\r\n"); printf("Press n to sample the data, don't care the status of the data enable pins.\r\n"); uc_key = 0; while ((uc_key != 'y') && (uc_key != 'n')) { usart_read(CONF_UART, &uc_key); } if (uc_key == 'y') { /* Sample the data when both data enable pins are enabled. */ config.smode = PARC_SMODE_PCEN1_AND_PCEN2_H; ioport_set_pin_level(PIN_PCEN1_INPUT, IOPORT_PIN_LEVEL_HIGH); ioport_set_pin_level(PIN_PCEN2_INPUT, IOPORT_PIN_LEVEL_HIGH); printf("Receive data when both data enable pins are enabled.\r\n"); } else { /* Sample the data, don't care the status of the data enable pins. */ config.smode = PARC_SMODE_ALWAYS; printf("Receive data, don't care the status of the data enable pins.\r\n"); } printf("Press y to sample all the data.\r\n"); printf("Press n to sample the data only one out of two.\r\n"); uc_key = 0; while ((uc_key != 'y') && (uc_key != 'n')) { usart_read(CONF_UART, &uc_key); } if (uc_key == 'y') { /* Sample all the data. */ config.capture_mode = PARC_BOTH_CAPTURE; printf("All data are sampled.\r\n"); } else { /* Sample the data only one out of two. */ config.capture_mode = PARC_EVEN_CAPTURE; printf("Only one out of two data is sampled, with an even index.\r\n"); } //! [parc_init_enable_and_start] //! [parc_init_enable_and_start_1] // Initialize PARC. parc_init(&module_inst, PARC, &config); //! [parc_init_enable_and_start_1] //! [parc_init_enable_and_start_2] // Enable the PARC parc_enable(&module_inst); // Start capture. parc_start_capture(&module_inst); //! [parc_init_enable_and_start_2] //! [parc_init_enable_and_start] /* Enable PDCA module clock */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PDCA_PARC_CHANNEL, &PDCA_PARC_OPTIONS); /* Set callback for PDCA interrupt. */ pdca_channel_set_callback(PDCA_PARC_CHANNEL, pdca_parc_callback,PDCA_0_IRQn,1,PDCA_IER_RCZ); /* Enable PDCA channel, start receiving data. */ pdca_channel_enable(PDCA_PARC_CHANNEL); /* Start read PARC data capture via PDCA. */ pdca_channel_write_load(PDCA_PARC_CHANNEL, (void *)gs_puc_buffer, BUFFER_SIZE); /* Main loop. */ while(1) { } }
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)); }
/** * \brief Initialize the PDCA transfer for the example. */ static void init_pdca(void) { /* PDCA channel options */ static const pdca_channel_config_t pdca_tx_configs = { .addr = (void *)event_string, .pid = CONF_PDCA_PID_USART_TX, .size = sizeof(event_string), .r_addr = 0, .r_size = 0, .ring = false, .etrig = true, .transfer_size = PDCA_MR_SIZE_BYTE }; /* Enable PDCA module */ pdca_enable(PDCA); /* Init PDCA channel with the pdca_options.*/ pdca_channel_set_config(PEVC_ID_USER_PDCA_0, &pdca_tx_configs); /* Set callback for PDCA channel */ pdca_channel_set_callback(PEVC_ID_USER_PDCA_0, pdca_tranfer_done, PDCA_0_IRQn, 1, PDCA_IER_TRC | PDCA_IER_TERR); /* Enable PDCA channel */ pdca_channel_enable(PEVC_ID_USER_PDCA_0); } /** * \brief Configure serial console. */ static void configure_console(void) { const usart_serial_options_t uart_serial_options = { .baudrate = CONF_UART_BAUDRATE, #ifdef CONF_UART_CHAR_LENGTH .charlength = CONF_UART_CHAR_LENGTH, #endif /* CONF_UART_CHAR_LENGTH */ .paritytype = CONF_UART_PARITY, #ifdef CONF_UART_STOP_BITS .stopbits = CONF_UART_STOP_BITS, #endif /* CONF_UART_STOP_BITS */ }; /* Configure console. */ stdio_serial_init(CONF_UART, &uart_serial_options); } /** * \brief Main entry point for event example. */ int main(void) { /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console uart */ configure_console(); /* Output example information */ printf("\r\n\r\n-- Events example 1 --\r\n"); printf("-- %s\r\n", BOARD_NAME); printf("-- Compiled: %s %s --\r\n", __DATE__, __TIME__); //! [quick_start_init_all_basic_use] /* Initialize AST as event generator. */ //! [quick_start_init_ast_basic_use] init_ast(); //! [quick_start_init_ast_basic_use] /* Initialise events for this example. */ //! [quick_start_init_events_basic_use] init_events(); //! [quick_start_init_events_basic_use] /* Initialize the PDCA as event user */ //! [quick_start_init_pdca_basic_use] init_pdca(); //! [quick_start_init_pdca_basic_use] //! [quick_start_init_all_basic_use] while (1) { /* Toggle LED0 every 500 ms */ LED_Toggle(LED0); delay_ms(500); } }