Hello,
I will use the I2S driver instead the direct acess to the registers.
I have implemented the registers version like this and it works / sounds normaly.
main()
{
// Enable transmission
NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos);
// Enable MCK generator
NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos);
// MCKFREQ
NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
// Ratio = 96
NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_32X << I2S_CONFIG_RATIO_RATIO_Pos; //64
// Master mode, 16Bit, 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;
// Format = I2S
NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S << I2S_CONFIG_FORMAT_FORMAT_Pos;
// Use stereo
//NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_STEREO << I2S_CONFIG_CHANNELS_CHANNELS_Pos;
NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_Left << I2S_CONFIG_CHANNELS_CHANNELS_Pos;
// Configure pins
NRF_I2S->PSEL.MCK = (I2S_CONFIG_MCK_PIN << I2S_PSEL_MCK_PIN_Pos);
NRF_I2S->PSEL.SCK = (I2S_CONFIG_SCK_PIN << I2S_PSEL_SCK_PIN_Pos);
NRF_I2S->PSEL.LRCK = (I2S_CONFIG_LRCK_PIN << I2S_PSEL_LRCK_PIN_Pos);
NRF_I2S->PSEL.SDOUT = (I2S_SDOUT_PIN << I2S_PSEL_SDOUT_PIN_Pos);
NRF_I2S->ENABLE = 1;
while(1)
{
....
if(NRF_I2S->EVENTS_TXPTRUPD != 0)
{
NRF_I2S->TXD.PTR = (uint32_t)OpusInstanz.pcm_bytes[bufferNr];
NRF_I2S->EVENTS_TXPTRUPD = 0;
newFrame = 1;
bufferNr ^= (1 << 0);
}
....
now I have modified the code to the driver code but the output sound is slower than the original. Its like the handler is too slow.
static void i2sdata_handler(nrf_drv_i2s_buffers_t const * p_released, uint32_t status)
{
ASSERT(p_released);
if (!(status & NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED))
return;
nrf_drv_i2s_buffers_t const next_buffers = {
.p_rx_buffer = NULL,
.p_tx_buffer = (uint32_t *)OpusInstanz.pcm_bytes[bufferNr],
};
APP_ERROR_CHECK(nrf_drv_i2s_next_buffers_set(&next_buffers));
newFrame = 1;
bufferNr ^= (1 << 0);
}
main()
{
....
nrf_drv_i2s_config_t config = NRF_DRV_I2S_DEFAULT_CONFIG;
config.mck_setup = NRF_I2S_MCK_32MDIV21;
config.ratio = NRF_I2S_RATIO_32X;
err = nrf_drv_i2s_init(&config, i2sdata_handler);
APP_ERROR_CHECK(err);
...
nrf_drv_i2s_buffers_t const initial_buffers = {
.p_tx_buffer = (uint32_t *)OpusInstanz.pcm_bytes[bufferNr],
.p_rx_buffer = NULL,
};
APP_ERROR_CHECK(nrf_drv_i2s_start(&initial_buffers, FRAME_SIZE/2, 0));
So I had checked the config but I can not find a mistake. I have watched the registers and they were the same in both variants.
Is there another mistake?