I2C scanner readouts fail on XIAO nrf52840 code developped in VSCode/nrfConnect/Zephyr

Hi.

I'm fighting to get an i2c scanner (re)expose external devices' hex addresses on an Xiao nrf52840 board under VsCode nrfConnect (the basic board, not the Sense version).  

I say (re) expose because my code initially ran fine displaying i2c connected devices on I2C bus pins D4/D5, but by then, minor code tweaks i do not recall made the thing getting wrong. 

Now, the code still runs on my prototyping board, but no I2C device address shows up when running  my VSCode project,

To make sure this was not a wiring issue, i tested my single BME280 pressure sensor with an Arduino sketch on the exact same XIA board.. the sensor is showing up its 0x77 i2c address correctly.

I am lost in the abyssal complexity of the nRf & Zephyr framework and options and would greatly appreciate any kind of recommendations, specifically : where to dig in my project or build files to identify the location of the fault.

I was not able to see any way to attach my full project's zip archive or any file there (Firefox?)...Thank you.

main.c

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/printk.h>

#define CONFIG_I2C_SCAN_ADDR_START 0x08
#define CONFIG_I2C_SCAN_ADDR_STOP  0x77

static const struct device *scan_dev = DEVICE_DT_GET(DT_ALIAS(myi2c));

int main(void)
{
    // wait max 5 seconds for i2c to be ready
    k_sleep(K_SECONDS(5));
    
    if (!scan_dev) {
        printk("I2C: Device driver not found.\n");
        return -1;
    }

    printk("*** Digikey I2C scanner started ***\n");
    printk("Board:           %s\n", CONFIG_BOARD);
    printk("I2C device:      %s\n", scan_dev->name);

    /* Print pin information if available in devicetree */

    if (!device_is_ready(scan_dev)) {
        printk("I2C device not ready\n");
        return -1;
    }

    printk("Scanning on I2C bus...\n\n");

    printk("    | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f |\n");
    printk("****|*********************************************************************************");

    uint8_t error = 0u;
    uint8_t dst;
    uint8_t i2c_dev_cnt = 0;
    struct i2c_msg msgs[1];
    msgs[0].buf = &dst;
    msgs[0].len = 1U;
    msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
    //uint16_t slave_addr = 0;

    /* Use the full range of I2C address for display purpose */
    for (uint16_t x = 0; x <= 0x7f; x++) {
        /* New line every 0x10 address */
        if (x % 0x10 == 0) {
            printk("|\n0x%02x| ",x);
        }
        /* Range the test with the start and stop value configured in the kconfig */
        if (x >= CONFIG_I2C_SCAN_ADDR_START && x <= CONFIG_I2C_SCAN_ADDR_STOP)	{
            /* Send the address to read from */
            error = i2c_transfer(scan_dev, &msgs[0], 1, x);
                /* I2C device found on current address */
                if (error == 0) {
                    printk("0x%02x ",x);
                    //slave_addr = x;
                    ++i2c_dev_cnt;
                }
                else {
                    printk(".... ");
                }
        } else {
            /* Scan value out of range, not scanned */
            printk("     ");
        }
        k_sleep(K_MSEC(15));
    }
    printk("|\n");
    printk("\nI2C device(s) found on the bus : %d\nScanning complete!\n\n", i2c_dev_cnt);
    
}

Overlay file

/ {
    aliases {
        myi2c = &i2c0;
    };
};

&i2c0{
    status = "okay";
    clock-frequency = <I2C_BITRATE_STANDARD>;
    pinctrl-0 = <&i2c0_default>;
    pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
};

prj.conf

CONFIG_I2C=y
CONFIG_BUILD_OUTPUT_UF2=y
CONFIG_BUILD_OUTPUT_UF2_FAMILY_ID="0xada52840"

Makelists.txt

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(XIAO_i2c_scanner_02_test)
target_sources(app PRIVATE src/main.c)

OS: Windows 10
nRF Connect SDK Toolchain v3.2.3

  • @Nordic team. No need to spend time on this anymore. Solved by your AI recommendations I followed to the letter.The culprit was my overlay file and nothing else. Changed it as suggested, and it works nicely upfront. I2C address of connected device shows-up now (0x77). 

    / {
        aliases {
            myi2c = &i2c0;
        };
    };
    
    &i2c0{
        compatible = "nordic,nrf-twim";
        status = "okay";
        clock-frequency = <I2C_BITRATE_STANDARD>;
        pinctrl-0 = <&i2c0_default>;
        pinctrl-1 = <&i2c0_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &pinctrl {
        i2c0_default: i2c0_default {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 0, 5)>,  
                        <NRF_PSEL(TWIM_SDA, 0, 4)>;
            };
        };
        i2c0_sleep: i2c0_sleep {
            group1 {
                psels = <NRF_PSEL(TWIM_SCL, 0, 5)>,
                        <NRF_PSEL(TWIM_SDA, 0, 4)>;
                low-power-enable;
            };
        };
    };

Related