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

  • This works for me

    Windows10
    nrf v1.2.0

    main.c

    #include <zephyr.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <drivers/i2c.h>
    #include <device.h>
    
    #define I2C_ACCEL_ADDR (0x32 >> 1)
    #define ACCEL_REG_WHO_AM_I 0x0F
    
    struct device *i2c_2;
    
    u8_t configure_accelerometer() {
    
        if (i2c_reg_write_byte(i2c_2, I2C_ACCEL_ADDR, 0x20, 0x2F) != 0) { // CTRL_REG1 (20h), Enable x,y,z axis, 10Hz, normal mode
                return -1;
        }
        if (i2c_reg_write_byte(i2c_2, I2C_ACCEL_ADDR, 0x21, 0x01) != 0) { // CTRL_REG2 (21h), High-pass filter enabled for AOI function on Interrupt 1.
                return -1;
        }
        if (i2c_reg_write_byte(i2c_2, I2C_ACCEL_ADDR, 0x22, 0x40) != 0) { // CTRL_REG3 (23h), IA1 interrupt on INT1 pin enable
                return -1;
        }
        if (i2c_reg_write_byte(i2c_2, I2C_ACCEL_ADDR, 0x30, 0x2A) != 0) { // INT1_CFG (30h), Enable interrupt generation on X,Y,Z high event or on direction recognition
                return -1;
        }
        if (i2c_reg_write_byte(i2c_2, I2C_ACCEL_ADDR, 0x32, 0x08) != 0) { // INT1_THS (32h), 1 LSb = 16 mg, threshold = 128mg
                return -1;
        }
        if (i2c_reg_write_byte(i2c_2, I2C_ACCEL_ADDR, 0x33, 0x00) != 0) { // INT1_DURATION (33h), Set the minimum duration of the Interrupt 1 event to be recognized
                return -1;
        }
    
        return 0;
    }
    
    void main(void)
    {
        u8_t rx_buf[1];
        int8_t ret;
    
        i2c_2 = device_get_binding("I2C_2");
        if (!i2c_2) {
            sys_reboot(0);
        }
    
        if(configure_accelerometer() != 0) {
            sys_reboot(0);
        }
    
        u8_t reg = ACCEL_REG_WHO_AM_I;
    
        while (1) {
            printk("loop head\r\n");
            ret = i2c_burst_read(i2c_2, I2C_ACCEL_ADDR, reg, rx_buf, sizeof(rx_buf));
            if(ret == 0){ /* success */
                printk( "Read:  register = 0x%02X, value = 0x%02X\r\n", reg, rx_buf[0]);
            } else { /* ret = -EIO */
                printk( "i2c_burst_read fail!, register = 0x%02X, ret = %d\r\n", reg, ret);
            }
    
            k_sleep(3000);
        }            
    }
    

    prj.conf

    # General
    CONFIG_TRUSTED_EXECUTION_NONSECURE=y
    CONFIG_AT_HOST_LIBRARY=n
    CONFIG_SERIAL=y
    
    # I2C
    CONFIG_I2C=y
    CONFIG_I2C_NRFX=y
    CONFIG_I2C_2=y
    CONFIG_I2C_2_NRF_TWIM=y
    
    # Rebooot
    CONFIG_REBOOT=y
    
    # SEGGER RTT for Dev
    CONFIG_PRINTK=y
    CONFIG_CONSOLE=y
    CONFIG_STDOUT_CONSOLE=y
    CONFIG_UART_CONSOLE=n
    CONFIG_RTT_CONSOLE=y
    CONFIG_USE_SEGGER_RTT=y

    nrf9160_pca10090ns.overlay

    &i2c2 {
    	status = "okay";
    	sda-pin = <15>;
    	scl-pin = <16>;
    	clock-frequency = <100000>; 
    };

  • Hi

    I tried the code the works for you. but i am getting below error

Related