#pragma once extern "C" { #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_log.h" #include "sdkconfig.h" #include #include "freertos/semphr.h" #include "freertos/queue.h" #include "driver/uart.h" } #include "types.hpp" //idea with time gap dropped, replaced with encoding //#define UART_RECEIVE_DURATION 10 //receive interval may not miss messages but also may not read multiple messages //has to be significantly smaller than WRITE_MNIN_DELAY but larger than longest message //semaphore for assuring min delay between sent data //extern SemaphoreHandle_t uart_semaphoreSend; //==== parameters message frame ==== #define START_PATTERN 0xAA #define END_PATTERN 0xBB #define MAX_MESSAGE_LENGTH 1024 #define ESCAPE_BYTE 0xCC //min delay after each message (no significant effect) #define UART_WRITE_MIN_DELAY 50 #define UART_WRITE_WAIT_TIMEOUT 2000 extern bool uart_isInitialized; //struct for testing uart typedef struct { uint32_t timestamp; int id; float value; } uartData_test_t; //unnecessary, using commands struct directly typedef struct { uint32_t timestamp; motorCommands_t commands; } uartData_motorCommands_t; //function that handles receieved messages as byte array //-> do something with received data typedef void (*messageHandleFunc_t)(uint8_t *data, int length); //===== uart_init ===== //should be run once at startup void uart_init(void); //===== uart_processReceivedByte ===== //decode received message to byte array (start, stop, escape pattern) //has to be run for each receibed byte //runs provided messageHandler function when complete message received void uart_processReceivedByte(uint8_t data, messageHandleFunc_t messageHandler); //===== uart_sendBinary ===== //encode byte array to message (start, stop, escape pattern) //and send it via uart void uart_sendBinary(uint8_t *data, int length); //============================ //====== uart_sendStruct ===== //============================ //send and struct via uart //waits when another struct was sent less than UART_WRITE_MIN_DELAY ago template void uart_sendStruct(T dataStruct) { static const char * TAG = "uart-common"; //check if uart is initialized if (!uart_isInitialized){ ESP_LOGE(TAG, "uart not initialized! droping data"); return; } uint8_t dataSerial[sizeof(T)]; //struct to serial bytes memcpy(dataSerial, &dataStruct, sizeof(T)); // //wait for min delay after last write DROPPED // if (xSemaphoreTake(uart_semaphoreSend, UART_WRITE_WAIT_TIMEOUT / portTICK_PERIOD_MS) == pdTRUE){ // //send bytes // uart_write_bytes(UART_NUM_1, (const char *)dataSerial, sizeof(T)); // ESP_LOGW(TAG, "sent data struct with len %d", sizeof(T)); // } else ESP_LOGE(TAG, "timeout waiting for uart write semaphore! dropping data"); // //wait min delay before next write is allowed // vTaskDelay(UART_WRITE_MIN_DELAY / portTICK_PERIOD_MS); // xSemaphoreGive(uart_semaphoreSend); uart_sendBinary(dataSerial, sizeof(T)); } //============================== //====== serialData2Struct ===== //============================== //convert serial data (byte array) to given struct and return it //note check whether serial data length actually matches size of struct is necessary before template T serialData2Struct(uint8_t *dataSerial){ static const char * TAG = "uart-common"; T dataStruct; memcpy(&dataStruct, dataSerial, sizeof(T)); ESP_LOGI(TAG, "converted serial data len=%d to struct", sizeof(T)); return dataStruct; }