xmos / xcore_iot

Other
30 stars 40 forks source link

Cannot read I2S stream from CODEC on `explorer-board` demo #634

Closed nrs23 closed 1 month ago

nrs23 commented 2 months ago

System information

Describe the current behavior The Setup Trying to implement reading I2S stream from the onboard CODEC.

Using the documentation, and the standard bare-metal/explorer-board demo (which only implements I2S sending) as a baseline I have made the following changes:

in main.c, initialise i2s_master with the correct port information (set in headers):

        PJOB(i2s_master, (&tile1_ctx->i2s_cb_group, tile1_ctx->p_i2s_dout, 1, tile1_ctx->p_i2s_din, 1, tile1_ctx->p_bclk, tile1_ctx->p_lrclk, tile1_ctx->p_mclk, tile1_ctx->bclk)),

in platform_init_tile1.c, provide a callback function for receiving an I2S frame:

I2S_CALLBACK_ATTR
static void i2s_receive(chanend_t *input_c, size_t num_in, const int32_t *i2s_sample_buf)
{
    s_chan_out_buf_word(*input_c, (uint32_t*)i2s_sample_buf, appconfFRAMES_IN_ALL_CHANS);
}

in audio_pipeline.c and again in main.c, modify the pipeline stages to receive from the opposite end of the i2s_receive callback channel, and pass that straight back into the the i2s_send callback via the other end of the channel. Also disabled the pdm mics (because initially I thought they were causing a problem but it's more like they weren't and it was this bug).

The Behaviour On starting the application, the BCLK and LRCK do not start (checked with oscilloscope). This means that the CODEC sends no data, and therefore the receive callback never fires, and we do not attempt to send data.

I have checked the CODEC and I2S stream is being properly initialised by running the standard bare-metal/explorer-board demo and checking the I2S in/out and clock pins with signal analyser.

Using this knowledge I tried sending a single 'empty frame' of data on initialising the application. It seems like this succeeds in starting up the CODEC, as the empty frame seems to transfer over succesfully, and the CODEC subsequently also sends an I2S frame to the XMOS, firing off the receive callback.

However as soon as I try to read from the i2s_sample_buf (to send it to the chanend), or shortly thereafter, this process hangs indefinitely and no more data is either sent or received. There are no errors to indicate what is wrong, and it seems like the LRCLK and BCLK have also stopped again by this time.

For the sake of completeness, I have also tried sending separate chanends to the send/receive callbacks, in case I was misunderstanding the bi-directionality of streaming_channel_t, but got the exact same result.

Describe the expected behavior If I have the I2S setup correctly, I expect to receive I2s without freeze-ups.

Other comments Could demo code for the bare-metal/explorer-board be provided?

nrs23 commented 2 months ago

commit 74daaef on the develop branch

nrs23 commented 2 months ago

Sorry I forgot an important note (this is essentially what the bug boils down to): If I do everything in the setup section above but don't try to read from the CODEC, i.e. simply remove the following line from the receiving callback:

s_chan_out_buf_word(*input_c, (uint32_t*)i2s_sample_buf, appconfFRAMES_IN_ALL_CHANS);

Then the LRCLK, BCLK both seem to come up and stay up, and using the oscope it's possible to see that the CODEC is still sending I2S data to the XMOS on the ADC_DAT line.

So it seems clear that this is an issue/bug with reading the data frame when it is received.

xhuw commented 1 month ago

continued here: https://www.xcore.com/viewtopic.php?p=41331#p41331

nrs23 commented 1 month ago

This has been resolved/progressed into a different issue via the discussion in the link above. Closing.