- Move push button handling to seaparate *.c and *.h files

- Store SIM card and gsm network registration status in dedicated enums
- Power cycle and reset GPRS modem if there is SIM card failure or its not able to register to network
- Put aprsis connect function in a one second pooler
- Optionally power cycle and reset GPRS modem if there is a timeout while TCP connection to APRS-IS is established.
master
Mateusz Lubecki 2023-06-10 17:51:41 +02:00
rodzic 6b9f965466
commit 83526ea506
27 zmienionych plików z 505 dodań i 92 usunięć

Wyświetl plik

@ -10,6 +10,7 @@ C_SRCS += \
../src/_write.c \
../src/api.c \
../src/aprsis.c \
../src/button_parameteo.c \
../src/config_data_default.c \
../src/config_data_first.c \
../src/config_data_second.c \
@ -43,6 +44,7 @@ OBJS += \
./src/_write.o \
./src/api.o \
./src/aprsis.o \
./src/button_parameteo.o \
./src/config_data_default.o \
./src/config_data_first.o \
./src/config_data_second.o \
@ -76,6 +78,7 @@ C_DEPS += \
./src/_write.d \
./src/api.d \
./src/aprsis.d \
./src/button_parameteo.d \
./src/config_data_default.d \
./src/config_data_first.d \
./src/config_data_second.d \

Wyświetl plik

@ -57,7 +57,7 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;&gt;&#10; &lt;memoryBlockExpression address=&quot;134342656&quot; label=&quot;0x0801E800&quot;/&gt;&#10;&lt;/memoryBlockExpressionList&gt;&#10;"/>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;&gt;&#10; &lt;memoryBlockExpression address=&quot;134342656&quot; label=&quot;0x0801E800&quot;/&gt;&#10; &lt;memoryBlockExpression address=&quot;536873000&quot; label=&quot;srl_usart3_rx_buffer&quot;/&gt;&#10;&lt;/memoryBlockExpressionList&gt;&#10;"/>
<stringAttribute key="org.eclipse.embedcdt.debug.gdbjtag.core.PERIPHERALS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;peripherals&gt;&#10; &lt;peripheral name=&quot;GPIOA&quot;/&gt;&#10; &lt;peripheral name=&quot;USART2&quot;/&gt;&#10;&lt;/peripherals&gt;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
</launchConfiguration>

Wyświetl plik

