mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/ina3221: Added SAUL integration
This commit is contained in:
parent
5311de7131
commit
7e8cce875a
178
drivers/ina3221/ina3221_saul.c
Normal file
178
drivers/ina3221/ina3221_saul.c
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_ina3221
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief SAUL adaption for INA3221 device
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "phydat.h"
|
||||
#include "saul.h"
|
||||
#include "ina3221.h"
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define SAUL_INA3221_NO_VALUE (0)
|
||||
|
||||
static int read_bus_voltage(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
ina3221_enable_ch_t ench = 0;
|
||||
int16_t voltage[INA3221_NUM_CH] = { 0 };
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
ina3221_channel_t ch = (((ench & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) |
|
||||
((ench & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) |
|
||||
((ench & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0));
|
||||
ina3221_read_bus_mv(_dev, ch, voltage, NULL);
|
||||
res->scale = -3; /* mV to V*/
|
||||
res->unit = UNIT_V;
|
||||
for (int i = 0, j = 0; i < INA3221_NUM_CH; i++) {
|
||||
res->val[i] = (ch & (1 << i))
|
||||
? voltage[j++] : SAUL_INA3221_NO_VALUE;
|
||||
}
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int read_current(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
ina3221_enable_ch_t ench = 0;
|
||||
int32_t shunt_uv[INA3221_NUM_CH] = { 0 };
|
||||
int32_t current[INA3221_NUM_CH] = { 0 };
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
ina3221_channel_t ch = (((ench & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) |
|
||||
((ench & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) |
|
||||
((ench & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0));
|
||||
ina3221_read_shunt_uv(_dev, ch, shunt_uv, NULL);
|
||||
ina3221_calculate_current_ua(_dev, ch, shunt_uv, current);
|
||||
res->scale = -6; /* uA to A*/
|
||||
res->unit = UNIT_A;
|
||||
for (int i = 0, j = 0; i < INA3221_NUM_CH; i++) {
|
||||
res->val[i] = (ch & (1 << i))
|
||||
? (int16_t)current[j++] : SAUL_INA3221_NO_VALUE;
|
||||
}
|
||||
ina3221_ch_align(ch, current, current, sizeof(int32_t));
|
||||
phydat_fit(res, current, 3);
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int read_power(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
ina3221_enable_ch_t ench = 0;
|
||||
int32_t shunt_uv[INA3221_NUM_CH] = { 0 };
|
||||
int32_t current_ua[INA3221_NUM_CH] = { 0 };
|
||||
int16_t bus_mv[INA3221_NUM_CH] = { 0 };
|
||||
int32_t power[INA3221_NUM_CH] = { 0 };
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
ina3221_channel_t ch = (((ench & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) |
|
||||
((ench & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) |
|
||||
((ench & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0));
|
||||
int num_ch_shunt_uv = ina3221_read_shunt_uv(_dev, ch, shunt_uv, NULL);
|
||||
ina3221_calculate_current_ua(_dev, ch, shunt_uv, current_ua);
|
||||
ina3221_read_bus_mv(_dev, ch, bus_mv, NULL);
|
||||
ina3221_calculate_power_uw(bus_mv, current_ua, num_ch_shunt_uv, power);
|
||||
res->scale = -6; /* uW to W*/
|
||||
res->unit = UNIT_W;
|
||||
for (int i = 0, j = 0; i < INA3221_NUM_CH; i++) {
|
||||
res->val[i] = (ch & (1 << i))
|
||||
? (int16_t)power[j++] : SAUL_INA3221_NO_VALUE;
|
||||
}
|
||||
ina3221_ch_align(ch, power, power, sizeof(int32_t));
|
||||
phydat_fit(res, power, 3);
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int read_shunt_voltage_sum(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
ina3221_enable_ch_t ench = 0;
|
||||
int32_t shunt_voltage_sum = SAUL_INA3221_NO_VALUE;
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
ina3221_read_shunt_sum_uv(_dev, &shunt_voltage_sum, NULL);
|
||||
res->scale = -6; /* uV to V*/
|
||||
res->unit = UNIT_V;
|
||||
res->val[0] = shunt_voltage_sum;
|
||||
phydat_fit(res, &shunt_voltage_sum, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int configure_channel(const void *dev, phydat_t *data)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
ina3221_enable_ch_t ench =
|
||||
((data->val[0] & INA3221_CH1) ? INA3221_ENABLE_CH1 : 0) |
|
||||
((data->val[0] & INA3221_CH2) ? INA3221_ENABLE_CH2 : 0) |
|
||||
((data->val[0] & INA3221_CH3) ? INA3221_ENABLE_CH3 : 0);
|
||||
|
||||
if (_ina3221_set_enable_channel(_dev, ench) != INA3221_OK) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int configure_channel_sum(const void *dev, phydat_t *data)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
ina3221_enable_sum_ch_t esch =
|
||||
((data->val[0] & INA3221_CH1) ? INA3221_ENABLE_SUM_CH1 : 0) |
|
||||
((data->val[0] & INA3221_CH2) ? INA3221_ENABLE_SUM_CH2 : 0) |
|
||||
((data->val[0] & INA3221_CH3) ? INA3221_ENABLE_SUM_CH3 : 0);
|
||||
|
||||
if (_ina3221_set_enable_sum_channel(_dev, esch) != INA3221_OK) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
const saul_driver_t ina3221_saul_drivers[] = {
|
||||
{
|
||||
.read = read_bus_voltage,
|
||||
.write = configure_channel,
|
||||
.type = SAUL_SENSE_VOLTAGE
|
||||
},
|
||||
{
|
||||
.read = read_current,
|
||||
.write = configure_channel,
|
||||
.type = SAUL_SENSE_CURRENT
|
||||
},
|
||||
{
|
||||
.read = read_power,
|
||||
.write = configure_channel,
|
||||
.type = SAUL_SENSE_POWER
|
||||
},
|
||||
{
|
||||
.read = read_shunt_voltage_sum,
|
||||
.write = configure_channel_sum,
|
||||
.type = SAUL_SENSE_VOLTAGE
|
||||
}
|
||||
};
|
@ -105,6 +105,7 @@ enum {
|
||||
SAUL_SENSE_CAPACITANCE = 0x97, /**< sensor: capacitance */
|
||||
SAUL_SENSE_VOLTAGE = 0x98, /**< sensor: voltage */
|
||||
SAUL_SENSE_PH = 0x99, /**< sensor: pH */
|
||||
SAUL_SENSE_POWER = 0x9A, /**< sensor: (electrical) power */
|
||||
SAUL_CLASS_ANY = 0xff /**< any device - wildcard */
|
||||
/* extend this list as needed... */
|
||||
};
|
||||
|
@ -62,6 +62,7 @@ const char *saul_class_to_str(const uint8_t class_id)
|
||||
case SAUL_SENSE_CAPACITANCE: return "SENSE_CAPACITANCE";
|
||||
case SAUL_SENSE_VOLTAGE: return "SENSE_VOLTAGE";
|
||||
case SAUL_SENSE_PH: return "SENSE_PH";
|
||||
case SAUL_SENSE_POWER: return "SENSE_POWER";
|
||||
case SAUL_CLASS_ANY: return "CLASS_ANY";
|
||||
default: return "CLASS_UNKNOWN";
|
||||
}
|
||||
|
@ -422,6 +422,10 @@ void auto_init(void)
|
||||
extern void auto_init_hts221(void);
|
||||
auto_init_hts221();
|
||||
#endif
|
||||
#ifdef MODULE_INA3221
|
||||
extern void auto_init_ina3221(void);
|
||||
auto_init_ina3221();
|
||||
#endif
|
||||
#ifdef MODULE_IO1_XPLAINED
|
||||
extern void auto_init_io1_xplained(void);
|
||||
auto_init_io1_xplained();
|
||||
|
65
sys/auto_init/saul/auto_init_ina3221.c
Normal file
65
sys/auto_init/saul/auto_init_ina3221.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_auto_init_saul
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Auto initialization for HTS221 devices
|
||||
*
|
||||
* @author Fabian Hüßler <fabian.huessler@ovgu.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_INA3221
|
||||
|
||||
#include "assert.h"
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
#include "ina3221_params.h"
|
||||
#include "ina3221.h"
|
||||
|
||||
#define INA3221_NUM ARRAY_SIZE(ina3221_params)
|
||||
|
||||
#define INA3221_SAUL_INFO_NUM ARRAY_SIZE(ina3221_saul_info)
|
||||
|
||||
#define INA3221_SAUL_DRIVERS_NUM (4)
|
||||
extern const saul_driver_t ina3221_saul_drivers[INA3221_SAUL_DRIVERS_NUM];
|
||||
|
||||
static ina3221_t ina3221_devs[INA3221_NUM];
|
||||
|
||||
static saul_reg_t saul_entries[INA3221_NUM * INA3221_SAUL_DRIVERS_NUM];
|
||||
|
||||
void auto_init_ina3221(void)
|
||||
{
|
||||
assert(INA3221_SAUL_INFO_NUM == INA3221_SAUL_DRIVERS_NUM * INA3221_NUM);
|
||||
|
||||
for (unsigned i = 0; i < INA3221_NUM; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing ina3221 #%u\n", i);
|
||||
int status = ina3221_init(&ina3221_devs[i], &ina3221_params[i]);
|
||||
if (status != INA3221_OK) {
|
||||
LOG_ERROR("[auto_init_saul] error(%d) initializing ina3221 #%u\n",
|
||||
status, i);
|
||||
continue;
|
||||
}
|
||||
for (unsigned j = 0; j < INA3221_SAUL_DRIVERS_NUM; j++) {
|
||||
saul_entries[i * INA3221_SAUL_DRIVERS_NUM + j] = (saul_reg_t) {
|
||||
.dev = &ina3221_devs[i],
|
||||
.name =
|
||||
ina3221_saul_info[i * INA3221_SAUL_DRIVERS_NUM + j].name,
|
||||
.driver = &ina3221_saul_drivers[j]
|
||||
};
|
||||
saul_reg_add(&saul_entries[i * INA3221_SAUL_DRIVERS_NUM + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
typedef int dont_be_pedantic;
|
||||
#endif /* MODULE_INA3221 */
|
@ -94,6 +94,7 @@ enum {
|
||||
/* electricity */
|
||||
UNIT_A, /**< Ampere */
|
||||
UNIT_V, /**< Volts */
|
||||
UNIT_W, /**< Watt */
|
||||
UNIT_GS, /**< gauss */
|
||||
UNIT_DBM, /**< decibel-milliwatts */
|
||||
UNIT_COULOMB, /**< coulomb */
|
||||
|
@ -92,6 +92,7 @@ const char *phydat_unit_to_str(uint8_t unit)
|
||||
case UNIT_GR: return "G";
|
||||
case UNIT_A: return "A";
|
||||
case UNIT_V: return "V";
|
||||
case UNIT_W: return "W";
|
||||
case UNIT_DBM: return "dBm";
|
||||
case UNIT_GS: return "Gs";
|
||||
case UNIT_BAR: return "Bar";
|
||||
|
Loading…
Reference in New Issue
Block a user