contain lorawan with serial_rx enabled
Dependencies: pulga-lorawan-drv SPI_MX25R Si1133 BME280
serial.cpp
- Committer:
- ruschigo
- Date:
- 2021-02-26
- Revision:
- 62:89df9529dbb0
- Child:
- 64:ed68ddac6360
File content as of revision 62:89df9529dbb0:
#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; }