Hi engineers,
I want to implement function that input i2s data and then output it directly.
I find that i2s demo includes two buffers which are used for current buffer and the next buffer. This part I don't understand.
static void data_handler(nrf_drv_i2s_buffers_t const * p_released,
uint32_t status)
{
// 'nrf_drv_i2s_next_buffers_set' is called directly from the handler
// each time next buffers are requested, so data corruption is not
// expected.
ASSERT(p_released);
// When the handler is called after the transfer has been stopped
// (no next buffers are needed, only the used buffers are to be
// released), there is nothing to do.
if (!(status & NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED))
{
return;
}
// First call of this handler occurs right after the transfer is started.
// No data has been transferred yet at this point, so there is nothing to
// check. Only the buffers for the next part of the transfer should be
// provided.
if (!p_released->p_rx_buffer)
{
nrf_drv_i2s_buffers_t const next_buffers = {
.p_rx_buffer = m_buffer_rx[1],
.p_tx_buffer = m_buffer_tx[1],
};
APP_ERROR_CHECK(nrf_drv_i2s_next_buffers_set(&next_buffers));
mp_block_to_fill = m_buffer_tx[1];
}
else
{
mp_block_to_check = p_released->p_rx_buffer;
// The driver has just finished accessing the buffers pointed by
// 'p_released'. They can be used for the next part of the transfer
// that will be scheduled now.
APP_ERROR_CHECK(nrf_drv_i2s_next_buffers_set(p_released));
// The pointer needs to be typecasted here, so that it is possible to
// modify the content it is pointing to (it is marked in the structure
// as pointing to constant data because the driver is not supposed to
// modify the provided data).
mp_block_to_fill = (uint32_t *)p_released->p_tx_buffer;
}
}
And in the main function, if I want to loopback, it means that I need to transfer data what I receive. Confusing.. Please help~
void main(void)
{
uint32_t err_code = NRF_SUCCESS;
for (;;)
{
m_blocks_transferred = 0;
mp_block_to_fill = NULL;
mp_block_to_check = NULL;
prepare_tx_data(m_buffer_tx[0]);
nrf_drv_i2s_buffers_t const initial_buffers = {
.p_tx_buffer = m_buffer_tx[0],
.p_rx_buffer = m_buffer_rx[0],
};
err_code = nrf_drv_i2s_start(&initial_buffers, I2S_DATA_BLOCK_WORDS, 0);
APP_ERROR_CHECK(err_code);
do {
// Wait for an event.
__WFE();
// Clear the event register.
__SEV();
__WFE();
if (mp_block_to_fill)
{
prepare_tx_data(mp_block_to_fill);
mp_block_to_fill = NULL;
}
if (mp_block_to_check)
{
check_rx_data(mp_block_to_check);
mp_block_to_check = NULL;
}
} while (m_blocks_transferred < BLOCKS_TO_TRANSFER);
nrf_drv_i2s_stop();
NRF_LOG_FLUSH();
bsp_board_leds_off();
nrf_delay_ms(PAUSE_TIME);
}
}
Best Wishes,
Sean