Evaluating direct access I2C operation with the NRF9160DK. I have a INA219 connected to pin 30 & pin 31. I am aware that there is a zephyr driver for the INA219, but I want to test direct I2C operation until the replacement device can be implemented. I am only trying to read register 0x00, which should provide the output of 0x39, 0x9F. I have tried different variations of the i2c read/write (i2c_write_read_dt, and separate write/read functions) and all return an error code -5.
To ensure that data is being transmitted to the INA219 (to eliminate connection issues) I am monitoring the SCL & SDA data lines using a DIGILENT Device to see what data is transmitted. I am also able to send I2C data to the INA219 to verify proper device operation. When sending data from the DIGILENT device I get the proper response and the proper returned data. Below is the protocol data that is captured when monitoring the SDA & SCL lines. By looking at the received protocol what is being sent from the DIGILENT device vs the NRF9160 is different
Protocol Captures
DIGILENT Sending/Receiving I2C data (WORKS)
Start, h80 [ h40 | WR ], h00, h00, Stop
Start, h80 [ h40 | WR ], h00,
Restart, h81 [ h40 | RD ], h39, h9F NACK, Stop
NRF9160DK Sending/Receiving I2C data (DOESNT WORK)
Start, h80 [ h40 | WR ], h00, h00,
Restart, h81 [ h40 | RD ], h01, h02 NACK, Stop
nrf9160dk_overlay file
&i2c2 { status = "okay"; pinctrl-0 = <&i2c2_default>; pinctrl-1 = <&i2c2_sleep>; pinctrl-names = "default", "sleep"; ina219: ina219@40{ compatible = "i2c-device"; status = "okay"; reg = < 0x40 >; label = "ina219"; }; }; &pinctrl { /omit-if-no-ref/ i2c2_default: i2c2_default { group1 { psels = <NRF_PSEL(TWIM_SCL, 0, 31)>, <NRF_PSEL(TWIM_SDA, 0, 30)>; }; }; /omit-if-no-ref/ i2c2_sleep: i2c2_sleep { group1 { psels = <NRF_PSEL(TWIM_SCL, 0, 31)>, <NRF_PSEL(TWIM_SDA, 0, 30)>; low-power-enable; }; }; };
static const struct i2c_dt_spec dev_i2c = I2C_DT_SPEC_GET(I2C_NODE); if (!device_is_ready(dev_i2c.bus)) { LOG_ERR("I2C bus %s is not ready!\n\r",dev_i2c.bus->name); //return -1; } // Step 1: Write to Register 0x00 ret = i2c_write_dt(&dev_i2c, ®_addr, 1); if (ret != 0) { LOG_ERR("Failed to write register address (Error %d)", ret); //return; } k_sleep(K_MSEC(10)); // Step 2: Read 2 bytes from Register 0x00 ret = i2c_read_dt(&dev_i2c, config_data, 2); if (ret != 0) { LOG_ERR("Failed to read INA219 register (Error %d)", ret); //return; }