refactoring stop2 sleeping cycles to be handled in main loop in main function

master
Mateusz Lubecki 2024-10-01 22:08:00 +02:00
rodzic b58f13a407
commit 6ca9151cae
7 zmienionych plików z 212 dodań i 152 usunięć

Wyświetl plik

@ -48,7 +48,7 @@
//#define INHIBIT_CUTOFF
/**
* Intermediate STOP2 cycle lenght within L7 or L6 mode.
* Intermediate STOP2 cycle length within L7 or L6 mode.
*/
#define PWR_SAVE_STOP2_CYCLE_LENGHT_SEC 30u

Wyświetl plik

@ -117,7 +117,10 @@
extern int8_t pwr_save_currently_cutoff;
void pwr_save_init(config_data_powersave_mode_t mode);
void pwr_save_enter_stop2(void);
void pwr_save_after_stop2_rtc_wakeup_it(void);
int pwr_save_check_stop2_cycles(void);
void pwr_save_exit_after_last_stop2_cycle(void);
int pwr_save_switch_mode_to_c0(void);
int pwr_save_switch_mode_to_c1(void);
void pwr_save_switch_mode_to_c2(void);

Wyświetl plik

@ -7,15 +7,15 @@
#include "message.h"
//!< Set immediately after waking up in RTC interrupt handler
#define RTE_MAIN_WOKEN_UP_RTC_INTERRUPT 1u
#define RTE_MAIN_WOKEN_UP_RTC_INTERRUPT 1u
//!< Set after exiting from RTC interrupt, but before reinitializing clocks
#define RTE_MAIN_WOKEN_UP_AFTER_RTC_IT 2u
#define RTE_MAIN_WOKEN_UP_AFTER_LAST_SLEEP 2u
//!< Set after everything was reinitialized from
#define RTE_MAIN_WOKEN_UP_EXITED 4u
#define RTE_MAIN_WOKEN_UP_EXITED 4u
#define RTE_MAIN_GO_TO_SLEEP 8u
#define RTE_MAIN_GO_TO_INTERMEDIATE_SLEEP 8u
#define RTE_MAIN_REBOOT_SCHEDULED_APRSMSG 1u
@ -45,6 +45,8 @@ extern uint8_t rte_main_trigger_radio_event_log;
//!< Trigger some reinitialization after waking up from deep sleep
extern uint8_t rte_main_woken_up;
extern uint8_t rte_main_woken_up_for_telemetry;
extern uint8_t rte_main_reboot_req;
extern uint8_t rte_main_reboot_scheduled_diag;

Wyświetl plik

@ -8,8 +8,8 @@
#ifndef SOFTWARE_VERSION_H_
#define SOFTWARE_VERSION_H_
#define SW_VER "EC03"
#define SW_DATE "17102024"
#define SW_VER "EC04"
#define SW_DATE "21102024"
#define SW_KISS_PROTO "C"
extern const char software_version_str[5];

Wyświetl plik

