This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Undocumented I2S ratios

I'm trying to achieve as close as possible to 48KHz (or 24KHz) LRCLK rate, in 24-bit mode (MCK/LRCLK = 48), on an nRF52832. With the values defined in `nrf_i2s_mck_t` the closest I can get is 32DIV15 (44.4 KHz, -7%) or 32DIV30 (22.2 KHz, -7%). However I can get closer if I use `0x12000000` (measured at 47.44 KHz, -1%) or `0x09000000` (measured at 23.74 KHz, -1%). 

Is there any reason to prefer the values in `nrf_i2s_mck_t` over the experimentally-determined rates? The custom values seem to work with my amplifier in practice, I can't hear any obvious issues.

Additionally, are there any better values than the ones I found experimentally? I couldn't find any documentation about how the register value corresponds to a clock frequency, so I was just guessing based on `I2S_CONFIG_MCKFREQ_MCKFREQ` definitions in `nrf52_bitfields.h`.

  • Hi,

     

    The base frequency is 32 MHz, so your wanted mclk must be a integer division of this base clock.

    2 ch * 24 bit * 48 kHz = 2.304 MHz.

    32M / 2.304M = 13.89 (similar scenario if we look at 24 kHz sampling rate)

     

    Rounding to the closest integer of 14.

    32M/14 = 2.2857 MHz

     

    As you have already found out:

    Wrt. the register value of div14, you can look at the definition:

    https://infocenter.nordicsemi.com/topic/ps_nrf52840/i2s.html?cp=4_0_0_5_10_9_13#register.CONFIG.MCKFREQ

     

    div15 = 0x11000000

    so If we write 0x12000000 to this register, we should get ~2.2857 MHz, which seems to be the case when I look at it with a logic analyzer:

      

    Is there any reason to prefer the values in `nrf_i2s_mck_t` over the experimentally-determined rates? The custom values seem to work with my amplifier in practice, I can't hear any obvious issues.

    The list was shortened to the most match the most popular settings, so it should not be an issue to use the register value that you found now. 

     

    Additionally, are there any better values than the ones I found experimentally? I couldn't find any documentation about how the register value corresponds to a clock frequency, so I was just guessing based on `I2S_CONFIG_MCKFREQ_MCKFREQ` definitions in `nrf52_bitfields.h`.

    No, unfortunately. The value must be an integer division of the base clock.

     

    Kind regards,

    Håkon 

  • Thanks for the information, this all makes sense. There's just one bit I'm unclear about

    If we write 0x12000000 to this register, we should get ~2.2857 MHz

    How do you get from the register value (0x12000000) to the corresponding division ratio (14)? I initially thought that the register value was just the division ratio with the bits reversed, but this doesn't seem to be the case?

  • Hi,

     

    This formula will give you a ballpark number, if you change the divider to be 32M instead of 16M:

    https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values/2046#2046

     

    However, since this specific module uses a pure clk division, and not a baudrate generator, it will not be accurate for all frequencies that you input. for instance, the formula does not match specifically for the frequency that you request.

     

    Kind regards,

    Håkon

Related