From 6e0075f0b3a23214a703ae92f3036b6d2f226f90 Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 5 May 2026 19:54:18 +0200 Subject: [PATCH] Added Uart Package Parsing --- main/CMakeLists.txt | 2 +- main/uart.c | 109 ++++++++++++++++++++++++++++++++++++++++++++ main/uart.h | 42 +++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 main/uart.c create mode 100644 main/uart.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 3e491e4..f75fff1 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "powerpod.c" "led_ring.c" +idf_component_register(SRCS "powerpod.c" "led_ring.c" "uart.c" INCLUDE_DIRS ".") diff --git a/main/uart.c b/main/uart.c new file mode 100644 index 0000000..381387b --- /dev/null +++ b/main/uart.c @@ -0,0 +1,109 @@ +#include "driver/uart.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "esp_log_buffer.h" +#include "freertos/idf_additions.h" +#include "hal/uart_types.h" +#include "nvs_flash.h" +#include "portmacro.h" +#include "uart.h" +#include +#include + +static const char *TAG = "[UART]"; +static QueueHandle_t uart_cmd_queue; + +void init_uart(QueueHandle_t cmd_queue) { + uart_cmd_queue = cmd_queue; + uart_config_t uart_config = {// .baud_rate = 115200, // 921600, 115200 + .baud_rate = 921600, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE}; + + uart_driver_install(UART_NUM, UART_BUF_SIZE * 2, 0, 0, NULL, 0); + uart_param_config(UART_NUM, &uart_config); + uart_set_pin(UART_NUM, UART_TXD_PIN, UART_RXD_PIN, UART_PIN_NO_CHANGE, + UART_PIN_NO_CHANGE); + + xTaskCreate(uart_read_task, "Read Uart", 4096, NULL, 1, NULL); +} + +void uart_read_task(void *param) { + // Send all Input from Uart to the Message Handler for Parsing + uint8_t *data = (uint8_t *)malloc(UART_BUF_SIZE); + int len = 0; + uart_packet_t packet = {.state = STATE_START}; + TickType_t last_byte_time = xTaskGetTickCount(); + const TickType_t timeout_ticks = pdMS_TO_TICKS(50); + + while (1) { + len = 0; + len = uart_read_bytes(UART_NUM, data, UART_BUF_SIZE, pdMS_TO_TICKS(20)); + if (len > 0) { + for (int i = 0; i < len; ++i) { + if (parse_uart_byte(data[i], &packet)) { + ESP_LOGI("UART", "Paket empfangen! Länge: %d", packet.len); + xQueueSend(uart_cmd_queue, &packet, 0); + } + } + last_byte_time = xTaskGetTickCount(); + } else { // reset message receive when there comes nothing new + if (packet.state != STATE_START) { + TickType_t now = xTaskGetTickCount(); + if ((now - last_byte_time) > timeout_ticks) { + packet.state = STATE_START; + ESP_LOGW("UART", "Parser Timeout - Resetting State"); + } + } + } + } +} + +bool parse_uart_byte(uint8_t byte, uart_packet_t *p) { + switch (p->state) { + case STATE_START: + if (byte == START_MARKER) { + p->index = 0; + p->checksum = 0; + p->state = STATE_LEN; + } + break; + + case STATE_LEN: + if (byte > MAX_PAYLOAD_SIZE || byte == 0) { + // corrupt length or fake start + p->state = STATE_START; + } else { + p->len = byte; + p->state = STATE_DATA; + } + break; + + case STATE_DATA: + p->payload[p->index++] = byte; + p->checksum ^= byte; + if (p->index >= p->len) { + p->state = STATE_CHECKSUM; + } + break; + + case STATE_CHECKSUM: + if (byte == p->checksum) { + p->state = STATE_STOP; + } else { + // CRC wrong: reset + p->state = STATE_START; + } + break; + + case STATE_STOP: + p->state = STATE_START; + if (byte == STOP_MARKER) { + return true; + } + break; + } + return false; +} diff --git a/main/uart.h b/main/uart.h new file mode 100644 index 0000000..b9dec38 --- /dev/null +++ b/main/uart.h @@ -0,0 +1,42 @@ +#ifndef UART_H +#define UART_H + +#include "freertos/idf_additions.h" +#include +#include +#define UART_NUM UART_NUM_1 +#define UART_BUF_SIZE 256 +#define UART_TXD_PIN 2 +#define UART_RXD_PIN 3 + +#define START_MARKER 0xAA +#define STOP_MARKER 0xCC +#define MAX_BUF_SIZE 256 +#define MAX_PAYLOAD_SIZE \ + MAX_BUF_SIZE - 4 // Buffer overhead, Start, Len, CRC, End + +typedef enum { + STATE_START, + STATE_LEN, + STATE_DATA, + STATE_CHECKSUM, + STATE_STOP +} parser_state_t; + +typedef struct { + uint8_t payload[MAX_PAYLOAD_SIZE]; + uint8_t len; + uint8_t index; + uint8_t checksum; + parser_state_t state; +} uart_packet_t; + +typedef struct { + uint8_t cmd; +} uart_command_t; + +void init_uart(QueueHandle_t cmd_queue); +void uart_read_task(void *param); +bool parse_uart_byte(uint8_t byte, uart_packet_t *p); + +#endif