I2C not working on nRF7002-DK

Hi All,

Working with the Nordic nRF7002-DK I've been going through the nRF Connect SDK Fundamentals course and have been unsuccessful with Lesson 6 - Serial Communication (I2C). In exercise 1, I've followed all the instructions, but I'm not able to see any signals on any of the I2C pins.  I don't even see them being pulled up by the internal pullup.  I have external pullup resistors, but I disconnected the slave device until I see some activity on the SCL or SDA lines.  I've added external pullups to the 2V on the VDD pins of the header near the power switch. Even if there's no slave device connected to the I2C bus, I should see the SDA line pull low when a transmission is started.  I know that the transaction won't complete, because there's no slave to ACK.

I feel like the problem is that I'm not setting up the I2C peripheral correctly.  I've tried using i2c1 and i2c2 with no positive results.  I'm new to this development ecosystem, and I don't have much confidence in getting all the appropriate settings right in all the appropriate files.

I'm running; Windows 11, VS Code, nRF Connect for VS Code, etc.  I've run all the lessons 1 through 5 without any problems.

I've downloaded and tried to run the project, "l6_e1_sol", just to make sure I didn't make any typos or other blunders that would cause this problem.

Following the instructions:

I added CONFIG_I2C=y to the prj.conf file.

#include <zephyr/drivers/i2c.h> is loading without any outward issues.

Same with #include zephyr/sys/printk.h

I added CONFIG_CBPRINTF_FP_SUPPORT=y to the prj.conf file.

I created an overlay file called "nrf7002dk_nrf5340_cpuapp_ns.overlay and added:
&i2c1 {
status = "okay";
pinctrl-0 = <&i2c1_default>;
pinctrl-1 = <&i2c1_sleep>;
pinctrl-names = "default", "sleep";
mysensor: mysensor@77{
compatible = "i2c-device";
status = "okay";
reg = < 0x77 >;
};
};

&pinctrl {
/omit-if-no-ref/ i2c1_default: i2c1_default {
group1 {
psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
<NRF_PSEL(TWIM_SDA, 1, 15)>;
};
};

/omit-if-no-ref/ i2c1_sleep: i2c1_sleep {
group1 {
psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
<NRF_PSEL(TWIM_SDA, 1, 15)>;
low-power-enable;
};
};
};

I'm using address 0x77 for my sensor, because it's actually a BME688 and that's its default address.

#define I2C_NODE DT_NODELABEL(mysensor)

static const struct i2c_dt_spec dev_i2c = I2C_DT_SPEC_GET(I2C_NODE);
if (!device_is_ready(dev_i2c.bus)) {
printk("I2C bus %s is not ready!\n", dev_i2c.bus->name);
return -1;
}

#define CTRLMEAS 0xF4
#define CALIB00 0x88
#define ID 0xD0
#define TEMPMSB 0xFA

uint8_t id = 0;
uint8_t regs[] = {ID}; int ret = i2c_write_read_dt(&dev_i2c, regs, 1, &id, 1); if (ret != 0) {
printk("Failed to read register %x \n", regs[0]);
return -1;
} if (id != CHIP_ID) {
printk("Invalid chip id! %x \n", id);
return -1;
}

uint8_t values[6]; int ret = i2c_burst_read_dt(spec, CALIB00, values, 6); if (ret != 0) {
printk("Failed to read register %x \n", CALIB00);
return;
}

And all the other code in the lesson.

It builds and flashes without any obvious errors, but nothing happens on the I2C pins.  When I reboot the DK, I get the following on the monitor:
Pins have been configured as secure.
GPIO port: 0x00000001
Pin: 0x00000000
Pin: 0x00000001
Booting TF-M v2.1.1-ncs3
[Sec Thread] Secure image initializing!
[DBG][Crypto] Init Mbed TLS 3.6.1...
[DBG][Crypto] Init Mbed TLS 3.6.1... complete.

I don't know what any of that means.

I've run a test on the BME688 board using a different, known good, I2C master, and the sensor responds as expected.

It seems like the default i2c setup uses P1.03 and P1.02 for i2c.  I read in the nRF5340 datasheet that any gpio pins can be used for i2c. I don't need to use any particular pins and am happy to use the defaults, but I'm not sure about how to go about getting them working.  I don't know how to change between i2c1 and i2c2.

When I use the following macro:

psels = <NRF_PSEL(TWIM_SCL, 1, 14)>, <NRF_PSEL(TWIM_SDA, 1, 15)>;

in &pinctrl in the overlay, a build results in this in zephyr.dts:

psels = < 0xc00002f >, < 0xb00002e >;

When I decipher the lower two bytes of the hex numbers, I believe they are referring to P1.15 and P1.14.  This is what I'd expect.  I'm not sure what the high bytes indicate.

The zephyr.dts file shows i2c1 at P1.02 & P1.03 and i2c2 at P1.14 & P1.15.

The nRF5340 datasheet indicates i2c on P1.02 and P1.03.  I don't know why that is either, or if it's related to my problem.  I've looked at them on a scope and don't see any activity there either.

If this isn't something obvious that I'm missing, it seems like someone would have run across it before.  I looked through the devzone posts and couldn't find this specific issue.

I've been working on this on-and-off since the end of last week.  My mind is pretty much spinning at this point. Can someone please help me find the root of this issue?

