nrf54L Series I2S MCLK divider?

Hi ... have code that outputs I2S in master mode.    The slave, a NAU8822 device requires Master Clock Source between 8 and 33MHz.

The 54L MCLK pin is duplicating the BCLK frequency, currently 1,2MHz odd.    Datasheet for 54L Series, page 324 says ..

Example:  NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_256X << I2S_CONFIG_RATIO_RATIO_Pos;      

The issue however is that the SDK uses a i2c_config struct for setting up the I2S.   No option exists to set the divide ratio.   

No examples or test example code seem to show a solution for this.  

Can you please assist in how I can set the divide ratio for the MCLK.

Thank you

Brian 

  

Parents
  • Hi Brian,

    I think you are using the Zephyr I2S driver together and the i2s_config struct, rather than i2c, right?

    The Zephyr I2S driver is several layers of abstraction higher than the registers you are referring from the datasheet. With the Zephyr I2S driver, you will care about the two fields of the i2s_config struct:

    frame_clk_freq

    word_size

    You just need to configure those fields to the appropriate values for your I2S device, and the driver will calculate and configure the ratio under the hood.

    For reference, the function that does the conversion is: sdk-zephyr/drivers/i2s/i2s_nrfx.c at v4.0.99-ncs1-1 · nrfconnect/sdk-zephyr.

    Hieu

  • Hi Hieu

    Firstly, the 'i2c' referenced in my question is a typo .. indeed it was meant to be i2s.
    Your response does not answer my question I'm afraid. Let me explain ..

    So my code has the following bit of code .. straight from Nordic Zephyr example. Those that exist all seem to follow the exact same setup.

    /* Configure I2S stream */
    i2s_cfg.word_size = 16U;
    i2s_cfg.channels = 2U;
    i2s_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
    i2s_cfg.frame_clk_freq = 44100;
    i2s_cfg.block_size = BLOCK_SIZE;
    i2s_cfg.timeout = 2000;

    This code produces an approx. 44100Hz LR Clock a expected. The word size being 16 bits results in a clock of approx. 1,38MHz.  
    All as expected. But Master Clock pin output still the same frequency as the bit clock pin output.

    Regards the response pointing out 'word_size" and "frame_clk_freq"
    The WORD Size referenced is 16 bits and frame is 44,1KHz. These variables produce correct bit pattern output.

    Your response - "You just need to configure those fields to the appropriate values for your I2S device, and the driver will calculate and configure the ratio under the hood"

    Well no .. not for Master Clock. I need a multiple of the 1,38MHz clocked out of the MASTER CLOCK pin. This is what the Master Clock pin is for.   What am I missing?

    Thank you

    Brian 

  • Hi Brian,

    My apology. I was optimistic with the driver's capability. While it indeed automatically calculates an I2S configuration based on the i2s_config struct, it doesn't take into account restriction such as the NAU8822's MCK requirement.

    I am not certain yet whether I should file an internal ticket about this limitation. It originates from the design of the Zephyr driver, which doesn't take in MCK frequency as an input at all. There is little we can do about that, as changing Zephyr APIs affect all chip vendors, thus isn't something we from Nordic can just unilaterally do.

    To proceed, we have two options, which unfortunately both require some level of effort. 

    1. Use the nrfx driver instead to work with I2S.
    I don't have anything to add for option 1. Unfortunately, there isn't a sample, beyond the implementation of the Zephyr I2S driver itself.

    2. Hack the Zephyr I2S driver a little.
    Considering what I have investigated, this is likely feasible and simpler than option 1.
    However, please keep in mind that this is nonetheless modifying existing design, and there can be unexpected consequences. 

    For this option, we need to look into the current implementation.

    The configuration isn't set to the peripheral with the i2s_configure() function. That function only stores the configuration in a structure in the driver. This stored configuration is then set to the peripheral every time i2s_trigger() is called.

    Therefore, we need to add a new API to override only the clock related fields of the stored configurations. Here are a few points to note:

    My apologies, but I am unable to think of any easier approach.

    Hieu

  • Thank you for the detailed response Hieu.    I will need to look into the details you have mentioned.    Will do so when I have time for this.  The project will need to do without i2s for now unfortunately.    Thank you once again.

Reply Children
Related