Example added. rework library with float.

This commit is contained in:
lilian 2016-12-22 15:01:10 +01:00
parent 69280f8ec8
commit 1ee624c5fb
4 changed files with 174 additions and 72 deletions

View file

@ -0,0 +1,3 @@
PROGRAM=ina3221_test
EXTRA_COMPONENTS = extras/i2c extras/mcp4725
include ../../common.mk

View file

@ -0,0 +1,106 @@
/*
* Example of using INA3221
*
* Part of esp-open-rtos
* Copyright (C) 2016 Zaltora
* MIT Licensed as described in the file LICENSE
*/
#include "espressif/esp_common.h"
#include "FreeRTOS.h"
#include "task.h"
#include <esp/uart.h>
#include <stdbool.h>
#include "ina3221/ina3221.h"
#define PIN_SCL 4
#define PIN_SDA 2
#define ADDR INA3221_ADDR_0
//#define STRUCT_SETTING 1
void loop(void *pvParameters)
{
uint32_t measure_number = 0;
float bus_voltage;
float shunt_voltage;
float shunt_current;
// Create ina3221 device
ina3221_t dev = {
.addr = ADDR,
.shunt = { 100 ,100 ,100 }, // shunt values are 100 mOhm for each channel
.mask.mask_register = INA3221_DEFAULT_MASK, // Init
.config.config_register = INA3221_DEFAULT_CONFIG, // Init
};
#ifndef STRUCT_SETTING
if(ina3221_setting(&dev ,false, true, true)) // trigger mode, bus and shunt activated
goto error_loop;
if(ina3221_enableChannel(&dev , true, true, true)) // Enable all channels
goto error_loop;
if(ina3221_setAverage(&dev, INA3221_AVG_64)) // 64 samples average
goto error_loop;
if(ina3221_setBusConversionTime(&dev, INA3221_CT_2116)) // 2ms by channel
goto error_loop;
if(ina3221_setShuntConversionTime(&dev, INA3221_CT_2116)) // 2ms by channel
goto error_loop;
#else
dev.config.mode = false; // trigger mode
dev.config.esht = true; // shunt enable
dev.config.ebus = true; // bus enable
dev.config.ch1 = true; // channel 1 enable
dev.config.ch2 = true; // channel 2 enable
dev.config.ch3 = true; // channel 3 enable
dev.config.avg = INA3221_AVG_64; // 64 samples average
dev.config.vbus = INA3221_CT_2116; // 2ms by channel (bus)
dev.config.vsht = INA3221_CT_2116; // 2ms by channel (shunt)
if(ina3221_sync(&dev))
goto error_loop;
#endif
while(1)
{
measure_number++;
do
{
if (ina3221_trigger(&dev)) // Start a measure & get mask
goto error_loop;
} while(!(dev.mask.cvrf)); // check if measure done
for (uint8_t i = 0 ; i < BUS_NUMBER ; i++) {
if(ina3221_getBusVoltage(&dev, i, &bus_voltage)) // Get voltage in V
goto error_loop;
if(ina3221_getShuntValue(&dev, i, &shunt_voltage, &shunt_current)) // Get voltage in mV and currant in mA
goto error_loop;
printf("Measure number %u\n", measure_number);
printf("Bus voltage: %.02f V\n", bus_voltage );
printf("Shunt voltage: %.02f mV\n", shunt_voltage );
printf("Shunt current: %.02f mA\n\n", shunt_current );
}
vTaskDelay(5000/portTICK_PERIOD_MS);
}
error_loop:
printf("%s: error while com with INA3221\n", __func__);
for(;;){
vTaskDelay(2000 / portTICK_PERIOD_MS);
printf("%s: error loop\n", __FUNCTION__);
}
}
void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
i2c_init(PIN_SCL,PIN_SDA);
xTaskCreate(loop, "tsk1", 512, NULL, 2, NULL);
}

View file

