a lot of work on powersaving

pull/7/head
Mateusz Lubecki 2021-09-10 22:38:13 +02:00
rodzic 4b40720947
commit 0c367465de
18 zmienionych plików z 537 dodań i 108 usunięć

Wyświetl plik

@ -13,6 +13,7 @@ RM := rm -rf
-include system/src/stm32f1-stdperiph/subdir.mk
-include system/src/newlib/subdir.mk
-include system/src/modbus_rtu/subdir.mk
-include system/src/drivers/f1/subdir.mk
-include system/src/drivers/subdir.mk
-include system/src/diag/subdir.mk
-include system/src/davis_vantage/subdir.mk

Wyświetl plik

@ -34,6 +34,7 @@ system/src/cortexm \
system/src/davis_vantage \
system/src/diag \
system/src/drivers \
system/src/drivers/f1 \
system/src/modbus_rtu \
system/src/newlib \
system/src/stm32f1-stdperiph \

Wyświetl plik

@ -20,10 +20,12 @@ C_SRCS += \
../src/it_handlers.c \
../src/main.c \
../src/packet_tx_handler.c \
../src/pwr_switch.c \
../src/rte_main.c \
../src/rte_pv.c \
../src/rte_rtu.c \
../src/rte_wx.c \
../src/rtu_pwr.c \
../src/wx_handler.c \
../src/wx_handler_humidity.c \
../src/wx_handler_pressure.c \
@ -46,10 +48,12 @@ OBJS += \
./src/it_handlers.o \
./src/main.o \
./src/packet_tx_handler.o \
./src/pwr_switch.o \
./src/rte_main.o \
./src/rte_pv.o \
./src/rte_rtu.o \
./src/rte_wx.o \
./src/rtu_pwr.o \
./src/wx_handler.o \
./src/wx_handler_humidity.o \
./src/wx_handler_pressure.o \
@ -72,10 +76,12 @@ C_DEPS += \
./src/it_handlers.d \
./src/main.d \
./src/packet_tx_handler.d \
./src/pwr_switch.d \
./src/rte_main.d \
./src/rte_pv.d \
./src/rte_rtu.d \
./src/rte_wx.d \
./src/rtu_pwr.d \
./src/wx_handler.d \
./src/wx_handler_humidity.d \
./src/wx_handler_pressure.d \

Wyświetl plik

@ -12,7 +12,6 @@ C_SRCS += \
../system/src/aprs/crc.c \
../system/src/aprs/dac.c \
../system/src/aprs/digi.c \
../system/src/aprs/raw.c \
../system/src/aprs/telemetry.c \
../system/src/aprs/wx.c
@ -25,7 +24,6 @@ OBJS += \
./system/src/aprs/crc.o \
./system/src/aprs/dac.o \
./system/src/aprs/digi.o \
./system/src/aprs/raw.o \
./system/src/aprs/telemetry.o \
./system/src/aprs/wx.o
@ -38,7 +36,6 @@ C_DEPS += \
./system/src/aprs/crc.d \
./system/src/aprs/dac.d \
./system/src/aprs/digi.d \
./system/src/aprs/raw.d \
./system/src/aprs/telemetry.d \
./system/src/aprs/wx.d

Wyświetl plik

@ -8,30 +8,21 @@ C_SRCS += \
../system/src/drivers/bme280.c \
../system/src/drivers/dallas.c \
../system/src/drivers/dma_helper_functions.c \
../system/src/drivers/gpio_conf.c \
../system/src/drivers/i2c.c \
../system/src/drivers/ms5611.c \
../system/src/drivers/serial.c
../system/src/drivers/ms5611.c
OBJS += \
./system/src/drivers/analog_anemometer.o \
./system/src/drivers/bme280.o \
./system/src/drivers/dallas.o \
./system/src/drivers/dma_helper_functions.o \
./system/src/drivers/gpio_conf.o \
./system/src/drivers/i2c.o \
./system/src/drivers/ms5611.o \
./system/src/drivers/serial.o
./system/src/drivers/ms5611.o
C_DEPS += \
./system/src/drivers/analog_anemometer.d \
./system/src/drivers/bme280.d \
./system/src/drivers/dallas.d \
./system/src/drivers/dma_helper_functions.d \
./system/src/drivers/gpio_conf.d \
./system/src/drivers/i2c.d \
./system/src/drivers/ms5611.d \
./system/src/drivers/serial.d
./system/src/drivers/ms5611.d
# Each subdirectory must supply rules for building sources it contributes

Wyświetl plik

