Technical Inquiry About Configuring I2S MCLK

Dear Nordic Semiconductor Team,

Hello! I have been exploring your I2S sample code, specifically the example located at “C:\ncs\v2.4.2\zephyr\samples\drivers\i2s\echo”. While I have gained a good understanding of most parts, I am encountering some difficulties in configuring the MCLK (Master Clock) for I2S.

I noticed that the sample code does not seem to explicitly mention how to configure the MCLK output. Given the importance of the MCLK in the overall I2S communication, I am seeking specific guidance on how to correctly set up the MCLK.

It would be greatly helpful if you could provide relevant code examples or configuration instructions for this. Thank you for your support and assistance. I look forward to your response.

Best regards, [Your Name] [Your Contact Information, such as email, phone number, etc.]

Parents
  • Hi

    For the best understanding of the I2S peripheral in the nRF52840 I would recommend starting by reading the I2S chapter in the nRF52840 product specification, here.

    When using the Zephyr driver the I2S registers will be set indirectly depending on the configuration you set in the i2s_config struct, such as the word_size, channels and frame_clk_freq fields. 

    Given the importance of the MCLK in the overall I2S communication, I am seeking specific guidance on how to correctly set up the MCLK.

    This question is a bit open. What kind of audio settings do you require, and do you need to connect to any particular I2S device? 

    Otherwise it is hard to say what would be the correct I2S configuration. 

    Best regards
    Torbjørn

  • Thank you for your answer, and I'm very sorry that I didn't surface my development platform, I'm using the nRF5340 for development. Through the nRF5340 + CS47L35 architecture. I originally used the i2s driver from nrfx_i2s.h to accomplish this, where the nRF5340 acts as the master device MCLK sending a synchronization frequency of 12.288MHz.
    Recently I found out that the new sdk version has the extra demo i2s_echo, which is an i2s driver implemented through the device tree and zephyr api, using want to know if there is a way to configure the MCLK to output a synchronization frequency of 12.288MHz;

  • Hi

    Thanks for the clarification. For some reason the nRF52840 tag was set in your case, which is why I assumed you were using this device. 

    One tip in order to get more information about the I2S settings used is to enable logging for the nrfx_i2s driver, by adding the following lines to the prj.conf file:

    CONFIG_LOG=y
    CONFIG_NRFX_I2S_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=4

    Then you can see which MCK frequency gets configured by the driver. 

    A MCK frequency of 12.288MHz sounds quite high. Does your settings match any of the examples in the documentation

    Could you let me know which other settings you are planning to use, such as the LRCK and RATIO settings? 

    Best regards
    Torbjørn

Reply
  • Hi

    Thanks for the clarification. For some reason the nRF52840 tag was set in your case, which is why I assumed you were using this device. 

    One tip in order to get more information about the I2S settings used is to enable logging for the nrfx_i2s driver, by adding the following lines to the prj.conf file:

    CONFIG_LOG=y
    CONFIG_NRFX_I2S_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=4

    Then you can see which MCK frequency gets configured by the driver. 

    A MCK frequency of 12.288MHz sounds quite high. Does your settings match any of the examples in the documentation

    Could you let me know which other settings you are planning to use, such as the LRCK and RATIO settings? 

    Best regards
    Torbjørn

