contain lorawan with serial_rx enabled
Dependencies: pulga-lorawan-drv SPI_MX25R Si1133 BME280
Diff: serial.cpp
- Revision:
- 62:89df9529dbb0
- Child:
- 64:ed68ddac6360
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serial.cpp Fri Feb 26 17:07:12 2021 +0000 @@ -0,0 +1,157 @@ +#include "serial.h" + +RawSerial pc(P0_28, P0_25); + +static char circ_buffer[512]; +static int rd_index = 0; +static int wr_index = 0; +static int buf_len = 0; + +void SerialRx(void) +{ + char msg[32]; + int msg_incompleta; + int msg_len; + int i, j; + + /// Execucao do comando nao deve fazer parte da recepcao de dados serial! + /// Deve existir separacao entre camada fisica, protocolo de baixo nivel + /// e de alto nivel. + + /// 1) Vamos implementar a parte de recepcao serial com buffer circular. + /// 2) Vamos implementar rejeicao de ruido. + /// 3) Interpretamos, executamos ou descartamos comandos. + + /// Recepcao serial + while(pc.readable()) + { + /// buffer circular cheio entao sai do loop + if (buf_len >= sizeof(circ_buffer)) { + break; + } + circ_buffer[wr_index] = pc.getc(); + + buf_len++; + wr_index++; + + if (wr_index >= sizeof(circ_buffer)) { + wr_index = 0; + } + } + + /// Vamos retirar todos os caracteres invalidos antes do comando + /// Um comando sempre inicia com '<' + while(buf_len > 0) + { + if (circ_buffer[rd_index] == '<') { + break; /// rd_index fica com o indice do inicio da mensagem + } + + buf_len--; + rd_index++; + + if (rd_index >= sizeof(circ_buffer)) { + rd_index = 0; + } + } + + /// Se ficou vazio, tudo era ruido, limpa todas as variaveis globais e sai + if (buf_len <= 0) + { + //printf("ruido\n"); + rd_index = 0; + wr_index = 0; + buf_len = 0; + pc.attach(&serial_post_to_queue, RawSerial::RxIrq); + return; + } + + /// Agora vamos verificar se a mensagem esta completa. + /// Procura o final (terminada em '>'). + /// Nao altero rd_index!! + i = 0; + j = rd_index; + msg_incompleta = 1; + + while (i < buf_len) + { + if (circ_buffer[j] == '>') + { + ///encontrou final de cmd + msg_incompleta = 0; + break; + } + j++; + i++; + + if (j >= sizeof(circ_buffer)) { + j = 0; + } + } + + /// Se a mensagem esta incompleta, deixa para a proxima vez. + /// Mas aqui tem uma sacada, se o buffer circular estiver cheio, + /// nunca receberei o final... Entao o codigo nao receberia nunca mais. + /// Para evitar o travamento permanente, limpa tudo nesse caso. + /// <------------ Isso causava o erro !!!!!! + if (msg_incompleta) + { + if (buf_len >= sizeof(circ_buffer)) + { + rd_index = 0; + wr_index = 0; + buf_len = 0; + } + pc.attach(&serial_post_to_queue, RawSerial::RxIrq); + return; + } + + /// Finalmente copio a msg + msg_len = 0; + while(buf_len > 0) + { + if (msg_len < sizeof(msg)) + { + msg[msg_len] = circ_buffer[rd_index]; + msg_len++; + } + else + { + /// A mensagem esta errada, grande demais. + msg_len = 0; + break; + } + + if (circ_buffer[rd_index] == '>') + { + ///encontrou final de cmd + break; + } + + buf_len--; + rd_index++; + + if (rd_index >= sizeof(circ_buffer)) { + rd_index = 0; + } + } + + /// Agora posso limpar todo o buffer circular + rd_index = 0; + wr_index = 0; + buf_len = 0; + + /// A mensagem foi truncada entao sai. + if (msg_len == 0) { + pc.attach(&serial_post_to_queue, RawSerial::RxIrq); + return; + } + + /// Troco o '>' do final por null + msg[msg_len - 1] = '\0'; + + SerialCommandRun(msg); + + pc.attach(&serial_post_to_queue, RawSerial::RxIrq); + return; +}