diff --git a/.cproject b/.cproject
index ce43bdd..562bd93 100644
--- a/.cproject
+++ b/.cproject
@@ -298,7 +298,7 @@
-
+
@@ -415,6 +415,7 @@
+
@@ -492,6 +493,7 @@
+
diff --git a/STM32L476_ParaMETEO/makefile b/STM32L476_ParaMETEO/makefile
index f218faa..6ce8032 100644
--- a/STM32L476_ParaMETEO/makefile
+++ b/STM32L476_ParaMETEO/makefile
@@ -74,6 +74,9 @@ BUILD_ARTIFACT := $(BUILD_ARTIFACT_PREFIX)$(BUILD_ARTIFACT_NAME)$(if $(BUILD_ART
SECONDARY_FLASH += \
ParaTNC.hex \
+SECONDARY_LIST += \
+ParaTNC.lst \
+
SECONDARY_SIZE += \
ParaTNC.siz \
@@ -98,6 +101,12 @@ ParaTNC.hex: ParaTNC.elf makefile objects.mk $(OPTIONAL_TOOL_DEPS)
@echo 'Finished building: $@'
@echo ' '
+ParaTNC.lst: ParaTNC.elf makefile objects.mk $(OPTIONAL_TOOL_DEPS)
+ @echo 'Invoking: Cross ARM GNU Create Listing'
+ arm-none-eabi-objdump --source --all-headers --demangle --line-numbers --wide "ParaTNC.elf" > "ParaTNC.lst"
+ @echo 'Finished building: $@'
+ @echo ' '
+
ParaTNC.siz: ParaTNC.elf makefile objects.mk $(OPTIONAL_TOOL_DEPS)
@echo 'Invoking: Cross ARM GNU Print Size'
arm-none-eabi-size --format=berkeley "ParaTNC.elf"
@@ -106,10 +115,10 @@ ParaTNC.siz: ParaTNC.elf makefile objects.mk $(OPTIONAL_TOOL_DEPS)
# Other Targets
clean:
- -$(RM) $(CC_DEPS)$(C++_DEPS)$(OBJS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS) ParaTNC.elf
+ -$(RM) $(CC_DEPS)$(C++_DEPS)$(OBJS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_LIST)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS) ParaTNC.elf
-@echo ' '
-secondary-outputs: $(SECONDARY_FLASH) $(SECONDARY_SIZE)
+secondary-outputs: $(SECONDARY_FLASH) $(SECONDARY_LIST) $(SECONDARY_SIZE)
.PHONY: all clean dependents main-build
diff --git a/STM32L476_ParaMETEO/sources.mk b/STM32L476_ParaMETEO/sources.mk
index 581599e..65695bf 100644
--- a/STM32L476_ParaMETEO/sources.mk
+++ b/STM32L476_ParaMETEO/sources.mk
@@ -19,6 +19,7 @@ OBJS :=
C_UPPER_DEPS :=
CXX_DEPS :=
SECONDARY_FLASH :=
+SECONDARY_LIST :=
SECONDARY_SIZE :=
ASM_DEPS :=
S_UPPER_DEPS :=
diff --git a/include/aprsis.h b/include/aprsis.h
index cae8e0f..58011f0 100644
--- a/include/aprsis.h
+++ b/include/aprsis.h
@@ -51,6 +51,7 @@ aprsis_return_t aprsis_connect_and_login_default(uint8_t auto_send_beacon);
sim800_return_t aprsis_disconnect(void);
void aprsis_receive_callback(srl_context_t* srl_context);
void aprsis_check_alive(void);
+int aprsis_check_connection_attempt_alive(void);
void aprsis_send_wx_frame(uint16_t windspeed,
uint16_t windgusts,
diff --git a/include/main.h b/include/main.h
index bc962eb..8c0f77d 100644
--- a/include/main.h
+++ b/include/main.h
@@ -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
diff --git a/include/pwr_save.h b/include/pwr_save.h
index 5283569..7b926af 100644
--- a/include/pwr_save.h
+++ b/include/pwr_save.h
@@ -123,6 +123,7 @@ void pwr_save_switch_mode_to_l6(uint16_t sleep_time);
void pwr_save_switch_mode_to_l7(uint16_t sleep_time);
config_data_powersave_mode_t pwr_save_pooling_handler(const config_data_mode_t * config, const config_data_basic_t * timers, int16_t minutes_to_wx, uint16_t vbatt); // this should be called from 10 seconds pooler
+int pwr_save_is_currently_cutoff(void);
#endif
uint8_t pwr_save_get_inhibit_pwr_switch_periodic(void);
diff --git a/src/aprsis.c b/src/aprsis.c
index 6eef072..8624afa 100644
--- a/src/aprsis.c
+++ b/src/aprsis.c
@@ -134,11 +134,24 @@ static uint16_t aprsis_another_received_counter = 0;
*/
static uint32_t aprsis_last_keepalive_ts = 0;
+/**
+ * This is the second timestamp of last keepalive message
+ * from APRS-IS server. It is used by 'aprsis_check_connection_attempt_alive'
+ * and not incremented anywhere except receive callback. Where a timeout
+ * calculated using this value is too long the controller is restarted.
+ */
+static uint32_t aprsis_last_keepalive_long_ts = 0;
+
/**
* A timestamp when any packet has been sent to
*/
static uint32_t aprsis_last_packet_transmit_ts = 0;
+/**
+ *
+ */
+static uint32_t aprsis_last_packet_transmit_long_ts = 0;
+
/**
* Only for debugging purposes
*/
@@ -280,6 +293,8 @@ aprsis_return_t aprsis_connect_and_login(const char * address, uint8_t address_l
// set current timestamp as last
aprsis_last_keepalive_ts = master_time;
+ aprsis_last_keepalive_long_ts = aprsis_last_keepalive_ts;
+
if (auto_send_beacon != 0) {
aprsis_send_beacon(0, aprsis_callsign_with_ssid, main_string_latitude, main_symbol_f, main_string_longitude, main_symbol_s, main_config_data_basic);
}
@@ -372,6 +387,8 @@ void aprsis_receive_callback(srl_context_t* srl_context) {
if (*(srl_get_rx_buffer(srl_context)) == '#') {
aprsis_last_keepalive_ts = main_get_master_time();
+ aprsis_last_keepalive_long_ts = main_get_master_time();
+
aprsis_keepalive_received_counter++;
gsm_sim800_tcpip_async_receive(aprsis_serial_port, aprsis_gsm_modem_state, 0, 61000, aprsis_receive_callback);
@@ -439,6 +456,30 @@ void aprsis_check_alive(void) {
}
}
+/**
+ * This is another alive check which is fully independent from
+ * if the connection has been even already established and how many times
+ * it waas. The intention here is to reset the whole controller if
+ * for some reason APRS-++IS connection cannot be established for very long time
+ * @return
+ */
+int aprsis_check_connection_attempt_alive(void) {
+
+ int out = 0;
+
+ const uint32_t timestamp = main_get_master_time();
+
+ if (timestamp > (aprsis_last_keepalive_long_ts + APRSIS_TIMEOUT_MS * 6)) {
+ out = 1;
+ }
+
+ if (timestamp > (aprsis_last_packet_transmit_long_ts + APRSIS_TIMEOUT_MS * 6 )) {
+ out = 1;
+ }
+
+ return out;
+}
+
/**
*
* @param windspeed
@@ -522,6 +563,8 @@ void aprsis_send_wx_frame(
aprsis_last_packet_transmit_ts = main_get_master_time();
+ aprsis_last_packet_transmit_long_ts = main_get_master_time();
+
gsm_sim800_tcpip_async_write((uint8_t *)aprsis_packet_tx_buffer, aprsis_packet_tx_message_size, aprsis_serial_port, aprsis_gsm_modem_state);
}
diff --git a/src/main.c b/src/main.c
index cd5fd34..24552f7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1425,6 +1425,17 @@ int main(int argc, char* argv[]){
}
}
+
+ if (main_config_data_gsm->aprsis_enable != 0) {
+
+ if (pwr_save_is_currently_cutoff() == 0) {
+ const int i_am_ok_with_aprsis = aprsis_check_connection_attempt_alive();
+
+ if (i_am_ok_with_aprsis != 0) {
+ NVIC_SystemReset();
+ }
+ }
+ }
#endif
main_one_minute_pool_timer = 60000;
diff --git a/src/pwr_save.c b/src/pwr_save.c
index 6e772e4..d960d65 100644
--- a/src/pwr_save.c
+++ b/src/pwr_save.c
@@ -1168,6 +1168,16 @@ config_data_powersave_mode_t pwr_save_pooling_handler(const config_data_mode_t *
return psave_mode;
}
+int pwr_save_is_currently_cutoff(void) {
+ int out = 0;
+
+ if ((pwr_save_currently_cutoff & CURRENTLY_CUTOFF) != 0) {
+ out = 1;
+ }
+
+ return out;
+}
+
uint8_t pwr_save_get_inhibit_pwr_switch_periodic(void) {
if ((REGISTER & INHIBIT_PWR_SWITCH_PERIODIC_H) != 0){