Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
33f5531
Copied INA232 driver files and started modifying them for the BQ25820
mbella-sofar Mar 5, 2025
6dca878
changed charger function prototype
mbella-sofar Mar 28, 2025
bcc3a70
Prevent Errors From Being Sent When INA232 Cannot Be Initialized (#267)
matt001k Mar 3, 2025
54c58f6
Adds Power Information Timing Service To Bridge App (#266)
matt001k Mar 5, 2025
6cba018
fix: handle RBR negative temperatures correctly (#268)
towynlin Mar 5, 2025
3f70d45
Fix/do aggregation (#269)
victorsowa12 Mar 8, 2025
1ad30a4
change wipe time config to use hardware parition (#271)
victorsowa12 Mar 18, 2025
34332f5
Optimize Bridge To Spotter Transactions And Increase 921600 Baud Rate…
matt001k Mar 26, 2025
927e03f
brought this branch up to date with changes in develop (rebase)
mbella-sofar Mar 28, 2025
5dfdcb7
fixed up cmakelists stuff and fixed copy/paste errors plus typos
mbella-sofar Mar 29, 2025
3fe4034
Charger is communicating correctly now, added delays that might not b…
mbella-sofar Apr 2, 2025
2f27c26
Adding readSensors function for the BQ25820 so I can poll the battery…
mbella-sofar May 14, 2025
93611e6
Added function to enable the adc and read its measurements
mbella-sofar May 16, 2025
af2d171
More updates to help with EE bench debugging.
mbella-sofar May 30, 2025
1fcc64e
shortened delay between sensor reads
mbella-sofar Jun 3, 2025
11020ec
More tweaks as I wrap up the PCBAs we are going to ship
mbella-sofar Jun 17, 2025
cf06898
Made the changes to the driver needed to send csv lines to the spotte…
mbella-sofar Jun 18, 2025
db0f3b6
Enabled the VFB ADC and changed the data pipeline to send VFB_ADC to …
mbella-sofar Jun 24, 2025
792516f
Including both VLSNS and VFB_ADC measurements in the data sent to spo…
mbella-sofar Jun 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/apps/bridge/bridgePowerController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "stm32_rtc.h"
#include "task.h"
#include "task_priorities.h"
#include "uptime.h"
#include <cinttypes>
#include <stdio.h>
#ifdef RAW_PRESSURE_ENABLE
Expand Down Expand Up @@ -67,6 +68,8 @@ BridgePowerController::BridgePowerController(
BaseType_t rval = xTaskCreate(BridgePowerController::powerControllerRun, "Power Controller",
128 * 4, this, BRIDGE_POWER_TASK_PRIORITY, &_task_handle);
configASSERT(rval == pdTRUE);

configASSERT(power_info_service_init(powerInfoStatsCb, this) == BmOK);
}

/*!
Expand Down Expand Up @@ -304,6 +307,57 @@ void BridgePowerController::powerControllerRun(void *arg) {
}
}

PowerInfoReplyData BridgePowerController::powerInfoStatsCb(void *arg) {
PowerInfoReplyData d = {};
BridgePowerController *power_controller = reinterpret_cast<BridgePowerController *>(arg);

if ((!power_controller->_initDone || !power_controller->_timebaseSet) &&
power_controller->isPowerControlEnabled()) {
static const uint64_t init_uptime_s = 0;
uint64_t current_uptime_s = uptimeGetMs() / 1000;

// Calculate how long the bus will be on before initialization is done
d.total_on_s = INIT_POWER_ON_TIMEOUT_MS / 1000;
d.remaining_on_s = timeRemainingGeneric(init_uptime_s, current_uptime_s, d.total_on_s);
d.upcoming_off_s = POWER_SERVICE_UNDEFINED;
} else if (power_controller->isSubsampleEnabled() &&
power_controller->isPowerControlEnabled()) {
uint32_t sample_duration_remain = timeRemainingGeneric(
power_controller->_sampleIntervalStartS, power_controller->getCurrentTimeS(),
power_controller->_sampleDurationS);

d.total_on_s = power_controller->_subsampleDurationS;
if (power_controller->isBridgePowerOn()) {
d.remaining_on_s = timeRemainingGeneric(power_controller->_subsampleIntervalStartS,
power_controller->getCurrentTimeS(),
power_controller->_subsampleDurationS);
}

// Account for sample interval off time after sample duration in subsampling
if (sample_duration_remain >= d.total_on_s) {
d.upcoming_off_s = power_controller->_subsampleIntervalS - d.total_on_s;
} else {
d.upcoming_off_s =
(power_controller->_sampleIntervalStartS + power_controller->_sampleIntervalS) -
(power_controller->_subsampleIntervalStartS + power_controller->_subsampleDurationS);
}
} else if (power_controller->isPowerControlEnabled()) {
d.total_on_s = power_controller->_sampleDurationS;
if (power_controller->isBridgePowerOn()) {
d.remaining_on_s = timeRemainingGeneric(power_controller->_sampleIntervalStartS,
power_controller->getCurrentTimeS(),
power_controller->_sampleDurationS);
}
d.upcoming_off_s = power_controller->_sampleIntervalS - d.total_on_s;
} else {
d.total_on_s = POWER_SERVICE_UNDEFINED;
d.remaining_on_s = POWER_SERVICE_UNDEFINED;
d.upcoming_off_s = 0;
}

return d;
}

void BridgePowerController::checkAndUpdateTimebase() {
if ((isRTCSet() || _ticksSamplingEnabled) && !_timebaseSet) {
printf("Bridge Power Controller timebase is set.\n");
Expand Down
2 changes: 2 additions & 0 deletions src/apps/bridge/bridgePowerController.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "FreeRTOS.h"
#include "event_groups.h"
#include "io.h"
#include "power_info_service.h"
#include "task.h"
#include <stdint.h>

Expand Down Expand Up @@ -32,6 +33,7 @@ class BridgePowerController {
private:
void powerBusAndSetSignal(bool on, bool notifyL2 = true);
static void powerControllerRun(void *arg);
static PowerInfoReplyData powerInfoStatsCb(void *arg);
void checkAndUpdateTimebase();
uint32_t getCurrentTimeS();
void stateLogPrintTarget(const char *state, uint32_t target);
Expand Down
17 changes: 17 additions & 0 deletions src/apps/bridge/sensor_drivers/pmeDissolvedOxygenSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,23 @@ void PmeDissolvedOxygenSensor::aggregate(void) {
dissolved_oxygen_aggs.quality_mean = quality.getMean();
dissolved_oxygen_aggs.do_saturation_pct_mean = do_saturation_pct.getMean();
dissolved_oxygen_aggs.reading_count = reading_count;

if (dissolved_oxygen_aggs.temperature_deg_c_mean < TEMP_SAMPLE_MEMBER_MIN ||
dissolved_oxygen_aggs.temperature_deg_c_mean > TEMP_SAMPLE_MEMBER_MAX) {
dissolved_oxygen_aggs.temperature_deg_c_mean = NAN;
}
if (dissolved_oxygen_aggs.do_mg_per_l_mean < DO_SAMPLE_MEMBER_MIN ||
dissolved_oxygen_aggs.do_mg_per_l_mean > DO_SAMPLE_MEMBER_MAX) {
dissolved_oxygen_aggs.do_mg_per_l_mean = NAN;
}
if (dissolved_oxygen_aggs.quality_mean < QUALITY_SAMPLE_MEMBER_MIN ||
dissolved_oxygen_aggs.quality_mean > QUALITY_SAMPLE_MEMBER_MAX) {
dissolved_oxygen_aggs.quality_mean = NAN;
}
if (dissolved_oxygen_aggs.do_saturation_pct_mean < DO_SATURATION_SAMPLE_MEMBER_MIN ||
dissolved_oxygen_aggs.do_saturation_pct_mean > DO_SATURATION_SAMPLE_MEMBER_MAX) {
dissolved_oxygen_aggs.do_saturation_pct_mean = NAN;
}
}

BmErr err = send_spotter_log_aggregate(
Expand Down
9 changes: 9 additions & 0 deletions src/apps/bridge/sensor_drivers/pmeDissolvedOxygenSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ typedef struct PmeDissolvedOxygenSensor : public AbstractSensor {
static constexpr uint32_t DEFAULT_PME_DISSOLVED_READING_PERIOD_MS = 10 * 60 * 1000;
static constexpr uint32_t N_SAMPLES_PAD = 2;
static constexpr uint8_t MIN_READINGS_FOR_AGGREGATION = 1;
static constexpr double TEMP_SAMPLE_MEMBER_MIN = -0.414;
static constexpr double TEMP_SAMPLE_MEMBER_MAX = 35.6;
static constexpr double DO_SAMPLE_MEMBER_MIN = -1.0;
static constexpr double DO_SAMPLE_MEMBER_MAX = 100.0;
static constexpr double QUALITY_SAMPLE_MEMBER_MIN = 0.0;
static constexpr double QUALITY_SAMPLE_MEMBER_MAX = 1.0;
static constexpr double DO_SATURATION_SAMPLE_MEMBER_MIN = 0.0;
static constexpr double DO_SATURATION_SAMPLE_MEMBER_MAX = 150.0;


public:
bool subscribe() override;
Expand Down
11 changes: 11 additions & 0 deletions src/apps/bridge/sensor_drivers/seapointTurbiditySensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ void SeapointTurbiditySensor::aggregate(void) {
turbidity_aggs.turbidity_s_mean_ftu = turbidity_s_ftu.getMean();
turbidity_aggs.turbidity_r_mean_ftu = turbidity_r_ftu.getMean();
turbidity_aggs.reading_count = reading_count;

if (turbidity_aggs.turbidity_s_mean_ftu < S_SAMPLE_MEMBER_MIN) {
turbidity_aggs.turbidity_s_mean_ftu = -HUGE_VAL;
} else if (turbidity_aggs.turbidity_s_mean_ftu > S_SAMPLE_MEMBER_MAX) {
turbidity_aggs.turbidity_s_mean_ftu = HUGE_VAL;
}
if (turbidity_aggs.turbidity_r_mean_ftu < R_SAMPLE_MEMBER_MIN) {
turbidity_aggs.turbidity_r_mean_ftu = -HUGE_VAL;
} else if (turbidity_aggs.turbidity_r_mean_ftu > R_SAMPLE_MEMBER_MAX) {
turbidity_aggs.turbidity_r_mean_ftu = HUGE_VAL;
}
}
static constexpr uint8_t TIME_STR_BUFSIZE = 50;
char time_str[TIME_STR_BUFSIZE];
Expand Down
4 changes: 4 additions & 0 deletions src/apps/bridge/sensor_drivers/seapointTurbiditySensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ typedef struct SeapointTurbiditySensor : public AbstractSensor {
// 2 minutes is the minimum bridge on period and the turbidity sensor by default is sampling at 1Hz. So 1*120 + 30 = 150.
static constexpr uint32_t N_SAMPLES_PAD = 150;
static constexpr uint8_t MIN_READINGS_FOR_AGGREGATION = 3;
static constexpr double S_SAMPLE_MEMBER_MIN = 0.0;
static constexpr double S_SAMPLE_MEMBER_MAX = 20971.48;
static constexpr double R_SAMPLE_MEMBER_MIN = 0.0;
static constexpr double R_SAMPLE_MEMBER_MAX = 163800.00;

public:
bool subscribe() override;
Expand Down
16 changes: 16 additions & 0 deletions src/apps/bringup_mote/app_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "gpioISR.h"
#include "htu21d.h"
#include "ina232.h"
#include "bq25820.h"
#include "io.h"
#include "l2.h"
#include "lpm.h"
Expand Down Expand Up @@ -214,6 +215,8 @@ static INA::INA232 *debugIna[NUM_INA232_DEV] = {
&debugIna2,
};

static BQ::BQ25820 Charger(&i2c1);

static MS5803 debugPressure(&i2c1, MS5803_ADDR);
static Bme280 debugPHTU(&i2c1, Bme280::I2C_ADDR);
static HTU21D debugHTU(&i2c1);
Expand Down Expand Up @@ -372,7 +375,20 @@ static void defaultTask(void *parameters) {
// Commenting out while we test usart1
// lpmPeripheralInactive(LPM_BOOT);

bristlefin.enableVbus();
vTaskDelay(pdMS_TO_TICKS(1000)); // Complete SWAG on how long we need to wait before talking to the BQ25820

if(Charger.init()) {
printf("BQ25820 Initialized\n");
Charger.disablePfm();
}
else {
printf("Failed to init BQ25820.\n");
}

while (1) {
vTaskDelay(1000);
Charger.readSensors();
Charger.readFaults();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static bool validSpecialChar(char c) {
switch (c) {
case ',':
case '.':
case '-':
return true;
default:
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ void ledAllOff() {
}

void saveLastWipeEpoch(uint32_t newLastWipeEpochS) {
set_config_uint(BM_CFG_PARTITION_SYSTEM, LAST_WIPE_EPOCH_KEY, strlen(LAST_WIPE_EPOCH_KEY),
set_config_uint(BM_CFG_PARTITION_HARDWARE, LAST_WIPE_EPOCH_KEY, strlen(LAST_WIPE_EPOCH_KEY),
newLastWipeEpochS);
save_config(BM_CFG_PARTITION_SYSTEM, false);
save_config(BM_CFG_PARTITION_HARDWARE, false);
lastWipeEpochS = newLastWipeEpochS;
}

uint32_t loadLastWipeEpoch() {
bool success = get_config_uint(BM_CFG_PARTITION_SYSTEM, LAST_WIPE_EPOCH_KEY,
bool success = get_config_uint(BM_CFG_PARTITION_HARDWARE, LAST_WIPE_EPOCH_KEY,
strlen(LAST_WIPE_EPOCH_KEY), &lastWipeEpochS);
if (!success) {
printf("LAST_WIPE_EPOCH_KEY not found. Initializing to 0.\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static bool validSpecialChar(char c) {
switch (c) {
case ',':
case '.':
case '-':
return true;
default:
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@
#include "uptime.h"
#include "usart.h"
#include "app_util.h"
#include "bq25820.h"
#include "ina232.h"
#include "string.h"

#define LED_ON_TIME_MS 20
#define LED_PERIOD_MS 1000

static BQ::BQ25820 Charger(&i2c1);

bool led_state = false;


// A buffer to put data from out payload sensor into.
char payload_buffer[2048];

Expand All @@ -33,37 +39,60 @@ void setup(void) {
IOWrite(&VBUS_EN, 0);
// ensure Vbus stable before enable Vout with a 5ms delay.
vTaskDelay(pdMS_TO_TICKS(5));
// enable Vout, 12V by default.
IOWrite(&PL_BUCK_EN, 0);
// Try to initialize the charger IC
if(Charger.init()) {
printf("Charger IC Initialized\n");
Charger.disablePfm();
}
else {
printf("Failed to init the charger IC.\n");
}

}

void loop(void) {
/* USER LOOP CODE GOES HERE */

// Read a byte if it is available
while (PLUART::byteAvailable()) {
uint8_t byte_read = PLUART::readByte();
printf("byte: %c\n", (char)byte_read);
}
char cdata[1024];
memset(cdata,0,sizeof(cdata));
char cfaults[512];
memset(cfaults,0,sizeof(cfaults));

// Read a line if it is available
if (PLUART::lineAvailable()) {
uint16_t read_len =
PLUART::readLine(payload_buffer, sizeof(payload_buffer));
printf("line: %s\n", payload_buffer);
// Get the RTC if available
RTCTimeAndDate_t time_and_date = {};
rtcGet(&time_and_date);
char rtcTimeBuffer[32];
rtcPrint(rtcTimeBuffer, &time_and_date);

// Read the BQ25820 ADCs and check for faults
Charger.readSensors(cdata, sizeof(cdata));
Charger.readFaults(cfaults, sizeof(cfaults));
strcat(cdata,cfaults);

// Get the RTC if available
RTCTimeAndDate_t time_and_date = {};
rtcGet(&time_and_date);
char rtcTimeBuffer[32];
rtcPrint(rtcTimeBuffer, &time_and_date);
spotter_log(0, "bq25820.log", USE_TIMESTAMP, "tick: %llu, rtc: %s, line: %.*s\n",
uptimeGetMs(), rtcTimeBuffer, strlen(cdata), cdata);

// Print the payload data to a file, to the spotter_log_console console, and to the printf console.
spotter_log(0, "payload_data.log", USE_TIMESTAMP, "tick: %llu, rtc: %s, line: %.*s\n",
uptimeGetMs(), rtcTimeBuffer, read_len, payload_buffer);
spotter_log_console(0, "[payload] | tick: %llu, rtc: %s, line: %.*s", uptimeGetMs(),
rtcTimeBuffer, read_len, payload_buffer);
printf("[payload] | tick: %llu, rtc: %s, line: %.*s\n", uptimeGetMs(),
rtcTimeBuffer, read_len, payload_buffer);
}
spotter_log_console(0, "[bq25820] | tick: %llu, rtc: %s, line: %.*s",
uptimeGetMs(), rtcTimeBuffer, strlen(cdata), cdata);

vTaskDelay(pdMS_TO_TICKS(1000));
/*
uint16_t read_len =
PLUART::readLine(payload_buffer, sizeof(payload_buffer));
printf("line: %s\n", payload_buffer);

// Get the RTC if available
RTCTimeAndDate_t time_and_date = {};
rtcGet(&time_and_date);
char rtcTimeBuffer[32];
rtcPrint(rtcTimeBuffer, &time_and_date);

// Print the payload data to a file, to the spotter_log_console console, and to the printf console.
spotter_log(0, "payload_data.log", USE_TIMESTAMP, "tick: %llu, rtc: %s, line: %.*s\n",
uptimeGetMs(), rtcTimeBuffer, read_len, payload_buffer);
spotter_log_console(0, "[payload] | tick: %llu, rtc: %s, line: %.*s", uptimeGetMs(),
rtcTimeBuffer, read_len, payload_buffer);
printf("[payload] | tick: %llu, rtc: %s, line: %.*s\n", uptimeGetMs(),
rtcTimeBuffer, read_len, payload_buffer);
*/
}
1 change: 1 addition & 0 deletions src/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ set(LIB_FILES
${LIB_DIR}/drivers/bme280driver.cpp
${LIB_DIR}/drivers/htu21d.cpp
${LIB_DIR}/drivers/ina232.cpp
${LIB_DIR}/drivers/bq25820.cpp
${LIB_DIR}/drivers/nau7802.cpp
${LIB_DIR}/drivers/ms5803.cpp
${LIB_DIR}/drivers/pca9535.c
Expand Down
Loading