Exemplo n.º 1
0
static inline void stop_i2s_playback(struct snd_soc_dai *cpu_dai)
{
	i2s_set_fifo_irq_on_err(cpu_dai->id, I2S_FIFO_TX, 0);
	i2s_set_fifo_irq_on_qe(cpu_dai->id, I2S_FIFO_TX, 0);
	i2s_fifo_enable(cpu_dai->id, I2S_FIFO_TX, 0);
	while (i2s_get_status(cpu_dai->id) & I2S_I2S_FIFO_TX_BUSY);
}
Exemplo n.º 2
0
/**
 * \brief Internal interrupt handler for I2S.
 */
static void i2s_interrupt_handler(I2sc *i2sc)
{
	uint32_t row_num;
	struct i2s_dev_inst i2s_instance;

	i2s_instance.hw_dev = i2sc;

	uint32_t status = i2s_get_status(&i2s_instance);
	uint32_t mask = i2s_get_interrupt_mask(&i2s_instance);

#if defined(ID_I2SC1)
	if (i2sc == I2SC1) {
		row_num = 1;
	}
#endif
	
#if defined(ID_I2SC0)
	if (i2sc == I2SC0) {
		row_num = 0;
	}
#endif

	if ((status & I2SC_SR_RXRDY) && (mask & I2SC_IMR_RXRDY)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_RXRDY]();
	}

	if ((status & I2SC_SR_RXOR) && (mask & I2SC_IMR_RXOR)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_RXOR]();
	}

	if ((status & I2SC_SR_TXRDY) && (mask & I2SC_IMR_TXRDY)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_TXRDY]();
	}

	if ((status & I2SC_SR_TXUR) && (mask & I2SC_IMR_TXUR)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_TXUR]();
	}

	if ((status & I2SC_SR_RXRDY) && (mask & I2SC_IMR_ENDRX)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_ENDRX]();
	}

	if ((status & I2SC_SR_RXOR) && (mask & I2SC_IMR_ENDTX)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_ENDTX]();
	}

	if ((status & I2SC_SR_TXRDY) && (mask & I2SC_IMR_RXFULL)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_RXBUFF]();
	}

	if ((status & I2SC_SR_TXUR) && (mask & I2SC_IMR_TXEMPTY)) {
		i2s_callback_pointer[row_num][I2S_INTERRUPT_TXBUFE]();
	}

}
Exemplo n.º 3
0
/**
 * \brief Test audio data transfer and receive.
 *
 * \param test Current test case.
 */
static void run_i2s_test(const struct test_case *test)
{
	uint32_t i;
	struct i2s_config config;
	struct i2s_dev_inst dev_inst;
	Pdc *p_i2sc_pdc;
	Pdc *p_i2sc_pdc2;
	pdc_packet_t pdc_i2sc_packet_tx, pdc_i2sc_packet_rx;
	pdc_packet_t pdc2_i2sc_packet_tx, pdc2_i2sc_packet_rx;

	/* Set the configuration */
	i2s_get_config_defaults(&config);
	config.data_format = I2S_DATE_16BIT;
	config.fs_ratio = I2S_FS_RATE_256;
	config.loopback = true;
	i2s_init(&dev_inst, I2SC0, &config);

	/* Enable the I2SC module. */
	i2s_enable(&dev_inst);

	/* Get pointer to I2SC PDC register base */
	p_i2sc_pdc = i2s_get_pdc_base(&dev_inst);
	p_i2sc_pdc2 = (Pdc *)((uint32_t)p_i2sc_pdc + 0x100U);
	/* Initialize PDC data packet for transfer */
	pdc_i2sc_packet_tx.ul_addr = (uint32_t) output_samples_left;
	pdc_i2sc_packet_tx.ul_size = SOUND_SAMPLES;
	pdc_i2sc_packet_rx.ul_addr = (uint32_t) input_samples_left;
	pdc_i2sc_packet_rx.ul_size = SOUND_SAMPLES;
	pdc2_i2sc_packet_tx.ul_addr = (uint32_t) output_samples_right;
	pdc2_i2sc_packet_tx.ul_size = SOUND_SAMPLES;
	pdc2_i2sc_packet_rx.ul_addr = (uint32_t) input_samples_right;
	pdc2_i2sc_packet_rx.ul_size = SOUND_SAMPLES;
	/* Configure PDC for data transfer */
	pdc_tx_init(p_i2sc_pdc, &pdc_i2sc_packet_tx, NULL);
	pdc_rx_init(p_i2sc_pdc, &pdc_i2sc_packet_rx, NULL);
	pdc_tx_init(p_i2sc_pdc2, &pdc2_i2sc_packet_tx, NULL);
	pdc_rx_init(p_i2sc_pdc2, &pdc2_i2sc_packet_rx, NULL);
	/* Enable PDC transfers */
	pdc_enable_transfer(p_i2sc_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);
	pdc_enable_transfer(p_i2sc_pdc2, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);

	/* Enable the functions */
	i2s_enable_transmission(&dev_inst);
	i2s_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.
	 */
	for (i = 0; i < 0x8; i++) {
		input_samples_left[i] = i;
	}

	i2s_enable_reception(&dev_inst);

	/* Wait transfer complete */
	while (!(i2s_get_status(&dev_inst) & I2SC_SR_RXBUFF)) {
	}

	/**
	 * Wait a moment to let the PDC finish. The status bit is cleared
	 * before all transfer finish.
	 */
	delay_us(10);

	/* Disable the PDC module. */
	pdc_disable_transfer(p_i2sc_pdc, PERIPH_PTCR_RXTDIS| PERIPH_PTCR_TXTDIS);
	pdc_disable_transfer(p_i2sc_pdc2, PERIPH_PTCR_RXTDIS| PERIPH_PTCR_TXTDIS);

	/* Disable the I2SC module. */
	i2s_disable(&dev_inst);

	/* Compare the data. */
	for (i = 0; i < SOUND_SAMPLES; i++) {
		if ((input_samples_left[i] != output_samples_left[i]) ||
			(input_samples_right[i] != output_samples_right[i])) {
			flag = false;
		}
	}

	test_assert_true(test, flag == true, "Audio data did not match!");
}