@ -7,7 +7,7 @@
#include <drivers/f1/gpio_conf_stm32f1x.h>
#endif
#ifdef STM32L471xx
#ifdef STM32L471xx /////////
#include <stm32l4xx_hal_cortex.h>
#include <stm32l4xx.h>
#include <stm32l4xx_ll_iwdg.h>
@ -37,7 +37,9 @@
#include "ntp.h"
#include "gsm_comm_state_handler.h"
#endif
#include "./etc/pwr_save_configuration.h"
#endif ////////
#include <delay.h>
#include <LedConfig.h>
@ -290,6 +292,8 @@ static uint8_t main_kiss_response_message[32];
static io_vbat_state_t main_battery_measurement_res;
static uint8_t main_continue_loop = 0;
//!< Array to extract events from NVM into. *2 is applied to have more room for data sent to API
static event_log_exposed_t main_exposed_events[MAIN_HOW_MANY_EVENTS_SEND_REPORT * 3];
#endif
@ -1521,13 +1525,29 @@ int main(int argc, char* argv[]){
backup_reg_set_monitor(0);
#if defined(PARAMETEO)
if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_RTC_INTERRUPT) {
pwr_save_after_stop2_rtc_wakeup_it();
}
else if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_AFTER_RTC_IT) {
if (rte_main_woken_up == RTE_MAIN_GO_TO_INTERMEDIATE_SLEEP) {
// this sleep is used by @link{pwr_save_after_stop2_rtc_wakeup_it} to
// go to the intermediate sleep in L4 powersave mode, when xxx seconds
// long sleep is divided into 'PWR_SAVE_STOP2_CYCLE_LENGHT_SEC' to
// serwice IWDG in between
system_clock_configure_auto_wakeup_l4(PWR_SAVE_STOP2_CYCLE_LENGHT_SEC);
pwr_save_enter_stop2();
}
if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_EXITED) {
else if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_RTC_INTERRUPT) {
// controller is woken up from sleep in stop2 mode, now it must
// be checked if this was the last sleep in the row, or micro
// must go to sleep (stop2 mode) once again
pwr_save_after_stop2_rtc_wakeup_it();
}
else if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_AFTER_LAST_SLEEP) {
system_clock_configure_l4();
pwr_save_exit_after_last_stop2_cycle();
rte_main_woken_up = RTE_MAIN_WOKEN_UP_EXITED;
}
else if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_EXITED) {
// restart ADCs
io_vbat_meas_enable();
@ -1555,6 +1575,8 @@ int main(int argc, char* argv[]){
rte_main_woken_up = 0;
rte_main_reset_gsm_modem = 1;
main_check_adc = 1;
// reinitialize UART used to communicate with GPRS modem
@ -1562,9 +1584,6 @@ int main(int argc, char* argv[]){
backup_reg_set_monitor(1);
}
else if (rte_main_woken_up == RTE_MAIN_GO_TO_SLEEP) {
}
else {
#endif
@ -2160,7 +2179,11 @@ int main(int argc, char* argv[]){
// inhibit any power save switching when modem transmits data
if (!main_afsk.sending && rte_main_woken_up == 0 && packet_tx_is_gsm_meteo_pending() == 0) {
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx(), rte_main_average_battery_voltage, rte_main_battery_voltage);
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx(), rte_main_average_battery_voltage, rte_main_battery_voltage, &main_continue_loop);
}
if (main_continue_loop == 0) {
continue;
}
if ((main_config_data_mode->wx_dust_sensor & WX_DUST_SDS011_PWM) > 0) {

Wyświetl plik

@ -132,11 +132,76 @@ static void pwr_save_clear_powersave_idication_bits() {
pwr_save_lock_rtc_backup_regs();
}
/**
* This function initializes everything related to power saving features
* including programming Flash memory option bytes
*/
void pwr_save_init(config_data_powersave_mode_t mode) {
// make a pointer to option byte
uint32_t* option_byte = (uint32_t*)0x1FFF7800;
// content of option byte read from the flash memory
uint32_t option_byte_content = *option_byte;
// definition of bitmask
#define IWDG_STBY_STOP (0x3 << 17)
// check if IWDG_STDBY and IWDG_STOP is set in ''User and read protection option bytes''
// at 0x1FFF7800
if ((option_byte_content & IWDG_STBY_STOP) != IWDG_STBY_STOP) {
// unlock write/erase operations on flash memory
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
// wait for any possible flash operation to finish (rather impossible here, but ST manual recommend doing this)
while((FLASH->SR & FLASH_SR_BSY) != 0);
// unlock operations on option bytes
FLASH->OPTKEYR = 0x08192A3B;
FLASH->OPTKEYR = 0x4C5D6E7F;
// set the flash option register (in RAM!!)
FLASH->OPTR |= FLASH_OPTR_IWDG_STDBY;
FLASH->OPTR |= FLASH_OPTR_IWDG_STOP;
// trigger an update of flash option bytes with values from RAM (from FLASH->OPTR)
FLASH->CR |= FLASH_CR_OPTSTRT;
// wait for option bytes to be updated
while((FLASH->SR & FLASH_SR_BSY) != 0);
// lock flash memory
FLASH-> CR |= FLASH_CR_LOCK;
// forcre reloading option bytes
FLASH->CR |= FLASH_CR_OBL_LAUNCH;
}
// reset a status register
backup_reg_reset_all_powersave_states();
backup_reg_reset_inhibit_periodic_pwr_switch();
// switch power switch handler inhibition if it is needed
switch (mode) {
case PWSAVE_NONE:
break;
case PWSAVE_NORMAL:
case PWSAVE_AGGRESV:
backup_reg_inhibit_periodic_pwr_switch();
break;
}
}
/**
* Entering STOP2 power save mode. In this mode all clocks except LSI and LSE are disabled. StaticRAM content
* is preserved, optionally GPIO and few other peripherals can be kept power up depending on configuration
*/
static void pwr_save_enter_stop2(void) {
void pwr_save_enter_stop2(void) {
// set 31st monitor bit
backup_reg_set_monitor(31);
@ -182,11 +247,89 @@ static void pwr_save_enter_stop2(void) {
}
/**
* This function is called in two places within a pooler.
* 1st: just after the micro wakes up from STOP2 deep sleep caused by low battery
* voltage and returns from an interrupt
* from RTC interrupt handler.
* 2nd: just after the micro wakes up from STOP2 caues by aggressive powersave
* configuration.
*/
void pwr_save_after_stop2_rtc_wakeup_it(void) {
// if yes set curent state
rte_main_woken_up = RTE_MAIN_WOKEN_UP_AFTER_LAST_SLEEP;
// // check if this is an intermediate wakeup from STOP2
// pwr_save_check_stop2_cycles();
//
// system_clock_configure_l4();
//
// pwr_save_exit_after_last_stop2_cycle();
// reload internal watchdog
main_reload_internal_wdg();
// decrement stop2 cycles for current L7 or L6 powersave mode
pwr_save_number_of_sleep_cycles--;
// if there is time left to exit from depp sleep
if (pwr_save_number_of_sleep_cycles > 0) {
backup_reg_set_monitor(15);
// // go back to sleep
// // configure how long micro should sleep
// system_clock_configure_auto_wakeup_l4(PWR_SAVE_STOP2_CYCLE_LENGHT_SEC);
//
// pwr_save_enter_stop2();
rte_main_woken_up = RTE_MAIN_GO_TO_INTERMEDIATE_SLEEP;
}
else {
backup_reg_set_monitor(14);
rte_main_woken_up = RTE_MAIN_WOKEN_UP_AFTER_LAST_SLEEP;
rte_main_woken_up_for_telemetry = 1;
max31865_set_state_after_wkup(); // TODO: tatry variant
}
}
/**
* Used after each of 30 seconds long STOP2 sleep, to check
* how many sleeps the micro must be put in, to complete
* L6/L7 powersave mode
*/
//int pwr_save_check_stop2_cycles(void) {
//
// while(1) {
// // decrement stop2 cycles for current L7 or L6 powersave mode
// pwr_save_number_of_sleep_cycles--;
//
// // if there is time left to exit from depp sleep
// if (pwr_save_number_of_sleep_cycles > 0) {
// backup_reg_set_monitor(15);
//
// // go back to sleep
// // configure how long micro should sleep
// system_clock_configure_auto_wakeup_l4(PWR_SAVE_STOP2_CYCLE_LENGHT_SEC);
//
// pwr_save_enter_stop2();
// }
// else {
// backup_reg_set_monitor(14);
//
// // we are done sleeping so exit from this loop
// break;
// }
// }
//}
/**
* This function has to be called after last 30 second long cycle of STOP2 sleep,
* to bounce all frames transmission counters.
*/
static void pwr_save_exit_after_last_stop2_cycle(void) {
void pwr_save_exit_after_last_stop2_cycle(void) {
uint32_t counter = 0;
@ -269,128 +412,6 @@ static void pwr_save_exit_after_last_stop2_cycle(void) {
backup_reg_set_monitor(29);
}
/**
* This function is called in two places within a pooler.
* 1st: just after the micro wakes up from STOP2 deep sleep caused by low battery
* voltage and returns from an interrupt
* from RTC interrupt handler.
* 2nd: just after the micro wakes up from STOP2 caues by aggressive powersave
* configuration.
*/
static void pwr_save_after_stop2_rtc_wakeup_it(void) {
// check if we are just after waking up from STOP2 mode
if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_RTC_INTERRUPT) {
// if yes set curent state
rte_main_woken_up = RTE_MAIN_WOKEN_UP_AFTER_RTC_IT;
// check if this is an intermediate wakeup from STOP2
pwr_save_check_stop2_cycles();
system_clock_configure_l4();
pwr_save_exit_after_last_stop2_cycle();
rte_main_woken_up = RTE_MAIN_WOKEN_UP_EXITED;
}
}
/**
* This function initializes everything related to power saving features
* including programming Flash memory option bytes
*/
void pwr_save_init(config_data_powersave_mode_t mode) {
// make a pointer to option byte
uint32_t* option_byte = (uint32_t*)0x1FFF7800;
// content of option byte read from the flash memory
uint32_t option_byte_content = *option_byte;
// definition of bitmask
#define IWDG_STBY_STOP (0x3 << 17)
// check if IWDG_STDBY and IWDG_STOP is set in ''User and read protection option bytes''
// at 0x1FFF7800
if ((option_byte_content & IWDG_STBY_STOP) != IWDG_STBY_STOP) {
// unlock write/erase operations on flash memory
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
// wait for any possible flash operation to finish (rather impossible here, but ST manual recommend doing this)
while((FLASH->SR & FLASH_SR_BSY) != 0);
// unlock operations on option bytes
FLASH->OPTKEYR = 0x08192A3B;
FLASH->OPTKEYR = 0x4C5D6E7F;
// set the flash option register (in RAM!!)
FLASH->OPTR |= FLASH_OPTR_IWDG_STDBY;
FLASH->OPTR |= FLASH_OPTR_IWDG_STOP;
// trigger an update of flash option bytes with values from RAM (from FLASH->OPTR)
FLASH->CR |= FLASH_CR_OPTSTRT;
// wait for option bytes to be updated
while((FLASH->SR & FLASH_SR_BSY) != 0);
// lock flash memory
FLASH-> CR |= FLASH_CR_LOCK;
// forcre reloading option bytes
FLASH->CR |= FLASH_CR_OBL_LAUNCH;
}
// reset a status register
backup_reg_reset_all_powersave_states();
backup_reg_reset_inhibit_periodic_pwr_switch();
// switch power switch handler inhibition if it is needed
switch (mode) {
case PWSAVE_NONE:
break;
case PWSAVE_NORMAL:
case PWSAVE_AGGRESV:
backup_reg_inhibit_periodic_pwr_switch();
break;
}
}
/**
* Used after each of 30 seconds long STOP2 sleep, to check
* how many sleeps the micro must be put in, to complete
* L6/L7 powersave mode
*/
int pwr_save_check_stop2_cycles(void) {
while(1) {
// decrement stop2 cycles for current L7 or L6 powersave mode
pwr_save_number_of_sleep_cycles--;
// if there is time left to exit from depp sleep
if (pwr_save_number_of_sleep_cycles > 0) {
backup_reg_set_monitor(15);
// go back to sleep
// configure how long micro should sleep
system_clock_configure_auto_wakeup_l4(PWR_SAVE_STOP2_CYCLE_LENGHT_SEC);
pwr_save_enter_stop2();
}
else {
backup_reg_set_monitor(14);
// we are done sleeping so exit from this loop
break;
}
}
}
int pwr_save_switch_mode_to_c0(void) {
@ -890,9 +911,11 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
uint8_t * continue_loop) {
// this function should be called from 10 seconds pooler
*continue_loop = 1;
int8_t reinit_sensors = 0;
int8_t reinit_gprs = 0;
//int8_t reinit_gprs = 0;
packet_tx_counter_values_t counters;
@ -968,7 +991,8 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
pwr_save_switch_mode_to_l7(60 * PWR_SAVE_CUTOFF_SLEEP_TIME_IN_MINUTES);
// RTC interrupt is between this call and previous one (switching to l7)
pwr_save_after_stop2_rtc_wakeup_it();
//pwr_save_after_stop2_rtc_wakeup_it();
*continue_loop = 0;
return psave_mode;
}
@ -1117,8 +1141,10 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
// if there is more than two minutes to send wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60));
*continue_loop = 0;
// GSM module is kept turned on, but the connection must be reastablished
reinit_gprs = 1;
//reinit_gprs = 1;
}
else {
// TODO: Workaround here for HW-RevB!!!
@ -1163,7 +1189,9 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
// if there is more than WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES minutes to wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60)); // TODO: !!!
reinit_gprs = 1;
*continue_loop = 0;
//reinit_gprs = 1;
}
else {
@ -1189,7 +1217,9 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
// if there is more than WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES minutes to send wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - (WAKEUP_PERIOD_BEFORE_WX_FRAME_IN_MINUTES * 60));
reinit_gprs = 1;
*continue_loop = 0;
//reinit_gprs = 1;
}
else {
if (pwr_save_seconds_to_wx <= 30) {
@ -1222,14 +1252,14 @@ config_data_powersave_mode_t pwr_save_pooling_handler( const config_data_mode_t
backup_reg_set_monitor(16);
pwr_save_after_stop2_rtc_wakeup_it();
//pwr_save_after_stop2_rtc_wakeup_it();
backup_reg_set_monitor(13);
if (reinit_gprs != 0) {
// reset GSM modem, internally this also check if GSM modem is inhibited or not
rte_main_reset_gsm_modem = 1;
}
// if (reinit_gprs != 0) {
// // reset GSM modem, internally this also check if GSM modem is inhibited or not
// rte_main_reset_gsm_modem = 1;
// }
if (reinit_sensors != 0) {
// reinitialize all i2c sensors

Wyświetl plik

@ -55,6 +55,8 @@ uint8_t rte_main_trigger_radio_event_log = 0;
//!< Trigger some reinitialization after waking up from deep sleep
uint8_t rte_main_woken_up = 0;
uint8_t rte_main_woken_up_for_telemetry = 0;
//!< Current battery voltage as 10mV increments
uint16_t rte_main_battery_voltage;