#include "p_serial_mgr.h" #include "putil.h" #include "stm32l4xx_hal_def.h" #include "stm32l4xx_hal_uart.h" #define NUM_BUFFERS (10) uint8_t sbuffer[NUM_BUFFERS][MAX_MESSAGE_LEN]; uint8_t active_buffer = 0; uint8_t rxb[MAX_MESSAGE_LEN]; // this protocol is very similar to the digi api v2 (inspired from) // [0]{1} Start delimiter 0x7E // [1]{1} Source Address // [2]{1} Destination Address // [3]{1} Length Byte (of non-delimited framebuffer) // [4-n]{n} frame data // [n+1]{1} checksum // Escape bytes are 0x7D, only frame data can be escaped // Escaped bytes are followed by the byte to be escaped XOR'd with 0x20 // 0x7D and 0x7E need to be escaped (within the frame data) typedef enum serial_state_t { SS_IDLE = 0, // waiting SS_START = 1, // get start byte, interrupt after 4 more bytes SS_ERR = 2 } serial_state_t; static UART_HandleTypeDef *_serial_huart_inst = NULL; static uint8_t rxc = '\0'; static serial_state_t sstate = SS_IDLE; static void p_serial_mgr_flush() { HAL_UART_Receive(_serial_huart_inst, sbuffer[active_buffer], MAX_MESSAGE_LEN, 10); } void UART1_RxCpltCallback(UART_HandleTypeDef *huart) { PDEBUG("%c", sbuffer[active_buffer][0]); p_serial_mgr_start(); return; if (sstate == SS_IDLE && sbuffer[active_buffer][0] == 0x7E) { sstate = SS_START; } else { sstate = SS_ERR; } } void p_serial_mgr_init(UART_HandleTypeDef *huart) { _serial_huart_inst = huart; _serial_huart_inst->RxCpltCallback = UART1_RxCpltCallback; } void p_serial_mgr_service(void) { if (sstate == SS_START) { while (HAL_UART_Receive(_serial_huart_inst, &sbuffer[active_buffer][1], MAX_MESSAGE_LEN - 2, 20) != HAL_OK) {} for (int ind = 0; ind < 24; ind++) { PDEBUG("[%d]: 0x%02x\n", ind, sbuffer[active_buffer][ind]); } PDEBUG("\n\n"); memset(sbuffer[active_buffer], 0, MAX_MESSAGE_LEN); active_buffer = (active_buffer + 1) % NUM_BUFFERS; uint8_t sendbuffer[9] = {0x7E, DEVICE_ADDR, MASTER_ADDR, 4, 0x01, 0x02, 0x03, 0x04, 0xFF}; // HAL_UART_Transmit(_serial_huart_inst, sendbuffer, 9, 10); p_serial_mgr_start(); } else if (sstate == SS_ERR) { PDEBUG("MISSED BYTE 0x%02x\n", sbuffer[active_buffer][0]); p_serial_mgr_start(); } } void p_serial_mgr_start() { sstate = SS_IDLE; volatile HAL_StatusTypeDef ret = HAL_UART_Receive_IT(_serial_huart_inst, &sbuffer[active_buffer][0], 1); asm volatile("nop"); }