kopia lustrzana https://github.com/SP8EBC/ParaTNC
Merge: Fixing wakeup deadlock during cutoff (#7)
* averaging measred battery voltage * bugfix in average battery voltage, using average vbatt only in telemetry * sending status message on any change of cutoff state * bugfix with DCD deadlock after wakeup * some random debugging with deadlock * more debugging * bugfix in measuring Vbatt voltage, vbatt averager separated from getter * some commentssr9wxz_new_configuration_for_ZZ06
rodzic
0c481f7d42
commit
4896c6255e
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
||||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.PERIPHERALS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <peripherals> <peripheral name="GPIOB"/> <peripheral name="GPIOC"/> <peripheral name="GPIOA"/> <peripheral name="TIM3"/> </peripherals> "/>
|
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.PERIPHERALS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <peripherals> <peripheral name="RTC"/> <peripheral name="ADC2"/> <peripheral name="RCC"/> </peripherals> "/>
|
||||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
||||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
||||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
||||||
|
|
|
@ -24,9 +24,14 @@ void io_pwr_init(void);
|
||||||
void io_ext_watchdog_config(void);
|
void io_ext_watchdog_config(void);
|
||||||
void io_ext_watchdog_service(void);
|
void io_ext_watchdog_service(void);
|
||||||
|
|
||||||
|
#ifdef PARAMETEO
|
||||||
void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff);
|
void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff);
|
||||||
uint16_t io_vbat_meas_get(void);
|
uint16_t io_vbat_meas_get(void);
|
||||||
|
uint16_t io_vbat_meas_average(uint16_t sample);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VBAT_MEAS_A_COEFF 1000
|
||||||
|
#define VBAT_MEAS_B_COEFF 95
|
||||||
|
|
||||||
inline void io_5v_isol_sw_enable(void) {
|
inline void io_5v_isol_sw_enable(void) {
|
||||||
// ParaMETEO - UC_CNTRL_VS
|
// ParaMETEO - UC_CNTRL_VS
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "config_data.h"
|
#include "config_data.h"
|
||||||
|
|
||||||
#define SW_VER "EA05"
|
#define SW_VER "EA05"
|
||||||
#define SW_DATE "09042022"
|
#define SW_DATE "17042022"
|
||||||
|
|
||||||
#define SYSTICK_TICKS_PER_SECONDS 100
|
#define SYSTICK_TICKS_PER_SECONDS 100
|
||||||
#define SYSTICK_TICKS_PERIOD 10
|
#define SYSTICK_TICKS_PERIOD 10
|
||||||
|
@ -18,6 +18,22 @@
|
||||||
|
|
||||||
#define OWN_APRS_MSG_LN 160
|
#define OWN_APRS_MSG_LN 160
|
||||||
|
|
||||||
|
// backup registers (ParaMETEO)
|
||||||
|
// 0 -> powersave status
|
||||||
|
// 1 -> last sleep rtc time
|
||||||
|
// 2 -> last wakeup rtc time
|
||||||
|
// 3 -> controller configuration status
|
||||||
|
// 4 -> wakeup events MSB, sleep events LSB
|
||||||
|
|
||||||
|
#ifdef STM32L471xx
|
||||||
|
#define REGISTER RTC->BKP0R
|
||||||
|
#define REGISTER_LAST_SLEEP RTC->BKP1R
|
||||||
|
#define REGISTER_LAST_WKUP RTC->BKP2R
|
||||||
|
#define REGISTER_COUNTERS RTC->BKP4R
|
||||||
|
#define REGISTER_MONITOR RTC->BKP5R
|
||||||
|
#define REGISTER_LAST_SLTIM RTC->BKP6R
|
||||||
|
#endif
|
||||||
|
|
||||||
extern uint32_t master_time;
|
extern uint32_t master_time;
|
||||||
|
|
||||||
extern const config_data_mode_t * main_config_data_mode;
|
extern const config_data_mode_t * main_config_data_mode;
|
||||||
|
@ -55,14 +71,40 @@ extern srl_context_t* main_gsm_srl_ctx_ptr;
|
||||||
|
|
||||||
extern uint8_t main_kiss_enabled;
|
extern uint8_t main_kiss_enabled;
|
||||||
|
|
||||||
|
extern uint8_t main_woken_up;
|
||||||
|
|
||||||
extern char after_tx_lock;
|
extern char after_tx_lock;
|
||||||
|
|
||||||
extern unsigned short rx10m, tx10m, digi10m, digidrop10m, kiss10m;
|
extern unsigned short rx10m, tx10m, digi10m, digidrop10m, kiss10m;
|
||||||
|
|
||||||
|
//void main_set_monitor(int8_t bit);
|
||||||
|
|
||||||
uint16_t main_get_adc_sample(void);
|
uint16_t main_get_adc_sample(void);
|
||||||
|
|
||||||
void main_service_cpu_load_ticks(void);
|
void main_service_cpu_load_ticks(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inline used to trace an execution flow across main for(;;) loop and some
|
||||||
|
* powersaving functions. In case of software fault it's value may help to trace
|
||||||
|
* at witch point the crash has occured
|
||||||
|
*/
|
||||||
|
inline void main_set_monitor(int8_t bit) {
|
||||||
|
#ifdef STM32L471xx
|
||||||
|
// enable access to backup domain
|
||||||
|
PWR->CR1 |= PWR_CR1_DBP;
|
||||||
|
|
||||||
|
if (bit >= 0) {
|
||||||
|
REGISTER_MONITOR |= (1 << bit);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
REGISTER_MONITOR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWR->CR1 &= (0xFFFFFFFF ^ PWR_CR1_DBP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t main_get_master_time(void) {
|
inline uint32_t main_get_master_time(void) {
|
||||||
return master_time;
|
return master_time;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
* How long in minutes the controller will sleep in L7 state between checking
|
* How long in minutes the controller will sleep in L7 state between checking
|
||||||
* if battery has been charged.
|
* if battery has been charged.
|
||||||
*/
|
*/
|
||||||
#define PWR_SAVE_CUTOFF_SLEEP_TIME_IN_MINUTES 4
|
#define PWR_SAVE_CUTOFF_SLEEP_TIME_IN_MINUTES 10
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not uncomment this on production devices
|
||||||
|
*/
|
||||||
|
//#define INHIBIT_CUTOFF
|
||||||
|
|
||||||
#endif /* INCLUDE_PWR_SAVE_CONFIGURATION_H_ */
|
#endif /* INCLUDE_PWR_SAVE_CONFIGURATION_H_ */
|
||||||
|
|
|
@ -15,5 +15,12 @@ extern uint8_t rte_main_trigger_modbus_status;
|
||||||
extern uint8_t rte_main_trigger_wx_packet;
|
extern uint8_t rte_main_trigger_wx_packet;
|
||||||
|
|
||||||
extern uint16_t rte_main_battery_voltage;
|
extern uint16_t rte_main_battery_voltage;
|
||||||
|
extern uint16_t rte_main_average_battery_voltage;
|
||||||
|
|
||||||
|
extern uint16_t rte_main_wakeup_count;
|
||||||
|
|
||||||
|
extern uint16_t rte_main_going_sleep_count;
|
||||||
|
|
||||||
|
extern uint32_t rte_main_last_sleep_master_time;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
104
src/io.c
104
src/io.c
|
@ -25,7 +25,14 @@
|
||||||
#if defined(PARAMETEO)
|
#if defined(PARAMETEO)
|
||||||
LL_GPIO_InitTypeDef GPIO_InitTypeDef;
|
LL_GPIO_InitTypeDef GPIO_InitTypeDef;
|
||||||
|
|
||||||
int16_t io_vbat_a_coeff, io_vbat_b_coeff;
|
int16_t io_vbat_a_coeff = 0, io_vbat_b_coeff = 0;
|
||||||
|
|
||||||
|
#define VBATT_HISTORY_LN 16
|
||||||
|
static uint16_t io_vbatt_history[VBATT_HISTORY_LN];
|
||||||
|
|
||||||
|
static uint8_t io_vbatt_history_it = 0;
|
||||||
|
|
||||||
|
#define MINIMUM_SENSEFUL_VBATT_VOLTAGE 512u
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void io_oc_init(void) {
|
void io_oc_init(void) {
|
||||||
|
@ -154,10 +161,13 @@ void io_ext_watchdog_service(void) {
|
||||||
|
|
||||||
void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff) {
|
void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff) {
|
||||||
|
|
||||||
#ifdef STM32L471xx
|
#ifdef PARAMETEO
|
||||||
io_vbat_a_coeff = a_coeff;
|
if (a_coeff != io_vbat_a_coeff || b_coeff != io_vbat_b_coeff) {
|
||||||
io_vbat_b_coeff = b_coeff;
|
io_vbat_a_coeff = a_coeff;
|
||||||
|
io_vbat_b_coeff = b_coeff;
|
||||||
|
|
||||||
|
memset(io_vbatt_history, 0x00, VBATT_HISTORY_LN);
|
||||||
|
}
|
||||||
|
|
||||||
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_ANALOG;
|
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_ANALOG;
|
||||||
GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||||
|
@ -176,8 +186,14 @@ void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff) {
|
||||||
// RCC->AHB2ENR &= (0xFFFFFFFF ^ RCC_AHB2ENR_ADCEN);
|
// RCC->AHB2ENR &= (0xFFFFFFFF ^ RCC_AHB2ENR_ADCEN);
|
||||||
// RCC->AHB2ENR |= RCC_AHB2ENR_ADCEN;
|
// RCC->AHB2ENR |= RCC_AHB2ENR_ADCEN;
|
||||||
|
|
||||||
// the adc should be disabled now, but just to be sure that this is a case
|
// check if ADC is enabled
|
||||||
ADC2->CR &= (0xFFFFFFFF ^ ADC_CR_ADEN);
|
if ((ADC2->CR & ADC_CR_ADEN) != 0) {
|
||||||
|
// disable it
|
||||||
|
ADC2->CR |= ADC_CR_ADDIS;
|
||||||
|
|
||||||
|
// and wait for disabling to complete
|
||||||
|
while((ADC2->CR & ADC_CR_ADDIS) == ADC_CR_ADDIS);
|
||||||
|
}
|
||||||
|
|
||||||
// exit from deep-power-down mode
|
// exit from deep-power-down mode
|
||||||
ADC2->CR &= (0xFFFFFFFF ^ ADC_CR_DEEPPWD);
|
ADC2->CR &= (0xFFFFFFFF ^ ADC_CR_DEEPPWD);
|
||||||
|
@ -211,37 +227,93 @@ void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t io_vbat_meas_get(void) {
|
/**
|
||||||
|
* This function will measure current B+ voltage using ADC and return
|
||||||
|
* either average (if 0) or current / momentary value (non zero)
|
||||||
|
*/
|
||||||
|
uint16_t io_vbat_meas_get() {
|
||||||
|
|
||||||
uint16_t out = 0;
|
uint16_t out = 0;
|
||||||
#ifdef STM32L471xx
|
|
||||||
|
#ifdef PARAMETEO
|
||||||
|
|
||||||
float temp = 0.0f;
|
float temp = 0.0f;
|
||||||
|
|
||||||
// start ADC
|
// if ADC is not enabled
|
||||||
ADC2->CR |= ADC_CR_ADEN;
|
if ((ADC2->CR & ADC_CR_ADEN) == 0) {
|
||||||
|
// start ADC
|
||||||
|
ADC2->CR |= ADC_CR_ADEN;
|
||||||
|
|
||||||
// wait for startup
|
// wait for startup
|
||||||
while((ADC2->ISR & ADC_ISR_ADRDY) == 0);
|
while((ADC2->ISR & ADC_ISR_ADRDY) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// start conversion
|
// start conversion
|
||||||
ADC2->CR |= ADC_CR_ADSTART;
|
ADC2->CR |= ADC_CR_ADSTART;
|
||||||
|
|
||||||
// wait for conversion to finish
|
// wait for conversion to finish
|
||||||
while((ADC2->ISR & ADC_ISR_EOC) != ADC_ISR_EOC) {
|
while((ADC2->ISR & ADC_ISR_EOC) == 0) {
|
||||||
;
|
if ((ADC2->ISR & ADC_ISR_EOS) != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get conversion result
|
||||||
out = ADC2->DR;
|
out = ADC2->DR;
|
||||||
|
|
||||||
// disable ADC
|
// if end of sequence flag is not cleared
|
||||||
ADC2->CR &= (0xFFFFFFFF ^ ADC_CR_ADEN);
|
if ((ADC2->ISR & ADC_ISR_EOS) != 0) {
|
||||||
|
ADC2->ISR |= ADC_ISR_EOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable conversion
|
||||||
|
ADC2->CR |= ADC_CR_ADSTP;
|
||||||
|
|
||||||
// adc has a resulution of 12bit, so with VDDA of 3.3V it gives about .00081V per division
|
// adc has a resulution of 12bit, so with VDDA of 3.3V it gives about .00081V per division
|
||||||
temp = (float)out * 0.00081f; // real voltage on ADC input
|
temp = (float)out * 0.00081f; // real voltage on ADC input
|
||||||
|
|
||||||
out = (uint16_t) (temp * (float)io_vbat_a_coeff + (float)io_vbat_b_coeff);
|
out = (uint16_t) (temp * (float)io_vbat_a_coeff + (float)io_vbat_b_coeff);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t io_vbat_meas_average(uint16_t sample) {
|
||||||
|
|
||||||
|
uint16_t out = 0;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
uint32_t average_acc = 0;
|
||||||
|
|
||||||
|
// if the iterator reached the end of buffer
|
||||||
|
if (io_vbatt_history_it >= VBATT_HISTORY_LN) {
|
||||||
|
// reset it to the begining
|
||||||
|
io_vbatt_history_it = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// but new sample in the buffer
|
||||||
|
io_vbatt_history[io_vbatt_history_it++] = sample;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < VBATT_HISTORY_LN; i++) {
|
||||||
|
|
||||||
|
// break from the loop if buffer isn't fully filled with data
|
||||||
|
if (io_vbatt_history[i] < MINIMUM_SENSEFUL_VBATT_VOLTAGE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum sample
|
||||||
|
average_acc += io_vbatt_history[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if whole buffer has been used for average calculation
|
||||||
|
if (i >= VBATT_HISTORY_LN) {
|
||||||
|
// replace output
|
||||||
|
out = (uint16_t)(average_acc / VBATT_HISTORY_LN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,8 @@ void it_handlers_set_priorities(void) {
|
||||||
#ifdef STM32L471xx
|
#ifdef STM32L471xx
|
||||||
void RTC_WKUP_IRQHandler(void) {
|
void RTC_WKUP_IRQHandler(void) {
|
||||||
|
|
||||||
|
main_woken_up = 1;
|
||||||
|
|
||||||
// clear pending interrupt
|
// clear pending interrupt
|
||||||
NVIC_ClearPendingIRQ(RTC_WKUP_IRQn);
|
NVIC_ClearPendingIRQ(RTC_WKUP_IRQn);
|
||||||
|
|
||||||
|
@ -96,14 +98,12 @@ void RTC_WKUP_IRQHandler(void) {
|
||||||
|
|
||||||
EXTI->PR1 |= EXTI_PR1_PIF20;
|
EXTI->PR1 |= EXTI_PR1_PIF20;
|
||||||
|
|
||||||
|
main_set_monitor(12);
|
||||||
|
|
||||||
system_clock_configure_l4();
|
system_clock_configure_l4();
|
||||||
|
|
||||||
pwr_save_exit_from_stop2();
|
pwr_save_exit_from_stop2();
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
85
src/main.c
85
src/main.c
|
@ -19,6 +19,8 @@
|
||||||
#include "gsm/sim800c_engineering.h"
|
#include "gsm/sim800c_engineering.h"
|
||||||
#include "gsm/sim800c_poolers.h"
|
#include "gsm/sim800c_poolers.h"
|
||||||
#include "gsm/sim800c_gprs.h"
|
#include "gsm/sim800c_gprs.h"
|
||||||
|
#include "http_client/http_client.h"
|
||||||
|
|
||||||
|
|
||||||
#include "aprsis.h"
|
#include "aprsis.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,7 +103,11 @@
|
||||||
|
|
||||||
// backup registers (ParaMETEO)
|
// backup registers (ParaMETEO)
|
||||||
// 0 -> powersave status
|
// 0 -> powersave status
|
||||||
|
// 1 -> last sleep rtc time
|
||||||
|
// 2 -> last wakeup rtc time
|
||||||
// 3 -> controller configuration status
|
// 3 -> controller configuration status
|
||||||
|
// 4 -> wakeup events MSB, sleep events LSB
|
||||||
|
// 5 -> monitor
|
||||||
|
|
||||||
|
|
||||||
#define CONFIG_FIRST_RESTORED (1)
|
#define CONFIG_FIRST_RESTORED (1)
|
||||||
|
@ -220,10 +226,6 @@ umb_retval_t main_umb_retval = UMB_UNINITIALIZED;
|
||||||
// result of CRC calculation
|
// result of CRC calculation
|
||||||
uint32_t main_crc_result = 0;
|
uint32_t main_crc_result = 0;
|
||||||
|
|
||||||
char after_tx_lock;
|
|
||||||
|
|
||||||
unsigned short rx10m = 0, tx10m = 0, digi10m = 0, digidrop10m = 0, kiss10m = 0;
|
|
||||||
|
|
||||||
#if defined(STM32L471xx)
|
#if defined(STM32L471xx)
|
||||||
LL_GPIO_InitTypeDef GPIO_InitTypeDef;
|
LL_GPIO_InitTypeDef GPIO_InitTypeDef;
|
||||||
|
|
||||||
|
@ -231,6 +233,14 @@ gsm_sim800_state_t main_gsm_state;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PARAMETEO)
|
||||||
|
uint8_t main_woken_up = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char after_tx_lock;
|
||||||
|
|
||||||
|
unsigned short rx10m = 0, tx10m = 0, digi10m = 0, digidrop10m = 0, kiss10m = 0;
|
||||||
|
|
||||||
static void message_callback(struct AX25Msg *msg) {
|
static void message_callback(struct AX25Msg *msg) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -497,7 +507,7 @@ int main(int argc, char* argv[]){
|
||||||
pwr_save_init(main_config_data_mode->powersave);
|
pwr_save_init(main_config_data_mode->powersave);
|
||||||
|
|
||||||
// initialize B+ measurement
|
// initialize B+ measurement
|
||||||
io_vbat_meas_init(1000, 95);
|
io_vbat_meas_init(VBAT_MEAS_A_COEFF, VBAT_MEAS_B_COEFF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// initalizing separated Open Collector output
|
// initalizing separated Open Collector output
|
||||||
|
@ -712,7 +722,7 @@ int main(int argc, char* argv[]){
|
||||||
main_wx_srl_ctx_ptr->te_pin = GPIO_Pin_8;
|
main_wx_srl_ctx_ptr->te_pin = GPIO_Pin_8;
|
||||||
main_wx_srl_ctx_ptr->te_port = GPIOA;
|
main_wx_srl_ctx_ptr->te_port = GPIOA;
|
||||||
#endif
|
#endif
|
||||||
#if defined(PARAMETEO)
|
#if defined(STM32L471xx)
|
||||||
main_wx_srl_ctx_ptr->te_pin = LL_GPIO_PIN_8;
|
main_wx_srl_ctx_ptr->te_pin = LL_GPIO_PIN_8;
|
||||||
main_wx_srl_ctx_ptr->te_port = GPIOA;
|
main_wx_srl_ctx_ptr->te_port = GPIOA;
|
||||||
|
|
||||||
|
@ -941,8 +951,7 @@ int main(int argc, char* argv[]){
|
||||||
if (main_config_data_mode->gsm == 1) {
|
if (main_config_data_mode->gsm == 1) {
|
||||||
gsm_sim800_init(&main_gsm_state, 1);
|
gsm_sim800_init(&main_gsm_state, 1);
|
||||||
|
|
||||||
http_client_init(&main_gsm_state, main_gsm_srl_ctx_ptr, 0);
|
//http_client_init(&main_gsm_state, main_gsm_srl_ctx_ptr, 0);
|
||||||
|
|
||||||
//aprsis_init(&main_gsm_srl_ctx, &main_gsm_state, "SP8EBC", 10, 23220);
|
//aprsis_init(&main_gsm_srl_ctx, &main_gsm_state, "SP8EBC", 10, 23220);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -954,11 +963,16 @@ int main(int argc, char* argv[]){
|
||||||
beacon_send_own(0);
|
beacon_send_own(0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
delay_fixed(1500);
|
||||||
|
|
||||||
|
telemetry_send_status_powersave_registers(REGISTER_LAST_SLEEP, REGISTER_LAST_WKUP, REGISTER_COUNTERS, REGISTER_MONITOR, REGISTER_LAST_SLTIM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Infinite loop
|
// Infinite loop
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
main_set_monitor(-1);
|
||||||
|
|
||||||
// incrementing current cpu ticks
|
// incrementing current cpu ticks
|
||||||
main_current_cpu_idle_ticks++;
|
main_current_cpu_idle_ticks++;
|
||||||
|
|
||||||
|
@ -969,6 +983,7 @@ int main(int argc, char* argv[]){
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(0);
|
||||||
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
|
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
|
||||||
// read the state of a button input
|
// read the state of a button input
|
||||||
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
|
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
|
||||||
|
@ -1003,6 +1018,24 @@ int main(int argc, char* argv[]){
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PARAMETEO)
|
||||||
|
if (main_woken_up == 1) {
|
||||||
|
// io_vbat_meas_init(VBAT_MEAS_A_COEFF, VBAT_MEAS_B_COEFF);
|
||||||
|
|
||||||
|
rte_main_battery_voltage = io_vbat_meas_get();
|
||||||
|
|
||||||
|
// reinitialize APRS radio modem to clear all possible intermittent state caused by
|
||||||
|
// switching power state in the middle of reception APRS packet
|
||||||
|
ax25_new_msg_rx_flag = 0;
|
||||||
|
main_ax25.dcd = false;
|
||||||
|
|
||||||
|
main_woken_up = 0;
|
||||||
|
|
||||||
|
main_set_monitor(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
main_set_monitor(11);
|
||||||
|
|
||||||
// if new packet has been received from radio channel
|
// if new packet has been received from radio channel
|
||||||
if(ax25_new_msg_rx_flag == 1) {
|
if(ax25_new_msg_rx_flag == 1) {
|
||||||
|
@ -1135,11 +1168,19 @@ int main(int argc, char* argv[]){
|
||||||
rtu_serial_pool();
|
rtu_serial_pool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(2);
|
||||||
|
|
||||||
// get all meteo measuremenets each 65 seconds. some values may not be
|
// get all meteo measuremenets each 65 seconds. some values may not be
|
||||||
// downloaded from sensors if _METEO and/or _DALLAS_AS_TELEM aren't defined
|
// downloaded from sensors if _METEO and/or _DALLAS_AS_TELEM aren't defined
|
||||||
if (main_wx_sensors_pool_timer < 10) {
|
if (main_wx_sensors_pool_timer < 10) {
|
||||||
|
|
||||||
rte_main_battery_voltage = io_vbat_meas_get();
|
rte_main_battery_voltage = io_vbat_meas_get();
|
||||||
|
rte_main_average_battery_voltage = io_vbat_meas_average(rte_main_battery_voltage);
|
||||||
|
|
||||||
|
// meas average will return 0 if internal buffer isn't filled completely
|
||||||
|
if (rte_main_average_battery_voltage == 0) {
|
||||||
|
rte_main_average_battery_voltage = rte_main_battery_voltage;
|
||||||
|
}
|
||||||
|
|
||||||
if (main_modbus_rtu_master_enabled == 1) {
|
if (main_modbus_rtu_master_enabled == 1) {
|
||||||
rtu_serial_start();
|
rtu_serial_start();
|
||||||
|
@ -1171,19 +1212,31 @@ int main(int argc, char* argv[]){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(3);
|
||||||
|
|
||||||
main_wx_sensors_pool_timer = 65500;
|
main_wx_sensors_pool_timer = 65500;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (main_one_minute_pool_timer < 10) {
|
if (main_one_minute_pool_timer < 10) {
|
||||||
|
|
||||||
|
main_set_monitor(4);
|
||||||
|
|
||||||
#ifndef _MUTE_OWN
|
#ifndef _MUTE_OWN
|
||||||
packet_tx_handler(main_config_data_basic, main_config_data_mode);
|
packet_tx_handler(main_config_data_basic, main_config_data_mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
main_set_monitor(5);
|
||||||
|
|
||||||
#ifdef STM32L471xx
|
#ifdef STM32L471xx
|
||||||
if (main_config_data_mode->gsm == 1) {
|
if (main_config_data_mode->gsm == 1) {
|
||||||
|
|
||||||
gsm_sim800_poolers_one_minute(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
gsm_sim800_poolers_one_minute(main_gsm_srl_ctx_ptr, &main_gsm_state);
|
||||||
|
|
||||||
|
|
||||||
|
// if (gsm_sim800_gprs_ready == 1) {
|
||||||
|
// retval = http_client_async_get("http://pogoda.cc:8080/meteo_backend/status", strlen("http://pogoda.cc:8080/meteo_backend/status"), 0xFFF0, 0x1, 0);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1192,7 +1245,7 @@ int main(int argc, char* argv[]){
|
||||||
|
|
||||||
if (main_one_second_pool_timer < 10) {
|
if (main_one_second_pool_timer < 10) {
|
||||||
|
|
||||||
//digi_pool_viscous();
|
main_set_monitor(6);
|
||||||
|
|
||||||
digi_pool_viscous();
|
digi_pool_viscous();
|
||||||
|
|
||||||
|
@ -1221,6 +1274,8 @@ int main(int argc, char* argv[]){
|
||||||
analog_anemometer_direction_handler();
|
analog_anemometer_direction_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(7);
|
||||||
|
|
||||||
main_one_second_pool_timer = 1000;
|
main_one_second_pool_timer = 1000;
|
||||||
}
|
}
|
||||||
else if (main_one_second_pool_timer < -10) {
|
else if (main_one_second_pool_timer < -10) {
|
||||||
|
@ -1247,6 +1302,8 @@ int main(int argc, char* argv[]){
|
||||||
|
|
||||||
if (main_ten_second_pool_timer < 10) {
|
if (main_ten_second_pool_timer < 10) {
|
||||||
|
|
||||||
|
main_set_monitor(8);
|
||||||
|
|
||||||
if (rte_main_trigger_wx_packet == 1) {
|
if (rte_main_trigger_wx_packet == 1) {
|
||||||
|
|
||||||
packet_tx_send_wx_frame();
|
packet_tx_send_wx_frame();
|
||||||
|
@ -1256,13 +1313,17 @@ int main(int argc, char* argv[]){
|
||||||
|
|
||||||
#ifdef PARAMETEO
|
#ifdef PARAMETEO
|
||||||
// inhibit any power save switching when modem transmits data
|
// inhibit any power save switching when modem transmits data
|
||||||
if (!main_afsk.sending) {
|
if (!main_afsk.sending && 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_battery_voltage);
|
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx(), rte_main_battery_voltage);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
main_set_monitor(9);
|
||||||
|
|
||||||
#ifdef STM32L471xx
|
#ifdef STM32L471xx
|
||||||
if (main_config_data_mode->gsm == 1) {
|
if (main_config_data_mode->gsm == 1) {
|
||||||
|
// TODO
|
||||||
|
|
||||||
// retval = aprsis_connect_and_login(TEST_IP, strlen(TEST_IP), 14580);
|
// retval = aprsis_connect_and_login(TEST_IP, strlen(TEST_IP), 14580);
|
||||||
//
|
//
|
||||||
// if (retval == 0) {
|
// if (retval == 0) {
|
||||||
|
@ -1295,6 +1356,8 @@ int main(int argc, char* argv[]){
|
||||||
main_ten_second_pool_timer = 10000;
|
main_ten_second_pool_timer = 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(10);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Infinite loop, never return.
|
// Infinite loop, never return.
|
||||||
|
|
|
@ -140,6 +140,15 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
||||||
|
|
||||||
SendWXFrame(rte_wx_average_windspeed, rte_wx_max_windspeed, rte_wx_average_winddirection, rte_wx_temperature_average_external_valid, rte_wx_pressure_valid, rte_wx_humidity_valid);
|
SendWXFrame(rte_wx_average_windspeed, rte_wx_max_windspeed, rte_wx_average_winddirection, rte_wx_temperature_average_external_valid, rte_wx_pressure_valid, rte_wx_humidity_valid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* debug
|
||||||
|
*
|
||||||
|
* #define REGISTER_LAST_SLEEP RTC->BKP1R
|
||||||
|
#define REGISTER_LAST_WKUP RTC->BKP2R
|
||||||
|
#define REGISTER_COUNTERS RTC->BKP4R
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef EXTERNAL_WATCHDOG
|
#ifdef EXTERNAL_WATCHDOG
|
||||||
io_ext_watchdog_service();
|
io_ext_watchdog_service();
|
||||||
#endif
|
#endif
|
||||||
|
@ -209,6 +218,8 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
||||||
|
|
||||||
if (packet_tx_telemetry_counter >= packet_tx_telemetry_interval) {
|
if (packet_tx_telemetry_counter >= packet_tx_telemetry_interval) {
|
||||||
|
|
||||||
|
telemetry_send_status_powersave_registers(REGISTER_LAST_SLEEP, REGISTER_LAST_WKUP, REGISTER_COUNTERS, REGISTER_MONITOR, REGISTER_LAST_SLTIM);
|
||||||
|
|
||||||
packet_tx_multi_per_call_handler();
|
packet_tx_multi_per_call_handler();
|
||||||
|
|
||||||
// if there weren't any erros related to communication with DS12B20 from previous function call
|
// if there weren't any erros related to communication with DS12B20 from previous function call
|
||||||
|
@ -301,7 +312,6 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
||||||
rte_wx_wind_qf = AN_WIND_QF_UNKNOWN;
|
rte_wx_wind_qf = AN_WIND_QF_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (config_mode->victron == 1) {
|
if (config_mode->victron == 1) {
|
||||||
telemetry_send_values_pv(rx10m, digi10m, rte_pv_battery_current, rte_pv_battery_voltage, rte_pv_cell_voltage, dallas_qf, pressure_qf, humidity_qf, wind_qf);
|
telemetry_send_values_pv(rx10m, digi10m, rte_pv_battery_current, rte_pv_battery_voltage, rte_pv_cell_voltage, dallas_qf, pressure_qf, humidity_qf, wind_qf);
|
||||||
}
|
}
|
||||||
|
@ -314,11 +324,11 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
|
||||||
|
|
||||||
// if _METEO will be enabled, but without _DALLAS_AS_TELEM the fifth channel will be used to transmit temperature from MS5611
|
// if _METEO will be enabled, but without _DALLAS_AS_TELEM the fifth channel will be used to transmit temperature from MS5611
|
||||||
// which may be treated then as 'rack/cabinet internal temperature'. Dallas DS12B10 will be used for ragular WX frames
|
// which may be treated then as 'rack/cabinet internal temperature'. Dallas DS12B10 will be used for ragular WX frames
|
||||||
telemetry_send_values(rx10m, tx10m, digi10m, rte_main_battery_voltage, digidrop10m, rte_wx_temperature_internal_valid, dallas_qf, pressure_qf, humidity_qf, wind_qf, pwr_save_currently_cutoff, config_mode);
|
telemetry_send_values(rx10m, tx10m, digi10m, rte_main_average_battery_voltage, digidrop10m, rte_wx_temperature_internal_valid, dallas_qf, pressure_qf, humidity_qf, wind_qf, pwr_save_currently_cutoff, config_mode);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if user will disable both _METEO and _DALLAS_AS_TELEM value will be zeroed internally anyway
|
// if user will disable both _METEO and _DALLAS_AS_TELEM value will be zeroed internally anyway
|
||||||
telemetry_send_values(rx10m, tx10m, digi10m, rte_main_battery_voltage, digidrop10m, 0.0f, dallas_qf, pressure_qf, humidity_qf, wind_qf, pwr_save_currently_cutoff, config_mode);
|
telemetry_send_values(rx10m, tx10m, digi10m, rte_main_average_battery_voltage, digidrop10m, 0.0f, dallas_qf, pressure_qf, humidity_qf, wind_qf, pwr_save_currently_cutoff, config_mode);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// if _DALLAS_AS_TELEM will be enabled the fifth channel will be set to temperature measured by DS12B20
|
// if _DALLAS_AS_TELEM will be enabled the fifth channel will be set to temperature measured by DS12B20
|
||||||
|
|
139
src/pwr_save.c
139
src/pwr_save.c
|
@ -18,14 +18,12 @@
|
||||||
#include "packet_tx_handler.h"
|
#include "packet_tx_handler.h"
|
||||||
#include "wx_handler.h"
|
#include "wx_handler.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "telemetry.h"
|
||||||
|
|
||||||
#include "rte_main.h"
|
#include "rte_main.h"
|
||||||
|
|
||||||
#include "drivers/analog_anemometer.h"
|
#include "drivers/analog_anemometer.h"
|
||||||
|
|
||||||
|
|
||||||
#define REGISTER RTC->BKP0R
|
|
||||||
|
|
||||||
#define INHIBIT_PWR_SWITCH_PERIODIC_H 1
|
#define INHIBIT_PWR_SWITCH_PERIODIC_H 1
|
||||||
#define IN_STOP2_MODE (1 << 1)
|
#define IN_STOP2_MODE (1 << 1)
|
||||||
#define IN_C0_STATE (1 << 2)
|
#define IN_C0_STATE (1 << 2)
|
||||||
|
@ -51,6 +49,12 @@ int16_t pwr_save_sleep_time_in_seconds = -1;
|
||||||
*/
|
*/
|
||||||
int8_t pwr_save_currently_cutoff = 0;
|
int8_t pwr_save_currently_cutoff = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This stores a previous value of 'pwr_save_currently_cutoff' which is required to
|
||||||
|
* trigger a status message when controller goes into low battery voltage or cutoff state
|
||||||
|
*/
|
||||||
|
int8_t pwr_save_previously_cutoff = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is cutoff voltage at which the power saving subsystem will keep ParaMETEO constantly
|
* 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
|
* in L7 mode and wakeup once every 20 minutes to check B+ once again
|
||||||
|
@ -160,7 +164,13 @@ void pwr_save_init(config_data_powersave_mode_t mode) {
|
||||||
*/
|
*/
|
||||||
void pwr_save_enter_stop2(void) {
|
void pwr_save_enter_stop2(void) {
|
||||||
|
|
||||||
rte_main_battery_voltage = io_vbat_meas_get();
|
uint16_t counter = 0;
|
||||||
|
|
||||||
|
// set 31st monitor bit
|
||||||
|
main_set_monitor(31);
|
||||||
|
|
||||||
|
// clear main battery voltage to be sure that it'd be updated???
|
||||||
|
rte_main_battery_voltage = 0;
|
||||||
|
|
||||||
analog_anemometer_deinit();
|
analog_anemometer_deinit();
|
||||||
|
|
||||||
|
@ -174,11 +184,22 @@ void pwr_save_enter_stop2(void) {
|
||||||
RTC->WPR = 0xCA;
|
RTC->WPR = 0xCA;
|
||||||
RTC->WPR = 0x53;
|
RTC->WPR = 0x53;
|
||||||
|
|
||||||
|
// unlock an access to backup domain
|
||||||
pwr_save_unclock_rtc_backup_regs();
|
pwr_save_unclock_rtc_backup_regs();
|
||||||
|
|
||||||
// save an information that STOP2 mode has been applied
|
// save an information that STOP2 mode has been applied
|
||||||
RTC->BKP0R |= IN_STOP2_MODE;
|
RTC->BKP0R |= IN_STOP2_MODE;
|
||||||
|
|
||||||
|
// save a timestamp when micro has been switched to STOP2 mode
|
||||||
|
REGISTER_LAST_SLEEP = RTC->TR;
|
||||||
|
|
||||||
|
// increment the STOP2 sleep counters
|
||||||
|
counter = (uint16_t)(REGISTER_COUNTERS & 0xFFFF);
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
REGISTER_COUNTERS = (REGISTER_COUNTERS & 0xFFFF0000) | counter;
|
||||||
|
|
||||||
pwr_save_lock_rtc_backup_regs();
|
pwr_save_lock_rtc_backup_regs();
|
||||||
|
|
||||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||||
|
@ -198,6 +219,31 @@ void pwr_save_enter_stop2(void) {
|
||||||
*/
|
*/
|
||||||
void pwr_save_exit_from_stop2(void) {
|
void pwr_save_exit_from_stop2(void) {
|
||||||
|
|
||||||
|
uint32_t counter = 0;
|
||||||
|
|
||||||
|
// set 30th minitor bit
|
||||||
|
main_set_monitor(30);
|
||||||
|
|
||||||
|
// unlock access to backup registers
|
||||||
|
pwr_save_unclock_rtc_backup_regs();
|
||||||
|
|
||||||
|
// save a timestamp of this wakeup event
|
||||||
|
REGISTER_LAST_WKUP = RTC->TR;
|
||||||
|
|
||||||
|
// increase wakeup counter
|
||||||
|
counter = (uint32_t)((REGISTER_COUNTERS & 0xFFFF0000) >> 16);
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
// check counter overflow conditions
|
||||||
|
if (counter > 0xFFFF) {
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_COUNTERS = (REGISTER_COUNTERS & 0x0000FFFF) | (counter << 16);
|
||||||
|
|
||||||
|
pwr_save_lock_rtc_backup_regs();
|
||||||
|
|
||||||
// packet tx timers values
|
// packet tx timers values
|
||||||
packet_tx_counter_values_t timers;
|
packet_tx_counter_values_t timers;
|
||||||
|
|
||||||
|
@ -240,6 +286,8 @@ void pwr_save_exit_from_stop2(void) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(29);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pwr_save_switch_mode_to_c0(void) {
|
int pwr_save_switch_mode_to_c0(void) {
|
||||||
|
@ -450,6 +498,8 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(28);
|
||||||
|
|
||||||
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
|
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
|
||||||
io___cntrl_vbat_s_disable();
|
io___cntrl_vbat_s_disable();
|
||||||
|
|
||||||
|
@ -471,6 +521,8 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
|
||||||
// set for C3 mode
|
// set for C3 mode
|
||||||
REGISTER |= IN_L6_STATE;
|
REGISTER |= IN_L6_STATE;
|
||||||
|
|
||||||
|
REGISTER_LAST_SLTIM = sleep_time;
|
||||||
|
|
||||||
// lock access to backup
|
// lock access to backup
|
||||||
pwr_save_lock_rtc_backup_regs();
|
pwr_save_lock_rtc_backup_regs();
|
||||||
|
|
||||||
|
@ -485,6 +537,8 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
|
||||||
|
|
||||||
pwr_save_enter_stop2();
|
pwr_save_enter_stop2();
|
||||||
|
|
||||||
|
main_set_monitor(27);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,6 +548,8 @@ void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(26);
|
||||||
|
|
||||||
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
|
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
|
||||||
io___cntrl_vbat_s_disable();
|
io___cntrl_vbat_s_disable();
|
||||||
|
|
||||||
|
@ -515,6 +571,8 @@ void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
|
||||||
// set for C3 mode
|
// set for C3 mode
|
||||||
REGISTER |= IN_L7_STATE;
|
REGISTER |= IN_L7_STATE;
|
||||||
|
|
||||||
|
REGISTER_LAST_SLTIM = sleep_time;
|
||||||
|
|
||||||
// lock access to backup
|
// lock access to backup
|
||||||
pwr_save_lock_rtc_backup_regs();
|
pwr_save_lock_rtc_backup_regs();
|
||||||
|
|
||||||
|
@ -529,6 +587,8 @@ void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
|
||||||
led_control_led2_bottom(false);
|
led_control_led2_bottom(false);
|
||||||
|
|
||||||
pwr_save_enter_stop2();
|
pwr_save_enter_stop2();
|
||||||
|
|
||||||
|
main_set_monitor(25);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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) {
|
||||||
|
@ -541,6 +601,11 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
// by default use powersave mode from controller configuration
|
// by default use powersave mode from controller configuration
|
||||||
config_data_powersave_mode_t psave_mode = config->powersave;
|
config_data_powersave_mode_t psave_mode = config->powersave;
|
||||||
|
|
||||||
|
main_set_monitor(24);
|
||||||
|
|
||||||
|
// save previous state
|
||||||
|
pwr_save_previously_cutoff = pwr_save_currently_cutoff;
|
||||||
|
|
||||||
// check if battery voltage measurement is done and senseful
|
// check if battery voltage measurement is done and senseful
|
||||||
if (vbatt < MINIMUM_SENSEFUL_VBATT_VOLTAGE) {
|
if (vbatt < MINIMUM_SENSEFUL_VBATT_VOLTAGE) {
|
||||||
// inhibit both cutoff and aggresive powersave if vbatt measurement is either not
|
// inhibit both cutoff and aggresive powersave if vbatt measurement is either not
|
||||||
|
@ -548,21 +613,44 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
vbatt = 0xFFFFu;
|
vbatt = 0xFFFFu;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if battery voltage is below low voltage level
|
#ifdef INHIBIT_CUTOFF
|
||||||
if (vbatt <= pwr_save_aggressive_powersave_voltage) {
|
vbatt = 0xFFFFu;
|
||||||
// if battery voltage is low swtich to aggressive powersave mode
|
#endif
|
||||||
pwr_save_currently_cutoff |= CURRENTLY_VBATT_LOW;
|
|
||||||
|
|
||||||
psave_mode = PWSAVE_AGGRESV;
|
if (vbatt > PWR_SAVE_STARTUP_RESTORE_VOLTAGE_DEF) {
|
||||||
|
pwr_save_currently_cutoff = 0;
|
||||||
|
|
||||||
|
main_set_monitor(23);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pwr_save_currently_cutoff &= (0xFF ^ CURRENTLY_VBATT_LOW);
|
if (vbatt <= PWR_SAVE_CUTOFF_VOLTAGE_DEF) {
|
||||||
|
main_set_monitor(22);
|
||||||
|
|
||||||
|
// if the battery voltage is below cutoff level and the ParaMETEO controller is currently not cut off
|
||||||
|
pwr_save_currently_cutoff |= CURRENTLY_CUTOFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if battery voltage is below low voltage level
|
||||||
|
if (vbatt <= PWR_SAVE_AGGRESIVE_POWERSAVE_VOLTAGE) {
|
||||||
|
main_set_monitor(21);
|
||||||
|
|
||||||
|
// if battery voltage is low swtich to aggressive powersave mode
|
||||||
|
pwr_save_currently_cutoff |= CURRENTLY_VBATT_LOW;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
main_set_monitor(20);
|
||||||
|
|
||||||
|
// check if cutoff status has changed
|
||||||
|
if (pwr_save_currently_cutoff != pwr_save_previously_cutoff) {
|
||||||
|
telemetry_send_status_powersave_cutoff(vbatt, pwr_save_previously_cutoff, pwr_save_currently_cutoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (vbatt <= pwr_save_cutoff_voltage && ((pwr_save_currently_cutoff & CURRENTLY_CUTOFF) == 0)) {
|
if ((pwr_save_currently_cutoff & CURRENTLY_CUTOFF) != 0) {
|
||||||
// if the battery voltage is below cutoff level and the ParaMETEO controller is currently not cut off
|
main_set_monitor(19);
|
||||||
pwr_save_currently_cutoff |= CURRENTLY_CUTOFF;
|
|
||||||
|
|
||||||
// clear all previous powersave indication bits as we want to go sleep being already in L7 state
|
// clear all previous powersave indication bits as we want to go sleep being already in L7 state
|
||||||
pwr_save_clear_powersave_idication_bits();
|
pwr_save_clear_powersave_idication_bits();
|
||||||
|
@ -571,22 +659,15 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
pwr_save_switch_mode_to_l7(60 * PWR_SAVE_CUTOFF_SLEEP_TIME_IN_MINUTES);
|
pwr_save_switch_mode_to_l7(60 * PWR_SAVE_CUTOFF_SLEEP_TIME_IN_MINUTES);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (vbatt <= pwr_save_startup_restore_voltage && ((pwr_save_currently_cutoff & CURRENTLY_CUTOFF) != 0)) {
|
|
||||||
// clear all previous powersave indication bits as we want to go sleep being already in L7 state
|
|
||||||
pwr_save_clear_powersave_idication_bits();
|
|
||||||
|
|
||||||
// if the ParaMETEO is cutted off currently but battery hasn't been charged above restore voltage
|
if ((pwr_save_currently_cutoff & CURRENTLY_VBATT_LOW) != 0) {
|
||||||
pwr_save_switch_mode_to_l7(60 * PWR_SAVE_CUTOFF_SLEEP_TIME_IN_MINUTES);
|
main_set_monitor(18);
|
||||||
|
|
||||||
return;
|
psave_mode = PWSAVE_AGGRESV;
|
||||||
}
|
|
||||||
else {
|
|
||||||
// if battery level is above restore voltage and aggressive powersave voltage
|
|
||||||
pwr_save_currently_cutoff &= (0xFF ^ CURRENTLY_CUTOFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get current counter values
|
// get current counter values
|
||||||
packet_tx_get_current_counters(&counters);
|
packet_tx_get_current_counters(&counters);
|
||||||
|
|
||||||
|
@ -705,6 +786,8 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
}
|
}
|
||||||
else { // WX
|
else { // WX
|
||||||
if (minutes_to_wx > 2) {
|
if (minutes_to_wx > 2) {
|
||||||
|
main_set_monitor(17);
|
||||||
|
|
||||||
// if there is more than two minutes to send wx packet
|
// if there is more than two minutes to send wx packet
|
||||||
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 120);
|
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 120);
|
||||||
}
|
}
|
||||||
|
@ -747,6 +830,8 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
// if stations is configured to send wx packet less often than every 5 minutes
|
// if stations is configured to send wx packet less often than every 5 minutes
|
||||||
|
|
||||||
if (minutes_to_wx > 1) {
|
if (minutes_to_wx > 1) {
|
||||||
|
main_set_monitor(16);
|
||||||
|
|
||||||
// if there is more than one minute to wx packet
|
// if there is more than one minute to wx packet
|
||||||
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60); // TODO: !!!
|
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60); // TODO: !!!
|
||||||
}
|
}
|
||||||
|
@ -765,6 +850,8 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
// if station is configured to sent wx packet in every 5 minutes or more often
|
// if station is configured to sent wx packet in every 5 minutes or more often
|
||||||
|
|
||||||
if (minutes_to_wx > 1) {
|
if (minutes_to_wx > 1) {
|
||||||
|
main_set_monitor(15);
|
||||||
|
|
||||||
pwr_save_switch_mode_to_l6((timers->wx_transmit_period * 60) - 60); // TODO: !!!
|
pwr_save_switch_mode_to_l6((timers->wx_transmit_period * 60) - 60); // TODO: !!!
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -785,6 +872,8 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
}
|
}
|
||||||
else { // WX
|
else { // WX
|
||||||
if (minutes_to_wx > 1) {
|
if (minutes_to_wx > 1) {
|
||||||
|
main_set_monitor(14);
|
||||||
|
|
||||||
// if there is more than one minute to send wx packet
|
// if there is more than one minute to send wx packet
|
||||||
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60);
|
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60);
|
||||||
}
|
}
|
||||||
|
@ -812,6 +901,8 @@ void pwr_save_pooling_handler(const config_data_mode_t * config, const config_da
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_set_monitor(13);
|
||||||
|
|
||||||
if (reinit_sensors != 0) {
|
if (reinit_sensors != 0) {
|
||||||
// reinitialize all i2c sensors
|
// reinitialize all i2c sensors
|
||||||
wx_force_i2c_sensor_reset = 1;
|
wx_force_i2c_sensor_reset = 1;
|
||||||
|
|
|
@ -16,6 +16,16 @@ uint8_t rte_main_trigger_modbus_status = 0;
|
||||||
|
|
||||||
uint8_t rte_main_trigger_wx_packet = 0;
|
uint8_t rte_main_trigger_wx_packet = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef PARAMETEO
|
||||||
uint16_t rte_main_battery_voltage;
|
uint16_t rte_main_battery_voltage;
|
||||||
|
|
||||||
|
uint16_t rte_main_average_battery_voltage = 0;
|
||||||
|
|
||||||
|
uint16_t rte_main_wakeup_count = 0;
|
||||||
|
|
||||||
|
uint16_t rte_main_going_sleep_count = 0;
|
||||||
|
|
||||||
|
uint32_t rte_main_last_sleep_master_time = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,9 @@ void telemetry_send_status(void);
|
||||||
|
|
||||||
void telemetry_send_status_raw_values_modbus(void);
|
void telemetry_send_status_raw_values_modbus(void);
|
||||||
|
|
||||||
|
void telemetry_send_status_powersave_cutoff(uint16_t battery_voltage, int8_t vbatt_low, int8_t cutoff);
|
||||||
|
void telemetry_send_status_powersave_registers(uint32_t register_last_sleep, uint32_t register_last_wakeup, uint32_t register_counters, uint32_t monitor, uint32_t last_sleep_time);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,7 +20,7 @@ void beacon_send_own(uint16_t voltage) {
|
||||||
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, "=%s%c%c%s%c%c %s", main_string_latitude, main_config_data_basic->n_or_s, main_symbol_f, main_string_longitude, main_config_data_basic->e_or_w, main_symbol_s, main_config_data_basic->comment);
|
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, "=%s%c%c%s%c%c %s", main_string_latitude, main_config_data_basic->n_or_s, main_symbol_f, main_string_longitude, main_config_data_basic->e_or_w, main_symbol_s, main_config_data_basic->comment);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, "=%s%c%c%s%c%c %s Vbatt %dV", main_string_latitude, main_config_data_basic->n_or_s, main_symbol_f, main_string_longitude, main_config_data_basic->e_or_w, main_symbol_s, main_config_data_basic->comment, (int)voltage);
|
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, "=%s%c%c%s%c%c %s [Vbatt: %dV]", main_string_latitude, main_config_data_basic->n_or_s, main_symbol_f, main_string_longitude, main_config_data_basic->e_or_w, main_symbol_s, main_config_data_basic->comment, (int)voltage);
|
||||||
}
|
}
|
||||||
main_own_aprs_msg[main_own_aprs_msg_len] = 0;
|
main_own_aprs_msg[main_own_aprs_msg_len] = 0;
|
||||||
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, main_own_aprs_msg, main_own_aprs_msg_len);
|
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, main_own_aprs_msg, main_own_aprs_msg_len);
|
||||||
|
|
|
@ -19,6 +19,16 @@
|
||||||
|
|
||||||
uint16_t telemetry_counter = 0;
|
uint16_t telemetry_counter = 0;
|
||||||
|
|
||||||
|
#ifdef PARAMETEO
|
||||||
|
#include "pwr_save.h"
|
||||||
|
|
||||||
|
const char * telemetry_vbatt_normal = "VBATT_GOOD";
|
||||||
|
const char * telemetry_vbatt_low = "VBATT_LOW";
|
||||||
|
const char * telemetry_vbatt_cutoff = "VBATT_CUTOFF";
|
||||||
|
const char * telemetry_vbatt_unknown = "VBATT_UNKNOWN";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void telemetry_send_chns_description_pv(const config_data_basic_t * const config_basic) {
|
void telemetry_send_chns_description_pv(const config_data_basic_t * const config_basic) {
|
||||||
|
|
||||||
// a buffer to assembly the 'call-ssid' string at the begining of the frame
|
// a buffer to assembly the 'call-ssid' string at the begining of the frame
|
||||||
|
@ -549,5 +559,56 @@ void telemetry_send_status_raw_values_modbus(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void telemetry_send_status_powersave_cutoff(uint16_t battery_voltage, int8_t previous_cutoff, int8_t current_cutoff) {
|
||||||
|
const char *p, *c;
|
||||||
|
|
||||||
|
// telemetry_vbatt_unknown
|
||||||
|
|
||||||
|
if ((previous_cutoff & CURRENTLY_CUTOFF) != 0) {
|
||||||
|
p = telemetry_vbatt_cutoff;
|
||||||
|
}
|
||||||
|
else if ((previous_cutoff & CURRENTLY_VBATT_LOW) != 0) {
|
||||||
|
p = telemetry_vbatt_low;
|
||||||
|
}
|
||||||
|
else if (((previous_cutoff & CURRENTLY_CUTOFF) == 0) && (previous_cutoff & CURRENTLY_VBATT_LOW) == 0){
|
||||||
|
p = telemetry_vbatt_normal;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = telemetry_vbatt_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((current_cutoff & CURRENTLY_CUTOFF) != 0) {
|
||||||
|
c = telemetry_vbatt_cutoff;
|
||||||
|
}
|
||||||
|
else if ((current_cutoff & CURRENTLY_VBATT_LOW) != 0) {
|
||||||
|
c = telemetry_vbatt_low;
|
||||||
|
}
|
||||||
|
else if (((current_cutoff & CURRENTLY_CUTOFF) == 0) && (current_cutoff & CURRENTLY_VBATT_LOW) == 0){
|
||||||
|
c = telemetry_vbatt_normal;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = telemetry_vbatt_unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
main_wait_for_tx_complete();
|
||||||
|
|
||||||
|
memset(main_own_aprs_msg, 0x00, sizeof(main_own_aprs_msg));
|
||||||
|
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, ">[powersave cutoff change][Vbatt: %dV][previous: %d - %s][currently: %d - %s]", battery_voltage, previous_cutoff, p, current_cutoff, c);
|
||||||
|
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, main_own_aprs_msg, main_own_aprs_msg_len);
|
||||||
|
//while (main_ax25.dcd == 1);
|
||||||
|
afsk_txStart(&main_afsk);
|
||||||
|
main_wait_for_tx_complete();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void telemetry_send_status_powersave_registers(uint32_t register_last_sleep, uint32_t register_last_wakeup, uint32_t register_counters, uint32_t monitor, uint32_t last_sleep_time) {
|
||||||
|
main_wait_for_tx_complete();
|
||||||
|
|
||||||
|
memset(main_own_aprs_msg, 0x00, sizeof(main_own_aprs_msg));
|
||||||
|
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, ">[powersave registers][register_last_sleep: 0x%lX][register_last_wakeup: 0x%lX][register_counters: 0x%lX][monitor: 0x%lX][last_sleep_time: 0x%lX]",register_last_sleep, register_last_wakeup, register_counters, monitor, last_sleep_time);
|
||||||
|
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, main_own_aprs_msg, main_own_aprs_msg_len);
|
||||||
|
//while (main_ax25.dcd == 1);
|
||||||
|
afsk_txStart(&main_afsk);
|
||||||
|
main_wait_for_tx_complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ void SendWXFrame(uint16_t windspeed, uint16_t windgusts, uint16_t winddirection,
|
||||||
|
|
||||||
if (wind_speed_mph > wind_gusts_mph) {
|
if (wind_speed_mph > wind_gusts_mph) {
|
||||||
return;
|
return;
|
||||||
rte_main_reboot_req = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pressure = (unsigned)(cisnienie * 10);
|
pressure = (unsigned)(cisnienie * 10);
|
||||||
|
|
|
@ -425,6 +425,39 @@ int system_clock_configure_l4(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void system_clock_start_rtc_l4(void) {
|
||||||
|
// starting RTC
|
||||||
|
RCC->BDCR |= RCC_BDCR_RTCEN;
|
||||||
|
|
||||||
|
// enable write access to RTC registers by writing two magic words
|
||||||
|
RTC->WPR = 0xCA;
|
||||||
|
RTC->WPR = 0x53;
|
||||||
|
|
||||||
|
// enter the clock set mode
|
||||||
|
RTC->ISR |= RTC_ISR_INIT;
|
||||||
|
|
||||||
|
// wait for going into clock set mode
|
||||||
|
while((RTC->ISR & RTC_ISR_INITF) == 0);
|
||||||
|
|
||||||
|
// set date
|
||||||
|
RTC->DR = 0x0021A820;
|
||||||
|
|
||||||
|
// set time
|
||||||
|
RTC->TR = 0x00232711;
|
||||||
|
|
||||||
|
// exit RTC set mode
|
||||||
|
RTC->ISR &= (0xFFFFFFFF ^ RTC_ISR_INIT);
|
||||||
|
|
||||||
|
// disable wakeup interrupt and wakeup interrupt
|
||||||
|
RTC->CR = 0;
|
||||||
|
|
||||||
|
// wait for wakeup timer to disable
|
||||||
|
while((RTC->ISR & RTC_ISR_WUTWF) == 0);
|
||||||
|
|
||||||
|
// set the source clock for RTC wakeup as CK_SPRE
|
||||||
|
RTC->CR |= RTC_CR_WUCKSEL_2;
|
||||||
|
}
|
||||||
|
|
||||||
int system_clock_configure_rtc_l4(void) {
|
int system_clock_configure_rtc_l4(void) {
|
||||||
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
@ -434,6 +467,9 @@ int system_clock_configure_rtc_l4(void) {
|
||||||
// check if LSE is working now
|
// check if LSE is working now
|
||||||
uint8_t lse_is_working = ((RCC->BDCR & RCC_BDCR_LSERDY) > 0) ? 1 : 0;
|
uint8_t lse_is_working = ((RCC->BDCR & RCC_BDCR_LSERDY) > 0) ? 1 : 0;
|
||||||
|
|
||||||
|
// enable access to backup domain
|
||||||
|
PWR->CR1 |= PWR_CR1_DBP;
|
||||||
|
|
||||||
// if LSE is not working reinitialize everything
|
// if LSE is not working reinitialize everything
|
||||||
if (lse_is_working == 0) {
|
if (lse_is_working == 0) {
|
||||||
|
|
||||||
|
@ -449,9 +485,6 @@ int system_clock_configure_rtc_l4(void) {
|
||||||
// but clear reset flag before
|
// but clear reset flag before
|
||||||
RCC->BDCR &= (0xFFFFFFFF ^ RCC_BDCR_BDRST);
|
RCC->BDCR &= (0xFFFFFFFF ^ RCC_BDCR_BDRST);
|
||||||
|
|
||||||
// enable access to backup domain
|
|
||||||
PWR->CR1 |= PWR_CR1_DBP;
|
|
||||||
|
|
||||||
// set the clock source for RTC clock to LSE
|
// set the clock source for RTC clock to LSE
|
||||||
RCC->BDCR |= RCC_BDCR_RTCSEL_0;
|
RCC->BDCR |= RCC_BDCR_RTCSEL_0;
|
||||||
|
|
||||||
|
@ -463,35 +496,13 @@ int system_clock_configure_rtc_l4(void) {
|
||||||
|
|
||||||
// wait for LSE to start
|
// wait for LSE to start
|
||||||
while((RCC->BDCR & RCC_BDCR_LSERDY) == 0);
|
while((RCC->BDCR & RCC_BDCR_LSERDY) == 0);
|
||||||
|
|
||||||
// starting RTC
|
|
||||||
RCC->BDCR |= RCC_BDCR_RTCEN;
|
|
||||||
|
|
||||||
// enable write access to RTC registers by writing two magic words
|
|
||||||
RTC->WPR = 0xCA;
|
|
||||||
RTC->WPR = 0x53;
|
|
||||||
|
|
||||||
// enter the clock set mode
|
|
||||||
RTC->ISR |= RTC_ISR_INIT;
|
|
||||||
|
|
||||||
// wait for going into clock set mode
|
|
||||||
while((RTC->ISR & RTC_ISR_INITF) == 0);
|
|
||||||
|
|
||||||
// set date
|
|
||||||
RTC->DR = 0x0021A820;
|
|
||||||
|
|
||||||
// set time
|
|
||||||
RTC->TR = 0x00232711;
|
|
||||||
|
|
||||||
// exit RTC set mode
|
|
||||||
RTC->ISR &= (0xFFFFFFFF ^ RTC_ISR_INIT);
|
|
||||||
|
|
||||||
// set the source clock for RTC wakeup as CK_SPRE
|
|
||||||
RTC->CR |= RTC_CR_WUCKSEL_2;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// starting and configuring the RTC itself
|
||||||
|
system_clock_start_rtc_l4();
|
||||||
|
|
||||||
|
// disable access do backup domain
|
||||||
|
PWR->CR1 &= (0xFFFFFFFF ^ PWR_CR1_DBP);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -501,6 +512,11 @@ void system_clock_configure_auto_wakeup_l4(uint16_t seconds) {
|
||||||
// enable access to backup domain
|
// enable access to backup domain
|
||||||
PWR->CR1 |= PWR_CR1_DBP;
|
PWR->CR1 |= PWR_CR1_DBP;
|
||||||
|
|
||||||
|
// check if RTC is working
|
||||||
|
if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) {
|
||||||
|
system_clock_start_rtc_l4();
|
||||||
|
}
|
||||||
|
|
||||||
// enable write access to RTC registers by writing two magic words
|
// enable write access to RTC registers by writing two magic words
|
||||||
RTC->WPR = 0xCA;
|
RTC->WPR = 0xCA;
|
||||||
RTC->WPR = 0x53;
|
RTC->WPR = 0x53;
|
||||||
|
@ -534,6 +550,9 @@ void system_clock_configure_auto_wakeup_l4(uint16_t seconds) {
|
||||||
|
|
||||||
// enable wakeup interrupt
|
// enable wakeup interrupt
|
||||||
NVIC_EnableIRQ(RTC_WKUP_IRQn);
|
NVIC_EnableIRQ(RTC_WKUP_IRQn);
|
||||||
|
|
||||||
|
// disable access do backup domain
|
||||||
|
PWR->CR1 &= (0xFFFFFFFF ^ PWR_CR1_DBP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -670,7 +670,7 @@ void rtu_get_raw_values_string(char* out, uint16_t out_buffer_ln, uint8_t* gener
|
||||||
|
|
||||||
f6_value = rte_wx_modbus_rtu_f6.registers_values[0];
|
f6_value = rte_wx_modbus_rtu_f6.registers_values[0];
|
||||||
|
|
||||||
string_ln = snprintf(out, out_buffer_ln, ">F1V %X, F2V %X, F3V %X, F4V %X, F5V %X, F6V %X",
|
string_ln = snprintf(out, out_buffer_ln, ">[F1V: %X][F2V: %X][F3V: %X][F4V: %X][F5V: %X][F6V: %X]",
|
||||||
(int) f1_value,
|
(int) f1_value,
|
||||||
(int) f2_value,
|
(int) f2_value,
|
||||||
(int) f3_value,
|
(int) f3_value,
|
||||||
|
|
Ładowanie…
Reference in New Issue