diff --git a/examples/ina3221_test/Makefile b/examples/ina3221_test/Makefile index 328435a..a257987 100644 --- a/examples/ina3221_test/Makefile +++ b/examples/ina3221_test/Makefile @@ -1,3 +1,3 @@ PROGRAM=ina3221_test -EXTRA_COMPONENTS = extras/i2c extras/mcp4725 +EXTRA_COMPONENTS = extras/i2c extras/ina3221 include ../../common.mk diff --git a/examples/ina3221_test/main.c b/examples/ina3221_test/main.c index 9d4f3ea..709ae82 100644 --- a/examples/ina3221_test/main.c +++ b/examples/ina3221_test/main.c @@ -13,20 +13,23 @@ #include #include "ina3221/ina3221.h" -#define PIN_SCL 4 +#define PIN_SCL 5 #define PIN_SDA 2 #define ADDR INA3221_ADDR_0 -//#define STRUCT_SETTING 1 +#define WARNING_CHANNEL 1 +#define WARNING_CURRENT (40.0) + +//#define STRUCT_SETTING 0 #define MODE false // true : continuous measurements // false : trigger measurements - -void ina_tast(void *pvParameters) +void ina_measure(void *pvParameters) { uint32_t measure_number = 0; float bus_voltage; float shunt_voltage; float shunt_current; + bool warning = false ; // Create ina3221 device ina3221_t dev = { @@ -37,7 +40,7 @@ void ina_tast(void *pvParameters) }; #ifndef STRUCT_SETTING - if(ina3221_setting(&dev ,false, true, MODE)) // mode selection , bus and shunt activated + if(ina3221_setting(&dev ,MODE, true, true)) // mode selection , bus and shunt activated goto error_loop; if(ina3221_enableChannel(&dev , true, true, true)) // Enable all channels goto error_loop; @@ -61,15 +64,28 @@ void ina_tast(void *pvParameters) goto error_loop; #endif + ina3221_setWarningAlert(&dev, WARNING_CHANNEL-1, WARNING_CURRENT); //Set security flag overcurrent + while(1) { measure_number++; #if !MODE + if (ina3221_trigger(&dev)) // Start a measure + goto error_loop; do { - if (ina3221_trigger(&dev)) // Start a measure & get mask + printf("measure not ready"); + if (ina3221_getStatus(&dev)) // get mask goto error_loop; + vTaskDelay(100/portTICK_PERIOD_MS); + if(dev.mask.wf&(1<<(3-WARNING_CHANNEL))) + warning = true ; } while(!(dev.mask.cvrf)); // check if measure done +#else + if (ina3221_getStatus(&dev)) // get mask + goto error_loop; + if(dev.mask.wf&(1<<(3-WARNING_CHANNEL))) + warning = true ; #endif for (uint8_t i = 0 ; i < BUS_NUMBER ; i++) { @@ -78,11 +94,14 @@ void ina_tast(void *pvParameters) 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 ); + printf("\nC%u:Measure number %u\n",i+1,measure_number); + if (warning && (i+1) == WARNING_CHANNEL) printf("C%u:Warning Current > %.2f mA !!\n",i+1,WARNING_CURRENT); + printf("C%u:Bus voltage: %.02f V\n",i+1,bus_voltage ); + printf("C%u:Shunt voltage: %.02f mV\n",i+1,shunt_voltage ); + printf("C%u:Shunt current: %.02f mA\n\n",i+1,shunt_current ); + } + warning = false ; vTaskDelay(5000/portTICK_PERIOD_MS); } @@ -102,5 +121,5 @@ void user_init(void) i2c_init(PIN_SCL,PIN_SDA); - xTaskCreate(ina_tast, "Measurements_task", 512, NULL, 2, NULL); + xTaskCreate(ina_measure, "Measurements_task", 512, NULL, 2, NULL); } diff --git a/extras/ina3221/ina3221.c b/extras/ina3221/ina3221.c index 23b39ec..f507b2c 100644 --- a/extras/ina3221/ina3221.c +++ b/extras/ina3221/ina3221.c @@ -1,8 +1,11 @@ -/* - * ina3221.c +/** + * INA3221 driver for esp-open-rtos. * - * Created on: 4 oct. 2016 - * Author: lilian + * Copyright (c) 2016 Zaltora (https://github.com/Zaltora) + * + * MIT Licensed as described in the file LICENSE + * + * @todo Interupt system for critical and warning alert pin */ #include "ina3221.h" @@ -25,6 +28,7 @@ static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value) if (!i2c_write(value & 0xFF)) goto error; i2c_stop(); + debug("Data write to %02X : %02X+%04X\n",addr,reg,value); return 0 ; @@ -36,7 +40,7 @@ static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value) static int _wireReadRegister(uint8_t addr, uint8_t reg, uint16_t *value) { - uint8_t* tampon = (uint8_t*)&value; + uint8_t tampon[2] = { 0 } ; i2c_start(); if (!i2c_write(addr<<1)) // adress + W @@ -50,6 +54,9 @@ static int _wireReadRegister(uint8_t addr, uint8_t reg, uint16_t *value) tampon[1] = i2c_read(0); tampon[0] = i2c_read(1); i2c_stop(); + *value = tampon[1]<<8 | tampon[0] ; + debug("Data read from %02X: %02X+%04X\n",addr,reg,*value); + return 0; error: @@ -59,20 +66,33 @@ static int _wireReadRegister(uint8_t addr, uint8_t reg, uint16_t *value) } int ina3221_trigger(ina3221_t *dev) +{ + return _wireWriteRegister(dev->addr, INA3221_REG_CONFIG, dev->config.config_register); +} + +int ina3221_getStatus(ina3221_t *dev) { return _wireReadRegister(dev->addr, INA3221_REG_MASK, &dev->mask.mask_register); } int ina3221_sync(ina3221_t *dev) { - uint16_t ptr_config ; + uint16_t ptr_data; int err = 0; - if ((err = _wireReadRegister(dev->addr, INA3221_REG_CONFIG, &ptr_config))) // Read config + //////////////////////// Sync config register + if ((err = _wireReadRegister(dev->addr, INA3221_REG_CONFIG, &ptr_data))) // Read config return err; - if( ptr_config != dev->config.config_register) { + if( ptr_data != dev->config.config_register) { if ((err = _wireWriteRegister(dev->addr, INA3221_REG_CONFIG, dev->config.config_register))) // Update config return err; } + //////////////////////// Sync mask register config + if ((err = _wireReadRegister(dev->addr, INA3221_REG_MASK, &ptr_data))) // Read mask + return err; + if( (ptr_data & INA3221_MASK_CONFIG) != (dev->mask.mask_register & INA3221_MASK_CONFIG)) { + if ((err = _wireWriteRegister(dev->addr, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG))) // Update config + return err; + } return 0; } @@ -97,14 +117,14 @@ int ina3221_enableChannelSum(ina3221_t *dev ,bool ch1, bool ch2, bool ch3) dev->mask.scc1 = ch1; dev->mask.scc2 = ch2; dev->mask.scc3 = ch3; - return _wireWriteRegister(dev->addr, INA3221_REG_MASK, dev->mask.mask_register); + return _wireWriteRegister(dev->addr, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG); } int ina3221_enableLatchPin(ina3221_t *dev ,bool warning, bool critical) { dev->mask.wen = warning; dev->mask.cen = critical; - return _wireWriteRegister(dev->addr, INA3221_REG_MASK, dev->mask.mask_register); + return _wireWriteRegister(dev->addr, INA3221_REG_MASK, dev->mask.mask_register & INA3221_MASK_CONFIG); } int ina3221_setAverage(ina3221_t *dev, ina3221_avg_t avg) diff --git a/extras/ina3221/ina3221.h b/extras/ina3221/ina3221.h index 667a913..000919c 100644 --- a/extras/ina3221/ina3221.h +++ b/extras/ina3221/ina3221.h @@ -1,14 +1,17 @@ -/* - * ina3221.h +/** + * INA3221 driver for esp-open-rtos. + * + * Copyright (c) 2016 Zaltora (https://github.com/Zaltora) + * + * MIT Licensed as described in the file LICENSE * - * Created on: 4 oct. 2016 - * Author: lilian */ #ifndef INA3221_H_ #define INA3221_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -42,6 +45,7 @@ extern "C" { #define INA3221_DEFAULT_POWER_UPPER_LIMIT (0x2710) //10V #define INA3221_DEFAULT_POWER_LOWER_LIMIT (0x2328) //9V +#define INA3221_MASK_CONFIG (0x7C00) /* * Numbrer of samples */ @@ -109,16 +113,12 @@ typedef union uint16_t cvrf : 1 ; // Conversion ready flag (1: ready) // LSB uint16_t tcf : 1 ; // Timing control flag uint16_t pvf : 1 ; // Power valid flag - uint16_t wf3 : 1 ; // Warning alert flag (Read mask to clear) - uint16_t wf2 : 1 ; // Warning alert flag (Read mask to clear) - uint16_t wf1 : 1 ; // Warning alert flag (Read mask to clear) + uint16_t wf : 3 ; // Warning alert flag (Read mask to clear) (order : Channel1:channel2:channel3) uint16_t sf : 1 ; // Sum alert flag (Read mask to clear) - uint16_t cf3 : 1 ; // Critical alert flag (Read mask to clear) - uint16_t cf2 : 1 ; // Critical alert flag (Read mask to clear) - uint16_t cf1 : 1 ; // Critical alert flag (Read mask to clear) + uint16_t cf : 3 ; // Critical alert flag (Read mask to clear) (order : Channel1:channel2:channel3) uint16_t cen : 1 ; // Critical alert latch (1:enable) uint16_t wen : 1 ; // Warning alert latch (1:enable) - uint16_t scc3 : 1 ; // channel 2 sum (1:enable) + uint16_t scc3 : 1 ; // channel 3 sum (1:enable) uint16_t scc2 : 1 ; // channel 2 sum (1:enable) uint16_t scc1 : 1 ; // channel 1 sum (1:enable) uint16_t : 1 ; //Reserved //MSB @@ -137,19 +137,26 @@ typedef struct { } ina3221_t; /** - * sync internal config buffer with external device register + * sync internal config buffer and mask with external device register ( When struct is manually set ) * @param dev Pointer to device descriptor * @return Non-zero if error occured */ int ina3221_sync(ina3221_t *dev); /** - * get mask register from the device (trig measurement if single-shot mode) + * send current config register to trig a measurement in single-shot mode * @param dev Pointer to device descriptor * @return Non-zero if error occured */ int ina3221_trigger(ina3221_t *dev); +/** + * get mask register from the device ( Used to read flags ) + * @param dev Pointer to device descriptor + * @return Non-zero if error occured + */ +int ina3221_getStatus(ina3221_t *dev); + /** * Set options for bus and shunt * @param dev Pointer to device descriptor