Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(First draft) Added functions for reading/writing registers and conve… #189

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions general/include/INA226.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
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;
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;
}
Loading