@ -63,8 +63,11 @@ typedef struct config_data_mode_t {
uint8_t digi_viscous_delay_sec;
// only for ParaMETEO
config_data_powersave_mode_t powersave;
// only for ParaMETEO
uint8_t gsm;
} config_data_mode_t;

Wyświetl plik

@ -10,6 +10,20 @@
#include "config_data.h"
typedef struct packet_tx_counter_values_t {
uint8_t beacon_counter;
uint8_t wx_counter;
uint8_t telemetry_counter;
uint8_t telemetry_desc_counter;
uint8_t kiss_counter;
} packet_tx_counter_values_t;
void packet_tx_configure(uint8_t meteo_interval, uint8_t beacon_interval);
void packet_tx_handler(const config_data_basic_t * const config_basic, const config_data_mode_t * const config_mode);
void packet_tx_get_current_counters(packet_tx_counter_values_t * out);
void packet_tx_set_current_counters(packet_tx_counter_values_t * in);
int16_t packet_tx_get_minutes_to_next_wx(void);
#endif /* PACKET_TX_HANDLER_H_ */

Wyświetl plik

@ -30,79 +30,86 @@
* | L7 | Stop2 | OFF | OFF | OFF |
* \------------------------------------------------------------/
*
* C = modes with communication enabled
* M = mode with measuremenet only w/o any communication
* I = idle / initialization mode with anything disabled
* L = low power consumption modes with CPU halted in STOP2 mode
* C = modes with communication enabled
* M = mode with measuremenet only w/o any communication
* I = idle / initialization mode with anything disabled
* L = low power consumption modes with CPU halted in STOP2 mode
*
* Stop2 mode is a power saving mode defined in STM paperwork (DM0083560
* aka Reference Manual RM0351). This mode halts CPU core completely and
* disable HCLK, AHB1 & AHB2 buses, but preserves StaticRAM and registers
* content. 32k-LSE and RTC works normally and wakeups the core every
* programmed amount of seconds.
* Stop2 mode is a power saving mode defined in STM paperwork (DM0083560
* aka Reference Manual RM0351). This mode halts CPU core completely and
* disable HCLK, AHB1 & AHB2 buses, but preserves StaticRAM and registers
* content. 32k-LSE and RTC works normally and wakeups the core every
* programmed amount of seconds.
*
* C0 - Mode with everything avaliable. Used when station shall works
* as APRS digi / igate and is (probably) powered from mains instead
* of PV
* C0 - Mode with everything avaliable. Used when station shall works
* as APRS digi / igate and is (probably) powered from mains instead
* of PV
*
* C1 - Mode with everything except GPRS modem is powered. This is
* default mode when station is powered from PV and works as DIGI.
* Digi required constant participation in radio channel traffic
* so VHF radio must operates constantly.
* C1 - Mode with everything except GPRS modem is powered. This is
* default mode when station is powered from PV and works as DIGI.
* Digi required constant participation in radio channel traffic
* so VHF radio must operates constantly.
*
* C2 - Simmilar to C1 but with all meteo sensors disabled. This helps
* save some mA of current drain (but presumably radio will consume more
* than sensors)
* C2 - Simmilar to C1 but with all meteo sensors disabled. This helps
* save some mA of current drain (but presumably radio will consume more
* than sensors)
*
* M4 - Measurement only mode when only meteo sensors are enabled
* M4 - Measurement only mode when only meteo sensors are enabled
*
* I5 - Idle / initialization mode when only micro is operating normally but
* all aux voltages are turned off. This is mode CPU starts after poweron/reset
* and wakes up from Stop2
* I5 - Idle / initialization mode when only micro is operating normally but
* all aux voltages are turned off. This is mode CPU starts after poweron/reset
* and wakes up from Stop2
*
* L6 - This is Low power STOP2 mode with GSM radio kept in standby mode. +4V_G
* is powered on but GSM radio is left in most power efficient mode available.
* This is used when WX packet interval is shorter than 5 minutes. In such case
* GSM modem reinitialization and tuning & logging into network will consume more
* power than keeping modem on standby.
* L6 - This is Low power STOP2 mode with GSM radio kept in standby mode. +4V_G
* is powered on but GSM radio is left in most power efficient mode available.
* This is used when WX packet interval is shorter than 5 minutes. In such case
* GSM modem reinitialization and tuning & logging into network will consume more
* power than keeping modem on standby.
*
* L7 - Deep sleep mode with everything powered off and CPU kept in STOP2 mode.
* L7 - Deep sleep mode with everything powered off and CPU kept in STOP2 mode.
*
*
*
* Transitions between states depends on configuration and value of config_data_powersave_mode_t
* Transitions between states depends on configuration and value of config_data_powersave_mode_t
*
* ====================================================================================================================================|
* | Mode | Powersave Mode | |
* |=======================|===================|=======================================================================================|
* | DIGI | don't care | Always stays in C2 no matter of how config_data_powersave_mode_t is set |
* | DIGI + WX | PWSAVE_NONE | C1 |
* | DIGI + WX | PWSAVE_NORMAL | C2 --- (1 minute before WX frame)---> C1 -> C2 |
* | DIGI + WX | PWSAVE_AGGRESV | C2 --- (1 minute before WX frame)---> C1 -> C2 |
* | DIGI + WX + GSM | PWSAVE_NONE | C0 |
* | DIGI + WX + GSM | PWSAVE_NORMAL | C2 --- (1 minute before WX frame)---> C0 -> C2 ; if WX_INTERVAL >= 5 minutes |
* | DIGI + WX + GSM | PWSAVE_NORMAL | C3 --- (1 minute before WX frame)---> C0 -> C3 ; if WX_INTERVAL < 5 minutes |
* | DIGI + WX + GSM | PWSAVE_AGGRESV | C2 --- (1 minute before WX frame)---> C0 -> C2 ; no matter WX_INTERVAL |
* | WX | PWSAVE_NONE | C2 --- (30 seconds before WX frame)---> C1 -> C2 |
* | WX | PWSAVE_NORMAL | M4 --- (30 seconds before WX frame)---> C1 -> M4 |
* | WX | PWSAVE_AGGRESV | L7 --- (1 minute before WX frame)---> M4 --- (30 sec before)---> C1 -> L7 |
* ====================================================================================================================================|
* | Mode | Powersave Mode | |
* |=======================|===================|=======================================================================================|
* | DIGI | don't care | Always stays in C2 no matter of how config_data_powersave_mode_t is set |
* | DIGI + WX | PWSAVE_NONE | C1 |
* | DIGI + WX | PWSAVE_NORMAL | C2 --- (1 minute before WX frame)---> C1 -> C2 |
* | DIGI + WX | PWSAVE_AGGRESV | C2 --- (1 minute before WX frame)---> C1 -> C2 |
* | DIGI + WX + GSM | PWSAVE_NONE | C0 |
* | DIGI + WX + GSM | PWSAVE_NORMAL | C2 --- (1 minute before WX frame)---> C0 -> C2 ; if WX_INTERVAL >= 5 minutes |
* | DIGI + WX + GSM | PWSAVE_NORMAL | C3 --- (1 minute before WX frame)---> C0 -> C3 ; if WX_INTERVAL < 5 minutes |
* | DIGI + WX + GSM | PWSAVE_AGGRESV | C2 --- (1 minute before WX frame)---> C0 -> C2 ; no matter WX_INTERVAL |
* | WX + GSM | PWSAVE_NONE | C0 |
* | WX + GSM | PWSAVE_NORMAL | M4 --- (1 minute before WX frame)---> C0 -> M4 |
* | WX + GSM (only) | PWSAVE_AGGRESV | L6 --- (1 minute before WX frame)---> C0 -> L6 ; if WX_INTERVAL < 5 minutes |
* | WX + GSM (only) | PWSAVE_AGGRESV | L7 --- (1 minute before WX frame)---> M4 --- (30 sec before)---> C0 -> L7 |
* | WX | PWSAVE_NONE | C2 --- (30 seconds before WX frame)---> C1 -> C2 |
* | WX | PWSAVE_NORMAL | M4 --- (30 seconds before WX frame)---> C1 -> M4 |
* | WX | PWSAVE_AGGRESV | L7 --- (1 minute before WX frame)---> M4 --- (30 sec before)---> C1 -> L7 |
* ====================================================================================================================================|
*
*/
#include "config_data.h"
#if defined(STM32L471xx)
void pwr_save_init(void);
void pwr_save_enter_stop2(void);
void pwr_save_exit_from_stop2(void);
void pwr_save_switch_mode_to_c0(void);
void pwr_save_switch_mode_to_c1(void);
void pwr_save_switch_mode_to_c2(void);
void pwr_save_switch_mode_to_c3(void);
void pwr_save_switch_mode_to_m4(void);
void pwr_save_switch_mode_to_i5(void);
void pwr_save_switch_mode_to_l6(void);
void pwr_save_switch_mode_to_l7(void);
void pwr_save_pooling_handler(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(config_data_mode_t * config, config_data_basic_t * timers, int16_t minutes_to_wx); // this should be called from 10 seconds pooler

Wyświetl plik

@ -16,12 +16,11 @@
//#define _DIGI_ONLY_789 // Limit digipeater to handle only -7, -8 and -9 SSIDs
//#define _VICTRON // Enable support for Victron VE.Direct protocol
#define _GSM // only for ParaMETEO
/* MODES OF OPERATION */
/* ------------------ */
//#define PARATNC_HWREV_A
//#define PARATNC_HWREV_B
//#define PARATNC_HWREV_C
#define PARAMETEO
@ -66,23 +65,23 @@
/******** INTERNAL SENSORS CONFIGURATION *****************/
/*************** DATA SOURCES CONFIG ***********************/
//#define _TEMPERATURE_INTERNAL
#define _TEMPERATURE_INTERNAL
//#define _TEMPERATURE_UMB
//#define _TEMPERATURE_RTU
//#define _TEMPERATURE_DAVIS
//
//#define _PRESSURE_INTERNAL
#define _PRESSURE_INTERNAL
//#define _PRESSURE_UMB
//#define _PRESSURE_RTU
//#define _PRESSURE_DAVIS
//
//#define _HUMIDITY_INTERNAL
#define _HUMIDITY_INTERNAL
//#define _HUMIDITY_UMB
//#define _HUMIDITY_RTU
//#define _HUMIDITY_DAVIS
//
//
//#define _WIND_INTERNAL
#define _WIND_INTERNAL
//#define _WIND_UMB
//#define _WIND_RTU
//#define _WIND_FULL_RTU

Wyświetl plik

@ -105,11 +105,17 @@ volatile const config_data_mode_t config_data_mode_default = {
#endif
#if (defined _POWERSAVE_NORMAL)
.powersave = PWSAVE_NONE
.powersave = PWSAVE_NONE,
#elif (defined _POWERSAVE_AGGRESIVE)
.powersave = PWSAVE_AGGRESV
.powersave = PWSAVE_AGGRESV,
#else
.powersave = PWSAVE_NONE
.powersave = PWSAVE_NONE,
#endif
#if (defined _GSM)
.gsm = 1
#else
.gsm = 0
#endif
};

Wyświetl plik

@ -109,11 +109,17 @@ const config_data_mode_t __attribute__((section(".config_section_first.mode")))
#endif
#if (defined _POWERSAVE_NORMAL)
.powersave = PWSAVE_NONE
.powersave = PWSAVE_NONE,
#elif (defined _POWERSAVE_AGGRESIVE)
.powersave = PWSAVE_AGGRESV
.powersave = PWSAVE_AGGRESV,
#else
.powersave = PWSAVE_NONE
.powersave = PWSAVE_NONE,
#endif
#if (defined _GSM)
.gsm = 1
#else
.gsm = 0
#endif
};