@ -13,8 +13,6 @@
#define debug(fmt, ...) #define debug(fmt, ...)
#endif #endif
#define sign(x) ((x > 0) - (x < 0))
static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value) static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value)
{ {
i2c_start(); i2c_start();
@ -31,7 +29,7 @@ static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value)
return 0 ; return 0 ;
error: error:
debug("Error while xmitting I2C slave INA3221\n"); debug("Error while xmitting I2C slave\n");
i2c_stop(); i2c_stop();
return -EIO; return -EIO;
} }
@ -55,7 +53,7 @@ static int _wireReadRegister(uint8_t addr, uint8_t reg, uint16_t *value)
return 0; return 0;
error: error:
debug("Error while xmitting I2C slave INA3221\n"); debug("Error while xmitting I2C slave\n");
i2c_stop(); i2c_stop();
return -EIO; return -EIO;
} }
@ -131,87 +129,82 @@ int ina3221_reset(ina3221_t *dev)
{ {
dev->config.config_register = INA3221_DEFAULT_CONFIG ; //dev reset dev->config.config_register = INA3221_DEFAULT_CONFIG ; //dev reset
dev->mask.mask_register = INA3221_DEFAULT_CONFIG ; //dev reset dev->mask.mask_register = INA3221_DEFAULT_CONFIG ; //dev reset
dev->config.reset = 1 ; dev->config.rst = 1 ;
return _wireWriteRegister(dev->addr, INA3221_REG_CONFIG, dev->config.config_register); // send reset to device return _wireWriteRegister(dev->addr, INA3221_REG_CONFIG, dev->config.config_register); // send reset to device
} }
int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage) int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, float *voltage)
{ {
int16_t raw_value; int16_t raw_value;
int err = 0; int err = 0;
if ((err = _wireReadRegister(dev->addr,INA3221_REG_BUSVOLTAGE_1+channel*2, (uint16_t*)&raw_value))) if ((err = _wireReadRegister(dev->addr,INA3221_REG_BUSVOLTAGE_1+channel*2, (uint16_t*)&raw_value)))
return err; return err;
*voltage = (raw_value>>3)*8; //mV 8mV step *voltage = raw_value*0.001 ; //V 8mV step
return 0; return 0;
} }
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage, int32_t *current) int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, float *voltage, float *current)
{ {
int16_t raw_value; int16_t raw_value;
int err = 0; int err = 0;
if ((err = _wireReadRegister(dev->addr,INA3221_REG_SHUNTVOLTAGE_1+channel*2, (uint16_t*)&raw_value))) if ((err = _wireReadRegister(dev->addr,INA3221_REG_SHUNTVOLTAGE_1+channel*2, (uint16_t*)&raw_value)))
return err; return err;
*voltage = (raw_value>>3)*40 ; //uV 40uV step *voltage = raw_value*0.005; //mV 40uV step
if(!dev->shunt[channel]) if(!dev->shunt[channel])
{ {
debug("No shunt configured for channel %u. Dev:%X INA3221\n",channel+1, dev->addr); debug("No shunt configured for channel %u. Dev:%X\n",channel+1, dev->addr);
return -EINVAL; return -EINVAL;
} }
*current = *voltage/dev->shunt[channel] ; //mA = uV / mOhm *current = (*voltage*1000.0)/dev->shunt[channel] ; //mA
return 0; return 0;
} }
int ina3221_getSumShuntValue(ina3221_t *dev, int32_t *voltage) int ina3221_getSumShuntValue(ina3221_t *dev, float *voltage)
{ {
int16_t raw_value; int16_t raw_value;
int err = 0; int err = 0;
if ((err = _wireReadRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM, (uint16_t*)&raw_value))) if ((err = _wireReadRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM, (uint16_t*)&raw_value)))
return err; return err;
*voltage = (raw_value>>1)*40; //uV 40uV step *voltage = raw_value*0.02; //uV 40uV step
return 0; return 0;
} }
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current) int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, float current)
{ {
int16_t raw_value = ((current*dev->shunt[channel]+20*sign(current))/40)<<3; // round and format int16_t raw_value = current*dev->shunt[channel]*0.2; // format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ? return _wireWriteRegister(dev->addr,INA3221_REG_CRITICAL_ALERT_1+channel*2, *(uint16_t*)&raw_value);
return _wireWriteRegister(dev->addr,INA3221_REG_CRITICAL_ALERT_1+channel*2, *ptr_value);
} }
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current) int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, float current)
{ {
int16_t raw_value = ((current*dev->shunt[channel]+ 20*sign(current))/40)<<3; // round and format int16_t raw_value = current*dev->shunt[channel]*0.2 ; // format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ? return _wireWriteRegister(dev->addr,INA3221_REG_WARNING_ALERT_1+channel*2, *(uint16_t*)&raw_value);
return _wireWriteRegister(dev->addr,INA3221_REG_WARNING_ALERT_1+channel*2, *ptr_value);
} }
int ina3221_setSumWarningAlert(ina3221_t *dev, int32_t voltage) int ina3221_setSumWarningAlert(ina3221_t *dev, float voltage)
{ {
int16_t raw_value = ((voltage + 20*sign(voltage))/40)<<1; // round and format int16_t raw_value = voltage*50.0 ; // format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ? return _wireWriteRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, *(uint16_t*)&raw_value);
return _wireWriteRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, *ptr_value);
} }
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, int32_t voltage) int ina3221_setPowerValidUpperLimit(ina3221_t *dev, float voltage)
{ {
if(!dev->config.ebus) if(!dev->config.ebus)
{ {
debug("Bus not enable. Dev:%X INA3221\n", dev->addr); debug("Bus not enable. Dev:%X\n", dev->addr);
return -ENOTSUP; return -ENOTSUP;
} }
int16_t raw_value = ((voltage+4*sign(voltage))/8)<<3; // round and format int16_t raw_value = voltage*1000.0; //format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ? return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_UPPER_LIMIT, *(uint16_t*)&raw_value);
return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_UPPER_LIMIT, *ptr_value);
} }
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, int32_t voltage) int ina3221_setPowerValidLowerLimit(ina3221_t *dev, float voltage)
{ {
if(!dev->config.ebus) if(!dev->config.ebus)
{ {
debug("Bus not enable. Dev:%X INA3221\n", dev->addr); debug("Bus not enable. Dev:%X\n", dev->addr);
return -ENOTSUP; return -ENOTSUP;
} }
int16_t raw_value = ((voltage+4*sign(voltage))/8)<<3; // round and format int16_t raw_value = voltage*1000.0; // round and format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ? return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_LOWER_LIMIT, *(uint16_t*)&raw_value);
return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_LOWER_LIMIT, *ptr_value);
} }

