blob: 3f27d3f3ad5ab4f5f2616e0390a9437d58c2cce9 [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <sys/printk.h>
#include <device.h>
#include <drivers/i2c.h>
/**
* @file Sample app using the TI INA219 through I2C.
*/
#define I2C_SLV_ADDR 0x40
/* The calibration value is based on components on
* Adafruit's breakout board
* (https://www.adafruit.com/products/904), where
* the current sensing resistor is 0.1 ohm.
* This enables measurements up to 32V, 2A.
*/
#define CAL_VAL (4096)
/* With default calibration above,
* Each current LSB is 100 uA == 0.1 mA == 0.0001 A.
* Each power LSB is 2000 uW == 2 mW = 0.002W.
*/
#define CUR_LSB 100
#define PWR_LSB 2000
int read_reg16(struct device *i2c_dev, u8_t reg_addr,
u8_t *data)
{
u8_t wr_addr;
struct i2c_msg msgs[2];
/* Register address */
wr_addr = reg_addr;
/* Setup I2C messages */
/* Send the address to read */
msgs[0].buf = &wr_addr;
msgs[0].len = 1U;
msgs[0].flags = I2C_MSG_WRITE;
/* Read from device. RESTART as neededm and STOP after this. */
msgs[1].buf = data;
msgs[1].len = 2U;
msgs[1].flags = I2C_MSG_READ | I2C_MSG_RESTART | I2C_MSG_STOP;
return i2c_transfer(i2c_dev, &msgs[0], 2, I2C_SLV_ADDR);
}
int write_reg16(struct device *i2c_dev, u8_t reg_addr,
u8_t *data)
{
u8_t wr_addr;
struct i2c_msg msgs[2];
/* Register address */
wr_addr = reg_addr;
/* Setup I2C messages */
/* Send the address to read */
msgs[0].buf = &wr_addr;
msgs[0].len = 1U;
msgs[0].flags = I2C_MSG_WRITE;
/* Read from device. RESTART as neededm and STOP after this. */
msgs[1].buf = data;
msgs[1].len = 2U;
msgs[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
return i2c_transfer(i2c_dev, &msgs[0], 2, I2C_SLV_ADDR);
}
void main(void)
{
struct device *i2c_dev;
u8_t data[2];
u32_t shunt_volt, bus_volt, current, power;
i2c_dev = device_get_binding("I2C_0");
if (!i2c_dev) {
printk("I2C: Device not found.\n");
return;
}
/* Configure the chip using default values */
data[0] = 0x03;
data[1] = 0x99;
write_reg16(i2c_dev, 0x00, data);
/* Write the calibration value */
data[0] = (CAL_VAL & 0xFF00) >> 8;
data[1] = CAL_VAL & 0xFF;
write_reg16(i2c_dev, 0x05, data);
/* Read bus voltage */
read_reg16(i2c_dev, 0x02, data);
bus_volt = (data[0] << 8) | data[1];
bus_volt >>= 3; /* 3 LSBs are not data */
bus_volt *= 4U; /* each LSB is 4 mV */
printk("Bus Voltage: %d mV\n", bus_volt);
/* Read shunt voltage */
read_reg16(i2c_dev, 0x01, data);
shunt_volt = (data[0] << 8) | data[1];
shunt_volt *= 10U; /* to uV since each LSB is 0.01 mV */
printk("Shunt Voltage: %d uV\n", shunt_volt);
/* Read current */
read_reg16(i2c_dev, 0x04, data);
current = (data[0] << 8) | data[1];
current *= CUR_LSB;
printk("Current: %d uA\n", current);
/* Read power */
read_reg16(i2c_dev, 0x03, data);
power = (data[0] << 8) | data[1];
power *= PWR_LSB;
printk("Power: %d uW\n", power);
}