diff --git a/src/it_handlers.c b/src/it_handlers.c index 9e93fea..efd2831 100644 --- a/src/it_handlers.c +++ b/src/it_handlers.c @@ -130,6 +130,7 @@ void SysTick_Handler(void) { srl_keep_timeout(main_kiss_srl_ctx_ptr); srl_keep_timeout(main_wx_srl_ctx_ptr); + srl_keep_timeout(main_gsm_srl_ctx_ptr); srl_keep_tx_delay(main_wx_srl_ctx_ptr); diff --git a/src/main.c b/src/main.c index ed81652..a708635 100644 --- a/src/main.c +++ b/src/main.c @@ -897,7 +897,7 @@ int main(int argc, char* argv[]){ io_ext_watchdog_service(); if (main_config_data_mode->gsm == 1) { - gsm_sim800_init(&main_gsm_state); + gsm_sim800_init(&main_gsm_state, 1); } if (main_config_data_basic-> beacon_at_bootup == 1) { @@ -976,10 +976,10 @@ int main(int argc, char* argv[]){ if (main_config_data_mode->gsm == 1) { // if data has been received - if (main_gsm_srl_ctx_ptr->srl_rx_state == SRL_RX_DONE || main_kiss_srl_ctx_ptr->srl_rx_state == SRL_RX_ERROR) { + if (main_gsm_srl_ctx_ptr->srl_rx_state == SRL_RX_DONE || main_gsm_srl_ctx_ptr->srl_rx_state == SRL_RX_ERROR) { // receive callback for communicatio with the modem - gsm_sim800_rx_done_callback(main_gsm_srl_ctx_ptr, &main_gsm_state); + //gsm_sim800_rx_done_callback(main_gsm_srl_ctx_ptr, &main_gsm_state); } } diff --git a/system/include/drivers/serial.h b/system/include/drivers/serial.h index 9626813..eb43374 100644 --- a/system/include/drivers/serial.h +++ b/system/include/drivers/serial.h @@ -32,6 +32,18 @@ #define SRL_MODE_ZERO 0 #define SRL_MODE_DEFLN 1 +#define SRL_NO_START_CHR 0 +#define SRL_NO_STOP_CHR 0 + +#define SRL_ECHO_ENABLE 1 +#define SRL_ECHO_DISABLE 0 + +/** + * Callback definition which may be called after receiving each byte by an UART + * + * @param current_data received byte + * @param rx_bytes_counter receive bytes counter incremented AFTER this callback is processed so it's point to the byte which triggered this call + */ typedef uint8_t(*srl_rx_termination_callback_t)(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter); typedef enum srlRxState { diff --git a/system/include/gsm/sim800c.h b/system/include/gsm/sim800c.h index 0feddcb..c5cab18 100644 --- a/system/include/gsm/sim800c.h +++ b/system/include/gsm/sim800c.h @@ -19,9 +19,9 @@ typedef enum gsm_sim800_state_t { SIM800_GPRS_CONNECTED }gsm_sim800_state_t; -void gsm_sim800_init(gsm_sim800_state_t * state); +void gsm_sim800_init(gsm_sim800_state_t * state, uint8_t enable_echo); void gsm_sim800_pool(srl_context_t * srl_context, gsm_sim800_state_t * state); -void gsm_sim800_rx_done_callback(srl_context_t * srl_context, gsm_sim800_state_t * state); +uint8_t gsm_sim800_rx_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter); // callback used to detect echo #endif /* INCLUDE_GSM_SIM800C_H_ */ diff --git a/system/src/gsm/sim800c.c b/system/src/gsm/sim800c.c index 05bf74f..6a88a76 100644 --- a/system/src/gsm/sim800c.c +++ b/system/src/gsm/sim800c.c @@ -11,12 +11,25 @@ #include -static const char * AUTOBAUD_STRING = "AT\r\n\0"; +static const char * AUTOBAUD_STRING = "AT\r\0"; static const char * OK = "OK\0"; uint32_t gsm_time_of_last_command_send_to_module = 0; -void gsm_sim800_init(gsm_sim800_state_t * state) { +// let's the library know if gsm module echoes every AT command send through serial port +uint8_t gsm_at_comm_echo = 1; + +// used to receive echo and response separately +uint8_t gsm_receive_newline_counter = 0; + +// first character of non-echo response from the module +uint16_t gsm_response_start_idx = 0; + +void gsm_sim800_init(gsm_sim800_state_t * state, uint8_t enable_echo) { + + gsm_at_comm_echo = enable_echo; + + gsm_response_start_idx = 0; if (state != 0x00) { *state = SIM800_NOT_YET_COMM; @@ -26,6 +39,10 @@ void gsm_sim800_init(gsm_sim800_state_t * state) { void gsm_sim800_pool(srl_context_t * srl_context, gsm_sim800_state_t * state) { if (*state == SIM800_NOT_YET_COMM) { + + // configure rx timeout + srl_switch_timeout(srl_context, 1, 0); + // send handshake srl_send_data(srl_context, (const uint8_t*) AUTOBAUD_STRING, SRL_MODE_ZERO, strlen(AUTOBAUD_STRING), SRL_INTERNAL); @@ -36,7 +53,8 @@ void gsm_sim800_pool(srl_context_t * srl_context, gsm_sim800_state_t * state) { srl_wait_for_tx_completion(srl_context); // start data reception - srl_receive_data(srl_context, 4, 0, '\r', 0, 0, 0); + //srl_receive_data(srl_context, 8, SRL_NO_START_CHR, SRL_NO_STOP_CHR, SRL_ECHO_DISABLE, 0, 0); + srl_receive_data_with_callback(srl_context, gsm_sim800_rx_callback); // record when the handshake has been sent gsm_time_of_last_command_send_to_module = main_get_master_time(); @@ -46,12 +64,35 @@ void gsm_sim800_pool(srl_context_t * srl_context, gsm_sim800_state_t * state) { /** * Callback to be called just after the reception is done */ -void gsm_sim800_rx_done_callback(srl_context_t * srl_context, gsm_sim800_state_t * state) { +uint8_t gsm_sim800_rx_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter) { - int response_compare_res = 123; + char current = (char) current_data; - if (state == SIM800_INITIALIZIG) { - // compare the response from the module - response_compare_res = strcmp(OK, srl_context->srl_rx_buf_pointer); + char before = '\0'; + + if (rx_bytes_counter > 0) { + before = (char) *(rx_buffer + rx_bytes_counter - 1); } + + // check what character has been received + if (current == '\n') { + // increase newline counter + gsm_receive_newline_counter++; + } + + // check if this is first character of response + if (current != '\n' && current != '\r' && (before == '\n' || before == '\r')) { + gsm_response_start_idx = rx_bytes_counter; + } + + // if an echo is enabled and second newline has been received + if (gsm_at_comm_echo == 1 && gsm_receive_newline_counter > 1 && gsm_response_start_idx > 0) { + + gsm_receive_newline_counter = 0; + + return 1; + } + + return 0; + }