diff --git a/include/pwr_save.h b/include/pwr_save.h index df6ad71..e303ec9 100644 --- a/include/pwr_save.h +++ b/include/pwr_save.h @@ -109,7 +109,7 @@ int pwr_save_switch_mode_to_m4(void); void pwr_save_switch_mode_to_i5(void); void pwr_save_switch_mode_to_l6(uint16_t sleep_time); void pwr_save_switch_mode_to_l7(uint16_t sleep_time); -void pwr_save_pooling_handler(const config_data_mode_t * config, const config_data_basic_t * timers, int16_t minutes_to_wx); // this should be called from 10 seconds pooler +void pwr_save_pooling_handler(const config_data_mode_t * config, const config_data_basic_t * timers, int16_t minutes_to_wx, uint16_t vbatt); // this should be called from 10 seconds pooler #endif diff --git a/include/rte_main.h b/include/rte_main.h index 49b39e4..9686ebb 100644 --- a/include/rte_main.h +++ b/include/rte_main.h @@ -14,5 +14,6 @@ extern uint8_t rte_main_trigger_modbus_status; extern uint8_t rte_main_trigger_wx_packet; +extern uint16_t rte_main_battery_voltage; #endif diff --git a/src/io.c b/src/io.c index 3f93e24..3bd29af 100644 --- a/src/io.c +++ b/src/io.c @@ -155,6 +155,7 @@ void io_vbat_meas_init(int8_t a_coeff, int8_t b_coeff) { io_vbat_a_coeff = a_coeff; io_vbat_b_coeff = b_coeff; +#ifdef STM32L471xx GPIO_InitTypeDef.Mode = LL_GPIO_MODE_ANALOG; GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitTypeDef.Pin = LL_GPIO_PIN_5; @@ -204,12 +205,13 @@ void io_vbat_meas_init(int8_t a_coeff, int8_t b_coeff) { // ignore overrun and overwrite data register content with new conversion result ADC2->CFGR |= ADC_CFGR_OVRMOD; - +#endif } uint16_t io_vbat_meas_get(void) { uint16_t out = 0; +#ifdef STM32L471xx float temp = 0.0f; @@ -235,7 +237,7 @@ uint16_t io_vbat_meas_get(void) { temp = (float)out * 0.00081f; out = (uint16_t) (temp * (float)io_vbat_a_coeff + (float)io_vbat_b_coeff); - +#endif return out; } diff --git a/src/it_handlers.c b/src/it_handlers.c index efd2831..2c18213 100644 --- a/src/it_handlers.c +++ b/src/it_handlers.c @@ -35,6 +35,8 @@ #include "diag/Trace.h" #include "io.h" +#include "rte_main.h" + #include "station_config.h" @@ -98,7 +100,9 @@ void RTC_WKUP_IRQHandler(void) { pwr_save_exit_from_stop2(); - pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, 1); + rte_main_battery_voltage = io_vbat_meas_get(); + + pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, 1, rte_main_battery_voltage); } diff --git a/src/main.c b/src/main.c index 076c109..7f07c9b 100644 --- a/src/main.c +++ b/src/main.c @@ -228,7 +228,6 @@ LL_GPIO_InitTypeDef GPIO_InitTypeDef; gsm_sim800_state_t main_gsm_state; -uint16_t main_battery_voltage; #endif static void message_callback(struct AX25Msg *msg) { @@ -868,7 +867,7 @@ int main(int argc, char* argv[]){ led_control_led2_bottom(false); #if defined(STM32L471xx) - main_battery_voltage = io_vbat_meas_get(); + rte_main_battery_voltage = io_vbat_meas_get(); pwr_save_switch_mode_to_c0(); @@ -1101,6 +1100,8 @@ int main(int argc, char* argv[]){ // downloaded from sensors if _METEO and/or _DALLAS_AS_TELEM aren't defined if (main_wx_sensors_pool_timer < 10) { + rte_main_battery_voltage = io_vbat_meas_get(); + if (main_modbus_rtu_master_enabled == 1) { rtu_serial_start(); } @@ -1207,7 +1208,7 @@ int main(int argc, char* argv[]){ #ifdef STM32L471xx // inhibit any power save switching when modem transmits data if (!main_afsk.sending) { - pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx()); + pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx(), rte_main_battery_voltage); } if (main_config_data_mode->gsm == 1) { diff --git a/src/packet_tx_handler.c b/src/packet_tx_handler.c index 141c92c..6ffc545 100644 --- a/src/packet_tx_handler.c +++ b/src/packet_tx_handler.c @@ -389,6 +389,13 @@ void packet_tx_set_current_counters(packet_tx_counter_values_t * in) { if (in->kiss_counter != 0) packet_tx_meteo_kiss_counter = in->kiss_counter; } + else { + packet_tx_beacon_counter = 0; + packet_tx_meteo_counter = 2; + packet_tx_telemetry_counter = 0; + packet_tx_telemetry_descr_counter = 10; + packet_tx_meteo_kiss_counter = 0; + } } int16_t packet_tx_get_minutes_to_next_wx(void) { diff --git a/src/pwr_save.c b/src/pwr_save.c index eb199eb..ff315c9 100644 --- a/src/pwr_save.c +++ b/src/pwr_save.c @@ -18,6 +18,8 @@ #include "wx_handler.h" #include "main.h" +#include "rte_main.h" + #include "drivers/analog_anemometer.h" @@ -40,6 +42,18 @@ int8_t pwr_save_seconds_to_wx = 0; int16_t pwr_save_sleep_time_in_seconds = -1; +int8_t pwr_save_currently_cutoff = 0; + +/** + * This is cutoff voltage at which the power saving subsystem will keep ParaMETEO constantly + * in L7 mode and wakeup once every 20 minutes to check B+ once again + */ +const uint16_t PWR_SAVE_CUTOFF_VOLTAGE = 112; // 11.2V + +/** + * This is the restore voltage a battery must be charged to for ParaMETEO to restore it's normal operation + */ +const uint16_t PWR_SAVE_STARTUP_RESTORE_VOLTAGE = 122; // 12.2V static void pwr_save_unclock_rtc_backup_regs(void) { // enable access to backup domain @@ -122,6 +136,8 @@ void pwr_save_init(config_data_powersave_mode_t mode) { */ void pwr_save_enter_stop2(void) { + rte_main_battery_voltage = io_vbat_meas_get(); + analog_anemometer_deinit(); // clear previous low power mode selection @@ -186,8 +202,13 @@ void pwr_save_exit_from_stop2(void) { timers.telemetry_counter += (pwr_save_sleep_time_in_seconds / 60); timers.telemetry_desc_counter += (pwr_save_sleep_time_in_seconds / 60); - // set counters back - packet_tx_set_current_counters(&timers); + if (pwr_save_currently_cutoff == 0) { + // set counters back + packet_tx_set_current_counters(&timers); + } + else { + packet_tx_set_current_counters(0); + } break; @@ -486,13 +507,34 @@ void pwr_save_switch_mode_to_l7(uint16_t sleep_time) { pwr_save_enter_stop2(); } -void pwr_save_pooling_handler(const config_data_mode_t * config, const config_data_basic_t * timers, int16_t minutes_to_wx) { +void pwr_save_pooling_handler(const config_data_mode_t * config, const config_data_basic_t * timers, int16_t minutes_to_wx, uint16_t vbatt) { // this function should be called from 10 seconds pooler int reinit_sensors = 0; packet_tx_counter_values_t counters; + if (vbatt < 0xF) { + vbatt = 0xFFFFu; + } + + if (vbatt <= PWR_SAVE_CUTOFF_VOLTAGE && pwr_save_currently_cutoff == 0) { + pwr_save_currently_cutoff = 1; + + pwr_save_switch_mode_to_l7(60 * 20); + + return; + + } + else if (vbatt <= PWR_SAVE_STARTUP_RESTORE_VOLTAGE && pwr_save_currently_cutoff == 1) { + pwr_save_switch_mode_to_l7(60 * 20); + + return; + } + else { + pwr_save_currently_cutoff = 0; + } + // get current counter values packet_tx_get_current_counters(&counters); diff --git a/src/rte_main.c b/src/rte_main.c index 4fbb257..6b92216 100644 --- a/src/rte_main.c +++ b/src/rte_main.c @@ -16,3 +16,6 @@ uint8_t rte_main_trigger_modbus_status = 0; uint8_t rte_main_trigger_wx_packet = 0; +uint16_t rte_main_battery_voltage; + +