reworking L6/L7 powersave modes with STOP2 sleep completely to engage iwdg

master
Mateusz Lubecki 2023-10-08 21:43:35 +02:00
rodzic d89d477de6
commit b650142c6f
11 zmienionych plików z 123 dodań i 38 usunięć

Wyświetl plik

@ -24,6 +24,7 @@ C_SRCS += \
../src/rte_pwr.c \
../src/rte_rtu.c \
../src/rte_wx.c \
../src/software_version.c \
../src/wx_handler.c \
../src/wx_handler_humidity.c \
../src/wx_handler_pressure.c \
@ -51,6 +52,7 @@ OBJS += \
./src/rte_pwr.o \
./src/rte_rtu.o \
./src/rte_wx.o \
./src/software_version.o \
./src/wx_handler.o \
./src/wx_handler_humidity.o \
./src/wx_handler_pressure.o \
@ -78,6 +80,7 @@ C_DEPS += \
./src/rte_pwr.d \
./src/rte_rtu.d \
./src/rte_wx.d \
./src/software_version.d \
./src/wx_handler.d \
./src/wx_handler_humidity.d \
./src/wx_handler_pressure.d \

Wyświetl plik

@ -58,6 +58,6 @@
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#10;"/>
<stringAttribute key="org.eclipse.embedcdt.debug.gdbjtag.core.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;peripherals&gt;&#10; &lt;peripheral name=&quot;ADC1&quot;/&gt;&#10;&lt;/peripherals&gt;&#10;"/>
<stringAttribute key="org.eclipse.embedcdt.debug.gdbjtag.core.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;peripherals&gt;&#10; &lt;peripheral name=&quot;ADC1&quot;/&gt;&#10; &lt;peripheral name=&quot;IWDG&quot;/&gt;&#10; &lt;peripheral name=&quot;DBGMCU&quot;/&gt;&#10;&lt;/peripherals&gt;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration>

Wyświetl plik

@ -37,4 +37,9 @@
*/
//#define INHIBIT_CUTOFF
/**
* Intermediate STOP2 cycle lenght within L7 or L6 mode.
*/
#define PWR_SAVE_STOP2_CYCLE_LENGHT_SEC 30u
#endif /* INCLUDE_PWR_SAVE_CONFIGURATION_H_ */

Wyświetl plik

@ -15,7 +15,7 @@
#define SYSTICK_TICKS_PER_SECONDS 100
#define SYSTICK_TICKS_PERIOD 10
//#define INTERNAL_WATCHDOG
#define INTERNAL_WATCHDOG
#define EXTERNAL_WATCHDOG
#define PWR_SWITCH_BOTH

Wyświetl plik

@ -113,6 +113,7 @@ 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_check_stop2_cycles(void);
void pwr_save_exit_from_stop2(void);
int pwr_save_switch_mode_to_c0(void);
int pwr_save_switch_mode_to_c1(void);

Wyświetl plik

@ -5,6 +5,18 @@
#include <stdint.h>
#include "stored_configuration_nvm/config_data.h"
//!< Set immediately after waking up in RTC interrupt handler
#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
//!< Set after everything was reinitialized from
#define RTE_MAIN_WOKEN_UP_EXITED 4u
//!< Trigger some reinitialization after waking up from deep sleep
extern uint8_t rte_main_woken_up;
extern uint8_t rte_main_reboot_req;
extern uint8_t rte_main_boot_cycles, rte_main_hard_faults;

Wyświetl plik

@ -8,8 +8,8 @@
#ifndef SOFTWARE_VERSION_H_
#define SOFTWARE_VERSION_H_
#define SW_VER "EA24"
#define SW_DATE "22072023"
#define SW_VER "EB00"
#define SW_DATE "07102023"
#define SW_KISS_PROTO "B"
extern const char software_version_str[5];

Wyświetl plik

