I2C read failed reg 0x00 err -5

I am faced "I2C read failed reg 0x00 err -5" issue 

&pinctrl {
	i2c22_default: i2c22_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 2, 7)>,
					<NRF_PSEL(TWIM_SDA, 2, 6)>;
					bias-pull-up;
		};
	};

	i2c22_sleep: i2c22_sleep {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 2, 7)>,
					<NRF_PSEL(TWIM_SDA, 2, 6)>;
					low-power-enable;
		};
	};

	i2s20_default: i2s20_default {
		group1 {
			psels = <NRF_PSEL(I2S_SDOUT, 0, 0)>,
			        <NRF_PSEL(I2S_SDIN, 0, 1)>,
			        <NRF_PSEL(I2S_SCK_S, 0, 2)>,
			        <NRF_PSEL(I2S_MCK, 0, 3)>,
			        <NRF_PSEL(I2S_LRCK_M, 0, 4)>;
		};
	};

	i2s20_sleep: i2s20_sleep {
		group1 {
			psels = <NRF_PSEL(I2S_SDOUT, 0, 0)>,
			        <NRF_PSEL(I2S_SDIN, 0, 1)>,
			        <NRF_PSEL(I2S_SCK_S, 0, 2)>,
			        <NRF_PSEL(I2S_MCK, 0, 3)>,
			        <NRF_PSEL(I2S_LRCK_M, 0, 4)>;
		};
	};
};

&i2c22 {
	status = "okay";
	pinctrl-0 = <&i2c22_default>;
	pinctrl-1 = <&i2c22_sleep>;
	pinctrl-names = "default", "sleep";

	audiocodec: audiocodec@18 {
		compatible = "i2c-device";
		status = "okay";
		reg = < 0x18 >;
	};
};

&i2s20 {
	status = "okay";
	pinctrl-0 = <&i2s20_default>;
	pinctrl-1 = <&i2s20_sleep>;
	pinctrl-names = "default", "sleep";
}; this is my overlay

// read command
int read_eg(void)
{
    int ret;
    uint8_t reg = 0x00;
    uint8_t val = 0;

    ret = i2c_write_read_dt(&dev_i2c,
                            &reg, 1,
                            &val, 1);
    if (ret)
    {
        printk("I2C read failed reg 0x%02x err %d\n", reg, ret);
        return ret;
    }

   printk("Read reg 0x%02x = 0x%02x\n", reg, val);

    return 0;
}

int codec_hw_reset(void)
 {
    int ret;

    ret=gpio_pin_set_dt(&codec_reset_pin, 1);
    k_msleep(20);

    /* HIGH → reset released */
    ret=gpio_pin_set_dt(&codec_reset_pin, 0);
    k_msleep(50);

    // return 0;

    // if(ret<3)
    // {
    //   printf("fail hw reset");
    // }

    return 0;
}

static int codec_i2c_config(void)
{
    if (!device_is_ready(dev_i2c.bus))
    {
        printk("Error: I2C bus %s is not ready!\n", dev_i2c.bus->name);
        return -1;
    }

    printk("I2C bus ready, addr=0x%02x\n", dev_i2c.addr); //dev_i2c.addr
 

    return 0;
}

static int codec_gpios_config(void)
{
    int ret;

    if (!gpio_is_ready_dt(&codec_reset_pin))
    {
        printk("Error: Codec reset pin not ready\n");
        return -1;
    }
    ret=gpio_pin_configure_dt(&codec_reset_pin,
                                GPIO_OUTPUT_ACTIVE |
                                GPIO_ACTIVE_LOW);

   
    ret=gpio_pin_configure_dt(&codec_reset_pin,
                                GPIO_OUTPUT_ACTIVE |
                                GPIO_ACTIVE_LOW);
   
    if (ret < 0)
    {
        printk("Error %d: Failed to configure codec reset pin\n", ret);
        return -1;
    }

    return 0;
}

int codec_init(void)
{
   
    //
    int ret;

    ret = codec_gpios_config();
    if (ret != 0)
    {
        return ret;
    }

    ret = codec_i2c_config();
    if (ret != 0)
    {
        return ret;
    }

    ret = codec_hw_reset();
    if (ret != 0)
    {
        return ret;
    }
    k_msleep(50);
    read_eg();

    return 0;
} this is my code i get -5 error 

  

