From 5528259517322645ec4e3db84df99840ad5fa81d Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sat, 24 Sep 2022 16:28:35 +0200 Subject: [PATCH 1/5] calibration: add development device --- src/calibration.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/calibration.h b/src/calibration.h index e0523cb..c8fbc75 100644 --- a/src/calibration.h +++ b/src/calibration.h @@ -6,10 +6,24 @@ * than the actual voltage, you have to scale by 1.02 and therefore specify * 1020 in this list. */ +/* Values for the device at the B26 tower */ + +#if 0 #define CAL_FACTOR_U_BAT 994 #define CAL_FACTOR_U_SOLAR 997 #define CAL_FACTOR_U_SW 996 #define CAL_FACTOR_I_SOLAR 1015 #define CAL_FACTOR_I_LOAD 1000 +#endif + +/* Values for the development device */ + +#if 1 +#define CAL_FACTOR_U_BAT 1012 +#define CAL_FACTOR_U_SOLAR 1015 +#define CAL_FACTOR_U_SW 1006 +#define CAL_FACTOR_I_SOLAR 3980 +#define CAL_FACTOR_I_LOAD 1000 +#endif #endif // CALIBRATION_H From 1e093978f31e287ec12ee8b8525264e29f0b7d00 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sat, 24 Sep 2022 16:39:46 +0200 Subject: [PATCH 2/5] config: avoid switching between sleep and active state too often Unfortunately, the offset voltage of the opamp for charge current measurement breaks measurement at low currents with a small shunt, so at dusk, when currents become low, it may happen that 0 current is measured while the battery is still being charged. This would falsely trigger the transition to sleep state. To improve this situation, we simply keep the charger active for a longer time. --- src/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.h b/src/config.h index 794488e..a9ea40c 100644 --- a/src/config.h +++ b/src/config.h @@ -30,7 +30,7 @@ #define SLEEP_SOLAR_CURRENT 1 /* Delay between state change and sleep state check (in ms). */ -#define SLEEP_STATE_DELAY 100 +#define SLEEP_STATE_DELAY 60000 /* Delay between charging switch state change and sleep state check(in ms). */ #define SLEEP_SWITCH_DELAY 1000 From 4ebb231346a04a8c621680442fad86aa57ad609d Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 25 Sep 2022 15:57:05 +0200 Subject: [PATCH 3/5] Preparations for dedicated configuration flash page --- .gitignore | 3 + Makefile | 2 +- ldscripts/lnsc-2420-debug.ld | 5 ++ ldscripts/lnsc-2420-release.ld | 10 ++- src/flash_config.h | 117 +++++++++++++++++++++++++++++++++ utils/config_b26.yaml | 108 ++++++++++++++++++++++++++++++ utils/config_dev.yaml | 108 ++++++++++++++++++++++++++++++ utils/config_to_hex.py | 69 +++++++++++++++++++ 8 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 src/flash_config.h create mode 100644 utils/config_b26.yaml create mode 100644 utils/config_dev.yaml create mode 100755 utils/config_to_hex.py diff --git a/.gitignore b/.gitignore index fd691c5..f8f3e6b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ # Vim swap files .*.sw? + +# generated config HEX files +utils/*.hex diff --git a/Makefile b/Makefile index 914eb14..9865c8d 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ LDFLAGS+=--static \ -nostartfiles -Wl,--gc-sections \ -mthumb -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -# the LD script +# the LD script (RAM-only does not work because the code is too large) #LDFLAGS+=-Tldscripts/lnsc-2420-$(BUILD).ld LDFLAGS+=-Tldscripts/lnsc-2420-release.ld diff --git a/ldscripts/lnsc-2420-debug.ld b/ldscripts/lnsc-2420-debug.ld index 097d4ca..541b106 100644 --- a/ldscripts/lnsc-2420-debug.ld +++ b/ldscripts/lnsc-2420-debug.ld @@ -7,6 +7,7 @@ MEMORY { /*rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K*/ + conf (r) : ORIGIN = 0x08007c00, LENGTH = 1K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K } @@ -96,6 +97,10 @@ SECTIONS . = ALIGN(4); end = .; + + .conf : { + __conf_start = .; + } >conf } PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); diff --git a/ldscripts/lnsc-2420-release.ld b/ldscripts/lnsc-2420-release.ld index 0b7c6ba..09fd4ca 100644 --- a/ldscripts/lnsc-2420-release.ld +++ b/ldscripts/lnsc-2420-release.ld @@ -3,10 +3,18 @@ /* Define memory regions. */ MEMORY { - rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 31K + conf (r) : ORIGIN = 0x08007c00, LENGTH = 1K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K } /* Include the common ld script. */ INCLUDE cortex-m-generic.ld +SECTIONS +{ + .conf : { + __conf_start = .; + . = ALIGN(4); + } >conf +} diff --git a/src/flash_config.h b/src/flash_config.h new file mode 100644 index 0000000..412d2c2 --- /dev/null +++ b/src/flash_config.h @@ -0,0 +1,117 @@ +#ifndef FLASH_CONFIG_H +#define FLASH_CONFIG_H + +#include + +extern uint8_t __conf_start; + +#define FLASH_CONFIG_BASE_PTR ((uint8_t*)(&__conf_start)) + +/***** Calibration factors *****/ + +/* Calibration factor defined here are divided by 1000 to determine the actual + * scaling factor. Therefore, if the voltage determined by the firmware is 2% + * lower than the actual voltage, you have to scale by 1.02 and therefore + * specify 1020 in this list. */ + +#define FLASH_CONFIG_CAL_FACTOR_U_BAT (*(uint16_t*)(FLASH_CONFIG_BASE_PTR + 0x0000)) +#define FLASH_CONFIG_CAL_FACTOR_U_SOLAR (*(uint16_t*)(FLASH_CONFIG_BASE_PTR + 0x0002)) +#define FLASH_CONFIG_CAL_FACTOR_U_SW (*(uint16_t*)(FLASH_CONFIG_BASE_PTR + 0x0004)) +#define FLASH_CONFIG_CAL_FACTOR_I_SOLAR (*(uint16_t*)(FLASH_CONFIG_BASE_PTR + 0x0006)) +#define FLASH_CONFIG_CAL_FACTOR_I_LOAD (*(uint16_t*)(FLASH_CONFIG_BASE_PTR + 0x0008)) + +/***** General configuration *****/ + +/* Battery regulation corridor width (in mV). */ +#define FLASH_CONFIG_U_BAT_REGULATION_CORRIDOR (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0100)) + +/* Initial charge battery voltage threshold (in mV). */ +#define FLASH_CONFIG_U_BAT_INITIAL_FULL (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0104)) + +/* Cancel initial charge voltage hold below this battery voltage (in mV). */ +#define FLASH_CONFIG_U_BAT_INITIAL_HOLD_CANCEL (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0108)) + +/* Transition to floating voltage levels after this time (in ms). */ +#define FLASH_CONFIG_INITIAL_CHARGE_HOLD_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x010C)) + +/* Duration of the transistion from initial charging to float (in ms). */ +#define FLASH_CONFIG_INITIAL_TO_FLOAT_TRANSITION_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0110)) + +/* Float charge battery voltage threshold (in mV). */ +#define FLASH_CONFIG_U_BAT_FLOAT_FULL (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0114)) + +/* Minimum voltage difference to U_bat that the solar panels must produce + * before charging is resumed after it was switched off (in mV). */ +#define FLASH_CONFIG_SLEEP_SOLAR_EXCESS_VOLTAGE (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0118)) + +/* Minimum charge current required before charging is stopped to save power at + * the charge pump (in mA). */ +#define FLASH_CONFIG_SLEEP_SOLAR_CURRENT (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x011C)) + +/* Delay between state change and sleep state check (in ms). */ +#define FLASH_CONFIG_SLEEP_STATE_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0120)) + +/* Delay between charging switch state change and sleep state check(in ms). */ +#define FLASH_CONFIG_SLEEP_SWITCH_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0124)) + +/* Maximum allowed microcontroller temperature (in units of 0.1 °C). If this + * temperature is exceeded, charging is stopped. The load is kept on. Do not + * set this too high as the heat has to propagate from the power MOSFETs. */ +#define FLASH_CONFIG_INTERNAL_TEMPERATURE_LIMIT (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0128)) + +/* Resume operation below this temperature (in units of 0.1 °C). */ +#define FLASH_CONFIG_INTERNAL_TEMPERATURE_RECOVERY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x012C)) + + +/* Thresholds for load control */ + +/* Voltage above which the load is turned on (in mV). */ +#define FLASH_CONFIG_U_BAT_LOAD_ON (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0130)) +/* Voltage below which the load is turned off (in mV). */ +#define FLASH_CONFIG_U_BAT_LOAD_OFF (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0134)) + +/* Current at which the overload protection triggers (in mA). */ +#define FLASH_CONFIG_LOAD_CURRENT_LIMIT_MA (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0138)) + +/* Inrush tolerance time (in ms). Overload protection is not enforced for this + * time after load power-on. */ +#define FLASH_CONFIG_LOAD_CURRENT_INRUSH_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x013C)) + +/* Minimum voltage that the charge pump must produce above U_bat before any + * power FET is switched on (in mV). */ +#define FLASH_CONFIG_MIN_CHARGE_PUMP_EXCESS_VOLTAGE (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0140)) + +/* The minimum time the load must be off before it can be switched on again (in ms). */ +#define FLASH_CONFIG_LOAD_ON_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0144)) + + +/* Measurement Averaging: + * Alpha is specified in units of 1/1000. 1000 means that only the latest + * value is relevant, 0 means that the measurement has no influence. The latter + * is useless. + * + * The formula to calculate the next averaged value avg from a measurement meas is: + * avg[k] = meas * (alpha/1000) + avg[k-1] * (1 - alpha/1000) + * + * For overload protection (battery voltage, load current), the latest values + * are always used. + * */ + +/* Averaging factor for load current. */ +#define FLASH_CONFIG_AVG_ALPHA_I_SOLAR (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0148)) +#define FLASH_CONFIG_AVG_ALPHA_I_LOAD (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x014C)) +#define FLASH_CONFIG_AVG_ALPHA_U_BAT (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0150)) +#define FLASH_CONFIG_AVG_ALPHA_U_SW (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0154)) +#define FLASH_CONFIG_AVG_ALPHA_U_SOLAR (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0158)) +#define FLASH_CONFIG_AVG_ALPHA_TEMP (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x015C)) + + +/* Generic configuration */ + +/* Time (in ms) to stay active in idle state before entering deep sleep. */ +#define FLASH_CONFIG_DEEPSLEEP_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0160)) + +/* Deep sleep duration (in seconds). */ +#define FLASH_CONFIG_DEEPSLEEP_DURATION (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0164)) + +#endif // FLASH_CONFIG_H diff --git a/utils/config_b26.yaml b/utils/config_b26.yaml new file mode 100644 index 0000000..8175032 --- /dev/null +++ b/utils/config_b26.yaml @@ -0,0 +1,108 @@ +# Values for the device at the B26 tower + +calibration: + # Calibration factor defined here are divided by 1000 to determine the actual + # scaling factor. Therefore, if the voltage determined by the firmware is 2% + # lower than the actual voltage, you have to scale by 1.02 and therefore + # specify 1020 in this list. + CAL_FACTOR_U_BAT: 994 + CAL_FACTOR_U_SOLAR: 997 + CAL_FACTOR_U_SW: 996 + CAL_FACTOR_I_SOLAR: 1015 + CAL_FACTOR_I_LOAD: 1000 + +config: + # Thresholds for charging control + + # Battery regulation corridor width (in mV). + U_BAT_REGULATION_CORRIDOR: 100 + + # Initial charge battery voltage threshold (in mV). + # stop charging if battery voltage reaches this threshold + U_BAT_INITIAL_FULL: 28600 + + # Cancel initial charge voltage hold below this battery voltage (in mV). + U_BAT_INITIAL_HOLD_CANCEL: 27000 + + # Transition to floating voltage levels after this time (in ms). + INITIAL_CHARGE_HOLD_TIME: 1800000 + + # Duration of the transistion from initial charging to float (in ms). + INITIAL_TO_FLOAT_TRANSITION_TIME: 600000 + + # Float charge battery voltage threshold (in mV). + # stop charging if battery voltage reaches this threshold + U_BAT_FLOAT_FULL: 27600 + + # Minimum voltage difference to U_bat that the solar panels must produce + # before charging is resumed after it was switched off (in mV). + SLEEP_SOLAR_EXCESS_VOLTAGE: 1000 + + # Minimum charge current required before charging is stopped to save power at + # the charge pump (in mA). + SLEEP_SOLAR_CURRENT: 1 + + # Delay between state change and sleep state check (in ms). + SLEEP_STATE_DELAY: 60000 + + # Delay between charging switch state change and sleep state check(in ms). + SLEEP_SWITCH_DELAY: 1000 + + # Maximum allowed microcontroller temperature (in units of 0.1 °C). If this + # temperature is exceeded, charging is stopped. The load is kept on. Do not + # set this too high as the heat has to propagate from the power MOSFETs. + INTERNAL_TEMPERATURE_LIMIT: 500 + + # Resume operation below this temperature (in units of 0.1 °C). + INTERNAL_TEMPERATURE_RECOVERY: 450 + + + # Thresholds for load control + + # Voltage above which the load is turned on (in mV). + U_BAT_LOAD_ON: 27000 + # Voltage below which the load is turned off (in mV). + U_BAT_LOAD_OFF: 24000 + + # Current at which the overload protection triggers (in mA). + LOAD_CURRENT_LIMIT_MA: 10000 + + # Inrush tolerance time (in ms). Overload protection is not enforced for this + # time after load power-on. + LOAD_CURRENT_INRUSH_TIME: 10 + + # Minimum voltage that the charge pump must produce above U_bat before any + # power FET is switched on (in mV). + MIN_CHARGE_PUMP_EXCESS_VOLTAGE: 10000 + + # The minimum time the load must be off before it can be switched on again (in ms). + LOAD_ON_DELAY: 10000 + + + # Measurement Averaging: + # Alpha is specified in units of 1/1000. 1000 means that only the latest + # value is relevant, 0 means that the measurement has no influence. The latter + # is useless. + # + # The formula to calculate the next averaged value avg from a measurement meas is: + # avg[k] = meas * (alpha/1000) + avg[k-1] * (1 alpha/1000) + # + # For overload protection (battery voltage, load current), the latest values + # are always used. + + # Averaging factor for load current. + AVG_ALPHA_I_SOLAR: 10 + AVG_ALPHA_I_LOAD: 10 + AVG_ALPHA_U_BAT: 100 + AVG_ALPHA_U_SW: 100 + AVG_ALPHA_U_SOLAR: 100 + AVG_ALPHA_TEMP: 10 + + + # Generic configuration + + # Time (in ms) to stay active in idle state before entering deep sleep. + DEEPSLEEP_DELAY: 1000 + + # Deep sleep duration (in seconds). + DEEPSLEEP_DURATION: 10 diff --git a/utils/config_dev.yaml b/utils/config_dev.yaml new file mode 100644 index 0000000..8a65a4d --- /dev/null +++ b/utils/config_dev.yaml @@ -0,0 +1,108 @@ +# Values for the development device + +calibration: + # Calibration factor defined here are divided by 1000 to determine the actual + # scaling factor. Therefore, if the voltage determined by the firmware is 2% + # lower than the actual voltage, you have to scale by 1.02 and therefore + # specify 1020 in this list. + CAL_FACTOR_U_BAT: 1012 + CAL_FACTOR_U_SOLAR: 1015 + CAL_FACTOR_U_SW: 1006 + CAL_FACTOR_I_SOLAR: 3980 + CAL_FACTOR_I_LOAD: 1000 + +config: + # Thresholds for charging control + + # Battery regulation corridor width (in mV). + U_BAT_REGULATION_CORRIDOR: 100 + + # Initial charge battery voltage threshold (in mV). + # stop charging if battery voltage reaches this threshold + U_BAT_INITIAL_FULL: 28600 + + # Cancel initial charge voltage hold below this battery voltage (in mV). + U_BAT_INITIAL_HOLD_CANCEL: 27000 + + # Transition to floating voltage levels after this time (in ms). + INITIAL_CHARGE_HOLD_TIME: 1800000 + + # Duration of the transistion from initial charging to float (in ms). + INITIAL_TO_FLOAT_TRANSITION_TIME: 600000 + + # Float charge battery voltage threshold (in mV). + # stop charging if battery voltage reaches this threshold + U_BAT_FLOAT_FULL: 27600 + + # Minimum voltage difference to U_bat that the solar panels must produce + # before charging is resumed after it was switched off (in mV). + SLEEP_SOLAR_EXCESS_VOLTAGE: 1000 + + # Minimum charge current required before charging is stopped to save power at + # the charge pump (in mA). + SLEEP_SOLAR_CURRENT: 1 + + # Delay between state change and sleep state check (in ms). + SLEEP_STATE_DELAY: 60000 + + # Delay between charging switch state change and sleep state check(in ms). + SLEEP_SWITCH_DELAY: 1000 + + # Maximum allowed microcontroller temperature (in units of 0.1 °C). If this + # temperature is exceeded, charging is stopped. The load is kept on. Do not + # set this too high as the heat has to propagate from the power MOSFETs. + INTERNAL_TEMPERATURE_LIMIT: 500 + + # Resume operation below this temperature (in units of 0.1 °C). + INTERNAL_TEMPERATURE_RECOVERY: 450 + + + # Thresholds for load control + + # Voltage above which the load is turned on (in mV). + U_BAT_LOAD_ON: 27000 + # Voltage below which the load is turned off (in mV). + U_BAT_LOAD_OFF: 24000 + + # Current at which the overload protection triggers (in mA). + LOAD_CURRENT_LIMIT_MA: 10000 + + # Inrush tolerance time (in ms). Overload protection is not enforced for this + # time after load power-on. + LOAD_CURRENT_INRUSH_TIME: 10 + + # Minimum voltage that the charge pump must produce above U_bat before any + # power FET is switched on (in mV). + MIN_CHARGE_PUMP_EXCESS_VOLTAGE: 10000 + + # The minimum time the load must be off before it can be switched on again (in ms). + LOAD_ON_DELAY: 10000 + + + # Measurement Averaging: + # Alpha is specified in units of 1/1000. 1000 means that only the latest + # value is relevant, 0 means that the measurement has no influence. The latter + # is useless. + # + # The formula to calculate the next averaged value avg from a measurement meas is: + # avg[k] = meas * (alpha/1000) + avg[k-1] * (1 alpha/1000) + # + # For overload protection (battery voltage, load current), the latest values + # are always used. + + # Averaging factor for load current. + AVG_ALPHA_I_SOLAR: 10 + AVG_ALPHA_I_LOAD: 10 + AVG_ALPHA_U_BAT: 100 + AVG_ALPHA_U_SW: 100 + AVG_ALPHA_U_SOLAR: 100 + AVG_ALPHA_TEMP: 10 + + + # Generic configuration + + # Time (in ms) to stay active in idle state before entering deep sleep. + DEEPSLEEP_DELAY: 1000 + + # Deep sleep duration (in seconds). + DEEPSLEEP_DURATION: 10 diff --git a/utils/config_to_hex.py b/utils/config_to_hex.py new file mode 100755 index 0000000..f96949c --- /dev/null +++ b/utils/config_to_hex.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +import sys +import struct + +import yaml +from intelhex import IntelHex + +BASE_ADDR = 0x08007C00 + +CALIBRATION_KEY_TO_OFFSET = { + "CAL_FACTOR_U_BAT": 0x0000, + "CAL_FACTOR_U_SOLAR": 0x0002, + "CAL_FACTOR_U_SW": 0x0004, + "CAL_FACTOR_I_SOLAR": 0x0006, + "CAL_FACTOR_I_LOAD": 0x0008, + } + +CONFIG_KEY_TO_OFFSET = { + "U_BAT_REGULATION_CORRIDOR": 0x0100, + "U_BAT_INITIAL_FULL": 0x0104, + "U_BAT_INITIAL_HOLD_CANCEL": 0x0108, + "INITIAL_CHARGE_HOLD_TIME": 0x010C, + "INITIAL_TO_FLOAT_TRANSITION_TIME": 0x0110, + "U_BAT_FLOAT_FULL": 0x0114, + "SLEEP_SOLAR_EXCESS_VOLTAGE": 0x0118, + "SLEEP_SOLAR_CURRENT": 0x011C, + "SLEEP_STATE_DELAY": 0x0120, + "SLEEP_SWITCH_DELAY": 0x0124, + "INTERNAL_TEMPERATURE_LIMIT": 0x0128, + "INTERNAL_TEMPERATURE_RECOVERY": 0x012C, + "U_BAT_LOAD_ON": 0x0130, + "U_BAT_LOAD_OFF": 0x0134, + "LOAD_CURRENT_LIMIT_MA": 0x0138, + "LOAD_CURRENT_INRUSH_TIME": 0x013C, + "MIN_CHARGE_PUMP_EXCESS_VOLTAGE": 0x0140, + "LOAD_ON_DELAY": 0x0144, + "AVG_ALPHA_I_SOLAR": 0x0148, + "AVG_ALPHA_I_LOAD": 0x014C, + "AVG_ALPHA_U_BAT": 0x0150, + "AVG_ALPHA_U_SW": 0x0154, + "AVG_ALPHA_U_SOLAR": 0x0158, + "AVG_ALPHA_TEMP": 0x015C, + "DEEPSLEEP_DELAY": 0x0160, + "DEEPSLEEP_DURATION": 0x0164, + } + + +if __name__ == "__main__": + output = IntelHex() + + if len(sys.argv) < 3: + print(f"usage: {sys.argv[0]} ") + sys.exit(1) + + with open(sys.argv[1], 'r') as configfile: + config = yaml.safe_load(configfile) + + for key, offset in CALIBRATION_KEY_TO_OFFSET.items(): + value = config['calibration'][key] + enc_bytes = struct.pack(' Date: Sun, 25 Sep 2022 17:24:21 +0200 Subject: [PATCH 4/5] Use the new flash config module --- src/charge_control.c | 40 +++++++++--------- src/config.h | 98 -------------------------------------------- src/flash_config.c | 7 ++++ src/flash_config.h | 42 +++++++++++-------- src/main.c | 25 ++++++++--- src/measurement.c | 16 ++++---- 6 files changed, 79 insertions(+), 149 deletions(-) delete mode 100644 src/config.h create mode 100644 src/flash_config.c diff --git a/src/charge_control.c b/src/charge_control.c index e719cfa..3b8a13a 100644 --- a/src/charge_control.c +++ b/src/charge_control.c @@ -6,7 +6,7 @@ #include "measurement.h" #include "charge_pump.h" #include "rs485.h" -#include "config.h" +#include "flash_config.h" #include "charge_control.h" @@ -92,9 +92,9 @@ static enum ChargeState control_solar_charging( } // low-current limit (go to sleep at night) - if((time_in_state > SLEEP_STATE_DELAY) + if((time_in_state > FLASH_CONFIG_SLEEP_STATE_DELAY) && (current_switch_state == true) - && (solar_switch_onoff_duration > SLEEP_SWITCH_DELAY) + && (solar_switch_onoff_duration > FLASH_CONFIG_SLEEP_SWITCH_DELAY) && (meas->avg_i_solar < sleep_solar_current)) { return CHARGE_SLEEP; } @@ -152,20 +152,20 @@ static void solar_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas) } // time limit for initial hold charging - if(charge_time_in_state > INITIAL_CHARGE_HOLD_TIME) { + if(charge_time_in_state > FLASH_CONFIG_INITIAL_CHARGE_HOLD_TIME) { charge_state = CHARGE_TRANSITION; } break; case CHARGE_TRANSITION: - if(charge_time_in_state < INITIAL_TO_FLOAT_TRANSITION_TIME) { + if(charge_time_in_state < FLASH_CONFIG_INITIAL_TO_FLOAT_TRANSITION_TIME) { // dynamically adjust thresholds fxp_t u_bat_full = fxp_add(u_bat_initial_full, fxp_mult( fxp_sub(u_bat_float_full, u_bat_initial_full), - fxp_div(charge_time_in_state, INITIAL_TO_FLOAT_TRANSITION_TIME))); + fxp_div(charge_time_in_state, FLASH_CONFIG_INITIAL_TO_FLOAT_TRANSITION_TIME))); fxp_t u_bat_low = fxp_sub(u_bat_full, u_bat_regulation_corridor); @@ -260,7 +260,7 @@ static void load_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas) } if((meas->i_load > load_current_limit) - && (discharge_time_in_state > LOAD_CURRENT_INRUSH_TIME)) { + && (discharge_time_in_state > FLASH_CONFIG_LOAD_CURRENT_INRUSH_TIME)) { discharge_state = DISCHARGE_OVERCURRENT; } @@ -277,7 +277,7 @@ static void load_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas) // Can only switch on again after a specific amount of time has passed if((meas->avg_u_bat > u_bat_load_on) - && (discharge_time_in_state > LOAD_ON_DELAY)) { + && (discharge_time_in_state > FLASH_CONFIG_LOAD_ON_DELAY)) { discharge_state = DISCHARGE_OK; } break; @@ -307,30 +307,30 @@ void charge_control_init(void) discharge_state_entered = true; /* calculate thresholds */ - u_bat_regulation_corridor = fxp_div(FXP_FROM_INT(U_BAT_REGULATION_CORRIDOR), + u_bat_regulation_corridor = fxp_div(FXP_FROM_INT(FLASH_CONFIG_U_BAT_REGULATION_CORRIDOR), FXP_FROM_INT(1000)); - u_bat_initial_full = fxp_div(FXP_FROM_INT(U_BAT_INITIAL_FULL), FXP_FROM_INT(1000)); + u_bat_initial_full = fxp_div(FXP_FROM_INT(FLASH_CONFIG_U_BAT_INITIAL_FULL), FXP_FROM_INT(1000)); u_bat_initial_low = fxp_sub(u_bat_initial_full, u_bat_regulation_corridor); - u_bat_initial_hold_cancel = fxp_div(FXP_FROM_INT(U_BAT_INITIAL_HOLD_CANCEL), FXP_FROM_INT(1000)); + u_bat_initial_hold_cancel = fxp_div(FXP_FROM_INT(FLASH_CONFIG_U_BAT_INITIAL_HOLD_CANCEL), FXP_FROM_INT(1000)); - u_bat_float_full = fxp_div(FXP_FROM_INT(U_BAT_FLOAT_FULL), FXP_FROM_INT(1000)); + u_bat_float_full = fxp_div(FXP_FROM_INT(FLASH_CONFIG_U_BAT_FLOAT_FULL), FXP_FROM_INT(1000)); u_bat_float_low = fxp_sub(u_bat_float_full, u_bat_regulation_corridor); - min_charge_pump_excess_voltage = fxp_div(FXP_FROM_INT(MIN_CHARGE_PUMP_EXCESS_VOLTAGE), + min_charge_pump_excess_voltage = fxp_div(FXP_FROM_INT(FLASH_CONFIG_MIN_CHARGE_PUMP_EXCESS_VOLTAGE), FXP_FROM_INT(1000)); - u_bat_load_on = fxp_div(FXP_FROM_INT(U_BAT_LOAD_ON), FXP_FROM_INT(1000)); - u_bat_load_off = fxp_div(FXP_FROM_INT(U_BAT_LOAD_OFF), FXP_FROM_INT(1000)); + u_bat_load_on = fxp_div(FXP_FROM_INT(FLASH_CONFIG_U_BAT_LOAD_ON), FXP_FROM_INT(1000)); + u_bat_load_off = fxp_div(FXP_FROM_INT(FLASH_CONFIG_U_BAT_LOAD_OFF), FXP_FROM_INT(1000)); - load_current_limit = fxp_div(FXP_FROM_INT(LOAD_CURRENT_LIMIT_MA), FXP_FROM_INT(1000)); + load_current_limit = fxp_div(FXP_FROM_INT(FLASH_CONFIG_LOAD_CURRENT_LIMIT_MA), FXP_FROM_INT(1000)); - internal_temperature_limit = fxp_div(FXP_FROM_INT(INTERNAL_TEMPERATURE_LIMIT), FXP_FROM_INT(10)); - internal_temperature_recovery = fxp_div(FXP_FROM_INT(INTERNAL_TEMPERATURE_RECOVERY), FXP_FROM_INT(10)); + internal_temperature_limit = fxp_div(FXP_FROM_INT(FLASH_CONFIG_INTERNAL_TEMPERATURE_LIMIT), FXP_FROM_INT(10)); + internal_temperature_recovery = fxp_div(FXP_FROM_INT(FLASH_CONFIG_INTERNAL_TEMPERATURE_RECOVERY), FXP_FROM_INT(10)); - sleep_solar_current = fxp_div(FXP_FROM_INT(SLEEP_SOLAR_CURRENT), FXP_FROM_INT(1000)); - sleep_solar_excess_voltage = fxp_div(FXP_FROM_INT(SLEEP_SOLAR_EXCESS_VOLTAGE), FXP_FROM_INT(1000)); + sleep_solar_current = fxp_div(FXP_FROM_INT(FLASH_CONFIG_SLEEP_SOLAR_CURRENT), FXP_FROM_INT(1000)); + sleep_solar_excess_voltage = fxp_div(FXP_FROM_INT(FLASH_CONFIG_SLEEP_SOLAR_EXCESS_VOLTAGE), FXP_FROM_INT(1000)); } diff --git a/src/config.h b/src/config.h deleted file mode 100644 index a9ea40c..0000000 --- a/src/config.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -/* Thresholds for charging control */ - -/* Battery regulation corridor width (in mV). */ -#define U_BAT_REGULATION_CORRIDOR 100 - -/* Initial charge battery voltage threshold (in mV). */ -#define U_BAT_INITIAL_FULL 28600 // stop charging if battery voltage reaches this threshold - -/* Cancel initial charge voltage hold below this battery voltage (in mV). */ -#define U_BAT_INITIAL_HOLD_CANCEL 27000 - -/* Transition to floating voltage levels after this time (in ms). */ -#define INITIAL_CHARGE_HOLD_TIME 1800000 - -/* Duration of the transistion from initial charging to float (in ms). */ -#define INITIAL_TO_FLOAT_TRANSITION_TIME 600000 - -/* Float charge battery voltage threshold (in mV). */ -#define U_BAT_FLOAT_FULL 27600 // stop charging if battery voltage reaches this threshold - -/* Minimum voltage difference to U_bat that the solar panels must produce - * before charging is resumed after it was switched off (in mV). */ -#define SLEEP_SOLAR_EXCESS_VOLTAGE 1000 - -/* Minimum charge current required before charging is stopped to save power at - * the charge pump (in mA). */ -#define SLEEP_SOLAR_CURRENT 1 - -/* Delay between state change and sleep state check (in ms). */ -#define SLEEP_STATE_DELAY 60000 - -/* Delay between charging switch state change and sleep state check(in ms). */ -#define SLEEP_SWITCH_DELAY 1000 - -/* Maximum allowed microcontroller temperature (in units of 0.1 °C). If this - * temperature is exceeded, charging is stopped. The load is kept on. Do not - * set this too high as the heat has to propagate from the power MOSFETs. */ -#define INTERNAL_TEMPERATURE_LIMIT 500 - -/* Resume operation below this temperature (in units of 0.1 °C). */ -#define INTERNAL_TEMPERATURE_RECOVERY 450 - - -/* Thresholds for load control */ - -/* Voltage above which the load is turned on (in mV). */ -#define U_BAT_LOAD_ON 27000 -/* Voltage below which the load is turned off (in mV). */ -#define U_BAT_LOAD_OFF 24000 - -/* Current at which the overload protection triggers (in mA). */ -#define LOAD_CURRENT_LIMIT_MA 10000 - -/* Inrush tolerance time (in ms). Overload protection is not enforced for this - * time after load power-on. */ -#define LOAD_CURRENT_INRUSH_TIME 10 - -/* Minimum voltage that the charge pump must produce above U_bat before any - * power FET is switched on (in mV). */ -#define MIN_CHARGE_PUMP_EXCESS_VOLTAGE 10000 - -/* The minimum time the load must be off before it can be switched on again (in ms). */ -#define LOAD_ON_DELAY 10000 - - -/* Measurement Averaging: - * Alpha is specified in units of 1/1000. 1000 means that only the latest - * value is relevant, 0 means that the measurement has no influence. The latter - * is useless. - * - * The formula to calculate the next averaged value avg from a measurement meas is: - * avg[k] = meas * (alpha/1000) + avg[k-1] * (1 - alpha/1000) - * - * For overload protection (battery voltage, load current), the latest values - * are always used. - * */ - -/* Averaging factor for load current. */ -#define AVG_ALPHA_I_SOLAR 10 -#define AVG_ALPHA_I_LOAD 10 -#define AVG_ALPHA_U_BAT 100 -#define AVG_ALPHA_U_SW 100 -#define AVG_ALPHA_U_SOLAR 100 -#define AVG_ALPHA_TEMP 10 - - -/* Generic configuration */ - -/* Time (in ms) to stay active in idle state before entering deep sleep. */ -#define DEEPSLEEP_DELAY 1000 - -/* Deep sleep duration (in seconds). */ -#define DEEPSLEEP_DURATION 10 - -#endif // CONFIG_H diff --git a/src/flash_config.c b/src/flash_config.c new file mode 100644 index 0000000..365769b --- /dev/null +++ b/src/flash_config.c @@ -0,0 +1,7 @@ +#include "flash_config.h" + +bool flash_config_is_present(void) +{ + return (FLASH_CONFIG_CAL_FACTOR_U_BAT != 0xFFFF) + && (FLASH_CONFIG_U_BAT_REGULATION_CORRIDOR != -1); +} diff --git a/src/flash_config.h b/src/flash_config.h index 412d2c2..24dfde0 100644 --- a/src/flash_config.h +++ b/src/flash_config.h @@ -2,6 +2,7 @@ #define FLASH_CONFIG_H #include +#include extern uint8_t __conf_start; @@ -23,13 +24,13 @@ extern uint8_t __conf_start; /***** General configuration *****/ /* Battery regulation corridor width (in mV). */ -#define FLASH_CONFIG_U_BAT_REGULATION_CORRIDOR (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0100)) +#define FLASH_CONFIG_U_BAT_REGULATION_CORRIDOR (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0100)) /* Initial charge battery voltage threshold (in mV). */ -#define FLASH_CONFIG_U_BAT_INITIAL_FULL (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0104)) +#define FLASH_CONFIG_U_BAT_INITIAL_FULL (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0104)) /* Cancel initial charge voltage hold below this battery voltage (in mV). */ -#define FLASH_CONFIG_U_BAT_INITIAL_HOLD_CANCEL (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0108)) +#define FLASH_CONFIG_U_BAT_INITIAL_HOLD_CANCEL (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0108)) /* Transition to floating voltage levels after this time (in ms). */ #define FLASH_CONFIG_INITIAL_CHARGE_HOLD_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x010C)) @@ -38,15 +39,15 @@ extern uint8_t __conf_start; #define FLASH_CONFIG_INITIAL_TO_FLOAT_TRANSITION_TIME (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0110)) /* Float charge battery voltage threshold (in mV). */ -#define FLASH_CONFIG_U_BAT_FLOAT_FULL (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0114)) +#define FLASH_CONFIG_U_BAT_FLOAT_FULL (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0114)) /* Minimum voltage difference to U_bat that the solar panels must produce * before charging is resumed after it was switched off (in mV). */ -#define FLASH_CONFIG_SLEEP_SOLAR_EXCESS_VOLTAGE (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0118)) +#define FLASH_CONFIG_SLEEP_SOLAR_EXCESS_VOLTAGE (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0118)) /* Minimum charge current required before charging is stopped to save power at * the charge pump (in mA). */ -#define FLASH_CONFIG_SLEEP_SOLAR_CURRENT (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x011C)) +#define FLASH_CONFIG_SLEEP_SOLAR_CURRENT (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x011C)) /* Delay between state change and sleep state check (in ms). */ #define FLASH_CONFIG_SLEEP_STATE_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0120)) @@ -57,21 +58,21 @@ extern uint8_t __conf_start; /* Maximum allowed microcontroller temperature (in units of 0.1 °C). If this * temperature is exceeded, charging is stopped. The load is kept on. Do not * set this too high as the heat has to propagate from the power MOSFETs. */ -#define FLASH_CONFIG_INTERNAL_TEMPERATURE_LIMIT (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0128)) +#define FLASH_CONFIG_INTERNAL_TEMPERATURE_LIMIT (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0128)) /* Resume operation below this temperature (in units of 0.1 °C). */ -#define FLASH_CONFIG_INTERNAL_TEMPERATURE_RECOVERY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x012C)) +#define FLASH_CONFIG_INTERNAL_TEMPERATURE_RECOVERY (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x012C)) /* Thresholds for load control */ /* Voltage above which the load is turned on (in mV). */ -#define FLASH_CONFIG_U_BAT_LOAD_ON (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0130)) +#define FLASH_CONFIG_U_BAT_LOAD_ON (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0130)) /* Voltage below which the load is turned off (in mV). */ -#define FLASH_CONFIG_U_BAT_LOAD_OFF (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0134)) +#define FLASH_CONFIG_U_BAT_LOAD_OFF (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0134)) /* Current at which the overload protection triggers (in mA). */ -#define FLASH_CONFIG_LOAD_CURRENT_LIMIT_MA (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0138)) +#define FLASH_CONFIG_LOAD_CURRENT_LIMIT_MA (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0138)) /* Inrush tolerance time (in ms). Overload protection is not enforced for this * time after load power-on. */ @@ -79,7 +80,7 @@ extern uint8_t __conf_start; /* Minimum voltage that the charge pump must produce above U_bat before any * power FET is switched on (in mV). */ -#define FLASH_CONFIG_MIN_CHARGE_PUMP_EXCESS_VOLTAGE (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0140)) +#define FLASH_CONFIG_MIN_CHARGE_PUMP_EXCESS_VOLTAGE (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0140)) /* The minimum time the load must be off before it can be switched on again (in ms). */ #define FLASH_CONFIG_LOAD_ON_DELAY (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0144)) @@ -98,12 +99,12 @@ extern uint8_t __conf_start; * */ /* Averaging factor for load current. */ -#define FLASH_CONFIG_AVG_ALPHA_I_SOLAR (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0148)) -#define FLASH_CONFIG_AVG_ALPHA_I_LOAD (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x014C)) -#define FLASH_CONFIG_AVG_ALPHA_U_BAT (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0150)) -#define FLASH_CONFIG_AVG_ALPHA_U_SW (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0154)) -#define FLASH_CONFIG_AVG_ALPHA_U_SOLAR (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0158)) -#define FLASH_CONFIG_AVG_ALPHA_TEMP (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x015C)) +#define FLASH_CONFIG_AVG_ALPHA_I_SOLAR (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0148)) +#define FLASH_CONFIG_AVG_ALPHA_I_LOAD (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x014C)) +#define FLASH_CONFIG_AVG_ALPHA_U_BAT (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0150)) +#define FLASH_CONFIG_AVG_ALPHA_U_SW (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0154)) +#define FLASH_CONFIG_AVG_ALPHA_U_SOLAR (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x0158)) +#define FLASH_CONFIG_AVG_ALPHA_TEMP (*(int32_t*)(FLASH_CONFIG_BASE_PTR + 0x015C)) /* Generic configuration */ @@ -114,4 +115,9 @@ extern uint8_t __conf_start; /* Deep sleep duration (in seconds). */ #define FLASH_CONFIG_DEEPSLEEP_DURATION (*(uint32_t*)(FLASH_CONFIG_BASE_PTR + 0x0164)) + +/* Functions */ + +bool flash_config_is_present(void); + #endif // FLASH_CONFIG_H diff --git a/src/main.c b/src/main.c index bb7a1d3..1d8ce43 100644 --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,7 @@ #include "deepsleep.h" #include "pinout.h" -#include "config.h" +#include "flash_config.h" volatile int wait_frame = 1; @@ -36,6 +36,16 @@ static void init_systick(int freq) } +static void config_err_blink_code(uint64_t timebase_ms) +{ + if(timebase_ms % 500 < 250) { + led_chplex_mask(0x3F); // all on + } else { + led_chplex_mask(0x00); // all off + } +} + + static bool ledtest(uint64_t timebase_ms) { if(timebase_ms == 0) { @@ -260,9 +270,14 @@ int main(void) ledtest_done = ledtest(timebase_ms); led_chplex_periodic(); } else if(!startup_done) { - charge_pump_start(); + if(flash_config_is_present()) { + charge_pump_start(); - startup_done = true; + startup_done = true; + } else { + config_err_blink_code(timebase_ms); + led_chplex_periodic(); + } } else { measurement_start(); @@ -297,8 +312,8 @@ int main(void) charge_control_idle_since = timebase_ms; } else { // charge control already idle - if((timebase_ms - charge_control_idle_since) > DEEPSLEEP_DELAY) { - low_power_mode(DEEPSLEEP_DURATION); + if((timebase_ms - charge_control_idle_since) > FLASH_CONFIG_DEEPSLEEP_DELAY) { + low_power_mode(FLASH_CONFIG_DEEPSLEEP_DURATION); charge_control_was_idle = false; } } diff --git a/src/measurement.c b/src/measurement.c index 713e8cb..e91b303 100644 --- a/src/measurement.c +++ b/src/measurement.c @@ -8,7 +8,7 @@ #include "measurement.h" #include "calibration.h" -#include "config.h" +#include "flash_config.h" #define ADC_NUM_CHANNELS 6 static volatile int16_t adc_values[ADC_NUM_CHANNELS]; @@ -55,7 +55,7 @@ static fxp_t calc_temperature(uint16_t adc_val) static fxp_t adc_val_to_pin_voltage(uint16_t adc_val) { return fxp_div( - fxp_mult(FXP_FROM_INT(adc_val), fxp_div(FXP_FROM_INT(33), FXP_FROM_INT(10))), + fxp_mult(FXP_FROM_INT((int32_t)adc_val), fxp_div(FXP_FROM_INT(33), FXP_FROM_INT(10))), FXP_FROM_INT(4096)); } @@ -105,12 +105,12 @@ void measurement_init(void) fxp_div(FXP_FROM_INT(CAL_FACTOR_I_LOAD), FXP_FROM_INT(1000)); // Convert and precalculate coefficients for exponential averaging - avg_alpha_i_solar = fxp_div(FXP_FROM_INT(AVG_ALPHA_I_SOLAR), FXP_FROM_INT(1000)); - avg_alpha_i_load = fxp_div(FXP_FROM_INT(AVG_ALPHA_I_LOAD), FXP_FROM_INT(1000)); - avg_alpha_u_bat = fxp_div(FXP_FROM_INT(AVG_ALPHA_U_BAT), FXP_FROM_INT(1000)); - avg_alpha_u_sw = fxp_div(FXP_FROM_INT(AVG_ALPHA_U_SW), FXP_FROM_INT(1000)); - avg_alpha_u_solar = fxp_div(FXP_FROM_INT(AVG_ALPHA_U_SOLAR), FXP_FROM_INT(1000)); - avg_alpha_temp = fxp_div(FXP_FROM_INT(AVG_ALPHA_TEMP), FXP_FROM_INT(1000)); + avg_alpha_i_solar = fxp_div(FXP_FROM_INT(FLASH_CONFIG_AVG_ALPHA_I_SOLAR), FXP_FROM_INT(1000)); + avg_alpha_i_load = fxp_div(FXP_FROM_INT(FLASH_CONFIG_AVG_ALPHA_I_LOAD), FXP_FROM_INT(1000)); + avg_alpha_u_bat = fxp_div(FXP_FROM_INT(FLASH_CONFIG_AVG_ALPHA_U_BAT), FXP_FROM_INT(1000)); + avg_alpha_u_sw = fxp_div(FXP_FROM_INT(FLASH_CONFIG_AVG_ALPHA_U_SW), FXP_FROM_INT(1000)); + avg_alpha_u_solar = fxp_div(FXP_FROM_INT(FLASH_CONFIG_AVG_ALPHA_U_SOLAR), FXP_FROM_INT(1000)); + avg_alpha_temp = fxp_div(FXP_FROM_INT(FLASH_CONFIG_AVG_ALPHA_TEMP), FXP_FROM_INT(1000)); // Inverse (1 - alpha) exponential averaging coefficients avg_alpha_i_solar_inv = fxp_sub(FXP_FROM_INT(1), avg_alpha_i_solar); From 16619397b16905eeabdddcb87c3ab64b65737dc3 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sun, 25 Sep 2022 17:35:37 +0200 Subject: [PATCH 5/5] Added script for flash config upload --- utils/upload_config_hex.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 utils/upload_config_hex.sh diff --git a/utils/upload_config_hex.sh b/utils/upload_config_hex.sh new file mode 100755 index 0000000..7352764 --- /dev/null +++ b/utils/upload_config_hex.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +set -euo pipefail + +HEXFILE="$1" + +if [ ! -f "$HEXFILE" ]; then + echo "$HEXFILE cannot be accessed." + exit 1 +fi + +JLinkExe -device STM32F030C8 -speed 1000 -if SWD <