Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I2S issue - last sample in memory always replaced with 0x0001

I'm using the nRF52 DK and attempting to use I2S to send data to a DAC. I'm using the nRF5 SDK, version 17.0.2. The last sample in the data I'm sending is always replaced with 0x0001. I've set up a simple example where the audio data I'm sending is only 4 16-bit samples, but I've seen the same thing in all my tests.

Here's the data I'm trying to send:

static int16_t audio_data[4] = {
    0,
    10,
    0,
    -10
};

And here's my I2S initalization:

// Enable transmission
NRF_I2S->CONFIG.TXEN = I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos;

// Enable MCK generator, set MCK to 1 MHz
NRF_I2S->CONFIG.MCKEN = I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos;
NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV32  << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;

// Set MCK/LRCK ratio to 64
NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_64X << I2S_CONFIG_RATIO_RATIO_Pos;

// Master mode, 16-bit, left-aligned
NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos;
NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_LEFT << I2S_CONFIG_ALIGN_ALIGN_Pos;

// I2S format
NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S << I2S_CONFIG_FORMAT_FORMAT_Pos;

// Left channel only
//NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_LEFT << I2S_CONFIG_CHANNELS_CHANNELS_Pos;
NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_STEREO << I2S_CONFIG_CHANNELS_CHANNELS_Pos;

// Configure pins
NRF_I2S->PSEL.MCK = PIN_MCK << I2S_PSEL_MCK_PIN_Pos;
NRF_I2S->PSEL.SCK = PIN_SCK << I2S_PSEL_SCK_PIN_Pos;
NRF_I2S->PSEL.LRCK = PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos;
NRF_I2S->PSEL.SDOUT = PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos;

NRF_I2S->ENABLE = 1;

NRF_I2S->TXD.PTR = (uint32_t)&audio_data[0];
NRF_I2S->RXTXD.MAXCNT = sizeof(audio_data) / sizeof(uint32_t);
NRF_LOG_INFO("TXDPTR: %ul", NRF_I2S->TXD.PTR);

NRF_I2S->TASKS_START = 1;

When I run the code and look at the location of NRF_I2S->TXD.PTR in memory, I see the 4 samples as expected (0x0000, 0x000A, 0x0000, 0xF6FF):

But when the data is actually being transmitted, the last sample (-10 or 0xF6FF in this case) is always replaced with 1 (see logic analyzer capture).

I see the same thing when I used different sized arrays for the audio data, as well as when I use a single channel instead of stereo. Some help would be much appreciated.

  • Hi,

    Sigurd is currently out on vacation and will not be back before August 2nd. Are you still having issues with this? We are a bit short on staffing at the moment so responses can be slow.

    tmurias said:
    I'm not clear on how zero padding would solve this issue. I wouldn't want extra zeros in the actual data, and having padding between periods of the waveform would mess with the timing given that this is sound data used to drive an audio DAC.

    From what Sigurd wrote in his last post I would guess that zero-padding will help if you are sending packets with different lengths. Have you tried to run the I2S example on the nRF5 SDK with any luck?

    Best regards,

    Marjeris

  • Hi Marjeris,

    I have run the I2S example from the nRF5 SDK and that seems to work fine. But that's a little different from what I'm trying to do because it sends one-shot transfers instead of looping. I run into issues when I point the I2S module to my waveform data and let it repeat, that's when the last sample is being replaced with 1. I've tried using the SDK functions from the example as well, but I see the same issue.

    Taylor

Related