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);