I2C clock stretching nRF54L / Zephyr

This is nRF54L10 with Zephyr, SDK & toolchain both v3.02 on a custom board.

I am investigating I2C crashing on the 54L10. This happens during writing data to a MAX41462 radio IC via 12c, this involves writing a packet of 25 bytes @10kbps. I am sending a burst of 5 packets at 100ms spacing, repeated every second as a test.

The transmit routine runs in a work queue. I use the following code to write:

rc = i2c_reg_write_byte(i2c_dev, I2C_ADDR,REG_ADDR, data);

The MAX41462 has a 4 byte FIFO buffer and implements flow control by I2C clock stretching which seems to be causing the crash - using a logic analyser I can see the clock signal being held low after 8 bits of data transfer. So are there any tricks techniques or tweaks or caveats when using I2C clock stretching peripherals?

(Note I do realise that my problem could lie with the peripheral IC latching, but I need to understand how nRF/Zephyr handles things to get a holistic view of the situation)

Incidentally the MAX41462 requires SDA to be toggled after power up. Is it OK to configure the line as a GPIO output and toggle before running i2c_configure() ?

Parents
  • Hello,

    ''I am investigating I2C crashing on the 54L10. This happens during writing data to a MAX41462 radio IC via 12c, this involves writing a packet of 25 bytes @10kbps.''

    The supported baudrate for nRF54l05/10/15 is 

    ''The main features of TWIM are the following:

    • I2C compatible for 100 kbps and 400 kbps
    • 1000 kbps bit rate support for selected pull-up resistor/bus capacitance combinations
    • Supported baud rates:
      • 100 kbps
      • 400 kbps
      • 1000 kbps''

    source:TWIM — I2C compatible two-wire interface controller with EasyDMA • nRF54L15 | nRF54L10 | nRF54L05 Datasheet • Technical Documentation

    You can try at least 100kbps as a first try to see if that helps.

    ''Incidentally the MAX41462 requires SDA to be toggled after power up. Is it OK to configure the line as a GPIO output and toggle before running i2c_configure() ?''

    It should be possible to implement if TWIM is disabled. ''

    The SCL and SDA signals are mapped to physical pins using the PSEL.SCL and PSEL.SDA registers.

    These registers and their configurations are only used when TWIM is enabled, and retained while the device is in System ON mode. When the peripheral is disabled, the pins behave as regular GPIOs and are configured according to their respective OUT bit field and PIN_CNF[n] register. Configure registers PSEL.SCL and PSEL.SDA when TWIM is disabled.''

    TWIM pin configuration • nRF54L15 | nRF54L10 | nRF54L05 Datasheet • Technical Documentation 

    Thanks.

    BR
    Kazi

  • You can try at least 100kbps as a first try to see if that helps.

    OK, but I don't want to blindly try things, I want to understand what's what.

    Is I2C clock stretching supported? Can I configure a timeout by code, kconfig etc?

    These registers and their configurations are only used when TWIM is enabled

    Do you mean enabled as in kconfig/devicetree, or enabled by running  i2c_configure()? Also, I'd rather not be talking directly to registers if possible while using Zephyr.

  • ''Run at 100 kbps minimum with the TWIM peripheral''

    The supported bit rate of TWIM is 100kbos, 400kbps, 100 kbps, which I mentioned in my previous reply with the source link. This frequency is enforced at the Zephyr driver level. You will configure this in the device tree file(overlay file). For example:

    &i2c20 {
        status = "okay";
        pinctrl-0 = <&i2c20_default>;
        pinctrl-1 = <&i2c20_sleep>;
        pinctrl-names = "default", "sleep";
        clock-frequency = <I2C_BITRATE_STANDARD>;  /* 100 kbps */
    
        /* Example sensor device */
        my_sensor: sensor@48 {
            compatible = "vendor,sensor";
            reg = <0x48>;
            status = "okay";
        };
    };

    When we set ''I2C_BITRATE_STANDARD'' as clock frequency, we set it as 100kbps.

    ''Do you mean enabled as in kconfig/devicetree, or enabled by running  i2c_configure()? Also, I'd rather not be talking directly to registers if possible while using Zephyr.''

    No, these PSEL.SCL and PSEL.SDA registers are not configured in the kconfig or not by running i2c_configure(). This is set in the pincntrl file of board file.

    for example:

    &pinctrl {
        /omit-if-no-ref/ i2c21_default: i2c21_default {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                bias-pull-up;
            };
        };
    
        /omit-if-no-ref/ i2c21_sleep: i2c21_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                low-power-enable;
            };
        };
    };
    
    

    Now getting back to the clock stretching of TWIM again, since it is supported in TWIM, it may possible to set the bit rate below 100kbps according to this old case (+) I2C frequencies below 100kbps - Nordic Q&A - Nordic DevZone - Nordic DevZone. I will talk to team to be sure.

    ''The MAX41462 has a 4 byte FIFO buffer and implements flow control by I2C clock stretching which seems to be causing the crash - using a logic analyser I can see the clock signal being held low after 8 bits of data transfer. ''

    Could you please share the error log and the output from logic analyser?

    Thanks.

    BR
    Kazi

Reply
  • ''Run at 100 kbps minimum with the TWIM peripheral''

    The supported bit rate of TWIM is 100kbos, 400kbps, 100 kbps, which I mentioned in my previous reply with the source link. This frequency is enforced at the Zephyr driver level. You will configure this in the device tree file(overlay file). For example:

    &i2c20 {
        status = "okay";
        pinctrl-0 = <&i2c20_default>;
        pinctrl-1 = <&i2c20_sleep>;
        pinctrl-names = "default", "sleep";
        clock-frequency = <I2C_BITRATE_STANDARD>;  /* 100 kbps */
    
        /* Example sensor device */
        my_sensor: sensor@48 {
            compatible = "vendor,sensor";
            reg = <0x48>;
            status = "okay";
        };
    };

    When we set ''I2C_BITRATE_STANDARD'' as clock frequency, we set it as 100kbps.

    ''Do you mean enabled as in kconfig/devicetree, or enabled by running  i2c_configure()? Also, I'd rather not be talking directly to registers if possible while using Zephyr.''

    No, these PSEL.SCL and PSEL.SDA registers are not configured in the kconfig or not by running i2c_configure(). This is set in the pincntrl file of board file.

    for example:

    &pinctrl {
        /omit-if-no-ref/ i2c21_default: i2c21_default {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                bias-pull-up;
            };
        };
    
        /omit-if-no-ref/ i2c21_sleep: i2c21_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                low-power-enable;
            };
        };
    };
    
    

    Now getting back to the clock stretching of TWIM again, since it is supported in TWIM, it may possible to set the bit rate below 100kbps according to this old case (+) I2C frequencies below 100kbps - Nordic Q&A - Nordic DevZone - Nordic DevZone. I will talk to team to be sure.

    ''The MAX41462 has a 4 byte FIFO buffer and implements flow control by I2C clock stretching which seems to be causing the crash - using a logic analyser I can see the clock signal being held low after 8 bits of data transfer. ''

    Could you please share the error log and the output from logic analyser?

    Thanks.

    BR
    Kazi

Children
No Data
Related