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.