Wyświetl plik

@ -103,11 +103,17 @@ const config_data_mode_t __attribute__((section(".config_section_second.mode")))
#endif
#if (defined _POWERSAVE_NORMAL)
.powersave = PWSAVE_NONE
.powersave = PWSAVE_NONE,
#elif (defined _POWERSAVE_AGGRESIVE)
.powersave = PWSAVE_AGGRESV
.powersave = PWSAVE_AGGRESV,
#else
.powersave = PWSAVE_NONE
.powersave = PWSAVE_NONE,
#endif
#if (defined _GSM)
.gsm = 1
#else
.gsm = 0
#endif
};

Wyświetl plik

@ -17,6 +17,8 @@
#include <stm32l4xx_ll_tim.h>
#include <stm32l4xx_ll_dma.h>
#include <stm32l471xx.h>
#include "cmsis/stm32l4xx/system_stm32l4xx.h"
#include "pwr_save.h"
#endif
#include "drivers/dallas.h"
@ -90,11 +92,11 @@ void RTC_WKUP_IRQHandler(void) {
system_clock_configure_l4();
led_flip_led1_upper();
pwr_save_exit_from_stop2();
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, 1);
led_flip_led2_bottom();
led_control_led1_upper(true);
}
#endif

Wyświetl plik

@ -392,6 +392,9 @@ int main(int argc, char* argv[]){
configuration_handler_load_configuration(REGION_DEFAULT);
}
// set packets intervals
packet_tx_configure(main_config_data_basic->wx_transmit_period, main_config_data_basic->beacon_transmit_period);
#if defined(PARATNC_HWREV_A) || defined(PARATNC_HWREV_B) || defined(PARATNC_HWREV_C)
// disabling access to BKP registers
RCC->APB1ENR &= (0xFFFFFFFF ^ (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN));
@ -535,6 +538,11 @@ int main(int argc, char* argv[]){
main_target_kiss_baudrate = 9600u;
main_target_wx_baudrate = _SERIAL_BAUDRATE;
#if defined(PARAMETEO)
// swtich power to M4. turn on sensors but keep GSM modem turned off
pwr_save_switch_mode_to_m4();
#endif
// if Victron VE-direct protocol is enabled set the baudrate to the 19200u
if (main_config_data_mode->victron == 1) {
main_target_kiss_baudrate = 19200u;
@ -823,6 +831,11 @@ int main(int argc, char* argv[]){
io_ext_watchdog_service();
#if defined(PARAMETEO)
// test
pwr_save_switch_mode_to_c0();
#endif
// Infinite loop
while (1)
{
@ -1061,6 +1074,10 @@ int main(int argc, char* argv[]){
if (main_ten_second_pool_timer < 10) {
#ifdef STM32L471xx
pwr_save_pooling_handler(main_config_data_mode, main_config_data_basic, packet_tx_get_minutes_to_next_wx());
#endif
if (main_config_data_mode->wx_umb == 1) {
umb_channel_pool(&rte_wx_umb, &rte_wx_umb_context, main_config_data_umb);
}

Wyświetl plik

@ -1,3 +1,5 @@
#include "packet_tx_handler.h"
#include "rte_wx.h"
#include "rte_pv.h"
#include "rte_main.h"
@ -20,13 +22,13 @@
#define _TELEM_DESCR_INTERVAL 150
uint8_t packet_tx_beacon_interval = _BCN_INTERVAL;
uint8_t packet_tx_beacon_interval = 0;
uint8_t packet_tx_beacon_counter = 0;
uint8_t packet_tx_error_status_interval = 2;
uint8_t packet_tx_error_status_counter = 0;
uint8_t packet_tx_meteo_interval = _WX_INTERVAL;
uint8_t packet_tx_meteo_interval = 0;
uint8_t packet_tx_meteo_counter = 2;
uint8_t packet_tx_meteo_kiss_interval = 2;
@ -35,14 +37,21 @@ uint8_t packet_tx_meteo_kiss_counter = 0;
uint8_t packet_tx_telemetry_interval = 10;
uint8_t packet_tx_telemetry_counter = 0;
uint8_t packet_tx_telemetry_descr_interval = _TELEM_DESCR_INTERVAL;
uint8_t packet_tx_telemetry_descr_interval = 0;
uint8_t packet_tx_telemetry_descr_counter = 10;
const uint8_t packet_tx_modbus_raw_values = (uint8_t)(_TELEM_DESCR_INTERVAL - _WX_INTERVAL * (uint8_t)(_TELEM_DESCR_INTERVAL / 38));
const uint8_t packet_tx_modbus_status = (uint8_t)(_TELEM_DESCR_INTERVAL - _WX_INTERVAL * (uint8_t)(_TELEM_DESCR_INTERVAL / 5));
uint8_t packet_tx_modbus_raw_values = (uint8_t)(_TELEM_DESCR_INTERVAL - _WX_INTERVAL * (uint8_t)(_TELEM_DESCR_INTERVAL / 38));
uint8_t packet_tx_modbus_status = (uint8_t)(_TELEM_DESCR_INTERVAL - _WX_INTERVAL * (uint8_t)(_TELEM_DESCR_INTERVAL / 5));
uint8_t packet_tx_more_than_one = 0;
void packet_tx_configure(uint8_t meteo_interval, uint8_t beacon_interval) {
packet_tx_meteo_interval = meteo_interval;
packet_tx_beacon_interval = beacon_interval;
}
/**
* This function is called from the inside of 'packet_rx_handler' to put an extra wait
* if more than one packet is sent from the single call to that function. This is required
@ -96,7 +105,7 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
packet_tx_error_status_counter = 0;
}
if (packet_tx_beacon_counter >= packet_tx_beacon_interval) {
if (packet_tx_beacon_counter >= packet_tx_beacon_interval && packet_tx_beacon_interval != 0) {
packet_tx_multi_per_call_handler();
@ -108,7 +117,7 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
}
if ((main_config_data_mode->wx & WX_ENABLED) == WX_ENABLED) {
if (packet_tx_meteo_counter >= packet_tx_meteo_interval) {
if (packet_tx_meteo_counter >= packet_tx_meteo_interval && packet_tx_meteo_interval != 0) {
packet_tx_multi_per_call_handler();
@ -324,3 +333,44 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
}
}
void packet_tx_get_current_counters(packet_tx_counter_values_t * out) {
if (out != 0x00) {
out->beacon_counter = packet_tx_beacon_counter;
out->wx_counter = packet_tx_meteo_counter;
out->telemetry_counter = packet_tx_telemetry_counter;
out->telemetry_desc_counter = packet_tx_telemetry_descr_counter;
out->kiss_counter = packet_tx_meteo_kiss_counter;
}
}
void packet_tx_set_current_counters(packet_tx_counter_values_t * in) {
if (in != 0x00) {
if (in->beacon_counter != 0)
packet_tx_beacon_counter = in->beacon_counter;
if (in->wx_counter != 0)
packet_tx_meteo_counter = in->wx_counter;
if (in->telemetry_counter != 0)
packet_tx_telemetry_counter = in->telemetry_counter;
if (in->telemetry_desc_counter != 0)
packet_tx_telemetry_descr_counter = in->telemetry_desc_counter;
if (in->kiss_counter != 0)
packet_tx_meteo_kiss_counter = in->kiss_counter;
}
}
int16_t packet_tx_get_minutes_to_next_wx(void) {
if (packet_tx_meteo_interval != 0) {
return packet_tx_meteo_interval - packet_tx_meteo_counter;
}
else {
return -1;
}
}

Wyświetl plik

@ -8,10 +8,13 @@
#include "pwr_save.h"
#include "stm32l4xx.h"
#include "system_stm32l4xx.h"
#include <stdint.h>
#include "pwr_switch.h"
#include "io.h"
#include "packet_tx_handler.h"
#include "main.h"
#define IN_STOP2_MODE (1 << 1)
#define IN_C0_STATE (1 << 2)
@ -23,10 +26,15 @@
#define IN_L6_STATE (1 << 8)
#define IN_L7_STATE (1 << 9)
#define CLEAR_ALL_STATES_BITMASK (0xFF << 2)
#define ALL_STATES_BITMASK (0xFF << 2)
#define REGISTER RTC->BKP0R
#if defined(STM32L471xx)
int8_t pwr_save_seconds_to_wx = 0;
int16_t pwr_save_sleep_time_in_seconds = -1;
/**
* This function initializes everything related to power saving features
* including programming Flash memory option bytes
@ -107,8 +115,55 @@ void pwr_save_enter_stop2(void) {
}
/**
* This function has to be called within RTC wakepup interrupt.
*/
void pwr_save_exit_from_stop2(void) {
// packet tx timers values
packet_tx_counter_values_t timers;
// check power saving mode set before switching uC to SLEEP2
uint16_t powersave_mode = (uint16_t)(REGISTER & ALL_STATES_BITMASK);
// check if sleep time is valid
if (pwr_save_sleep_time_in_seconds <= 0) {
// if for some reason the value is not valid change is to something meaningful
pwr_save_sleep_time_in_seconds = 60;
}
switch(powersave_mode) {
case IN_L6_STATE:
case IN_L7_STATE:
// get all timers values
packet_tx_get_current_counters(&timers);
// rewind all timers in packet tx handler as they were no updated when micro was sleeping
// sleep shall be always set as wx packet interval minus one minute
timers.beacon_counter += (pwr_save_sleep_time_in_seconds / 60);
timers.kiss_counter += (pwr_save_sleep_time_in_seconds / 60);
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);
break;
// something is screwed horribly as in all other modes a micro shall not be placed in STOP2 mode
default:
break;
}
}
void pwr_save_switch_mode_to_c0(void) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_C0_STATE) {
return;
}
// turn ON +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_enable();
@ -119,15 +174,20 @@ void pwr_save_switch_mode_to_c0(void) {
io_12v_sw___cntrl_vbat_g_enable();
// clear all previous powersave indication bits
RTC->BKP0R &= 0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK;
REGISTER &= 0xFFFFFFFF ^ ALL_STATES_BITMASK;
// set for C0 mode
RTC->BKP0R |= IN_C0_STATE;
REGISTER |= IN_C0_STATE;
}
// in HW-RevB this will disable external VHF radio!!
void pwr_save_switch_mode_to_c1(void) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_C1_STATE) {
return;
}
// turn ON +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_enable();
@ -138,16 +198,21 @@ void pwr_save_switch_mode_to_c1(void) {
io_12v_sw___cntrl_vbat_g_disable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C0 mode
RTC->BKP0R |= IN_C1_STATE;
REGISTER |= IN_C1_STATE;
}
// this mode is not avaliable in HW Revision B as internal radio
// is powered from +5V_S and external one is switched on with the same
// line which controls +4V_G
void pwr_save_switch_mode_to_c2(void) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_C2_STATE) {
return;
}
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_disable();
@ -158,13 +223,18 @@ void pwr_save_switch_mode_to_c2(void) {
io_12v_sw___cntrl_vbat_g_disable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C2 mode
RTC->BKP0R |= IN_C2_STATE;
REGISTER |= IN_C2_STATE;
}
void pwr_save_switch_mode_to_c3(void) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_C3_STATE) {
return;
}
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_disable();
@ -175,14 +245,19 @@ void pwr_save_switch_mode_to_c3(void) {
io_12v_sw___cntrl_vbat_g_enable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C3 mode
RTC->BKP0R |= IN_C3_STATE;
REGISTER |= IN_C3_STATE;
}
// in HW-RevB this will keep internal VHF radio module working!
void pwr_save_switch_mode_to_m4(void) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_M4_STATE) {
return;
}
// turn ON +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_enable();
@ -193,13 +268,18 @@ void pwr_save_switch_mode_to_m4(void) {
io_12v_sw___cntrl_vbat_g_disable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C3 mode
RTC->BKP0R |= IN_M4_STATE;
REGISTER |= IN_M4_STATE;
}
void pwr_save_switch_mode_to_i5(void) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_I5_STATE) {
return;
}
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_disable();
@ -210,15 +290,20 @@ void pwr_save_switch_mode_to_i5(void) {
io_12v_sw___cntrl_vbat_g_disable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C3 mode
RTC->BKP0R |= IN_I5_STATE;
REGISTER |= IN_I5_STATE;
}
// this will keep external VHF radio working in HW-RevB
void pwr_save_switch_mode_to_l6(void) {
void pwr_save_switch_mode_to_l6(uint16_t sleep_time) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_L6_STATE) {
return;
}
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_disable();
@ -229,16 +314,23 @@ void pwr_save_switch_mode_to_l6(void) {
io_12v_sw___cntrl_vbat_g_enable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C3 mode
RTC->BKP0R |= IN_L6_STATE;
REGISTER |= IN_L6_STATE;
system_clock_configure_auto_wakeup_l4(sleep_time);
pwr_save_enter_stop2();
}
void pwr_save_switch_mode_to_l7(void) {
void pwr_save_switch_mode_to_l7(uint16_t sleep_time) {
if ((REGISTER & ALL_STATES_BITMASK) == IN_L7_STATE) {
return;
}
// turn OFF +5V_S (and internal VHF radio module in HW-RevB)
io_5v_isol_sw___cntrl_vbat_s_disable();
@ -249,13 +341,244 @@ void pwr_save_switch_mode_to_l7(void) {
io_12v_sw___cntrl_vbat_g_disable();
// clear all previous powersave indication bits
RTC->BKP0R &= (0xFFFFFFFF ^ CLEAR_ALL_STATES_BITMASK);
REGISTER &= (0xFFFFFFFF ^ ALL_STATES_BITMASK);
// set for C3 mode
RTC->BKP0R |= IN_L7_STATE;
REGISTER |= IN_L7_STATE;
// configure how long micro should sleep
system_clock_configure_auto_wakeup_l4(sleep_time);
// save how long the micro will sleep - required for handling wakeup event
pwr_save_sleep_time_in_seconds = sleep_time;
pwr_save_enter_stop2();
}
void pwr_save_pooling_handler(config_data_mode_t * config, config_data_basic_t * timers, int16_t minutes_to_wx) {
// this function should be called from 10 seconds pooler
packet_tx_counter_values_t counters;
// get current counter values
packet_tx_get_current_counters(&counters);
// decrement seconds in last minute
if (pwr_save_seconds_to_wx != -1) {
pwr_save_seconds_to_wx -= 10;
}
// if there is more than one minute to next frame
if (minutes_to_wx > 1) {
// reset counter as we dont
pwr_save_seconds_to_wx = -1;
}
else if (minutes_to_wx == 1 && pwr_save_seconds_to_wx == -1) {
// if this is the last second to wx frame
pwr_save_seconds_to_wx = 60;
}
// handle depends on current powersave configuration
switch (config->powersave) {
/**
* PWSAVE_NONE = 0,
PWSAVE_NORMAL = 1,
PWSAVE_AGGRESV = 3
*/
case PWSAVE_NONE : {
// if weather station is enabled
if (config->wx == 1) {
// if GSM modem is enabled in configuration
if (config->gsm == 1) {
// if digipeater is enabled
if (config->digi == 1) { // DIGI + WX + GSM
pwr_save_switch_mode_to_c0();
}
else { // WX + GSM
pwr_save_switch_mode_to_c0();
}
}
else {
// if digipeater is enabled
if (config->digi == 1) { // DIGI + WX
pwr_save_switch_mode_to_c1();
}
else { // WX
if (minutes_to_wx > 1) {
// if there is more than one minute to send wx packet
pwr_save_switch_mode_to_c2();
}
else {
if (pwr_save_seconds_to_wx <= 30) {
pwr_save_switch_mode_to_c1();
}
}
}
}
}
else { // DIGI
// if weather station is not enabled just stay in C2 mode
// as this is default state for DIGI operation. Of course
// DIGI might not be enabled (which has no sense) but for
// sake of simplicity just agree that it is.
pwr_save_switch_mode_to_c2();
}
break;
}
case PWSAVE_NORMAL : {
// if weather station is enabled
if (config->wx == 1) {
// if GSM modem is enabled in configuration
if (config->gsm == 1) {
// if digipeater is enabled
if (config->digi == 1) { // DIGI + WX + GSM
// if weather packets are send 5 minutes or less often
if (timers->wx_transmit_period >= 5) {
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_c2();
}
else {
pwr_save_switch_mode_to_c0();
}
}
else {
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_c3();
}
else {
pwr_save_switch_mode_to_c0();
}
}
}
else { // WX + GSM
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_m4();
}
else {
pwr_save_switch_mode_to_c0();
}
}
}
else {
// if digipeater is enabled
if (config->digi == 1) { // DIGI + WX
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_c2();
}
else {
pwr_save_switch_mode_to_c1();
}
}
else { // WX
if (minutes_to_wx > 1) {
// if there is more than one minute to send wx packet
pwr_save_switch_mode_to_m4();
}
else {
if (pwr_save_seconds_to_wx <= 30) {
pwr_save_switch_mode_to_c1();
}
}
}
}
}
else { // DIGI
pwr_save_switch_mode_to_c2();
}
break;
}
case PWSAVE_AGGRESV : {
// if weather station is enabled
if (config->wx == 1) {
// if GSM modem is enabled in configuration
if (config->gsm == 1) {
// if digipeater is enabled
if (config->digi == 1) { // DIGI + WX + GSM
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_c2();
}
else {
pwr_save_switch_mode_to_c0();
}
}
else { // WX + GSM (only)
if (timers->wx_transmit_period > 5) {
// if stations is configured to send wx packet less often than every 5 minutes
if (minutes_to_wx > 1) {
// if there is more than one minute to wx packet
pwr_save_switch_mode_to_l7((timers->wx_transmit_period * 60) - 60); // TODO: !!!
}
else {
if (pwr_save_seconds_to_wx <= 30) {
// if there is 30 seconds or less to next wx packet
pwr_save_switch_mode_to_c0();
}
else {
// if there is 30 to 60 seconds to next wx packet
pwr_save_switch_mode_to_m4();
}
}
}
else {
// if station is configured to sent wx packet in every 5 minutes or more often
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_l6((timers->wx_transmit_period * 60) - 60); // TODO: !!!
}
else {
pwr_save_switch_mode_to_c0();
}
}
}
}
else {
// if digipeater is enabled
if (config->digi == 1) { // DIGI + WX
if (minutes_to_wx > 1) {
pwr_save_switch_mode_to_c2();
}
else {
pwr_save_switch_mode_to_c1();
}
}
else { // WX
if (minutes_to_wx > 1) {
// if there is more than one minute to send wx packet
pwr_save_switch_mode_to_m4();
}
else {
if (pwr_save_seconds_to_wx <= 30) {
pwr_save_switch_mode_to_c1();
}
}
}
}
}
else { // DIGI
pwr_save_switch_mode_to_c2();
}
break;
}
}
}
#endif

Wyświetl plik

@ -1,4 +1,4 @@
#include <drivers/gpio_conf_stm32f1x.h>
#include <drivers/f1/gpio_conf_stm32f1x.h>
void Configure_GPIO(GPIO_TypeDef* gpio, uint8_t pin, uint8_t conf){
volatile uint32_t *crPointer;

Wyświetl plik

@ -1,4 +1,4 @@
#include <drivers/gpio_conf_stm32f1x.h>
#include <drivers/f1/gpio_conf_stm32f1x.h>
#include "drivers/i2c.h"
#include <stm32f10x.h>