View file

@ -85,19 +85,19 @@ typedef enum {
typedef union typedef union
{ {
struct { struct {
uint16_t esht : 1 ; // Enable/Disable shunt measure // LSB uint16_t esht : 1; // Enable/Disable shunt measure // LSB
uint16_t ebus : 1 ; // Enable/Disable bus measure uint16_t ebus : 1; // Enable/Disable bus measure
uint16_t mode : 1 ; // Single shot measure or continious mode uint16_t mode : 1; // Single shot measure or continious mode
uint16_t vsht : 3 ; // Shunt voltage conversion time uint16_t vsht : 3; // Shunt voltage conversion time
uint16_t vbus : 3 ; // Bus voltage conversion time uint16_t vbus : 3; // Bus voltage conversion time
uint16_t avg : 3 ; // number of sample collected and averaged together uint16_t avg : 3; // number of sample collected and averaged together
uint16_t ch3 : 1 ; // Enable/Disable channel 3 uint16_t ch3 : 1; // Enable/Disable channel 3
uint16_t ch2 : 1 ; // Enable/Disable channel 2 uint16_t ch2 : 1; // Enable/Disable channel 2
uint16_t ch1 : 1 ; // Enable/Disable channel 1 uint16_t ch1 : 1; // Enable/Disable channel 1
uint16_t reset : 1 ; //Set this bit to 1 to reset device // MSB uint16_t rst : 1; //Set this bit to 1 to reset device // MSB
}; };
uint16_t config_register ; uint16_t config_register;
} ina3221_config_t ; } ina3221_config_t;
/* /*
@ -123,17 +123,17 @@ typedef union
uint16_t scc1 : 1 ; // channel 1 sum (1:enable) uint16_t scc1 : 1 ; // channel 1 sum (1:enable)
uint16_t : 1 ; //Reserved //MSB uint16_t : 1 ; //Reserved //MSB
}; };
uint16_t mask_register ; uint16_t mask_register;
} ina3221_mask_t ; } ina3221_mask_t;
/* /*
* Device description * Device description
*/ */
typedef struct { typedef struct {
uint8_t addr ; // ina3221 I2C address const uint8_t addr; // ina3221 I2C address
ina3221_config_t config ; //Memory of ina3221 config const uint16_t shunt[BUS_NUMBER]; //Memory of shunt value (mOhm)
ina3221_mask_t mask ; //Memory of mask_config ina3221_config_t config; //Memory of ina3221 config
uint16_t shunt[BUS_NUMBER] ; //Memory of shunt value (mOhm) ina3221_mask_t mask; //Memory of mask_config
} ina3221_t; } ina3221_t;
/** /**
@ -221,76 +221,76 @@ int ina3221_setShuntConversionTime(ina3221_t *dev,ina3221_ct_t ct);
int ina3221_reset(ina3221_t *dev); int ina3221_reset(ina3221_t *dev);
/** /**
* Get Bus voltage (mV) * Get Bus voltage (V)
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param channel Select channel value to get * @param channel Select channel value to get
* @param voltage Data pointer to get bus voltage (mV) * @param voltage Data pointer to get bus voltage (V)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage); int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, float *voltage);
/** /**
* Get Shunt voltage (uV) and current (mA) * Get Shunt voltage (mV) and current (mA)
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param channel Select channel value to get * @param channel Select channel value to get
* @param voltage Data pointer to get shunt voltage (uV) * @param voltage Data pointer to get shunt voltage (mV)
* @param current Data pointer to get shunt voltage (mA) * @param current Data pointer to get shunt voltage (mA)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage, int32_t *current); int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, float *voltage, float *current);
/** /**
* Get Shunt-voltage (uV) sum value of selected channels * Get Shunt-voltage (mV) sum value of selected channels
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param channel Select channel value to get * @param channel Select channel value to get
* @param voltage Data pointer to get shunt voltage (uV) * @param voltage Data pointer to get shunt voltage (mV)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_getSumShuntValue(ina3221_t *dev, int32_t *voltage); int ina3221_getSumShuntValue(ina3221_t *dev, float *voltage);
/** /**
* Set Critical alert (when measurement(s) is greater that value set ) * Set Critical alert (when measurement(s) is greater that value set )
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param channel Select channel value to set * @param channel Select channel value to set
* @param current Value to set (mA) * @param current Value to set (mA) // max : 163800/shunt (mOhm)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current); int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, float current);
/** /**
* Set Warning alert (when average measurement(s) is greater that value set ) * Set Warning alert (when average measurement(s) is greater that value set )
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param channel Select channel value to set * @param channel Select channel value to set
* @param current Value to set (mA) * @param current Value to set (mA) // max : 163800/shunt (mOhm)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current); int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, float current);
/** /**
* Set Sum Warning alert (Compared to each completed cycle of all selected channels : Sum register ) * Set Sum Warning alert (Compared to each completed cycle of all selected channels : Sum register )
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param voltage voltage to set (uV) : 40uV step * @param voltage voltage to set (mV) // max : 655.32
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_setSumWarningAlert(ina3221_t *dev, int32_t voltage); int ina3221_setSumWarningAlert(ina3221_t *dev, float voltage);
/** /**
* Set Power-valid upper-limit ( To determine if power conditions are met.)( bus need enable ) * Set Power-valid upper-limit ( To determine if power conditions are met.)( bus need enable )
* If bus voltage exceed the value set, PV pin is high * If bus voltage exceed the value set, PV pin is high
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param voltage voltage to set (mV) : 8mV step * @param voltage voltage to set (V)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, int32_t voltage); int ina3221_setPowerValidUpperLimit(ina3221_t *dev, float voltage);
/** /**
* Set Power-valid lower-limit ( To determine if power conditions are met.)( bus need enable ) * Set Power-valid lower-limit ( To determine if power conditions are met.)( bus need enable )
* If bus voltage drops below the value set, PV pin is low * If bus voltage drops below the value set, PV pin is low
* @param dev Pointer to device descriptor * @param dev Pointer to device descriptor
* @param voltage voltage to set (mV) : 8mV step * @param voltage voltage to set (V)
* @return Non-zero if error occured * @return Non-zero if error occured
*/ */
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, int32_t voltage); int ina3221_setPowerValidLowerLimit(ina3221_t *dev, float voltage);
#ifdef __cplusplus #ifdef __cplusplus
} }