/** * \brief The AES interrupt call back function. */ static void aes_callback_pdca(void) { /* Read the output(this will clear the DATRDY flag) by PDCA. */ pdca_channel_enable(PDCA_RX_CHANNEL); while (pdca_get_channel_status(PDCA_RX_CHANNEL) != PDCA_CH_TRANSFER_COMPLETED) { } state = true; }
/** * \internal * \brief Common PDCA channel interrupt handler * * Calls the channel callback with the channel status code. The following * status codes are possible: * - DMA_CH_TRANSFER_COMPLETED: Transfer completed successfully * - DMA_CH_TRANSFER_ERROR: Fault in transfer * * The optional callback used by the interrupt handler is set by the * pdca_channel_set_callback() function. * * \param pdca_ch_number PDCA channel number to handle interrupt for */ static void pdca_channel_interrupt(const pdca_channel_num_t pdca_ch_number) { enum pdca_channel_status status; status = pdca_get_channel_status(pdca_ch_number); if (pdca_callback_pointer[pdca_ch_number]) { pdca_callback_pointer[pdca_ch_number] (status); } else { Assert(false); /* Catch unexpected interrupt */ } }
/** * \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 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) { } }