Thanks,
robin

Parents
  • Hi,

     

    It builds and flashes without any obvious errors, but nothing happens on the I2C pins.  When I reboot the DK, I get the following on the monitor:
    Pins have been configured as secure.
    GPIO port: 0x00000001
    Pin: 0x00000000
    Pin: 0x00000001
    Booting TF-M v2.1.1-ncs3
    [Sec Thread] Secure image initializing!
    [DBG][Crypto] Init Mbed TLS 3.6.1...
    [DBG][Crypto] Init Mbed TLS 3.6.1... complete.

    This indicates that you are compiling for nonsecure, which will use uart1 as the default output for tfm logging.

    For the boards in this lesson, these configurations are added:

    https://github.com/NordicDeveloperAcademy/ncs-fund/blob/main/v2.9.0-v2.7.0/l6/l6_e2_sol/boards/thingy91_nrf9160_ns.conf

     

    You should create a nrf7002dk_nrf5340_cpuapp_ns.conf file in this folder with the same configs to ensure that TFM does not claim the uart1 interface, which again is a shared resource towards i2c1 (meaning; both cannot be enabled simulatenously)

     

    &pinctrl {
    /omit-if-no-ref/ i2c1_default: i2c1_default {
    group1 {
    psels = <NRF_PSEL(TWIM_SCL, 1, 14)>,
    <NRF_PSEL(TWIM_SDA, 1, 15)>;
    };
    };

    Unless you have external pull resistors or your sensor as internal pull-ups, I would recommend that you add "bias-pull-up;" to enable internal pull-up in the pads itself. You can check with a logic analyzer to see if the communication is occurring.

     

    If you still run into issues, please let me know.

     

    Kind regards,

    Håkon

  • Hi Håkon,

    github.com/.../quote]

    This is a broken link.  I found the "thingy91_nrf9160_ns.conf" in the downloaded lesson files, though.

    You should create a nrf7002dk_nrf5340_cpuapp_ns.conf file in this folder with the same configs

    I believe you mean that I should create the conf file with config settings like what would be found in the thingy91_nrf9160_ns.conf file

    When you say "... in this folder ...", do you mean that it should go in the "Boards" folder of the project?

    So, if I start with a clean copy of l6_e1_sol, and add a file named "nrf7002dk_nrf5340_cpuapp_ns.conf", which contains:

    #UART1 is used for TF-M logging should be disabled
    CONFIG_TFM_SECURE_UART=n
    CONFIG_TFM_LOG_LEVEL_SILENCE=y

    in the "Boards" folder, I should be able to build and flash and then I will see activity on the I2C pins?

    I've added the file and placed it in the Boards folder.  I do see activity on the I2C pins now.  With my I2C bus sniffer, I see the dk sending the correct address and the device is reading back its correct ID.  The code stops there, but then again, I'm not using the correct hardware sensor.

    It appears that I was missing the fact that the TFM was capturing the pins via UART1, and those same pins were assigned to i2c.  By adding the conf file, the system stopped trying to use those pins for UART1 and allowed my assignment of them to i2c.

    Your explanation has fixed the issue of not having i2c, but now I see where I went wrong in the lesson.  After step 2 in exercise 1, there is a message marked Important.  It describes adding:

    CONFIG_TFM_SECURE_UART=n

    CONFIG_TFM_LOG_LEVEL_SILENCE=y

    to the prj.conf file.  When I back out the changes you suggested and apply them in the prj.conf file, that works too.

    Thanks,
    robin

    [/quote]
Reply
  • Hi Håkon,

    github.com/.../quote]

    This is a broken link.  I found the "thingy91_nrf9160_ns.conf" in the downloaded lesson files, though.

    You should create a nrf7002dk_nrf5340_cpuapp_ns.conf file in this folder with the same configs

    I believe you mean that I should create the conf file with config settings like what would be found in the thingy91_nrf9160_ns.conf file

    When you say "... in this folder ...", do you mean that it should go in the "Boards" folder of the project?

    So, if I start with a clean copy of l6_e1_sol, and add a file named "nrf7002dk_nrf5340_cpuapp_ns.conf", which contains:

    #UART1 is used for TF-M logging should be disabled
    CONFIG_TFM_SECURE_UART=n
    CONFIG_TFM_LOG_LEVEL_SILENCE=y

    in the "Boards" folder, I should be able to build and flash and then I will see activity on the I2C pins?

    I've added the file and placed it in the Boards folder.  I do see activity on the I2C pins now.  With my I2C bus sniffer, I see the dk sending the correct address and the device is reading back its correct ID.  The code stops there, but then again, I'm not using the correct hardware sensor.

    It appears that I was missing the fact that the TFM was capturing the pins via UART1, and those same pins were assigned to i2c.  By adding the conf file, the system stopped trying to use those pins for UART1 and allowed my assignment of them to i2c.

    Your explanation has fixed the issue of not having i2c, but now I see where I went wrong in the lesson.  After step 2 in exercise 1, there is a message marked Important.  It describes adding:

    CONFIG_TFM_SECURE_UART=n

    CONFIG_TFM_LOG_LEVEL_SILENCE=y

    to the prj.conf file.  When I back out the changes you suggested and apply them in the prj.conf file, that works too.

    Thanks,
    robin

    [/quote]
Children
No Data
Related