Parents
  • Hi,

    You are using the TWIM22 I2C instance (&i2c22). On nRF54L15, TWIM20/21/22 can only be routed to GPIOs on port P1 (see the Block Diagram). P2 pins are not supported for TWIM, so using P2.06/P2.07 with &i2c22 will typically result in errors.

    You may try updating the devicetree so that TWIM20/21/22 use P1.xx pins (GPIO port 1), or alternatively switch to TWIM30 (&i2c30) if you want to use P0.xx pins (GPIO port 0).

    Kind Regards,
    Syed Maysum

  • hi ,

    when i am connect i2s ans i2c together is gettimg -5 i2c error . without i2s , i2c register read is proper ??


  • &pinctrl {
        i2c22_default: i2c22_default {
            group1 {
                psels =
                        <NRF_PSEL(TWIM_SCL, 1, 11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                       
            };
        };

        i2c22_sleep: i2c22_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1,11)>,
                        <NRF_PSEL(TWIM_SDA, 1, 12)>;
                        low-power-enable;
            };
        };

        i2s20_default: i2s20_default {
            group1 {
                psels = <NRF_PSEL(I2S_SDIN, 1, 4)>,
                        <NRF_PSEL(I2S_SDOUT, 1, 5)>,
                        <NRF_PSEL(I2S_SCK_S, 1, 6)>,
                        <NRF_PSEL(I2S_MCK, 1, 13)>,
                        <NRF_PSEL(I2S_LRCK_M, 1, 14)>;
            };
        };

        i2s20_sleep: i2s20_sleep {
            group1 {
                psels = <NRF_PSEL(I2S_SDIN, 1, 4)>,
                        <NRF_PSEL(I2S_SDOUT, 1, 5)>,
                        <NRF_PSEL(I2S_SCK_S, 1, 6)>,
                        <NRF_PSEL(I2S_MCK, 1, 13)>,
                        <NRF_PSEL(I2S_LRCK_M, 1, 14)>;
            };
        };
    };

    &i2c22 {
        status = "okay";
        pinctrl-0 = <&i2c22_default>;
        pinctrl-1 = <&i2c22_sleep>;
        pinctrl-names = "default", "sleep";

        audiocodec: audiocodec@18 {
            compatible = "i2c-device";
            status = "okay";
            reg = < 0x18 >;
        };
    };

    &i2s20 {
        status = "okay";
        pinctrl-0 = <&i2s20_default>;
        pinctrl-1 = <&i2s20_sleep>;
        pinctrl-names = "default", "sleep";
    };

    &led0 {status = "disabled";};

    / {
         custom_pins{
            compatible = "gpio-keys";

            codec_reset: codec-reset-node {
                gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
                label = "Codec Reset Pin";
            };
           
        };
    };






    &i2c30 {
        status = "disabled";
    };
    /delete-node/ &{/pin-controller/i2c22_default/group2/};
    /delete-node/ &{/pin-controller/i2s20_default/group5/};
    /delete-node/ &{/pin-controller/i2s20_default/group2/};
    /delete-node/ &{/pin-controller/i2s20_default/group3/};
    /delete-node/ &{/pin-controller/i2s20_default/group4/};

    // &button0 {
    //  /delete-property/ gpios;
    // };
  • Hi,

    Since the issue only appears when I2S is active, it may be related to marginal I2C signal integrity. Could you try enabling internal pull-ups on the I2C pins by adding bias-pull-up to the i2c22_default pinctrl node, and check if the behavior changes. You could trying adding this to the overlay:

    i2c22_default: i2c22_default {
        group1 {
            psels =
                <NRF_PSEL(TWIM_SCL, 1, 11)>,
                <NRF_PSEL(TWIM_SDA, 1, 12)>;
            bias-pull-up;
        };
    };

    Best Regards,
    Syed Maysum

Reply
  • Hi,

    Since the issue only appears when I2S is active, it may be related to marginal I2C signal integrity. Could you try enabling internal pull-ups on the I2C pins by adding bias-pull-up to the i2c22_default pinctrl node, and check if the behavior changes. You could trying adding this to the overlay:

    i2c22_default: i2c22_default {
        group1 {
            psels =
                <NRF_PSEL(TWIM_SCL, 1, 11)>,
                <NRF_PSEL(TWIM_SDA, 1, 12)>;
            bias-pull-up;
        };
    };

    Best Regards,
    Syed Maysum