Children
  • Thank you for your patience!

    Here are the details about my project;

    I am using nrf7002dk and the dts file used is nrf7002dk_nrf5340_cpuapp

    The target state I need to configure is:
    Sample rate 48KHz
    Bit width 24bi

    These are the parameters I initialized with nrfx_i2s_init:

            nrfx_i2s_config_t config;
        
    
            config.sck_pin        = AIF1BCLK;
            config.lrck_pin       = AIF1LRCLK;
            config.mck_pin        = AIF1MCLK;
            config.sdout_pin      = AIF1RXDAT;
            config.sdin_pin       = AIF1TXDAT;
            
            config.irq_priority   = 2;
            config.mode           = NRF_I2S_MODE_MASTER;
            config.format         = NRF_I2S_FORMAT_I2S;
            config.alignment      = I2S_CONFIG_ALIGN_ALIGN_Left;
    
            config.sample_width   = NRF_I2S_SWIDTH_16BIT;
    
            config.channels       = NRF_I2S_CHANNELS_STEREO;
            config.mck_setup      = NRF_I2S_MCK_32MDIV2;
            config.ratio          = NRF_I2S_RATIO_256X;
            config.clksrc         = I2S_CONFIG_CLKCONFIG_CLKSRC_ACLK;
            config.enable_bypass  = true;
    
            NRF_CLOCK->TASKS_HFCLKSTART = 1;
            while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
            NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    
            NRF_CLOCK->TASKS_HFCLKAUDIOSTART = 1;
            while (NRF_CLOCK->EVENTS_HFCLKAUDIOSTARTED == 0);
            NRF_CLOCK->EVENTS_HFCLKAUDIOSTARTED = 0;
    
            // dac_power_on();
    
            nrfx_i2s_uninit();
    
            if ( nrfx_i2s_init(&config, custom_i2s_irq_handler) == NRFX_SUCCESS )
            {
                LOG_INF("IIS INIT SUCCESSED\r\n");
            }

    Output in this configuration
    MCLK 12.288MHz
    BCLK 1.537MHz
    LRCK 48KHz

    I was hoping to achieve the same result with the device tree configuration;

    Here is my current configuration:

    in my prj.conf:

    CONFIG_LOG=y
    CONFIG_I2S=y
    

    Contents of my overlay file:

    &i2s0 {
        clock-source = "ACLK";
        status = "okay";
        pinctrl-0 = <&i2s0_default>;
        pinctrl-names = "default";
    };
    
    &clock {
        hfclkaudio-frequency = <12288000>;
    };
    &pinctrl {
        i2s0_default: i2s0_default {
            group1 {
                psels = <NRF_PSEL(I2S_SCK_M, 0, 4)>,
                        <NRF_PSEL(I2S_LRCK_M, 0, 5)>,
                        <NRF_PSEL(I2S_SDIN, 0, 6)>,
                        <NRF_PSEL(I2S_MCK, 0, 7)>;
            };
        };
    };
    

    This is my i2s initialization parameters:

        
    #define SAMPLE_FREQUENCY    48000
    #define SAMPLE_BIT_WIDTH    32
    #define BYTES_PER_SAMPLE    sizeof(int16_t)
    #define NUMBER_OF_CHANNELS  2
    /* Such block length provides an echo with the delay of 100 ms. */
    #define SAMPLES_PER_BLOCK   ((SAMPLE_FREQUENCY / 10) * NUMBER_OF_CHANNELS)
    #define INITIAL_BLOCKS      2
    #define TIMEOUT             1000
    
    if (!device_is_ready(i2s_dev)) {
    LOG_INF("%s is not ready\n", i2s_dev->name);
    return 0;
    }
    else
    {
    	LOG_INF("%s is ready\n", i2s_dev->name);
    }
    
    struct i2s_config config;
    config.word_size = SAMPLE_BIT_WIDTH;
    config.channels = NUMBER_OF_CHANNELS;
    config.format = I2S_FMT_DATA_FORMAT_I2S;
    config.options = I2S_OPT_BIT_CLK_MASTER |
    				 I2S_OPT_FRAME_CLK_MASTER;
    config.frame_clk_freq = SAMPLE_FREQUENCY;
    config.mem_slab = &mem_slab;
    config.block_size = BLOCK_SIZE;
    config.timeout = TIMEOUT;
    
    if (!configure_streams(i2s_dev, i2s_dev, &config))
    {
    	LOG_INF("Failed to configure streams\n");
    	return 0;
    }
    else
    {
    	LOG_INF("configure streams success\n");
    }

    I can see the frequency of my current configuration mclk output by the contents of the log:

    *** Booting Zephyr OS build v3.3.99-ncs1-1 ***
    [00:00:00.251,342] <inf> i2s: This is i2s demo
    [00:00:00.251,373] <inf> i2s: i2s@28000 is ready
    
    [00:00:00.251,403] <inf> i2s_nrfx: I2S MCK frequency: 3072000, actual PCM rate: 48000
    [00:00:00.251,403] <inf> i2s: configure streams success
    
    [00:00:00.255,035] <inf> i2s: Streams started

    Meanwhile I observed the status of the i2s registers via debug mode
    CLKSRC in NRF_I2S0->CONFIG.CLKCONFIG has been configured to ACLK, but BYPASS is Disable

    Maybe I want to configure the mclk to 12.288MHz output, I need to solve the problem that aclk is not paired configured as bypass, also please help me to see where I am having problems, thanks for your patience!

  • Hi 

    I don't think setting SAMPLE_BIT_WIDTH to 32 is correct. Looking at your old code it seems you are using 16-bits pr sample, and stereo, meaning you have 32 bits for both channels but not 32 bit pr sample? 

    Also, why do you want to enable bypass? 
    Are you not the I2S master?

    Best regards
    Torbjørn

  • Hi, I confirmed that the configuration of the bit width is indeed incorrect; I wanted to be able to configure it as a 24bit bit width, and the original code should have NRF_I2S_SWIDTH_24BIT_IN32BIT; so I put SAMPLE_BIT_WIDTH = 32 in the code behind;

    Again, sorry for misleading you with another mistake!

    Also, regarding the bypass issue, my considerations are located in the nRF5340 datasheet's FIGURE 63, where the figure shows that turning on config.bypass,allows to connect the pesl.mck directly to the clock source, i.e., hfclk or aclk; in PAGE 265, 7.15.10.27 CONFIG. CLKCONFIG description also says that when bypass is enabled, MCK will be equal to source input.

    I just accidentally clicked on the "Verify Answer" button, but my mclk output problem is still not solved, I hope to continue to get your help!

  • Hi 

    Thanks for the clarification.

    Looking at your various requirements, including the NRF_I2S_SWIDTH_24BIT_IN32BIT bit mode, I don't think you will be able to replicate these settings successfully using the Zephyr I2S driver. 

    The Zephyr driver is quite generic since it is made to support a wide range of hardware devices, and doesn't expose all the functionality of the I2S peripheral in the nRF devices. 

    In your case I believe you are better of using the nrfx_i2s driver directly, skipping the standard Zephyr driver. We also do this in the LE Audio application because the standard driver doesn't provide enough control over the hardware. 

    Best regards
    Torbjørn

  • Thank you so much for your patience and detailed response, it was very helpful!

Related