stroring and loading packet counters from backup registers

master
Mateusz Lubecki 2023-10-24 22:01:40 +02:00
rodzic 973fbd46e6
commit 09b6dda9d0
11 zmienionych plików z 372 dodań i 52 usunięć

Wyświetl plik

@ -26,6 +26,7 @@ C_SRCS += \
../src/rte_rtu.c \
../src/rte_wx.c \
../src/software_version.c \
../src/variant_parameteo.c \
../src/wx_handler.c \
../src/wx_handler_humidity.c \
../src/wx_handler_pressure.c \
@ -55,6 +56,7 @@ OBJS += \
./src/rte_rtu.o \
./src/rte_wx.o \
./src/software_version.o \
./src/variant_parameteo.o \
./src/wx_handler.o \
./src/wx_handler_humidity.o \
./src/wx_handler_pressure.o \
@ -84,6 +86,7 @@ C_DEPS += \
./src/rte_rtu.d \
./src/rte_wx.d \
./src/software_version.d \
./src/variant_parameteo.d \
./src/wx_handler.d \
./src/wx_handler_humidity.d \
./src/wx_handler_pressure.d \

Wyświetl plik

@ -16,23 +16,6 @@
#include <stm32f10x.h>
#endif
// backup registers (ParaTNC)
// 0 ->
// 2 -> boot and hard fault count
// 3 -> controller configuration status
// 4 ->
// 5 ->
// 6 -> weather and telemetry timers & counters
// backup registers (ParaMETEO)
// 0 -> powersave status - not handled here
// 1 -> last sleep rtc time
// 2 -> last wakeup rtc time
// 3 -> controller configuration status
// 4 -> wakeup events MSB, sleep events LSB
// 5 -> monitor
// 7 -> weather and telemetry timers & counters
#define REGISTER_MONITOR RTC->BKP5R
/**
@ -90,9 +73,13 @@ uint32_t backup_reg_is_periodic_pwr_switch_inhibited(void);
uint32_t backup_reg_get_last_sleep_duration(void);
void backup_reg_set_last_sleep_duration(uint32_t);
uint8_t backup_reg_get_telemetry(void);
void backup_reg_set_telemetry(void);
void backup_reg_reset_counters(void);
uint8_t backup_reg_get_telemetry(void);
void backup_reg_set_telemetry(uint8_t);
void backup_reg_get_packet_counters(uint8_t * beacon_counter, uint8_t * meteo_counter, uint8_t * meteo_gsm_counter);
void backup_reg_set_packet_counters(uint8_t beacon_counter, uint8_t meteo_counter, uint8_t meteo_gsm_counter);

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

@ -21,7 +21,7 @@ typedef struct packet_tx_counter_values_t {
} packet_tx_counter_values_t;
void packet_tx_send_wx_frame(void);
void packet_tx_configure(uint8_t meteo_interval, uint8_t beacon_interval, config_data_powersave_mode_t powersave);
void packet_tx_init(uint8_t meteo_interval, uint8_t beacon_interval, config_data_powersave_mode_t powersave);
void packet_tx_restore_from_backupregs(void);
void packet_tx_tcp_handler(void);
void packet_tx_handler(const config_data_basic_t * const config_basic, const config_data_mode_t * const config_mode);

17
include/variant.h 100644
Wyświetl plik

@ -0,0 +1,17 @@
/*
* variant.h
*
* Created on: Oct 24, 2023
* Author: mateusz
*/
#ifndef VARIANT_H_
#define VARIANT_H_
#include "stdint.h"
int variant_validate_is_within_ram(uint32_t address);
#endif /* VARIANT_H_ */

Wyświetl plik