@ -23,7 +23,19 @@ typedef enum aprsis_return {
extern uint8_t aprsis_connected;
void aprsis_init(srl_context_t * context, gsm_sim800_state_t * gsm_modem_state, char * callsign, uint8_t ssid, uint32_t passcode, char * default_server, uint16_t default_port);
/**
* Initialize APRS-IS client
* @param context
* @param gsm_modem_state
* @param callsign
* @param ssid
* @param passcode
* @param default_server
* @param default_port
* @param reset_on_timeout Set to one to reset GSM module in case of APRS-IS
* instead of only reconnecting
*/
void aprsis_init(srl_context_t * context, gsm_sim800_state_t * gsm_modem_state, char * callsign, uint8_t ssid, uint32_t passcode, char * default_server, uint16_t default_port, uint8_t reset_on_timeout);
aprsis_return_t aprsis_connect_and_login(const char * address, uint8_t address_ln, uint16_t port, uint8_t auto_send_beacon);
aprsis_return_t aprsis_connect_and_login_default(uint8_t auto_send_beacon);
void aprsis_disconnect(void);

29
include/button.h 100644
Wyświetl plik

@ -0,0 +1,29 @@
/*
* button.h
*
* Handles presses of buttons on ParaTNC or ParaMETEO pcb. IO pins
* initialization is implemented in io.c and io.h
*
* Created on: Jun 10, 2023
* Author: mateusz
*/
#ifndef BUTTON_H_
#define BUTTON_H_
#include "config_data.h"
/**
* Should be called from main for loop or in quite short interval, like
* 10 to 100 milliseconds. It reads a state of input pins coming from
* connected push buttons and then, depending on configuration, takes
* an appropriate action.
*/
void button_check_all(config_data_basic_t * config);
/**
* Resets debouncing inhibiter which enables button key presses back
*/
void button_debounce(void);
#endif /* BUTTON_H_ */

Wyświetl plik

@ -35,6 +35,16 @@ typedef enum config_data_powersave_mode_t {
}config_data_powersave_mode_t;
typedef enum config_data_button_function_t {
BUTTON_SEND_WX = 1,
BUTTON_SEND_WX_INTERNET = 2,
BUTTON_SEND_BEACON = 3,
BUTTON_FORCE_UART_KISS = 4,
BUTTON_FORCE_UART_LOG = 5,
BUTTON_RESET_GSM_GPRS = 6
}config_data_button_function_t;
typedef struct __attribute__((aligned (4))) config_data_mode_t {
#define WX_ENABLED (1)
@ -96,9 +106,10 @@ typedef struct __attribute__((aligned (4))) config_data_mode_t {
typedef struct __attribute__((aligned (4))) config_data_basic_t {
#define ENGINEERING1 (1)
#define ENGINEERING1_INH_WX_PWR_HNDL (1 << 1)
#define ENGINEERING1_EARLY_TX_ASSERT (1 << 2)
#define ENGINEERING1 (1)
#define ENGINEERING1_INH_WX_PWR_HNDL (1 << 1)
#define ENGINEERING1_EARLY_TX_ASSERT (1 << 2)
#define ENGINEERING1_PWRCYCLE_GSM_ON_NOCOMM (1 << 2)
#define ENGINEERING2 (1)
#define ENGINEERING2_REBOOT_AFTER_24 (1 << 1)
@ -168,6 +179,10 @@ typedef struct __attribute__((aligned (4))) config_data_basic_t {
uint16_t battery_scalling_b;
config_data_button_function_t button_one;
config_data_button_function_t button_two;
} config_data_basic_t;
typedef enum config_data_wx_sources_enum_t {

Wyświetl plik

@ -42,6 +42,7 @@ int configuration_get_inhibit_wx_pwr_handle(void);
int configuration_get_early_tx_assert(void);
int configuration_get_power_cycle_vbat_r(void);
int configuration_get_reboot_after_24_hours(void);
int configuration_get_power_cycle_gsmradio_on_no_communications(void);
uint16_t configuration_get_vbat_a_coeff(void);
uint16_t configuration_get_vbat_b_coeff(void);

Wyświetl plik

@ -32,6 +32,8 @@ void io_pwr_init(void);
void io_ext_watchdog_config(void);
void io_ext_watchdog_service(void);
void io_buttons_init(void);
#ifdef PARAMETEO
void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff);
uint16_t io_vbat_meas_get(void);

Wyświetl plik

@ -8,9 +8,10 @@
#include "aprs/ax25.h"
#include "drivers/serial.h"
#include "config_data.h"
#include "gsm/sim800_state_t.h"
#define SW_VER "EA21"
#define SW_DATE "01062023"
#define SW_VER "EA22"
#define SW_DATE "10062023"
#define SW_KISS_PROTO "A"
#define SYSTICK_TICKS_PER_SECONDS 100
@ -93,6 +94,8 @@ extern char after_tx_lock;
extern unsigned short rx10m, tx10m, digi10m, digidrop10m, kiss10m;
extern gsm_sim800_state_t main_gsm_state;
//void main_set_monitor(int8_t bit);
uint16_t main_get_adc_sample(void);

Wyświetl plik

@ -66,9 +66,11 @@ const char * aprsis_sucessfull_login = "# logresp\0";
*/
uint32_t aprsis_last_keepalive_ts = 0;
uint32_t aprsis_reset_on_timeout = 0;
#define APRSIS_TIMEOUT_MS 123000//123000
void aprsis_init(srl_context_t * context, gsm_sim800_state_t * gsm_modem_state, char * callsign, uint8_t ssid, uint32_t passcode, char * default_server, uint16_t default_port) {
void aprsis_init(srl_context_t * context, gsm_sim800_state_t * gsm_modem_state, char * callsign, uint8_t ssid, uint32_t passcode, char * default_server, uint16_t default_port, uint8_t reset_on_timeout) {
aprsis_serial_port = context;
aprsis_gsm_modem_state = gsm_modem_state;
@ -94,6 +96,8 @@ void aprsis_init(srl_context_t * context, gsm_sim800_state_t * gsm_modem_state,
aprsis_default_server_address_ln = strlen(aprsis_default_server_address);
aprsis_reset_on_timeout = reset_on_timeout;
}
aprsis_return_t aprsis_connect_and_login(const char * address, uint8_t address_ln, uint16_t port, uint8_t auto_send_beacon) {
@ -234,7 +238,14 @@ void aprsis_check_alive(void) {
// reset the flag
aprsis_logged = 0;
gsm_sim800_tcpip_close(aprsis_serial_port, aprsis_gsm_modem_state, 1);
aprsis_connected = 0;
if (aprsis_reset_on_timeout == 0) {
gsm_sim800_tcpip_close(aprsis_serial_port, aprsis_gsm_modem_state, 1);
}
else {
gsm_sim800_reset(aprsis_gsm_modem_state);
}
}
}

Wyświetl plik

@ -0,0 +1,66 @@
/*
* button_parameteo.c
*
* Created on: Jun 10, 2023
* Author: mateusz
*/
#include "button.h"
#include "main.h"
#include "./gsm/sim800c.h"
#include <stm32l4xx_ll_gpio.h>
/**
* Used for
*/
uint8_t button_left_previous_state = 1;
uint8_t button_right_previous_state = 1;
void button_check_all(config_data_basic_t * config) {
/**
* Naming convention: There are two buttons on the PCB. Lets call it
* left and right, with an assumption that You are holding a PCB
* horizontally with a battery and PV connector on bottom left corner.
*
* Left Button - BTN0 on schematic - connected to PA0
* Right Button - BTN1 on schematic - connected to PC3
*
* Buttons are present only on Hardware Revision C and later! They have
* internal wake pull-up enabled, so the io pin is in high state
* when a button is not pressed. the button shorts this to ground.
*/
// check if a configuration has been passed
if (config != 0) {
// current state of right button
const uint32_t state_right = LL_GPIO_IsInputPinSet(GPIOC, LL_GPIO_PIN_3);
// current state of left button
const uint32_t state_left = LL_GPIO_IsInputPinSet(GPIOA, LL_GPIO_PIN_0);
// check falling edge on right button
if (state_right == 0 && button_right_previous_state == 1) {
button_right_previous_state = 0;
switch (config->button_two) {
case BUTTON_RESET_GSM_GPRS:
gsm_sim800_reset(&main_gsm_state);
break;
default:
break;
}
}
}
}
void button_debounce(void) {
button_left_previous_state = 1;
button_right_previous_state = 1;
}

Wyświetl plik

@ -0,0 +1,10 @@
/*
* button.c
*
* Created on: Jun 10, 2023
* Author: mateusz
*/
#include "button.h"

Wyświetl plik

@ -44,7 +44,7 @@
#define CONFIG_MODE_PGM_CNTR 0x0
#define CONFIG_MODE_OFSET 0x20 // Current size: 0x14, free: 0x0C
#define CONFIG_BASIC_OFFSET 0x40 // Current size: 0xA4, free: 0x3C
#define CONFIG_BASIC_OFFSET 0x40 // Current size: 0xA6, free: 0x3A
#define CONFIG_SOURCES_OFFSET 0x120 // Current size: 0x8, free: 0x18
#define CONFIG_UMB_OFFSET 0x140 // Current size: 0x10, free: 0x10
#define CONFIG_RTU_OFFSET 0x160 // Current size: 0x10, free: 0x90
@ -841,6 +841,18 @@ int configuration_get_early_tx_assert(void) {
return out;
}
int configuration_get_power_cycle_gsmradio_on_no_communications(void) {
int out = 0;
if ((main_config_data_basic->engineering1 & ENGINEERING1) == 0) {
if ((main_config_data_basic->engineering1 & ENGINEERING1_PWRCYCLE_GSM_ON_NOCOMM) != 0) {
out = 1;
}
}
return out;
}
int configuration_get_power_cycle_vbat_r(void) {
int out = 0;

Wyświetl plik

@ -284,6 +284,27 @@ void io_ext_watchdog_service(void) {
#endif
}
void io_buttons_init(void){
#ifdef PARAMETEO
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_INPUT;
GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitTypeDef.Pin = LL_GPIO_PIN_3;
GPIO_InitTypeDef.Pull = LL_GPIO_PULL_UP;
GPIO_InitTypeDef.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitTypeDef.Alternate = LL_GPIO_AF_7;
LL_GPIO_Init(GPIOC, &GPIO_InitTypeDef);
GPIO_InitTypeDef.Mode = LL_GPIO_MODE_INPUT;
GPIO_InitTypeDef.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitTypeDef.Pin = LL_GPIO_PIN_0;
GPIO_InitTypeDef.Pull = LL_GPIO_PULL_UP;
GPIO_InitTypeDef.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitTypeDef.Alternate = LL_GPIO_AF_7;
LL_GPIO_Init(GPIOA, &GPIO_InitTypeDef);
#endif
}
void io_vbat_meas_init(int16_t a_coeff, int16_t b_coeff) {
#ifdef PARAMETEO

Wyświetl plik

@ -36,6 +36,7 @@
//#include "afsk.h"
#include "diag/Trace.h"
#include "io.h"
#include "button.h"
#include "rte_main.h"
@ -161,6 +162,8 @@ void SysTick_Handler(void) {
delay_decrement_counter();
button_debounce();
if (it_handlers_inhibit_radiomodem_dcd_led == 0) {
led_control_led1_upper(main_ax25.dcd);
}

Wyświetl plik

@ -311,8 +311,6 @@ int main(int argc, char* argv[]){
int32_t ln = 0;
uint8_t button_inhibit = 0;
it_handlers_inhibit_radiomodem_dcd_led = 1;
memset(main_own_aprs_msg, 0x00, OWN_APRS_MSG_LN);
@ -567,6 +565,9 @@ int main(int argc, char* argv[]){
// initializing GPIO used for swithing on and off voltages on pcb
io_pwr_init();
// initializing GPIO used for buttons
io_buttons_init();
// initialize sensor power control and switch off supply voltage
wx_pwr_switch_init();
@ -747,16 +748,6 @@ int main(int argc, char* argv[]){
break;
}
// if (main_config_data_mode->wx_davis == 1) {
// ;
// }
// else if (main_config_data_mode->wx_modbus == 1) {
// ;
// }
// else {
// ;
// }
#if defined(STM32F10X_MD_VL)
main_wx_srl_ctx_ptr->te_pin = GPIO_Pin_8;
main_wx_srl_ctx_ptr->te_port = GPIOA;
@ -1006,8 +997,6 @@ int main(int argc, char* argv[]){
led_control_led1_upper(true);
led_control_led2_bottom(false);
io___cntrl_gprs_pwrkey_press();
delay_fixed(1000);
led_control_led1_upper(false);
@ -1023,8 +1012,6 @@ int main(int argc, char* argv[]){
led_control_led1_upper(false);
led_control_led2_bottom(false);
io___cntrl_gprs_pwrkey_release();
#endif
// configuting system timers
@ -1062,7 +1049,14 @@ int main(int argc, char* argv[]){
}
if (main_config_data_gsm->api_enable == 0 && main_config_data_gsm->aprsis_enable == 1) {
aprsis_init(&main_gsm_srl_ctx, &main_gsm_state, (const char *)main_config_data_basic->callsign, main_config_data_basic->ssid, main_config_data_gsm->aprsis_passcode, (const char *)main_config_data_gsm->aprsis_server_address, main_config_data_gsm->aprsis_server_port);
aprsis_init(&main_gsm_srl_ctx,
&main_gsm_state,
(const char *)main_config_data_basic->callsign,
main_config_data_basic->ssid,
main_config_data_gsm->aprsis_passcode,
(const char *)main_config_data_gsm->aprsis_server_address,
main_config_data_gsm->aprsis_server_port,
configuration_get_power_cycle_gsmradio_on_no_communications());
}
}
@ -1330,6 +1324,8 @@ int main(int argc, char* argv[]){
rtu_serial_pool();
}
button_check_all(main_config_data_basic);
main_set_monitor(2);
// get all meteo measuremenets each 65 seconds. some values may not be

Wyświetl plik

@ -0,0 +1,44 @@
/*
* sim800_async_message_t.h
*
* Created on: Jun 10, 2023
* Author: mateusz
*/
#ifndef INCLUDE_GSM_SIM800_ASYNC_MESSAGE_T_H_
#define INCLUDE_GSM_SIM800_ASYNC_MESSAGE_T_H_
/**
* Those strings represent
*/
#define INCOMING_CALL "RING\0"
#define INCOMING_CALL_LN 4
#define NOCARRIER "NO CARRIER\0"
#define NOCARRIER_LN 10
#define UVP_PDOWN "UNDER-VOLTAGE POWER DOWN\0"
#define UVP_PDOWN_LN 24
#define UVP_WARNING "UNDER-VOLTAGE WARNNING\0"
#define UVP_WARNING_LN 22
#define OVP_PDWON "OVER-VOLTAGE POWER DOWN\0"
#define IVP_PDWON_LN 23
#define OVP_WARNING "OVER-VOLTAGE WARNNING\0"
#define OVP_WARNING_LN 21
#define CALL_RDY "Call Ready\0"
#define CALL_RDY_LN 10
#define SMS_RDY "SMS Ready\0"
#define SMS_RDY_LN 9
typedef enum sim800_async_message_t {
SIM800_ASYNC_RING,
SIM800_ASYNC_NOCARRIER,
SIM800_ASYNC_UNDERVOLTAGE_PDOWN,
SIM800_ASYNC_UNDERVOLTAGE_WARNING,
SIM800_ASYNC_OVERVOLTAGE_PDOWN,
SIM800_ASYNC_OVERVOLTAGE_WARNING,
SIM800_ASYNC_CALL_READY,
SIM800_ASYNC_SMS_READY,
SIM800_ASYNC_UNKNOWN
}sim800_async_message_t;
#endif /* INCLUDE_GSM_SIM800_ASYNC_MESSAGE_T_H_ */

Wyświetl plik

@ -0,0 +1,22 @@
/*
* sim800_network_status_t.h
*
* Created on: Jun 10, 2023
* Author: mateusz
*/
#ifndef INCLUDE_GSM_SIM800_NETWORK_STATUS_T_H_
#define INCLUDE_GSM_SIM800_NETWORK_STATUS_T_H_
/**
* Enum with possible statuses of GSM network registration
*/
typedef enum sim800_network_status_t {
NETWORK_STATUS_UNKNOWN, /**< NETWORK_STATUS_UNKNOWN */
NETWORK_NOT_REGISTERED, /**< NETWORK_NOT_REGISTERED */
NETWORK_REGISTERED, /**< NETWORK_REGISTERED */
NETWORK_REGISTERED_ROAMING/**< NETWORK_REGISTERED_ROAMING */
}sim800_network_status_t;
#endif /* INCLUDE_GSM_SIM800_NETWORK_STATUS_T_H_ */

Wyświetl plik

@ -0,0 +1,22 @@
/*
* sim800_simcard_status_t.h
*
* Created on: Jun 10, 2023
* Author: mateusz
*/
#ifndef INCLUDE_GSM_SIM800_SIMCARD_STATUS_T_H_
#define INCLUDE_GSM_SIM800_SIMCARD_STATUS_T_H_
/**
* Enum which holds a possible values of current SIM card status
*/
typedef enum sim800_simcard_status_t {
SIMCARD_READY, /**< SIMCARD_READY Simcard is unlocked and ready */
SIMCARD_PIN_REQUIRED,/**< SIMCARD_PIN_REQUIRED Simcard is present but requires a PIN code*/
SIMCARD_ERROR, /**< SIMCARD_ERROR No communication with card */
SIMCARD_UNKNOWN /**< SIMCARD_UNKNOWN */
}sim800_simcard_status_t;
#endif /* INCLUDE_GSM_SIM800_SIMCARD_STATUS_T_H_ */

Wyświetl plik

@ -10,10 +10,11 @@
#include "drivers/serial.h"
#include "gsm/sim800_state_t.h"
#include "gsm/sim800_async_message_t.h"
extern const char * gsm_at_command_sent_last;
extern char gsm_sim800_sim_status[10];
extern char gsm_sim800_simcard_status_string[10];
extern char gsm_sim800_registered_network[16];
extern int8_t gsm_sim800_signal_level_dbm;
extern float gsm_sim800_bcch_frequency;
@ -21,13 +22,15 @@ extern char gsm_sim800_cellid[5];
extern char gsm_sim800_lac[5];
uint32_t gsm_sim800_check_for_extra_newlines(uint8_t * ptr, uint16_t size);
void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t * offset);
sim800_async_message_t gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t * offset);
void gsm_sim800_init(gsm_sim800_state_t * state, uint8_t enable_echo);
void gsm_sim800_initialization_pool(srl_context_t * srl_context, gsm_sim800_state_t * state);
uint8_t gsm_sim800_rx_terminating_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter); // callback used to detect echo
void gsm_sim800_rx_done_event_handler(srl_context_t * srl_context, gsm_sim800_state_t * state);
void gsm_sim800_tx_done_event_handler(srl_context_t * srl_context, gsm_sim800_state_t * state);
void gsm_sim800_reset(gsm_sim800_state_t * state);
uint8_t gsm_sim800_get_waiting_for_command_response(void);
uint16_t gsm_sim800_get_response_start_idx(void);

Wyświetl plik

@ -27,5 +27,6 @@ extern int8_t gsm_sim800_gprs_ready;
void sim800_gprs_initialize(srl_context_t * srl_context, gsm_sim800_state_t * state, const config_data_gsm_t * config_gsm);
void sim800_gprs_create_apn_config_str(char * buffer, uint16_t buffer_ln);
void sim800_gprs_response_callback(srl_context_t * srl_context, gsm_sim800_state_t * state, uint16_t gsm_response_start_idx);
void sim800_gprs_reset(void);
#endif /* INCLUDE_GSM_SIM800C_GPRS_H_ */

Wyświetl plik

@ -36,6 +36,8 @@ void gsm_sim800_tcpip_tx_done_callback(srl_context_t * srl_context, gsm_sim800_s
uint8_t gsm_sim800_newline_terminating_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter);
void gsm_sim800_tcpip_reset(void);
// uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter
#endif /* INCLUDE_GSM_SIM800C_TCPIP_H_ */

Wyświetl plik

@ -9,10 +9,16 @@
#include "aprs/beacon.h"
#include "main.h"
#include "rte_main.h"
#include "pwr_save_configuration.h"
#include "station_config.h"
#include <stdio.h>
#include <string.h>
#ifdef INHIBIT_CUTOFF
const char * idiot = "You idiot!! You have INHIBIT_CUTOFF define uncomented!\0\0";
#endif
void beacon_send_own(uint16_t voltage, uint8_t rtc_ok) {
main_wait_for_tx_complete();
@ -36,9 +42,18 @@ void beacon_send_on_startup(void) {
afsk_txStart(&main_afsk);
}
#ifdef INHIBIT_CUTOFF
void beacon_send_from_user_content(uint16_t content_ln, char* content_ptr) {
main_wait_for_tx_complete();
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, idiot, strlen(idiot));
after_tx_lock = 1;
afsk_txStart(&main_afsk);
}
#else
void beacon_send_from_user_content(uint16_t content_ln, char* content_ptr) {
main_wait_for_tx_complete();
ax25_sendVia(&main_ax25, main_own_path, main_own_path_ln, content_ptr, content_ln);
after_tx_lock = 1;
afsk_txStart(&main_afsk);
}
#endif

Wyświetl plik

@ -11,14 +11,21 @@
#include "gsm/sim800c_inline.h"
#include "gsm/sim800c_tcpip.h"
#include "gsm/sim800_return_t.h"
#include "gsm/sim800_async_message_t.h"
#include "gsm/sim800_simcard_status_t.h"
#include "gsm/sim800_network_status_t.h"
#include "main.h"
#include "io.h"
#include <string.h>
#include <stdlib.h>
#define SIM800_DEFAULT_TIMEOUT 250 // in miliseconds
/**
* Const strings with AT commands sent to GSM module
*/
static const char * AUTOBAUD_STRING = "AT\r\0";
static const char * GET_SIGNAL_LEVEL = "AT+CSQ\r\0";
static const char * GET_NETWORK_REGISTRATION = "AT+CREG?\r\0";
@ -26,62 +33,60 @@ static const char * GET_PIN_STATUS = "AT+CPIN?\r\0";
static const char * GET_REGISTERED_NETWORK = "AT+COPS?\r\0";
extern const char * START_CONFIG_APN;
static const char * TRANSPARENT_MODE_ON = "AT+CIPMODE=1\r\0";
//static const char * TRANSPARENT_MODE_OFF = "AT+CIPMODE=0\r\0";
/**
* Const string with a responses to AT commands
*/
static const char * OK = "OK\r\n\0";
static const char * AT_ERROR = "ERROR\0\0";
static const char * SIGNAL_LEVEL = "+CSQ:\0";
static const char * NETWORK_REGISTRATION = "+CREG:\0";
static const char * CPIN = "+CPIN:\0";
//static const char * CPIN_READY = "READY";
//static const char * CPIN_SIMPIN = "SIMPIN";
static const char * REGISTERED_NETWORK = "+COPS:\0";
static const char * INCOMING_CALL = "RING\0";
#define INCOMING_CALL_LN 4
static const char * NOCARRIER = "NO CARRIER\0";
#define NOCARRIER_LN 10
static const char * UVP_PDOWN = "UNDER-VOLTAGE POWER DOWN\0";
#define UVP_PDOWN_LN 24
static const char * UVP_WARNING = "UNDER-VOLTAGE WARNNING\0";
#define UVP_WARNING_LN 22
static const char * OVP_PDWON = "OVER-VOLTAGE POWER DOWN\0";
#define IVP_PDWON_LN 23
static const char * OVP_WARNING = "OVER-VOLTAGE WARNNING\0";
#define OVP_WARNING_LN 21
static const char * CALL_RDY = "Call Ready\0";
#define CALL_RDY_LN 10
static const char * SMS_RDY = "SMS Ready\0";
#define SMS_RDY_LN 9
static const char * TRANSPARENT_MODE_ON = "AT+CIPMODE=1\r\0";
//static const char * TRANSPARENT_MODE_OFF = "AT+CIPMODE=0\r\0";
uint32_t gsm_time_of_last_command_send_to_module = 0;
// let's the library know if gsm module echoes every AT command send through serial port
//! let's the library know if gsm module echoes every AT command send through serial port
static uint8_t gsm_at_comm_echo = 1;
// how many newlines
//! how many newlines
volatile static int8_t gsm_terminating_newline_counter = 1;
// used to receive echo and response separately
//! used to receive echo and response separately
static uint8_t gsm_receive_newline_counter = 0;
// first character of non-echo response from the module
//! first character of non-echo response from the module
static uint16_t gsm_response_start_idx = 0;
// a pointer to the last command string which sent in SIM800_INITIALIZING state
//! a pointer to the last command string which sent in SIM800_INITIALIZING state
const char * gsm_at_command_sent_last = 0;
// set to one to lock 'gsm_sim800_pool' in SIM800_INITIALIZING state until the response is received
//! set to one to lock 'gsm_sim800_pool' in SIM800_INITIALIZING state until the response is received
static uint8_t gsm_waiting_for_command_response = 0;
uint8_t gsm_sim800_registration_status = 4; // unknown
// string with sim status
//! string with sim status
#define SIM_STATUS_LENGHT 10
char gsm_sim800_sim_status[SIM_STATUS_LENGHT];
char gsm_sim800_simcard_status_string[SIM_STATUS_LENGHT];
//! flag if SIM card is present, working and ulocked
sim800_simcard_status_t gsm_sim800_simcard_status = SIMCARD_UNKNOWN;
//! String with a name of currently registered network
#define REGISTERED_NETWORK_LN 16
char gsm_sim800_registered_network[REGISTERED_NETWORK_LN];
//! Current status of module registration in GSM network
sim800_network_status_t gsm_sim800_network_status = NETWORK_STATUS_UNKNOWN;
//! A delay in seconds between requesting for SIM card status and a request for network status
int8_t gsm_sim800_registration_delay_seconds = 8;
int8_t gsm_sim800_signal_level_dbm = 0;
float gsm_sim800_bcch_frequency = 0;
@ -90,8 +95,15 @@ char gsm_sim800_cellid[5] = {0, 0, 0, 0, 0};
char gsm_sim800_lac[5] = {0, 0, 0, 0, 0};
/**
* Replace all non printable TABs, NEWLINEs etc with a space. Stops on null terminator
* or a size of an input string
* @param str pointer to a string to be modified
* @param size its size
*/
inline static void gsm_sim800_replace_non_printable_with_space(char * str, int8_t size) {
for (int i = 0; *(str + i) != 0 && i < size; i++) {
for (int i = 0; i < size; i++) {
// currently processed character
char current = *(str + i);
if (current != 0x00) {
@ -99,14 +111,22 @@ inline static void gsm_sim800_replace_non_printable_with_space(char * str, int8_
*(str + i) = ' ';
}
}
else {
// stop processing on null terminator
break;
}
}
}
inline static void gsm_sim800_replace_space_with_null(char * str, int8_t size) {
// it goes from the end of a buffer towards its begining
for (int i = size - 1; i > 0; i--) {
char current = *(str + i);
if (current == '\"') {
// also replace this with null terminator
*(str + i) = 0x00;
break;
}
@ -114,36 +134,38 @@ inline static void gsm_sim800_replace_space_with_null(char * str, int8_t size) {
*(str + i) = 0x00;
}
}
// for (int i = 0; *(str + i) != 0 && i < size; i++) {
// char current = *(str + i);
//
// if (current == 0x20) {
// *(str + i) = 0x00;
// }
// }
}
inline static void gsm_sim800_power_off(void) {
io___cntrl_vbat_g_disable();
}
inline static void gsm_sim800_power_on(void) {
io___cntrl_vbat_g_enable();
}
inline static void gsm_sim800_press_pwr_button(void) {
io___cntrl_gprs_pwrkey_press();
}
inline static void gsm_sim800_depress_pwr_button(void) {
io___cntrl_gprs_pwrkey_release();
}
void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t * offset) {
/**
* Detect async messages which are not a response to AT commands, but a status
* sent by GSM module on it's own when some event is detected. If async message
* is dected it rewind an offset over this async, to the begin of real response
* @param ptr pointer to buffer with data to look through
* @param size size of this buffer
* @param offset
* @return Type of async message detected or unknown if nothing has been found
*/
sim800_async_message_t gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t * offset) {
// offset is a pointer to variable where this function will store a position of first response character
// after the async message
sim800_async_message_t out = SIM800_ASYNC_UNKNOWN;
int comparision_result = 123;
@ -155,6 +177,7 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
if (comparision_result == 0) {
start_i = INCOMING_CALL_LN;
out = SIM800_ASYNC_RING;
}
}
else if (*ptr == 'N') {
@ -162,6 +185,7 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
if (comparision_result == 0) {
start_i = NOCARRIER_LN;
out = SIM800_ASYNC_NOCARRIER;
}
}
else if (*ptr == 'S') {
@ -169,6 +193,7 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
if (comparision_result == 0) {
start_i = SMS_RDY_LN;
out = SIM800_ASYNC_SMS_READY;
}
}
else if (*ptr == 'C') {
@ -176,6 +201,7 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
if (comparision_result == 0) {
start_i = CALL_RDY_LN;
out = SIM800_ASYNC_CALL_READY;
}
}
else if (*ptr == 'O') {
@ -186,6 +212,7 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
}
else {
start_i = OVP_WARNING_LN;
out = SIM800_ASYNC_OVERVOLTAGE_WARNING;
}
}
else if (*ptr == 'U') {
@ -196,6 +223,7 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
}
else {
start_i = UVP_WARNING_LN;
out = SIM800_ASYNC_UNDERVOLTAGE_WARNING;
}
}
@ -212,8 +240,17 @@ void gsm_sim800_check_for_async_messages(uint8_t * ptr, uint16_t size, uint16_t
}
}
return out;
}
/**
* Function checks how many lines has been returned in a response from GSM modem
* which miht be a signal that async message was somewhere received.
* @param ptr
* @param size
* @return
*/
uint32_t gsm_sim800_check_for_extra_newlines(uint8_t * ptr, uint16_t size) {
// this bitmask stores positions of first four lines of text in input buffer
@ -369,23 +406,30 @@ void gsm_sim800_initialization_pool(srl_context_t * srl_context, gsm_sim800_stat
}
else if (gsm_at_command_sent_last == GET_PIN_STATUS) {
// ask for network registration status
srl_send_data(srl_context, (const uint8_t*) GET_REGISTERED_NETWORK, SRL_MODE_ZERO, strlen(GET_REGISTERED_NETWORK), SRL_INTERNAL);
// wait for command completion
srl_wait_for_tx_completion(srl_context);
// wait for some time to be sure that GSM module is registered into network
if (gsm_sim800_registration_delay_seconds > 0) {
gsm_sim800_registration_delay_seconds--;
}
else {
// ask for network registration status
srl_send_data(srl_context, (const uint8_t*) GET_REGISTERED_NETWORK, SRL_MODE_ZERO, strlen(GET_REGISTERED_NETWORK), SRL_INTERNAL);
gsm_at_command_sent_last = GET_REGISTERED_NETWORK;
// wait for command completion
srl_wait_for_tx_completion(srl_context);
gsm_waiting_for_command_response = 1;
gsm_at_command_sent_last = GET_REGISTERED_NETWORK;
srl_receive_data_with_callback(srl_context, gsm_sim800_rx_terminating_callback);
gsm_waiting_for_command_response = 1;
// start timeout calculation
srl_context->srl_rx_timeout_calc_started = 1;
srl_receive_data_with_callback(srl_context, gsm_sim800_rx_terminating_callback);
// record when the command has been sent
gsm_time_of_last_command_send_to_module = main_get_master_time();
// start timeout calculation
srl_context->srl_rx_timeout_calc_started = 1;
// record when the command has been sent
gsm_time_of_last_command_send_to_module = main_get_master_time();
}
}
else if (gsm_at_command_sent_last == GET_REGISTERED_NETWORK) {
// ask for signal level
@ -407,7 +451,13 @@ void gsm_sim800_initialization_pool(srl_context_t * srl_context, gsm_sim800_stat
gsm_time_of_last_command_send_to_module = main_get_master_time();
}
else if (gsm_at_command_sent_last == GET_SIGNAL_LEVEL) {
*state = SIM800_ALIVE;
if (gsm_sim800_simcard_status == SIMCARD_READY &&
(gsm_sim800_network_status == NETWORK_REGISTERED || gsm_sim800_network_status == NETWORK_REGISTERED_ROAMING)) {
*state = SIM800_ALIVE;
}
else {
gsm_sim800_reset(state);
}
gsm_at_command_sent_last = 0;
}
@ -594,7 +644,7 @@ void gsm_sim800_initialization_pool(srl_context_t * srl_context, gsm_sim800_stat
}
/**
* Callback to be called just after the reception is done
* Callback used to terminate UART serial transaction
*/
uint8_t gsm_sim800_rx_terminating_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter) {
@ -725,11 +775,22 @@ void gsm_sim800_rx_done_event_handler(srl_context_t * srl_context, gsm_sim800_st
comparision_result = strncmp(CPIN, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
if (comparision_result == 0) {
strncpy(gsm_sim800_sim_status, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 7), 10);
strncpy(gsm_sim800_simcard_status_string, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 7), 10);
gsm_sim800_replace_non_printable_with_space(gsm_sim800_sim_status, SIM_STATUS_LENGHT);
gsm_sim800_replace_non_printable_with_space(gsm_sim800_simcard_status_string, SIM_STATUS_LENGHT);
gsm_sim800_replace_space_with_null(gsm_sim800_sim_status, SIM_STATUS_LENGHT);
gsm_sim800_replace_space_with_null(gsm_sim800_simcard_status_string, SIM_STATUS_LENGHT);
gsm_sim800_simcard_status = SIMCARD_READY;
}
else {
// check ERROR conditions which may be caused by faulty or no
// SIM card inserted
comparision_result = strncmp(AT_ERROR, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
if (comparision_result == 0) {
gsm_sim800_simcard_status = SIMCARD_ERROR;
}
}
}
@ -737,11 +798,22 @@ void gsm_sim800_rx_done_event_handler(srl_context_t * srl_context, gsm_sim800_st
comparision_result = strncmp(REGISTERED_NETWORK, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx), 5);
if (comparision_result == 0) {
strncpy(gsm_sim800_registered_network, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 12), 16);
// check if GSM module is even registered into the network, if not it will
// return: SAT+COPS?\r\r\n+COPS: 0\r\n\r\nOK\r\n
if (*(const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 7) == '0' &&
*(const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 9) != '0') {
gsm_sim800_network_status = NETWORK_NOT_REGISTERED;
}
else {
gsm_sim800_network_status = NETWORK_REGISTERED;
gsm_sim800_replace_non_printable_with_space(gsm_sim800_registered_network, REGISTERED_NETWORK_LN);
strncpy(gsm_sim800_registered_network, (const char *)(srl_context->srl_rx_buf_pointer + gsm_response_start_idx + 12), 16);
gsm_sim800_replace_non_printable_with_space(gsm_sim800_registered_network, REGISTERED_NETWORK_LN);
gsm_sim800_replace_space_with_null(gsm_sim800_registered_network, REGISTERED_NETWORK_LN);
}
gsm_sim800_replace_space_with_null(gsm_sim800_registered_network, REGISTERED_NETWORK_LN);
}
}
else if (gsm_at_command_sent_last == GET_SIGNAL_LEVEL) {
@ -813,3 +885,34 @@ void gsm_sim800_tx_done_event_handler(srl_context_t * srl_context, gsm_sim800_st
}
}
/**
* Power cycle GSM modem
* @param state
*/
void gsm_sim800_reset(gsm_sim800_state_t * state) {
// turn power off
gsm_sim800_power_off();
*state = SIM800_UNKNOWN;
gsm_sim800_network_status = NETWORK_STATUS_UNKNOWN;
gsm_sim800_simcard_status = SIMCARD_UNKNOWN;
gsm_receive_newline_counter = 0;
gsm_response_start_idx = 0;
gsm_at_command_sent_last = 0;
gsm_waiting_for_command_response = 0;
gsm_sim800_registration_status = 4;
gsm_sim800_registration_delay_seconds = 8;
sim800_gprs_reset();
gsm_sim800_tcpip_reset();
}

Wyświetl plik

@ -188,3 +188,6 @@ void sim800_gprs_response_callback(srl_context_t * srl_context, gsm_sim800_state
}
}
void sim800_gprs_reset(void){
}

Wyświetl plik

@ -45,5 +45,12 @@ void gsm_sim800_poolers_one_second(srl_context_t * srl_context, gsm_sim800_state
return;
}
if ( gsm_sim800_engineering_is_enabled == 0 &&
gsm_sim800_gprs_ready == 1 &&
aprsis_connected == 0) {
aprsis_connect_and_login_default(1);
}
}
}

Wyświetl plik

@ -135,7 +135,7 @@ sim800_return_t gsm_sim800_tcpip_connect(char * ip_or_dns_address, uint8_t addre
srl_wait_for_tx_completion(srl_context);
// due to GPRS delays connecting may last some time, so increase maximum timeout
srl_switch_timeout(srl_context, 1, 2000);
srl_switch_timeout(srl_context, 1, 4000);
// trigger reception
srl_receive_data_with_callback(srl_context, gsm_sim800_connecting_terminating_callback);
@ -412,3 +412,10 @@ uint8_t gsm_sim800_newline_terminating_callback(uint8_t current_data, const uint
return out;
}
void gsm_sim800_tcpip_reset(void) {
gsm_sim800_tcpip_connection_died = 0;
gsm_sim800_tcpip_receiving = 0;
gsm_sim800_tcpip_transmitting = 0;
gsm_sim800_previous = ' ';
}

Wyświetl plik

@ -89,9 +89,9 @@ uint16_t rtu_serial_previous_crc = 0xFFFF;
*/
uint8_t rtu_waiting_for_slave_addr = 0x1;
volatile rtu_pool_queue_t* rtu_used_queue;
rtu_pool_queue_t* rtu_used_queue;
volatile srl_context_t* rtu_used_serial_context;
srl_context_t* rtu_used_serial_context;
volatile uint8_t rtu_current_03_slave_address;