@ -97,7 +97,11 @@ void it_handlers_set_priorities(void) {
#ifdef STM32L471xx
void RTC_WKUP_IRQHandler(void) {
main_woken_up = 1;
rte_main_woken_up = RTE_MAIN_WOKEN_UP_RTC_INTERRUPT;
main_set_monitor(13);
main_reload_internal_wdg();
// clear pending interrupt
NVIC_ClearPendingIRQ(RTC_WKUP_IRQn);
@ -105,14 +109,6 @@ void RTC_WKUP_IRQHandler(void) {
RTC->ISR &= (0xFFFFFFFF ^ RTC_ISR_WUTF_Msk);
EXTI->PR1 |= EXTI_PR1_PIF20;
main_set_monitor(12);
system_clock_configure_l4();
pwr_save_exit_from_stop2();
}
void SPI2_IRQHandler(void) {

Wyświetl plik

@ -282,9 +282,6 @@ volatile int i = 0;
#endif
#if defined(PARAMETEO)
//!< Trigger some reinitnialization after waking up from deep sleep
uint8_t main_woken_up = 0;
//!< Triggers additional check if ADC has properly reinitialized and conversion is working
uint8_t main_check_adc = 0;
#endif
@ -794,7 +791,6 @@ int main(int argc, char* argv[]){
// configuring an APRS path used to transmit own packets (telemetry, wx, beacons)
main_own_path_ln = ConfigPath(main_own_path, main_config_data_basic);
#ifdef INTERNAL_WATCHDOG
#if defined(STM32F10X_MD_VL)
// enable write access to watchdog registers
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
@ -822,8 +818,8 @@ int main(int argc, char* argv[]){
// unlock write access to configuratio registers
LL_IWDG_EnableWriteAccess(IWDG);
// set prescaler - watchdog timeout on about 16 seconds
LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_128);
// set prescaler - watchdog timeout on about 32 seconds
LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_256);
// wait for watchdog registers to update
while (LL_IWDG_IsActiveFlag_PVU(IWDG) != 0) {
@ -842,8 +838,6 @@ int main(int argc, char* argv[]){
// do not disable watchdog when MCU halts on breakpoints
DBGMCU->APB1FZR1 &= (0xFFFFFFFF ^ DBGMCU_APB1FZR1_DBG_IWDG_STOP);
#endif
#endif
// initialize i2c controller
@ -1050,10 +1044,8 @@ int main(int argc, char* argv[]){
umb_0x26_status_request(&rte_wx_umb, &rte_wx_umb_context, main_config_data_umb);
}
#ifdef INTERNAL_WATCHDOG
// reload watchdog counter
main_reload_internal_wdg();
#endif
io_ext_watchdog_service();
@ -1133,7 +1125,7 @@ int main(int argc, char* argv[]){
main_set_monitor(0);
#if defined(PARAMETEO)
if (main_woken_up == 1) {
if (rte_main_woken_up == RTE_MAIN_WOKEN_UP_EXITED) {
// restart ADCs
io_vbat_meas_enable();
@ -1160,7 +1152,7 @@ int main(int argc, char* argv[]){
ax25_init(&main_ax25, &main_afsk, 0, message_callback, 0);
//TimerConfig();
main_woken_up = 0;
rte_main_woken_up = 0;
main_check_adc = 1;
@ -1522,9 +1514,7 @@ int main(int argc, char* argv[]){
#ifdef PARAMETEO
max31865_pool();
#endif
#ifdef INTERNAL_WATCHDOG
main_reload_internal_wdg();
#endif
main_two_second_pool_timer = 2000;
}
@ -1552,7 +1542,7 @@ int main(int argc, char* argv[]){
}
// inhibit any power save switching when modem transmits data
if (!main_afsk.sending && main_woken_up == 0) {
if (!main_afsk.sending && rte_main_woken_up == 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);
}
@ -1637,7 +1627,6 @@ void main_service_cpu_load_ticks(void) {
}
void main_reload_internal_wdg(void){
#ifdef INTERNAL_WATCHDOG
#ifdef STM32F10X_MD_VL
// reload watchdog counter
@ -1647,7 +1636,6 @@ void main_reload_internal_wdg(void){
#ifdef STM32L471xx
LL_IWDG_ReloadCounter(IWDG);
#endif
#endif
}
uint32_t main_get_nvm_timestamp(void) {

Wyświetl plik

@ -47,6 +47,11 @@
int8_t pwr_save_seconds_to_wx = 0;
int16_t pwr_save_sleep_time_in_seconds = -1;
/**
* Number of 30 seconds cycles of SLEEP2 in L6 and L7 powersave mode
*/
int8_t pwr_save_number_of_sleep_cycles = -1;
/**
* Variable stores cutoff state and to save RAM it also keeps a low battery voltage flag
*/
@ -110,9 +115,9 @@ void pwr_save_init(config_data_powersave_mode_t mode) {
// definition of bitmask
#define IWDG_STBY_STOP (0x3 << 17)
// check if IWDG_STDBY and IWDG_STOP is not set in ''User and read protection option bytes''
// 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) {
if ((option_byte_content & IWDG_STBY_STOP) != IWDG_STBY_STOP) {
// unlock write/erase operations on flash memory
FLASH->KEYR = 0x45670123;
@ -126,7 +131,8 @@ void pwr_save_init(config_data_powersave_mode_t mode) {
FLASH->OPTKEYR = 0x4C5D6E7F;
// set the flash option register (in RAM!!)
FLASH->OPTR &= (0xFFFFFFFF ^ (FLASH_OPTR_IWDG_STDBY | FLASH_OPTR_IWDG_STOP));
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;
@ -172,6 +178,9 @@ void pwr_save_enter_stop2(void) {
// set 31st monitor bit
main_set_monitor(31);
// reload internal watchdog
main_reload_internal_wdg();
// clear main battery voltage to be sure that it'd be updated???
rte_main_battery_voltage = 0;
@ -201,6 +210,8 @@ void pwr_save_enter_stop2(void) {
counter++;
rte_main_going_sleep_count = counter;
REGISTER_COUNTERS = (REGISTER_COUNTERS & 0xFFFF0000) | counter;
pwr_save_lock_rtc_backup_regs();
@ -217,6 +228,31 @@ void pwr_save_enter_stop2(void) {
}
void 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) {
main_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 {
main_set_monitor(14);
// we are done sleeping so exit from this loop
break;
}
}
}
/**
* This function has to be called within RTC wakepup interrupt.
*/
@ -238,6 +274,9 @@ void pwr_save_exit_from_stop2(void) {
counter++;
// store current wakeup counter in RTE
rte_main_wakeup_count = counter;
// check counter overflow conditions
if (counter > 0xFFFF) {
counter = 0;
@ -577,6 +616,11 @@ void pwr_save_switch_mode_to_i5(void) {
// this will keep external VHF radio working in HW-RevB
void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
if (sleep_time > 3000u) {
// this is an error situation
sleep_time = 3000u;
}
if (system_is_rtc_ok() == 0) {
pwr_save_switch_mode_to_i5();
@ -587,6 +631,9 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
return;
}
// calculate amount of STOP2 cycles
pwr_save_number_of_sleep_cycles = (int8_t)(sleep_time / PWR_SAVE_STOP2_CYCLE_LENGHT_SEC) & 0x7Fu;
main_set_monitor(28);
// disable ADC used for vbat measurement
@ -627,7 +674,7 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
// lock access to backup
pwr_save_lock_rtc_backup_regs();
system_clock_configure_auto_wakeup_l4(sleep_time);
system_clock_configure_auto_wakeup_l4(PWR_SAVE_STOP2_CYCLE_LENGHT_SEC);
// save how long the micro will sleep - required for handling wakeup event
pwr_save_sleep_time_in_seconds = sleep_time;
@ -644,6 +691,12 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
}
void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
if (sleep_time > 3000u) {
// this is an error situation
sleep_time = 3000u;
}
///////////
if (system_is_rtc_ok() == 0) {
pwr_save_switch_mode_to_i5();
@ -655,6 +708,9 @@ void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
return;
}
// calculate amount of STOP2 cycles
pwr_save_number_of_sleep_cycles = (int8_t)(sleep_time / PWR_SAVE_STOP2_CYCLE_LENGHT_SEC) & 0x7Fu;
main_set_monitor(26);
// disconnect APRS-IS connection if it is established
@ -699,7 +755,7 @@ void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
pwr_save_lock_rtc_backup_regs();
// configure how long micro should sleep
system_clock_configure_auto_wakeup_l4(sleep_time);
system_clock_configure_auto_wakeup_l4(PWR_SAVE_STOP2_CYCLE_LENGHT_SEC);
// save how long the micro will sleep - required for handling wakeup event
pwr_save_sleep_time_in_seconds = sleep_time;
@ -962,7 +1018,7 @@ config_data_powersave_mode_t pwr_save_pooling_handler(const config_data_mode_t *
// if stations is configured to send wx packet less frequent than every 5 minutes
if (minutes_to_wx > 1) {
main_set_monitor(16);
main_set_monitor(17);
// if there is more than one minute to wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60); // TODO: !!!
@ -987,7 +1043,7 @@ config_data_powersave_mode_t pwr_save_pooling_handler(const config_data_mode_t *
// if station is configured to sent wx packet in every 5 minutes or more often
if (minutes_to_wx > 1) {
main_set_monitor(15);
main_set_monitor(17);
pwr_save_switch_mode_to_l6((timers->wx_transmit_period * 60) - 60); // TODO: !!!
}
@ -1009,7 +1065,7 @@ config_data_powersave_mode_t pwr_save_pooling_handler(const config_data_mode_t *
}
else { // WX
if (minutes_to_wx > 1) {
main_set_monitor(14);
main_set_monitor(17);
// if there is more than one minute to send wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60);
@ -1043,6 +1099,24 @@ config_data_powersave_mode_t pwr_save_pooling_handler(const config_data_mode_t *
}
}
main_set_monitor(16);
// 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_from_stop2();
rte_main_woken_up = RTE_MAIN_WOKEN_UP_EXITED;
}
main_set_monitor(13);
if (reinit_sensors != 0) {

Wyświetl plik

@ -19,8 +19,13 @@ uint8_t rte_main_trigger_modbus_status = 0;
uint8_t rte_main_trigger_wx_packet = 0;
#ifdef PARAMETEO
//!< Trigger some reinitialization after waking up from deep sleep
uint8_t rte_main_woken_up = 0;
//!< Current battery voltage as 10mV increments
uint16_t rte_main_battery_voltage;
//!< Average battery voltage as 10mV increments, lenght configured by VBATT_HISTORY_LN
uint16_t rte_main_average_battery_voltage = 0;
uint16_t rte_main_wakeup_count = 0;
@ -29,6 +34,7 @@ uint16_t rte_main_going_sleep_count = 0;
uint32_t rte_main_last_sleep_master_time = 0;
//!< Set to one after waking up from L7 / L6 powersave mode and
uint8_t rte_main_reset_gsm_modem = 0;
config_data_powersave_mode_t rte_main_curret_powersave_mode;