summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/stm32/usb_power.c99
-rw-r--r--chip/stm32/usb_power.h56
-rw-r--r--extra/usb_power/board.README7
-rw-r--r--extra/usb_power/board/marlin/marlin_pvc.scenario1
-rw-r--r--extra/usb_power/marlin_v.scenario1
-rwxr-xr-xextra/usb_power/powerlog.py130
6 files changed, 230 insertions, 64 deletions
diff --git a/chip/stm32/usb_power.c b/chip/stm32/usb_power.c
index ad2b6d55d6..bf9e824f84 100644
--- a/chip/stm32/usb_power.c
+++ b/chip/stm32/usb_power.c
@@ -16,8 +16,6 @@
#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args)
-
-
static int usb_power_init_inas(struct usb_power_config const *config);
static int usb_power_read(struct usb_power_config const *config);
static int usb_power_write_line(struct usb_power_config const *config);
@@ -102,9 +100,6 @@ static int usb_power_write_line(struct usb_power_config const *config)
return bytes;
}
- CPRINTS("usb_power_write_line: no data rs: %d, rc: %d",
- USB_POWER_RECORD_SIZE(state->ina_count),
- USB_POWER_MAX_CACHED(state->ina_count));
return 0;
}
@@ -133,12 +128,12 @@ static int usb_power_state_stop(struct usb_power_config const *config)
return USB_POWER_ERROR_NOT_CAPTURING;
}
- state->state = USB_POWER_STATE_SETUP;
+ state->state = USB_POWER_STATE_OFF;
state->reports_head = 0;
state->reports_tail = 0;
state->reports_xmit_active = 0;
state->stride_bytes = 0;
- CPRINTS("[STOP] STATE: CAPTURING -> SETUP");
+ CPRINTS("[STOP] STATE: CAPTURING -> OFF");
return USB_POWER_SUCCESS;
}
@@ -149,14 +144,16 @@ static int usb_power_state_start(struct usb_power_config const *config,
{
struct usb_power_state *state = config->state;
int integration_us = cmd->start.integration_us;
+ int ret;
if (state->state != USB_POWER_STATE_SETUP) {
CPRINTS("[START] Error not setup.");
return USB_POWER_ERROR_NOT_SETUP;
}
- if (count != 6) {
- CPRINTS("[START] Error count %d is not 6", (int)count);
+ if (count != sizeof(struct usb_power_command_start)) {
+ CPRINTS("[START] Error count %d is not %d", (int)count,
+ sizeof(struct usb_power_command_start));
return USB_POWER_ERROR_READ_SIZE;
}
@@ -170,7 +167,10 @@ static int usb_power_state_start(struct usb_power_config const *config,
state->max_cached = USB_POWER_MAX_CACHED(state->ina_count);
state->integration_us = integration_us;
- usb_power_init_inas(config);
+ ret = usb_power_init_inas(config);
+
+ if (ret)
+ return USB_POWER_ERROR_INVAL;
state->state = USB_POWER_STATE_CAPTURING;
CPRINTS("[START] STATE: SETUP -> CAPTURING %dus", integration_us);
@@ -198,7 +198,7 @@ static int usb_power_state_settime(struct usb_power_config const *config,
else
config->state->wall_offset = 0;
- return EC_SUCCESS;
+ return USB_POWER_SUCCESS;
}
@@ -207,6 +207,7 @@ static int usb_power_state_addina(struct usb_power_config const *config,
{
struct usb_power_state *state = config->state;
struct usb_power_ina_cfg *ina;
+ int i;
/* Only valid from OFF or SETUP */
if ((state->state != USB_POWER_STATE_OFF) &&
@@ -232,12 +233,48 @@ static int usb_power_state_addina(struct usb_power_config const *config,
state->ina_count = 0;
}
+ if ((cmd->addina.type < USBP_INA231_POWER) ||
+ (cmd->addina.type > USBP_INA231_SHUNTV)) {
+ CPRINTS("[ADDINA] Error INA type 0x%x invalid",
+ (int)(cmd->addina.type));
+ return USB_POWER_ERROR_INVAL;
+ }
+
+ if (cmd->addina.rs == 0) {
+ CPRINTS("[ADDINA] Error INA resistance cannot be zero!");
+ return USB_POWER_ERROR_INVAL;
+ }
+
/* Select INA to configure */
ina = state->ina_cfg + state->ina_count;
ina->port = cmd->addina.port;
ina->addr = (cmd->addina.addr) << 1; /* 7 to 8 bit addr. */
ina->rs = cmd->addina.rs;
+ ina->type = cmd->addina.type;
+
+ /*
+ * INAs can be shared, in that they will have various values
+ * (and therefore registers) read from them each cycle, including
+ * power, voltage, current. If only a single value is read,
+ * we an use i2c_readagain for faster transactions as we don't
+ * have to respecify the address.
+ */
+ ina->shared = 0;
+#ifdef USB_POWER_VERBOSE
+ ina->shared = 1;
+#endif
+
+ /* Check if shared with previously configured INAs. */
+ for (i = 0; i < state->ina_count; i++) {
+ struct usb_power_ina_cfg *tmp = state->ina_cfg + i;
+
+ if ((tmp->port == ina->port) &&
+ (tmp->addr == ina->addr)) {
+ ina->shared = 1;
+ tmp->shared = 1;
+ }
+ }
state->ina_count += 1;
return USB_POWER_SUCCESS;
@@ -305,7 +342,6 @@ static int usb_power_read(struct usb_power_config const *config)
if (ret)
return EC_SUCCESS;
- CPRINTS("[CAP] busy");
result = USB_POWER_ERROR_BUSY;
} else {
CPRINTS("[STOP] Error not capturing.");
@@ -353,7 +389,22 @@ static int usb_power_read(struct usb_power_config const *config)
#define INA231_MODE_BUS 0x6
#define INA231_MODE_BOTH 0x7
+int reg_type_mapping(enum usb_power_ina_type ina_type)
+{
+ switch (ina_type) {
+ case USBP_INA231_POWER:
+ return INA231_REG_PWR;
+ case USBP_INA231_BUSV:
+ return INA231_REG_BUSV;
+ case USBP_INA231_CURRENT:
+ return INA231_REG_CURR;
+ case USBP_INA231_SHUNTV:
+ return INA231_REG_RSHV;
+ default:
+ return INA231_REG_CONF;
+ }
+}
uint16_t ina2xx_readagain(uint8_t port, uint8_t addr)
{
@@ -407,6 +458,7 @@ int ina2xx_write(uint8_t port, uint8_t addr, uint8_t reg, uint16_t val)
*/
/* INA231 integration and averaging time presets, indexed by register value */
+#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
static const int average_settings[] = {
1, 4, 16, 64, 128, 256, 512, 1024};
static const int conversion_time_us[] = {
@@ -426,14 +478,14 @@ static int usb_power_init_inas(struct usb_power_config const *config)
}
/* Find an INA preset integration time less than specified */
- while (shunt_time < 7) {
+ while (shunt_time < (NELEMS(conversion_time_us) - 1)) {
if (conversion_time_us[shunt_time + 1] > target_us)
break;
shunt_time++;
}
/* Find an averaging setting from the INA presets that fits. */
- while (avg < 7) {
+ while (avg < (NELEMS(average_settings) - 1)) {
if ((conversion_time_us[shunt_time] *
average_settings[avg + 1])
> target_us)
@@ -464,6 +516,7 @@ static int usb_power_init_inas(struct usb_power_config const *config)
* CurrentLSB = uA per div = 80mV / (Rsh * 2^15)
* CurrentLSB 100x uA = 100x 80000000nV / (Rsh mOhm * 0x8000)
*/
+ /* TODO: allow voltage readings if no sense resistor. */
if (ina->rs == 0)
return -1;
@@ -524,7 +577,10 @@ static int usb_power_init_inas(struct usb_power_config const *config)
* will be cached and all ina2xx_readagain() calls will read
* from the same address.
*/
- ina2xx_read(ina->port, ina->addr, INA231_REG_PWR);
+ ina2xx_read(ina->port, ina->addr, reg_type_mapping(ina->type));
+#ifdef USB_POWER_VERBOSE
+ CPRINTS("[CAP] %d (%d,0x%02x): type:%d", (int)(ina->type));
+#endif
}
return EC_SUCCESS;
@@ -570,7 +626,7 @@ static int usb_power_get_samples(struct usb_power_config const *config)
r->timestamp = time;
for (i = 0; i < state->ina_count; i++) {
- int power;
+ int regval;
struct usb_power_ina_cfg *ina = inas + i;
/* Read INA231.
@@ -578,11 +634,16 @@ static int usb_power_get_samples(struct usb_power_config const *config)
* Readagain cached this address so we'll save an I2C
* transaction.
*/
- power = ina2xx_readagain(ina->port, ina->addr);
- r->power[i] = power;
+ if (ina->shared)
+ regval = ina2xx_read(ina->port, ina->addr,
+ reg_type_mapping(ina->type));
+ else
+ regval = ina2xx_readagain(ina->port, ina->addr);
+ r->power[i] = regval;
#ifdef USB_POWER_VERBOSE
{
int current;
+ int power;
int voltage;
int bvoltage;
@@ -590,7 +651,6 @@ static int usb_power_get_samples(struct usb_power_config const *config)
bvoltage = ina2xx_read(ina->port, ina->addr, INA231_REG_BUSV);
current = ina2xx_read(ina->port, ina->addr, INA231_REG_CURR);
power = ina2xx_read(ina->port, ina->addr, INA231_REG_PWR);
- }
{
int uV = ((int)voltage * 25) / 10;
int mV = ((int)bvoltage * 125) / 100;
@@ -604,6 +664,7 @@ static int usb_power_get_samples(struct usb_power_config const *config)
"%duW v:%04x, b:%04x, p:%04x",
uV, mV, uA, CuA, uW, voltage, bvoltage, power);
}
+ }
#endif
}
diff --git a/chip/stm32/usb_power.h b/chip/stm32/usb_power.h
index 976f849404..ff76603e63 100644
--- a/chip/stm32/usb_power.h
+++ b/chip/stm32/usb_power.h
@@ -15,56 +15,60 @@
/*
* Command:
+ *
+ * Commands are a 16 bit value, with optional command dependent data.
* +--------------+-----------------------------------+
* | command : 2B | |
* +--------------+-----------------------------------+
*
- * command: 2 bytes
+ * Responses are an 8 bit status value, with optional data.
+ * +----------+-----------------------------------+
+ * | res : 1B | |
+ * +----------+-----------------------------------+
*
* reset: 0x0000
- *
* +--------+
* | 0x0000 |
* +--------+
*
* stop: 0x0001
- *
* +--------+
* | 0x0001 |
* +--------+
*
* addina: 0x0002
- *
- * +--------+--------------------------+-------------+--------------+-----------+-------------+--------+
- * | 0x0002 | 1B: 4b: extender 4b: bus | 1B:INA type | 1B: INA addr | 1B: extra | 4B: voltage | 4B: Rs |
- * +--------+--------------------------+-------------+--------------+-----------+-------------+--------+
+ * +--------+--------------------------+-------------+--------------+-----------+--------+
+ * | 0x0002 | 1B: 4b: extender 4b: bus | 1B:INA type | 1B: INA addr | 1B: extra | 4B: Rs |
+ * +--------+--------------------------+-------------+--------------+-----------+--------+
*
* start: 0x0003
- *
* +--------+----------------------+
* | 0x0003 | 4B: integration time |
* +--------+----------------------+
*
- * next: 0x0004
+ * start response:
+ * +-------------+-----------------------------+
+ * | status : 1B | Actual integration time: 4B |
+ * +-------------+-----------------------------+
*
+ * next: 0x0004
* +--------+
* | 0x0004 |
* +--------+
*
- * settime: 0x0005
+ * next response:
+ * +-------------+----------+----------------+----------------------------+
+ * | status : 1B | size: 1B | timestamp : 8B | payload : may span packets |
+ * +-------------+----------+----------------+----------------------------+
*
+ * settime: 0x0005
* +--------+---------------------+
* | 0x0005 | 8B: Wall clock time |
* +--------+---------------------+
*
*
+ * Status: 1 byte status
*
- * Response:
- * +-------------+----------+----------------+------------------+
- * | status : 1B | size: 1B | timestamp : 8B | payload : <= 58B | Pad to multiple of 4 byte.
- * +-------------+----------+----------------+------------------+
- *
- * status: 1 byte status
* 0x00: Success
* 0x01: I2C Error
* 0x02: Overflow
@@ -75,16 +79,16 @@
* 0x06: Busy, outgoing queue is empty.
* 0x07: Size, command length is incorrect for command type..
* 0x08: More INAs specified than board limit.
+ * 0x09: Invalid input, eg. invalid INA type.
* 0x80: Unknown error
*
* size: 1 byte incoming INA reads count
*
* timestamp: 4 byte timestamp associated with these samples
*
- * read payload: up to 58 bytes of data, 29x INA reads of current
- *
*/
+/* 8b status field. */
enum usb_power_error {
USB_POWER_SUCCESS = 0x00,
USB_POWER_ERROR_I2C = 0x01,
@@ -95,9 +99,11 @@ enum usb_power_error {
USB_POWER_ERROR_BUSY = 0x06,
USB_POWER_ERROR_READ_SIZE = 0x07,
USB_POWER_ERROR_FULL = 0x08,
+ USB_POWER_ERROR_INVAL = 0x09,
USB_POWER_ERROR_UNKNOWN = 0x80,
};
+/* 16b command field. */
enum usb_power_command {
USB_POWER_CMD_RESET = 0x0000,
USB_POWER_CMD_STOP = 0x0001,
@@ -107,6 +113,15 @@ enum usb_power_command {
USB_POWER_CMD_SETTIME = 0x0005,
};
+/* Addina "INA Type" field. */
+enum usb_power_ina_type {
+ USBP_INA231_POWER = 0x01,
+ USBP_INA231_BUSV = 0x02,
+ USBP_INA231_CURRENT = 0x03,
+ USBP_INA231_SHUNTV = 0x04,
+};
+
+/* Internal state machine values */
enum usb_power_states {
USB_POWER_STATE_OFF = 0,
USB_POWER_STATE_SETUP,
@@ -132,6 +147,11 @@ struct usb_power_ina_cfg {
int rs;
/* uA per div as reported from INA */
int scale;
+
+ /* Is this power, shunt voltage, bus voltage, or current? */
+ int type;
+ /* Is this INA returning the one value only and can use readagain? */
+ int shared;
};
diff --git a/extra/usb_power/board.README b/extra/usb_power/board.README
index b898e16540..41c30c8e38 100644
--- a/extra/usb_power/board.README
+++ b/extra/usb_power/board.README
@@ -45,10 +45,16 @@ Scenario files:
Scenario files contain the set of rails to monitor in this session. The
file format is simply a list of rail names from the board file.
+Optionally, you can specify the type of measurement, from the set of
+"POWER", "BUSV", "CURRENT", "SHUNTV". If not specified, the default is
+power.
+
example.scenario:
[
"railname",
"another_railname",
+["railname", "BUSV"],
+["railname", "CURRENT"],
...
]
@@ -82,6 +88,7 @@ VBAT uW: microwatt reading from this rail, generated on the INA
voltage.
... uW: Further microwatt entry columns for each rail specified in
your scenario file.
+... xX: Measurement in uW, mW, mV, uA, uV as per config.
Calculate stats and store data and stats:
diff --git a/extra/usb_power/board/marlin/marlin_pvc.scenario b/extra/usb_power/board/marlin/marlin_pvc.scenario
new file mode 100644
index 0000000000..426cd1479c
--- /dev/null
+++ b/extra/usb_power/board/marlin/marlin_pvc.scenario
@@ -0,0 +1 @@
+["VBAT", ["VBAT", "BUSV"], ["VBAT", "CURRENT"], ["VBAT", "SHUNTV"]]
diff --git a/extra/usb_power/marlin_v.scenario b/extra/usb_power/marlin_v.scenario
new file mode 100644
index 0000000000..99c132cb27
--- /dev/null
+++ b/extra/usb_power/marlin_v.scenario
@@ -0,0 +1 @@
+[["VBAT", "BUSV"], ["VDD_1V8_PANEL", "BUSV"], ["V_EMMC_2V95", "BUSV"], ["V_SR_2V85", "BUSV"], ["V_USBSS_SW_1V8", "BUSV"], ["V_AUDIO_2V15", "BUSV"]]
diff --git a/extra/usb_power/powerlog.py b/extra/usb_power/powerlog.py
index 81d050bb91..6128ca2027 100755
--- a/extra/usb_power/powerlog.py
+++ b/extra/usb_power/powerlog.py
@@ -46,7 +46,19 @@ class Spower(object):
_write_ep: pyUSB write endpoint for this interface
"""
- INA231 = 1
+ # INA interface type.
+ INA_POWER = 1
+ INA_BUSV = 2
+ INA_CURRENT = 3
+ INA_SHUNTV = 4
+
+ # usb power commands
+ CMD_RESET = 0x0000
+ CMD_STOP = 0x0001
+ CMD_ADDINA = 0x0002
+ CMD_START = 0x0003
+ CMD_NEXT = 0x0004
+ CMD_SETTIME = 0x0005
# Map between header channel number (0-47)
# and INA I2C bus/addr on sweetberry.
@@ -180,7 +192,8 @@ class Spower(object):
""" Clear INA description struct."""
self._inas = []
- def append_ina_struct(self, name, rs, port, addr, data=None):
+ def append_ina_struct(self, name, rs, port, addr,
+ data=None, ina_type=INA_POWER):
"""Add an INA descriptor into the list of active INAs.
Args:
@@ -189,18 +202,22 @@ class Spower(object):
port: I2C channel this INA is connected to.
addr: I2C addr of this INA.
data: Misc data for special handling, board specific.
+ ina_type: INA function to use, power, voltage, etc.
"""
ina = {}
ina['name'] = name
ina['rs'] = rs
ina['port'] = port
ina['addr'] = addr
+ ina['type'] = ina_type
# Calculate INA231 Calibration register
# (see INA231 spec p.15)
# CurrentLSB = uA per div = 80mV / (Rsh * 2^15)
# CurrentLSB uA = 80000000nV / (Rsh mOhm * 0x8000)
ina['uAscale'] = 80000000. / (rs * 0x8000);
ina['uWscale'] = 25. * ina['uAscale'];
+ ina['mVscale'] = 1.25
+ ina['uVscale'] = 2.5
ina['data'] = data
self._inas.append(ina)
@@ -265,7 +282,7 @@ class Spower(object):
def send_reset(self):
"""Reset the power interface on the stm32"""
- cmd = struct.pack("<H", 0x0000)
+ cmd = struct.pack("<H", self.CMD_RESET)
ret = self.wr_command(cmd, rtimeout=50, wtimeout=50)
debuglog("Command RESET: %s" % "success" if ret == 0 else "failure")
@@ -292,7 +309,7 @@ class Spower(object):
def stop(self):
"""Stop any active data acquisition."""
- cmd = struct.pack("<H", 0x0001)
+ cmd = struct.pack("<H", self.CMD_STOP)
ret = self.wr_command(cmd)
debuglog("Command STOP: %s" % "success" if ret == 0 else "failure")
@@ -306,22 +323,23 @@ class Spower(object):
Returns:
actual sampling interval in ms.
"""
- cmd = struct.pack("<HI", 0x0003, integration_us)
+ cmd = struct.pack("<HI", self.CMD_START, integration_us)
read = self.wr_command(cmd, read_count=5)
actual_us = 0
if len(read) == 5:
ret, actual_us = struct.unpack("<BI", read)
- debuglog("Command START: %s %dus" % ("success" if ret == 0 else "failure", actual_us))
+ debuglog("Command START: %s %dus" % (
+ "success" if ret == 0 else "failure", actual_us))
else:
debuglog("Command START: FAIL")
return actual_us
- def add_ina_name(self, name):
+ def add_ina_name(self, name_tuple):
"""Add INA from board config.
Args:
- name: readable name of power rail in board config.
+ name_tuple: name and type of power rail in board config.
Returns:
True if INA added, False if the INA is not on this board.
@@ -329,6 +347,8 @@ class Spower(object):
Raises:
Exception on unexpected failure.
"""
+ name, ina_type = name_tuple
+
for datum in self._brdcfg:
if datum["name"] == name:
channel = int(datum["channel"])
@@ -337,7 +357,7 @@ class Spower(object):
if board == self._board:
port, addr = self.CHMAP[channel]
- self.add_ina(port, self.INA231, addr, 0, rs, data=datum)
+ self.add_ina(port, ina_type, addr, 0, rs, data=datum)
return True
else:
return False
@@ -350,7 +370,7 @@ class Spower(object):
timestamp_us: host timestmap in us.
"""
# 0x0005 , 8 byte timestamp
- cmd = struct.pack("<HQ", 0x0005, timestamp_us)
+ cmd = struct.pack("<HQ", self.CMD_SETTIME, timestamp_us)
ret = self.wr_command(cmd)
debuglog("Command SETTIME: %s" % "success" if ret == 0 else "failure")
@@ -360,20 +380,22 @@ class Spower(object):
Args:
bus: which i2c bus the INA is on. Same ordering as Si2c.
- ina_type: which model INA. 0x1 -> INA231
+ ina_type: Ina interface: INA_POWER/BUSV/etc.
addr: 7 bit i2c addr of this INA
extra: extra data for nonstandard configs.
resistance: int, shunt resistance in mOhm
"""
# 0x0002, 1B: bus, 1B:INA type, 1B: INA addr, 1B: extra, 4B: Rs
- cmd = struct.pack("<HBBBBI", 0x0002, bus, ina_type, addr, extra, resistance)
+ cmd = struct.pack("<HBBBBI", self.CMD_ADDINA,
+ bus, ina_type, addr, extra, resistance)
ret = self.wr_command(cmd)
if ret == 0:
if data:
name = data['name']
else:
name = "ina%d_%02x" % (bus, addr)
- self.append_ina_struct(name, resistance, bus, addr, data=data)
+ self.append_ina_struct(name, resistance, bus, addr,
+ data=data, ina_type=ina_type)
debuglog("Command ADD_INA: %s" % "success" if ret == 0 else "failure")
def report_header_size(self):
@@ -396,12 +418,12 @@ class Spower(object):
"""Read a line of data from the setup INAs
Returns:
- list of dicts of the values read, otherwise None.
- [{ts:100, vbat:450}, {ts:200, vbat:440}]
+ list of dicts of the values read by ina/type tuple, otherwise None.
+ [{ts:100, (vbat, power):450}, {ts:200, (vbat, power):440}]
"""
try:
expected_bytes = self.report_size(len(self._inas))
- cmd = struct.pack("<H", 0x0004)
+ cmd = struct.pack("<H", self.CMD_NEXT)
bytesread = self.wr_command(cmd, read_count=expected_bytes)
except usb.core.USBError as e:
print("READ LINE FAILED %s" % e)
@@ -455,11 +477,23 @@ class Spower(object):
for i in range(0, size):
idx = self.report_header_size() + 2*i
- raw_w = struct.unpack("<H", data[idx:idx+2])[0]
- uw = raw_w * self._inas[i]['uWscale']
name = self._inas[i]['name']
- debuglog("READ %d %s: %fs: %fuW" % (i, name, ftimestamp, uw))
- record[self._inas[i]['name']] = uw
+ name_tuple = (self._inas[i]['name'], self._inas[i]['type'])
+
+ raw_val = struct.unpack("<h", data[idx:idx+2])[0]
+
+ if self._inas[i]['type'] == Spower.INA_POWER:
+ val = raw_val * self._inas[i]['uWscale']
+ elif self._inas[i]['type'] == Spower.INA_BUSV:
+ val = raw_val * self._inas[i]['mVscale']
+ elif self._inas[i]['type'] == Spower.INA_CURRENT:
+ val = raw_val * self._inas[i]['uAscale']
+ elif self._inas[i]['type'] == Spower.INA_SHUNTV:
+ val = raw_val * self._inas[i]['uVscale']
+
+ debuglog("READ %d %s: %fs: 0x%04x %f" % (i,
+ name, ftimestamp, raw_val, val))
+ record[name_tuple] = val
return record
@@ -532,7 +566,7 @@ class powerlog(object):
with open(cfgfile) as data_file:
names = json.load(data_file)
- self._names = names
+ self._names = self.process_scenario(names)
for key in self._pwr:
self._pwr[key].load_board(brdfile)
@@ -562,6 +596,37 @@ class powerlog(object):
else:
self._pwr[key].set_time(0)
+ def process_scenario(self, name_list):
+ """Return list of tuples indicating name and type.
+
+ Args:
+ json originated list of names, or [name, type]
+ Returns:
+ list of tuples of (name, type) defaulting to type "POWER"
+ Raises: exception, invalid INA type.
+ """
+ names = []
+ for entry in name_list:
+ if isinstance(entry, list):
+ name = entry[0]
+ if entry[1] == "POWER":
+ type = Spower.INA_POWER
+ elif entry[1] == "BUSV":
+ type = Spower.INA_BUSV
+ elif entry[1] == "CURRENT":
+ type = Spower.INA_CURRENT
+ elif entry[1] == "SHUNTV":
+ type = Spower.INA_SHUNTV
+ else:
+ raise Exception("Invalid INA type", "Type of %s [%s] not recognized,"
+ " try one of POWER, BUSV, CURRENT" % (entry[0], entry[1]))
+ else:
+ name = entry
+ type = Spower.INA_POWER
+
+ names.append((name, type))
+ return names
+
def start(self, integration_us_request, seconds, sync_speed=.8):
"""Starts sampling.
@@ -585,8 +650,18 @@ class powerlog(object):
# CSV header
if self._print_raw_data:
title = "ts:%dus" % integration_us
- for name in self._names:
- unit = "mW" if self._use_mW else "uW"
+ for name_tuple in self._names:
+ name, ina_type = name_tuple
+
+ if ina_type == Spower.INA_POWER:
+ unit = "mW" if self._use_mW else "uW"
+ elif ina_type == Spower.INA_BUSV:
+ unit = "mV"
+ elif ina_type == Spower.INA_CURRENT:
+ unit = "uA"
+ elif ina_type == Spower.INA_SHUNTV:
+ unit = "uV"
+
title += ", %s %s" % (name, unit)
title += ", status"
logoutput(title)
@@ -625,10 +700,11 @@ class powerlog(object):
csv = "%f" % aggregate_record["ts"]
for name in self._names:
if name in aggregate_record:
- multiplier = 0.001 if self._use_mW else 1
- power = aggregate_record[name] * multiplier
- csv += ", %.2f" % power
- self._data.AddValue(name, power)
+ multiplier = 0.001 if (self._use_mW and
+ name[1]==Spower.INA_POWER) else 1
+ value = aggregate_record[name] * multiplier
+ csv += ", %.2f" % value
+ self._data.AddValue(name, value)
else:
csv += ", "
csv += ", %d" % aggregate_record["status"]