| #include <app/zedmon/ina.h> |
| |
| #include <app/zedmon/usb.h> |
| #include <assert.h> |
| #include <err.h> |
| #include <dev/i2c.h> |
| #include <lib/cbuf.h> |
| #include <lib/console.h> |
| #include <platform.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <target/gpioconfig.h> |
| |
| #include "ina231.h" |
| #include "ina233.h" |
| |
| typedef struct __attribute__((packed)) { |
| lk_bigtime_t time; |
| uint8_t channel; |
| } ina_alert_event_t; |
| |
| static cbuf_t ina_alert_events; |
| |
| static bool (*ina_sample)(uint16_t *v_shunt, uint16_t *v_bus); |
| static bool ina_initialized = false; |
| |
| static uint32_t ina_errors; |
| static uint32_t ina_samples; |
| static uint16_t ina_v_shunt; |
| static uint16_t ina_v_bus; |
| |
| |
| bool ina_alert_irq(int index, uint64_t timestamp) { |
| // We only handle a single channel right now. |
| assert(index == 0); |
| |
| if (!ina_initialized) { |
| return false; |
| } |
| |
| ina_alert_event_t event = { |
| .channel = 0, |
| .time = timestamp, |
| }; |
| |
| // This won't race because we're in interrupt context. |
| if (cbuf_space_avail(&ina_alert_events) >= sizeof(event)) { |
| cbuf_write(&ina_alert_events, &event, sizeof(event), false); |
| return true; |
| } |
| return false; |
| } |
| |
| void ina_init(void) { |
| cbuf_initialize(&ina_alert_events, 32); |
| |
| if (ina233_init()) { |
| printf("ina233 found\n"); |
| ina_sample = ina233_sample; |
| } else if (ina231_init()) { |
| printf("ina231 found\n"); |
| ina_sample = ina231_sample; |
| } |
| |
| ina_initialized = true; |
| |
| // call sample once to unstick the conversion ready flag. |
| uint16_t v_shunt; |
| uint16_t v_bus; |
| ina_sample(&v_shunt, &v_bus); |
| } |
| |
| |
| void ina_loop(void) { |
| while (true) { |
| ina_alert_event_t event; |
| cbuf_read(&ina_alert_events, &event, sizeof(event), true); |
| |
| if (ina_sample == NULL) { |
| continue; |
| } |
| |
| uint16_t v_shunt; |
| uint16_t v_bus; |
| |
| if (!ina_sample(&v_shunt, &v_bus)) { |
| ina_errors++; |
| continue; |
| } |
| |
| ina_v_shunt = v_shunt; |
| ina_v_bus = v_bus; |
| ina_samples++; |
| zedmon_usb_add_sample(event.time, v_shunt, v_bus); |
| } |
| } |
| |
| static int cmd_ina_status(int argc, const cmd_args *argv) { |
| float v_shunt = ina_v_shunt * 0.0025; |
| float v_bus = ina_v_bus * 0.00125; |
| |
| printf("samples: %u\n", ina_samples); |
| printf("errors: %u\n", ina_errors); |
| printf("v_bus: %f V \n", v_bus); |
| printf("v_shunt: %f mV\n", v_shunt); |
| return 0; |
| } |
| |
| STATIC_COMMAND_START |
| STATIC_COMMAND("ina_status", "ina status", &cmd_ina_status) |
| STATIC_COMMAND_END(ina); |
| |