Skip to content

Commit

Permalink
(First draft) Added functions for reading/writing registers and conve… (
Browse files Browse the repository at this point in the history
#189)

* (First draft) Added functions for reading/writing registers and converting to real current, power, and voltage

* Removed some comments

* Added public functions to INA226.h
  • Loading branch information
bjackson312006 authored Nov 4, 2024
1 parent a5c81fb commit 8325863
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 0 deletions.
74 changes: 74 additions & 0 deletions general/include/INA226.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
INA226AQDGSRQ1 Current Sensor I2C Driver
Datasheet:
https://www.ti.com/lit/ds/symlink/ina226-q1.pdf
*/

#ifndef INA226_H
#define INA226_H

// REGISTERS
#define INA226_CONFIGURATION 0x00
#define INA226_SHUNT_VOLTAGE 0x01
#define INA226_BUS_VOLTAGE 0x02
#define INA226_POWER 0x03
#define INA226_CURRENT 0x04
#define INA226_CALIBRATION 0x05
#define INA226_MASK_ENABLE 0x06
#define INA226_ALERT_LIMIT 0x07
#define INA226_MANUFACTURER 0xFE
#define INA226_DIE_ID 0xFF

// CONFIGURATION MASKS
#define INA226_CONFIG_RESET_MASK 0x8000 // Bit 15
#define INA226_CONFIG_AVERAGE_MASK 0x0E00 // Bits 9-11
#define INA226_CONFIG_BUSVC_MASK 0x01C0 // Bits 6-8
#define INA226_CONFIG_SHUNTVC_MASK 0x0038 // Bits 3-5
#define INA226_CONFIG_MODE_MASK 0x0007 // Bits 0-2

// Function Pointers
typedef int (*WritePtr)(uint16_t dev_addr, uint8_t reg, uint16_t *data);
typedef int (*ReadPtr)(uint16_t dev_addr, uint8_t reg, uint16_t *data);

typedef struct {
uint16_t dev_addr;
WritePtr write;
ReadPtr read;
float current_lsb;
} ina226_t;

void ina226_init(ina226_t *ina, WritePtr write, ReadPtr read,
uint16_t dev_addr);

int ina226_read_reg(ina226_t *ina, uint8_t reg, uint16_t *data);

int ina226_write_reg(ina226_t *ina, uint8_t reg, uint16_t *data);

// Writes calibration register. r_shunt in ohms, max_current in amps
int ina226_calibrate(ina226_t *ina, float r_shunt, float max_current);

// Reads current in amps
int ina226_read_current(ina226_t *ina, float *data);

// Reads power in watts
int ina226_read_power(ina226_t *ina, float *data);

// Reads shunt voltage in volts
int ina226_read_shunt_voltage(ina226_t *ina, float *data);

// Reads bus voltage in volts
int ina226_read_bus_voltage(ina226_t *ina, float *data);

// Sets configuration register bits 0-11 (operating mode, shunt voltage conversion time, bus voltage conversion time, and averaging mode)
// See datasheet for settings
int ina226_configure(ina226_t *ina, uint8_t mode, uint8_t vshct, uint8_t vbusct,
uint8_t avg);

// Resets all registers to default values
int ina226_reset(ina226_t ina);

// Reads manufacturer id register
int ina226_read_manufacturer_id(ina226_t ina, uint16_t *data);

// Reads die id
int ina226_read_die_id(ina226_t ina, uint16_t *data);
146 changes: 146 additions & 0 deletions general/src/INA226.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
INA226AQDGSRQ1 Current Sensor I2C Driver
Datasheet:
https://www.ti.com/lit/ds/symlink/ina226-q1.pdf
*/

#include "INA226.h"

void ina226_init(ina226_t *ina, WritePtr write, ReadPtr read, uint16_t dev_addr)
{
ina->write = write;
ina->read = read;
ina->dev_addr = dev_addr << 1u;
ina->current_lsb = 0;
}

int ina226_read_reg(ina226_t *ina, uint8_t reg, uint16_t *data)
{
return ina->read(ina->dev_addr, reg, data);
}

int ina226_write_reg(ina226_t *ina, uint8_t reg, uint16_t *data)
{
return ina->write(ina->dev_addr, reg, data);
}

// Writes calibration register. r_shunt in ohms, max_current in amps
int ina226_calibrate(ina226_t *ina, float r_shunt, float max_current)
{
float current_lsb = max_current / 32768;
float cal = 0.00512 / (current_lsb * r_shunt);
uint16_t cal_reg = (uint16_t)floorf(cal);
ina->current_lsb = 0.00512 / (cal_reg * r_shunt);

return ina226_write_reg(ina, INA226_CALIBRATION, &cal_reg);
}

// Reads current in amps
int ina226_read_current(ina226_t *ina, float *data)
{
uint16_t current_reg;

int status = ina226_read_reg(ina, INA226_CURRENT, &current_reg);
if (status != 0) {
return status;
}

*data = (float)(int16_t)current_reg * ina->current_lsb;

return status;
}

// Reads power in watts
int ina226_read_power(ina226_t *ina, float *data)
{
uint16_t power_reg;

int status = ina226_read_reg(ina, INA226_POWER, &power_reg);
if (status != 0) {
return status;
}

*data = (float)(int16_t)power_reg * (ina->current_lsb * 25);

return status;
}

// Reads shunt voltage in volts
int ina226_read_shunt_voltage(ina226_t *ina, float *data)
{
uint16_t shunt_voltage_reg;

int status =
ina226_read_reg(ina, INA226_SHUNT_VOLTAGE, &shunt_voltage_reg);
if (status != 0) {
return status;
}

*data = (float)(int16_t)shunt_voltage_reg *
2.5e-6; // LSB = 2.5 uV per bit

return status;
}

// Reads bus voltage in volts
int ina226_read_bus_voltage(ina226_t *ina, float *data)
{
uint16_t bus_voltage_reg;

int status = ina226_read_reg(ina, INA226_BUS_VOLTAGE, &bus_voltage_reg);
if (status != 0) {
return status;
}

*data = (float)bus_voltage_reg * 1.25e-3; // LSB = 1.25 mV per bit

return status;
}

// Sets configuration register bits 0-11 (operating mode, shunt voltage conversion time, bus voltage conversion time, and averaging mode)
// See datasheet for settings
int ina226_configure(ina226_t *ina, uint8_t mode, uint8_t vshct, uint8_t vbusct,
uint8_t avg)
{
uint16_t configuration;
configuration = (avg << 9) | (vbusct << 6) | (vshct << 3) | mode;
return ina226_write_reg(ina, INA226_CONFIGURATION, &configuration);
}

// Resets all registers to default values
int ina226_reset(ina226_t ina)
{
uint16_t reset = INA226_CONFIG_RESET_MASK;
return ina226_write_reg(ina, INA226_CONFIGURATION, &reset);
}

// Reads manufacturer id register
int ina226_read_manufacturer_id(ina226_t ina, uint16_t *data)
{
uint16_t manufacturer_id;

int status =
ina226_read_reg(ina, INA226_MANUFACTURER, &manufacturer_id);
if (status != 0) {
return status;
}

*data = manufacturer_id;

return status;
}

// Reads die id
int ina226_read_die_id(ina226_t ina, uint16_t *data)
{
uint16_t die_id;

int status = ina226_read_reg(ina, INA226_DIE_ID, &die_id);
if (status != 0) {
return status;
}

*data = die_id;

return status;
}

0 comments on commit 8325863

Please sign in to comment.