This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Trouble: TWI(I2C) stops at the function of i2c_reg_read_byte On nRF9160 DK. Why?

I'm trying to have nRF9160 DK communicate with an external accelerometer. 

nRF9160 stop working at the function of i2c_reg_read_byte in the code below.

Does anybody give any advice?

<main.c>

#include <nrf9160.h>
#include <zephyr.h>
#include <misc/printk.h>
#include <i2c.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#define I2C_ACCEL_WRITE_ADDR 0x32
#define I2C_ACCEL_READ_ADDR 0x33

struct device *i2c_accel;
uint8_t WhoAmI = 0u;

uint8_t init_accelerometer(){
    i2c_accel = device_get_binding("I2C_2");
    if (!i2c_accel) {
		printk("error\r\n");
        return -1;
	} else  {
        i2c_configure(i2c_accel, I2C_SPEED_SET(I2C_SPEED_STANDARD));
        return 0;
    }
}

void main(void)
{
    printk("Hello, World!\r\n");
    init_accelerometer();

	while (1) {
        printk("loop head\r\n");

        if (i2c_reg_read_byte(i2c_accel, I2C_ACCEL_READ_ADDR, 0x0F, WhoAmI) != 0) { // stop wroking at this line
                printk("Error on i2c_read()\n");
        } else {
                printk("no error\r\n");
        }

        printk("WhoAmI = %u\r\n", WhoAmI);
        printk("enter sleep\r\n");
        k_sleep(1000);
	}
}

<prj.conf>

CONFIG_TRUSTED_EXECUTION_SECURE=y
# needed to get the NRF_UARTE2 define
CONFIG_UART_2_NRF_UARTE=y

CONFIG_TRUSTED_EXECUTION_NONSECURE=y
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y

CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_I2C_2=y
CONFIG_I2C_INIT_PRIORITY=60

<overlay file>

/* needed to get the NRF_UARTE2 defined */
&uart2 {
	current-speed = <1000000>;
	status = "ok";
	tx-pin = <18>;
	rx-pin = <17>;
	rts-pin = <19>;
	cts-pin = <21>;
};

&i2c2 {
	status = "ok";
	sda-pin = <10>;
	scl-pin = <11>;
	clock-frequency = <100000>; 
};

UPDATE:

<printk>
***** Booting Zephyr OS v1.13.99-ncs2 *****
Hello, World!
loop head
// stack here

  • Also, before nrfx_twim_xfer() is executed, use your JTAG debugger to show all the values in nrfx_twim_xfer_desc_t data structure.

    Paste that data structure contents in this forum, so we can all help you with this issue.

    Info info info ...

  • I will inspect the code this weekend. By the way, can you reproduce the symptom on your nRF9160? Even If no I2C device is connected, "Error on i2c_read()" should be displayed if I2C works correctly.
    I'm using nRF91, not nRF52.
  • I created a new project and implemented almost same code. Then it works. I don't really figure out what was wrong. Anyway, this works.

    #include <nrf9160.h>
    #include <zephyr.h>
    #include <misc/printk.h>
    #include <i2c.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define I2C_ACCEL_WRITE_ADDR 0x32
    #define I2C_ACCEL_READ_ADDR 0x33
    
    struct device *i2c_accel;
    uint8_t WhoAmI = 0u;
    
    uint8_t init_accelerometer(){
        i2c_accel = device_get_binding("I2C_1");
        if (!i2c_accel) {
    		printk("error\r\n");
            return -1;
    	} else  {
                    i2c_configure(i2c_accel, I2C_SPEED_SET(I2C_SPEED_STANDARD));
            return 0;
        }
    }
    
    void main(void)
    {
            printk("Hello, World!\r\n");
            init_accelerometer();
    
    	while (1) {
                    printk("loop head\r\n");
    
                    if (i2c_reg_read_byte(i2c_accel, I2C_ACCEL_READ_ADDR >> 1, 0x0F, &WhoAmI) != 0) {
                            printk("Error on i2c_read()\n");
                    } else {
                            printk("no error\r\n");
                    }
    
                    printk("WhoAmI = %u\r\n", WhoAmI);
                    printk("enter sleep\r\n");
                    k_sleep(3000);
    	}
    }

    <prj.conf>
    CONFIG_TRUSTED_EXECUTION_SECURE=y
    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_I2C=y
    CONFIG_I2C_NRFX=y
    CONFIG_I2C_1=y
    CONFIG_I2C_INIT_PRIORITY=60
    

    <overlay file>
    /* needed to get the NRF_UARTE2 defined */
    &uart2 {
    	current-speed = <1000000>;
    	status = "ok";
    	tx-pin = <18>;
    	rx-pin = <17>;
    	rts-pin = <19>;
    	cts-pin = <21>;
    };
    
    &i2c1 {
    	status = "ok";
    	sda-pin = <10>;
    	scl-pin = <11>;
    	clock-frequency = <100000>; 
    };

  • Hello Yusuke,

    I'm also trying to communicate nRF9160 DK with an external accelerometer using I2C. I want to read the accelerometer and gyroscope values. I tried your code. When I don't connect the accelerometer, Error on i2c_read() is displayed which is correct. But when I connect the accelerometer nothing prints. The program stops there. After "loop head" nothing is printed on the terminal. Did you face the same problem? Do you know how to print the accelerometer values?

    Thanks

Related