@ -7,17 +7,46 @@
#include "backup_registers.h"
#include "variant.h"
#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_LAST_SLTIM RTC->BKP6R
#define REGISTER RTC->BKP0R
#define REGISTER_LAST_SLEEP RTC->BKP1R
#define REGISTER_LAST_WKUP RTC->BKP2R
#define REGISTER_COUNTERS RTC->BKP4R
#define REGISTER_LAST_SLTIM RTC->BKP6R
#define REGISTER_PACKET_COUNTERS RTC->BKP7R
#endif
#define BACKUP_REG_INHIBIT_PWR_SWITCH_PERIODIC_H 1u
#define BACKUP_REG_ALL_PWRSAVE_STATES_BITMASK (0xFFu << 2)
// backup registers (ParaTNC)
// 0 ->
// 2 -> boot and hard fault count
// 3 -> controller configuration status
// 4 -> telemetry counter
// 5 ->
// 6 -> weather counters
// 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
// 5 -> monitor
// 6 -> last sleep time
// 7 -> weather and telemetry timers & counters
// 7th register map
// xxxxyyAA - telemetry frames counter
// xxxxyAyy - value of packet_tx_meteo_counter limited to 15
// xxxxAyyy - value of packet_tx_meteo_gsm_counter limited to 15
// xxAAyyyy - value of packet_tx_beacon_counter
// Axxxyyyy - checksum
static void backup_reg_unclock(void) {
// enable access to backup domain
PWR->CR1 |= PWR_CR1_DBP;
@ -28,7 +57,54 @@ static void backup_reg_lock(void) {
}
/**
*
* Calculates checksum from register content
* @param reg
* @return
*/
inline static uint8_t backup_reg_calculate_checksum(uint32_t reg) {
uint8_t out = 0u;
uint32_t temp = 0u;
temp += (reg & 0xFu);
temp += ((reg & 0xF0u) >> 4);
temp += ((reg & 0xF00u) >> 8);
temp += ((reg & 0xF000u) >> 12);
temp += ((reg & 0xF0000u) >> 16);
temp += ((reg & 0xF00000u) >> 20);
temp += ((reg & 0xF000000u) >> 24);
temp = ~temp;
out = (temp & 0xFu);
return out;
}
inline static uint8_t backup_reg_get_checksum(uint32_t reg) {
uint8_t out = 0u;
out = ((reg & 0xF0000000u) >> 28);
return out;
}
inline static void backup_reg_set_checksum(volatile uint32_t * reg, const uint8_t checksum) {
if (variant_validate_is_within_ram((const uint32_t)reg) != 0) {
// clear existing checksum
(*reg) &= (0xFFFFFFFF ^ 0xF0000000);
// store new checksum
(*reg) |= ((checksum & 0xF) << 28);
}
}
/**
* Get the value of a register keeping a status which configuration
* sector is valid, and which is loaded
* @return
*/
uint32_t backup_reg_get_configuration(void) {
@ -47,20 +123,32 @@ uint32_t backup_reg_get_configuration(void) {
return out;
}
/**
* Set a register, which contains an information which configuration sector
* is valid, and which one has been loaded. It is mostly used to reset
* the register back to zero.
* @param value
*/
void backup_reg_set_configuration(uint32_t value) {
backup_reg_unclock();
#ifdef PARATNC
BKP->DR3 = value;
#endif
#ifdef PARAMETEO
backup_reg_unclock();
RTC->BKP3R = value;
#endif
backup_reg_lock();
#endif
}
/**
* Set certain bit in the register containing current configuration state.
* This is used to store a state of all configuration sectors.
* @param value
*/
void backup_reg_set_bits_configuration(uint32_t value) {
#ifdef PARATNC
BKP->DR3 |= value;
@ -77,24 +165,30 @@ void backup_reg_set_bits_configuration(uint32_t value) {
#endif
}
/**
* Clears certain bit in the register containing current configuration state.
* This is used to keep information that CRC checksum of a sector is no longer
* valid.
* @param value
*/
void backup_reg_clear_bits_configuration(uint32_t value) {
// enable access to backup domain
backup_reg_unclock();
#ifdef PARATNC
BKP->DR3 &= (0xFFFF ^ value);
#endif
#ifdef PARAMETEO
// enable access to backup domain
backup_reg_unclock();
RTC->BKP3R &= (0xFFFFFFFFu ^ value);
#endif
backup_reg_lock();
#endif
}
/**
*
* Resets all powersave mode flags.
*/
void backup_reg_reset_all_powersave_states(void) {
@ -108,6 +202,12 @@ void backup_reg_reset_all_powersave_states(void) {
}
/**
* Checks if controller is currently in given powersave mode using
* information from dedicated backup register
* @param state
* @return one if controller is in given powersave state
*/
int backup_reg_is_in_powersave_state(uint32_t state) {
int out = 0;
#ifdef PARAMETEO
@ -119,6 +219,11 @@ int backup_reg_is_in_powersave_state(uint32_t state) {
return out;
}
/**
* Set that controller is currently in given powersave state, it should be
* used along with \link #backup_reg_reset_all_powersave_states
* @param state
*/
void backup_reg_set_powersave_state(uint32_t state) {
#ifdef PARAMETEO
backup_reg_unclock();
@ -129,6 +234,10 @@ void backup_reg_set_powersave_state(uint32_t state) {
#endif
}
/**
* Returns current powersave state
* @return
*/
uint16_t backup_reg_get_powersave_state(void) {
int out = 0;
@ -140,7 +249,7 @@ uint16_t backup_reg_get_powersave_state(void) {
}
/**
*
* Return counter value with current number of wakeup events
* @return
*/
uint32_t backup_reg_get_wakeup_counter(void) {
@ -154,6 +263,10 @@ uint32_t backup_reg_get_wakeup_counter(void) {
return out;
}
/**
* Set current value of wakeup events
* @param in
*/
void backup_reg_set_wakeup_counter(uint32_t in) {
backup_reg_unclock();
@ -165,7 +278,7 @@ void backup_reg_set_wakeup_counter(uint32_t in) {
}
/**
*
* Return counter value with current number of sleep events
* @return
*/
uint32_t backup_reg_get_sleep_counter(void) {
@ -178,6 +291,10 @@ uint32_t backup_reg_get_sleep_counter(void) {
return out;
}
/**
* Set current value of sleep events
* @param in
*/
void backup_reg_set_sleep_counter(uint32_t in) {
backup_reg_unclock();
@ -190,7 +307,7 @@ void backup_reg_set_sleep_counter(uint32_t in) {
/**
*
* Returns a timestamp of last sleep event
*/
uint32_t backup_reg_get_last_sleep_timestamp(void) {
@ -203,6 +320,9 @@ uint32_t backup_reg_get_last_sleep_timestamp(void) {
return out;
}
/**
* Stores a timestamp of a sleep event from current RTC time
*/
void backup_reg_set_last_sleep_timestamp(void) {
#ifdef PARAMETEO
@ -216,9 +336,9 @@ void backup_reg_set_last_sleep_timestamp(void) {
}
/**
*
* Disables an inhibition of VBATT_S switching, when controller is in
* powersave mode in which weather sensors shall be kept powered down.
*/
void backup_reg_reset_inhibit_periodic_pwr_switch(void) {
backup_reg_unclock();
@ -229,6 +349,10 @@ void backup_reg_reset_inhibit_periodic_pwr_switch(void) {
backup_reg_lock();
}
/**
* Enables an inhibition of VBATT_S switching, when controller is in
* powersave mode in which weather sensors shall be kept powered down.
*/
void backup_reg_inhibit_periodic_pwr_switch(void) {
backup_reg_unclock();
@ -240,6 +364,10 @@ void backup_reg_inhibit_periodic_pwr_switch(void) {
}
/**
* Returns if VBATT_S switching inhibition is currently enabled
* @return
*/
uint32_t backup_reg_is_periodic_pwr_switch_inhibited(void) {
int out = 0;
@ -253,7 +381,7 @@ uint32_t backup_reg_is_periodic_pwr_switch_inhibited(void) {
}
/**
*
* gets last wakeup timestamp
* @return
*/
uint32_t backup_reg_get_last_wakeup_timestamp(void) {
@ -265,6 +393,9 @@ uint32_t backup_reg_get_last_wakeup_timestamp(void) {
return out;
}
/**
* Stores a timestamp of a wakeup event from current RTC time
*/
void backup_reg_set_last_wakeup_timestamp(void) {
#ifdef PARAMETEO
@ -301,3 +432,137 @@ void backup_reg_set_last_sleep_duration(uint32_t in) {
#endif
}
/**
* Set register containing packet counters, used when a configuration
* is reset to default
*/
void backup_reg_reset_counters(void) {
#ifdef PARAMETEO
backup_reg_unclock();
REGISTER_PACKET_COUNTERS = 0u;
backup_reg_lock();
#endif
}
/**
* Gets last telemetry frames counter stored in backup registers
* @return last telemetry counter or zero if backup registers contains crap
*/
uint8_t backup_reg_get_telemetry(void) {
uint8_t out = 0u;
#ifdef PARAMETEO
uint32_t reg_value = REGISTER_PACKET_COUNTERS;
// calculate checksum from register value
uint8_t calculated_checksum = backup_reg_calculate_checksum(reg_value);
uint8_t checksum_from_reg = backup_reg_get_checksum(reg_value);
// check if checksum is ok
if (calculated_checksum == checksum_from_reg) {
out = (uint8_t)(reg_value & 0xFFu);
}
else {
; // return zero if checksum is wrong
}
#endif
return out;
}
/**
*
*/
void backup_reg_set_telemetry(uint8_t in) {
backup_reg_unclock();
#ifdef PARAMETEO
// get current value
uint32_t reg_value = REGISTER_PACKET_COUNTERS;
// clear current telemetry counter using the bitmask
reg_value &= (0xFFFFFFFFu ^ 0xFFu);
// store updated value
reg_value |= in;
// recalculate checksum
const uint8_t new_checksum = backup_reg_calculate_checksum(reg_value);
// store new checksum
backup_reg_set_checksum(&reg_value, new_checksum);
REGISTER_PACKET_COUNTERS = reg_value;
#endif
backup_reg_lock();
}
void backup_reg_get_packet_counters(uint8_t * beacon_counter, uint8_t * meteo_counter, uint8_t * meteo_gsm_counter) {
#ifdef PARAMETEO
uint32_t reg_value = REGISTER_PACKET_COUNTERS;
// calculate checksum from register value
uint8_t calculated_checksum = backup_reg_calculate_checksum(reg_value);
uint8_t checksum_from_reg = backup_reg_get_checksum(reg_value);
// check if checksum is ok
if (calculated_checksum == checksum_from_reg) {
*meteo_counter = ((reg_value & 0x00000F00u) >> 8);
*meteo_gsm_counter = ((reg_value & 0x0000F000u) >> 12);
*beacon_counter = ((reg_value & 0x00FF0000u) >> 16);
}
else {
// if it is not ok revert to default values
*beacon_counter = 0u;
*meteo_counter = 2u;
*meteo_gsm_counter = 0u;
// and save it back into backup register
backup_reg_set_packet_counters(*beacon_counter, *meteo_counter, *meteo_gsm_counter);
}
#endif
}
void backup_reg_set_packet_counters(uint8_t beacon_counter, uint8_t meteo_counter, uint8_t meteo_gsm_counter) {
#ifdef PARAMETEO
volatile uint32_t reg_value = REGISTER_PACKET_COUNTERS;
// clear existing content
reg_value &= (0xFFFFFFFFu ^ 0x00FFFF00u);
// check if meteo_counter doesn't overflow
if (meteo_counter > 15) {
meteo_counter = 15;
}
if (meteo_gsm_counter > 15) {
meteo_gsm_counter = 15;
}
// put new values
reg_value |= ((beacon_counter << 16) | (meteo_gsm_counter << 12) | (meteo_counter << 8));
// calculate new checksum
const uint8_t new_checksum = backup_reg_calculate_checksum(reg_value);
// put new checksum value
backup_reg_set_checksum(&reg_value, new_checksum);
backup_reg_unclock();
REGISTER_PACKET_COUNTERS = reg_value;
backup_reg_lock();
#endif
}

Wyświetl plik

@ -408,6 +408,8 @@ int main(int argc, char* argv[]){
if (main_reset_config_to_default == 1) {
main_crc_result = 0;
backup_reg_reset_counters();
backup_reg_set_configuration(0);
#if defined(PARAMETEO)
@ -428,6 +430,9 @@ int main(int argc, char* argv[]){
// set also CRC flag because if restoring is successfull the region has good CRC
backup_reg_set_bits_configuration(CONFIG_FIRST_CRC_OK);
// additionally resets packet counters stored in backup registers
backup_reg_reset_counters();
}
else {
// if not store the flag in the backup register to block
@ -461,6 +466,9 @@ int main(int argc, char* argv[]){
// set also CRC flag as if restoring is successfull the region has good CRC
backup_reg_set_bits_configuration(CONFIG_SECOND_CRC_OK);
// additionally resets packet counters stored in backup registers
backup_reg_reset_counters();
}
else {
// if not store the flag in the backup register
@ -513,7 +521,10 @@ int main(int argc, char* argv[]){
main_button_two_right = configuration_get_right_button();
// set packets intervals
packet_tx_configure(main_config_data_basic->wx_transmit_period, main_config_data_basic->beacon_transmit_period, main_config_data_mode->powersave);
packet_tx_init(main_config_data_basic->wx_transmit_period, main_config_data_basic->beacon_transmit_period, main_config_data_mode->powersave);
// initialie telemetry frames counter
telemetry_init();
#if defined(STM32F10X_MD_VL)
// disabling access to BKP registers

Wyświetl plik

@ -42,7 +42,7 @@ uint8_t packet_tx_error_status_interval = 2;
uint8_t packet_tx_error_status_counter = 0;
uint8_t packet_tx_meteo_interval = 0;
uint8_t packet_tx_meteo_counter = 2;
uint8_t packet_tx_meteo_counter = 0;
uint8_t packet_tx_meteo_kiss_interval = 2;
uint8_t packet_tx_meteo_kiss_counter = 0;
@ -82,14 +82,20 @@ void packet_tx_send_wx_frame(void) {
}
void packet_tx_configure(uint8_t meteo_interval, uint8_t beacon_interval, config_data_powersave_mode_t powersave) {
void packet_tx_init(uint8_t meteo_interval, uint8_t beacon_interval, config_data_powersave_mode_t powersave) {
packet_tx_meteo_interval = meteo_interval;
packet_tx_beacon_interval = beacon_interval;
// if user selected aggressive powersave mode the meteo counter must be set back to zero
// to prevent quirks with waking from sleep mode
packet_tx_meteo_counter = 0;
backup_reg_get_packet_counters(&packet_tx_beacon_counter, &packet_tx_meteo_counter, &packet_tx_meteo_gsm_counter);
if (powersave == PWSAVE_AGGRESV) {
// if user selected aggressive powersave mode the meteo counter must be set back to zero
// to prevent quirks with waking from sleep mode
packet_tx_meteo_counter = 0;
}
}
@ -559,6 +565,9 @@ void packet_tx_handler(const config_data_basic_t * const config_basic, const con
packet_tx_telemetry_descr_counter = 0;
}
// store counters in backup registers
backup_reg_set_packet_counters(packet_tx_beacon_counter, packet_tx_meteo_counter, packet_tx_meteo_gsm_counter);
#ifdef STM32L471xx
// if powersave mode allow to sent extensive status messages
if (rte_main_curret_powersave_mode != PWSAVE_AGGRESV) {

Wyświetl plik

@ -0,0 +1,17 @@
/*
* variant.c
*
* Created on: Oct 24, 2023
* Author: mateusz
*/
#include "variant.h"
int variant_validate_is_within_ram(uint32_t address) {
if (address != 0x00) {
return 1;
}
else {
return 0;
}
}

Wyświetl plik

@ -45,6 +45,8 @@ typedef enum wind_qf {
WIND_QF_DEGRADATED = 3
}wind_qf_t;
void telemetry_init(void);
#ifdef __cplusplus
extern "C"
{
@ -62,7 +64,7 @@ void telemetry_send_values_pv ( uint8_t rx_pkts,
void telemetry_send_chns_description_pv(const config_data_basic_t * const config_basic);
void telemetry_send_status_pv(ve_direct_average_struct* avg, ve_direct_error_reason* last_error, ve_direct_system_state state, uint32_t master_time, uint16_t messages_count, uint16_t corrupted_messages_count);
#ifdef STM32L471xx
#ifdef PARAMETEO
void telemetry_send_values( uint8_t rx_pkts,
uint8_t tx_pkts,
uint8_t digi_pkts,

Wyświetl plik

@ -8,6 +8,7 @@
#include "aprs/telemetry.h"
#include "main.h"
#include "delay.h"
#include "backup_registers.h"
#include "ve_direct_protocol/parser.h"
@ -19,6 +20,10 @@
uint16_t telemetry_counter = 0;
void telemetry_init(void) {
telemetry_counter = backup_reg_get_telemetry();
}
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
@ -205,7 +210,7 @@ void telemetry_send_chns_description(const config_data_basic_t * const config_ba
// clear the output frame buffer
memset(main_own_aprs_msg, 0x00, sizeof(main_own_aprs_msg));
#ifdef STM32L471xx
#ifdef PARAMETEO
if (config_mode->digi_viscous == 0) {
// prepare a frame with channel names depending on SSID
if (config_basic->ssid == 0)
@ -269,7 +274,7 @@ void telemetry_send_chns_description(const config_data_basic_t * const config_ba
WAIT_FOR_CHANNEL_FREE();
#ifdef STM32L471xx
#ifdef PARAMETEO
if (config_basic->ssid == 0)
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, ":%-6s :EQNS.0,1,0,0,1,0,0,1,0,0,0.02,10,0,0.5,-50", config_basic->callsign);
else if (config_basic->ssid > 0 && config_basic->ssid < 10)
@ -300,7 +305,7 @@ void telemetry_send_chns_description(const config_data_basic_t * const config_ba
WAIT_FOR_CHANNEL_FREE();
#ifdef STM32L471xx
#ifdef PARAMETEO
if (config_basic->ssid == 0)
main_own_aprs_msg_len = sprintf(main_own_aprs_msg, ":%-6s :UNIT.Pkt,Pkt,Pkt,V,DegC,Hi,Hi,Hi,Hi,Hi,Hi,Hi,Hi", config_basic->callsign);
else if (config_basic->ssid > 0 && config_basic->ssid < 10)
@ -502,8 +507,12 @@ void telemetry_send_values( uint8_t rx_pkts,
#endif
// reset the frame counter if it overflowed
if (telemetry_counter > 999)
if (telemetry_counter > 255) {
telemetry_counter = 0;
}
// store telemetry conter in backup register
backup_reg_set_telemetry((uint8_t)(telemetry_counter & 0xFFu));
// put a null terminator at the end of frame (but it should be placed there anyway)
main_own_aprs_msg[main_own_aprs_msg_len] = 0;