Children
  • i have another issue in my code , when i read i2s 1 to 5 index is properly transmitted after enter to index 6 leads to -11 error

  • /*
     * Copyright 2023 NXP
     *
     * SPDX-License-Identifier: Apache-2.0
     */

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/i2s.h>
    #include <zephyr/drivers/gpio.h>
    #include <stdio.h>
    #include "codec_header.h"

    #define SAMPLE_NO   64
    #define CHANNELS    2
    #define NUM_BLOCKS  4

    /* BLOCK_SIZE in bytes */
    #define BLOCK_SIZE (CHANNELS * SAMPLE_NO * sizeof(int16_t))

    const struct device *dev_i2s = DEVICE_DT_GET(DT_NODELABEL(i2s20));

    /* Stereo interleaved buffers */
    static int16_t tx_block[NUM_BLOCKS][CHANNELS * SAMPLE_NO];

    /* Sine wave table */
    static const int16_t sine[SAMPLE_NO] = {
         3211,  6392,  9511, 12539, 15446, 18204, 20787, 23169,
        25329, 27244, 28897, 30272, 31356, 32137, 32609, 32767,
        32609, 32137, 31356, 30272, 28897, 27244, 25329, 23169,
        20787, 18204, 15446, 12539,  9511,  6392,  3211,     0,
        -3212, -6393, -9512,-12540,-15447,-18205,-20788,-23170,
       -25330,-27245,-28898,-30273,-31357,-32138,-32610,-32767,
       -32610,-32138,-31357,-30273,-28898,-27245,-25330,-23170,
       -20788,-18205,-15447,-12540, -9512, -6393, -3212,    -1
    };

    static void fill_buf(int16_t *buf, int shift)
    {
        for (int i = 0; i < SAMPLE_NO; i++) {
            buf[2 * i]     = sine[i] >> shift;                 /* Left */
            buf[2 * i + 1] = sine[(i + SAMPLE_NO / 4) % SAMPLE_NO] >> shift; /* Right */
        }
    }

    int main(void)
    {
        struct i2s_config i2s_cfg;
        int ret;

        printk("=== System start ===\n");

       // POWER-UP DELAY
        k_msleep(300);

        // INIT I2C
        ret = i2c_init_codec();
        if (ret)
        {
            printk("Codec I2C init failed (%d). STOP.\n", ret);
            while (1)
            {
                k_sleep(K_FOREVER);
            }
        }
        printk("Codec I2C init OK\n");

        // CHECK I2S DEVICE
        if (!device_is_ready(dev_i2s)) {
            printk("I2S device not ready\n");
            return -ENODEV;
        }

        // CONFIGURE I2S
        memset(&i2s_cfg, 0, sizeof(i2s_cfg));

        i2s_cfg.word_size = 16;
        i2s_cfg.channels = CHANNELS;
        i2s_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
        i2s_cfg.frame_clk_freq = 8000;
        i2s_cfg.block_size = BLOCK_SIZE;
        i2s_cfg.timeout =1000;
        i2s_cfg.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER;

        ret = i2s_configure(dev_i2s, I2S_DIR_TX, &i2s_cfg);
        if (ret)
        {
            printk("I2S configure failed (%d)\n", ret);
            return ret;
        }

        printk("I2S configured.........\n");

        // PREPARE AUDIO BUFFERS
        for (int i = 0; i < NUM_BLOCKS; i++)
        {
            fill_buf(tx_block[i], i % 3);
        }

        // QUEUE BUFFERS BEFORE START
        ret = i2s_write(dev_i2s, tx_block[0], BLOCK_SIZE);

        ret |= i2s_write(dev_i2s, tx_block[1], BLOCK_SIZE);

        if (ret)
        {
            printk("I2S write failed (%d)\n", ret);
            return ret;
        }

        printk("Initial TX buffers queued\n");

        // NOW START I2S -lrck
        ret = i2s_trigger(dev_i2s, I2S_DIR_TX, I2S_TRIGGER_START);
        if (ret)
        {
            printk("I2S start failed (%d)\n", ret);
            return ret;
        }

        printk("I2S started successfully\n");

     // remaining buffer
        int idx = 2;
        while (1)
        {
            ret = i2s_write(dev_i2s, tx_block[idx % NUM_BLOCKS], BLOCK_SIZE);
            if (ret == 0)
            {
                idx++;
                k_msleep(1);
            }
            else if (ret == -EAGAIN)
            {
                k_msleep(2);
            }
            else
            {
                printk("I2S write error (%d)\n", ret);
                break;
            }
        }
       printk("i2s_write.............");
        return 0;
    }


     
  • my overlay file is this ,


    &pinctrl {
        i2c21_default: i2c22_default {
            group1 {
                psels =
                        <NRF_PSEL(TWIM_SCL, 1, 12)>,
                        <NRF_PSEL(TWIM_SDA, 1, 13)>;
                        bias-pull-up;
                       
            };
        };

        i2c21_sleep: i2c22_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 1,12)>,
                        <NRF_PSEL(TWIM_SDA, 1, 13)>;
                        low-power-enable;
            };
        };

        i2s20_default: i2s20_default {
            group1 {
                psels = <NRF_PSEL(I2S_SDIN, 1, 6)>,
                        <NRF_PSEL(I2S_SDOUT, 1, 5)>,
                        <NRF_PSEL(I2S_SCK_S, 1, 3)>,
                        <NRF_PSEL(I2S_MCK, 1, 4)>,
                        <NRF_PSEL(I2S_LRCK_M, 1, 14)>;
            };
        };

        i2s20_sleep: i2s20_sleep {
            group1 {
                psels = <NRF_PSEL(I2S_SDIN, 1, 6)>,
                        <NRF_PSEL(I2S_SDOUT, 1, 5)>,
                        <NRF_PSEL(I2S_SCK_S, 1, 3)>,
                        <NRF_PSEL(I2S_MCK, 1, 4)>,
                        <NRF_PSEL(I2S_LRCK_M, 1, 14)>;
            };
        };
       // i2s20_default: i2s20_default

    };

    &i2c21 {
        status = "disabled";
        pinctrl-0 = <&i2c22_default>;
        pinctrl-1 = <&i2c22_sleep>;
        pinctrl-names = "default", "sleep";

        audiocodec: audiocodec@18 {
            compatible = "i2c-device";
            status = "okay";
            reg = < 0x18 >;
        };
    };

    &i2s20 {
        status = "okay";
        pinctrl-0 = <&i2s20_default>;
        pinctrl-1 = <&i2s20_sleep>;
        pinctrl-names = "default", "sleep";
    };

    &led0 {status = "disabled";};

    / {
         custom_pins{
            compatible = "gpio-keys";

            codec_reset: codec-reset-node {
                gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
                label = "Codec Reset Pin";
            };
        };
    };




    &i2c30 {
        status = "disabled";
    };
    /delete-node/ &{/pin-controller/i2c22_default/group2/};
    /delete-node/ &{/pin-controller/i2s20_default/group5/};
    /delete-node/ &{/pin-controller/i2s20_default/group2/};
    /delete-node/ &{/pin-controller/i2s20_default/group3/};
    /delete-node/ &{/pin-controller/i2s20_default/group4/};



    &i2c21 {
        status = "okay";
    };

    &i2c22 {
        status = "disabled";
    };



    &uart21 {
        status = "disabled";
    };
    /delete-node/ &button0;
    /delete-node/ &{/buttons/};

        / {
        button0: button_0 {
            compatible = "gpio-keys";
            button0_key: button0_key {
                gpios = <&gpio1 15 0>;
                label = "MCUBoot Button";
            };
        };

        // led0: led_0 {
        //     compatible = "gpio-leds";
        //     led0_green: led0_green {
        //         gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
        //         label = "MCUBoot LED";
        //     };
        // };
    };

    &uart20 {
        status = "okay";
    };

    &uart20_default {
        group1 {
            psels = <NRF_PSEL(UART_TX, 1, 8)>, <NRF_PSEL(UART_RX, 1, 7)>;
        };
    };
  • Hi,

    The -11 return value corresponds to -EAGAIN and indicates that the I2S TX queue is full and the operation timed out. This occurs when the application submits audio blocks faster than the I2S hardware can transmit them.

    Increasing NUM_BLOCKS (for example to 8) is the recommended first step to provide additional buffering. If the issue still occurs, you may also increase the .timeout value in your i2s_config to allow i2s_write() more time to wait for a free TX slot. Please confirm if it works. Thanks

    Best Regards,
    Syed Maysum

Related