diff --git a/main/.gitignore b/main/.gitignore index d3baa75..e69de29 100644 --- a/main/.gitignore +++ b/main/.gitignore @@ -1,2 +0,0 @@ -uart_prot.c -uart_prot.h diff --git a/main/uart_handler.c b/main/uart_handler.c index 67bcc69..97223bb 100644 --- a/main/uart_handler.c +++ b/main/uart_handler.c @@ -9,6 +9,7 @@ #include #include "uart_handler.h" +#include "uart_prot.h" static const char *TAG = "ALOX - UART"; @@ -23,10 +24,13 @@ void init_uart() { uart_param_config(MASTER_UART, &uart_config); uart_set_pin(MASTER_UART, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + + message_handler_init(); xTaskCreate(uart_read_task, "Read Uart", 4096, NULL, 1, NULL); } void uart_read_task(void *param) { + QueueHandle_t inputQueue = message_handler_get_input_queue(); uint8_t *data = (uint8_t *)malloc(BUF_SIZE); int len = 0; while (1) { @@ -34,9 +38,12 @@ void uart_read_task(void *param) { len = uart_read_bytes(MASTER_UART, data, BUF_SIZE, (20 / portTICK_PERIOD_MS)); if (len > 0) { - data[len] = '\0'; - ESP_LOGI(TAG, "GOT UART DATA %s", data); - uart_write_bytes(MASTER_UART, data, len); + for (int i = 0; i < len; ++i) { + BaseType_t res = xQueueSend(inputQueue, &data[i], 0); + if (res == errQUEUE_FULL) { + ESP_LOGW(TAG, "inputQueue full"); + } + } } } } @@ -54,3 +61,10 @@ void send_client_info(int clientid, bool isAvailable, TickType_t lastPing) { isAvailable ? 1 : 0, (unsigned int)lastPing); uart_write_bytes(MASTER_UART, buf, strlen(buf)); } + +void esp_send_message_hook(ESPTOPCBaseMessage *msg) { + // serialize + send via UART + uint8_t buffer[128]; + uart_write_bytes(UART_NUM_1, (const char *)buffer, + sizeof(ESPTOPCBaseMessage)); +} diff --git a/main/uart_prot.c b/main/uart_prot.c new file mode 100644 index 0000000..65ef861 --- /dev/null +++ b/main/uart_prot.c @@ -0,0 +1,97 @@ +#include "uart_prot.h" +#include + +#define MSG_QUEUE_LEN 64 +static QueueHandle_t input_queue; +static QueueHandle_t output_queue; + +QueueHandle_t message_handler_get_input_queue(void) { + return input_queue; +} + +QueueHandle_t message_handler_get_output_queue(void) { + return output_queue; +} + +void message_handler_init(void) { + input_queue = xQueueCreate(MSG_QUEUE_LEN, sizeof(uint8_t)); + output_queue = xQueueCreate(MSG_QUEUE_LEN, sizeof(uint8_t)); +} + +void message_handler_task(void *param) { + uint8_t byte; + while (1) { + if (xQueueReceive(input_queue, &byte, portMAX_DELAY)) { + // handle byte, check message recieve with start and stop byte length and crc + } + } +} + +// Message Dispatcher +void dispatch_message(uint8_t msg_id, void *payload) { + switch (msg_id) { + case RequestPing: + if (on_request_ping) + on_request_ping((RequestPingPayload *)payload); + break; + case RequestStatus: + if (on_request_status) + on_request_status((RequestStatusPayload *)payload); + break; + case PrepareFirmwareUpdate: + if (on_prepare_firmware_update) + on_prepare_firmware_update((PrepareFirmwareUpdatePayload *)payload); + break; + case FirmwareUpdateLine: + if (on_firmware_update_line) + on_firmware_update_line((FirmwareUpdateLinePayload *)payload); + break; + default: + // Unknown message + break; + } +} + +// Generic Send Function +void send_message(ESP_TO_PC_MESSAGE_IDS msgid, PayloadUnion *payload) { + ESPTOPCBaseMessage mes; + mes.Version = 1; + mes.MessageID = msgid; + mes.Payload = *payload; + + esp_send_message_hook(&mes); +} + +// Sepzific Send Functions +void send_clients(uint8_t clientCount, uint32_t clientAvaiableBitMask) { + ClientsPayload payload; + + // Payload-Daten zuweisen + payload.clientCount = clientCount; + payload.clientAvaiableBitMask = clientAvaiableBitMask; + + // Nachricht senden + send_message(Clients, (PayloadUnion *)&payload); +} + +void send_status(uint8_t clientId, uint8_t *mac) { + StatusPayload payload; + + // Payload-Daten zuweisen + payload.clientId = clientId; + memcpy(payload.mac, mac, 6); + + // Nachricht senden + send_message(Status, (PayloadUnion *)&payload); +} + +void send_pong(uint8_t clientId, uint32_t ping) { + PongPayload payload; + + // Payload-Daten zuweisen + payload.clientId = clientId; + payload.ping = ping; + + // Nachricht senden + send_message(Pong, (PayloadUnion *)&payload); +} diff --git a/main/uart_prot.h b/main/uart_prot.h new file mode 100644 index 0000000..9714830 --- /dev/null +++ b/main/uart_prot.h @@ -0,0 +1,100 @@ +#ifndef _PROTO_HEADER +#define _PROTO_HEADER + +#include "freertos/idf_additions.h" +#include + +void message_handler_init(void); +QueueHandle_t message_handler_get_input_queue(void); +QueueHandle_t message_handler_get_output_queue(void); + +// MessageIDs +typedef enum { + RequestPing = 0xE1, + RequestStatus = 0xE2, + PrepareFirmwareUpdate = 0xF1, + FirmwareUpdateLine = 0xF2, +} PC_TO_ESP_MESSAGE_IDS; + +typedef enum { + Clients = 0xE1, + Status = 0xE2, + Pong = 0xD1, +} ESP_TO_PC_MESSAGE_IDS; + +// Payloads for single Messages +typedef struct { + uint8_t clientId; +} RequestPingPayload; + +typedef struct { + uint8_t clientId; +} RequestStatusPayload; + +typedef struct { + // empty payload +} PrepareFirmwareUpdatePayload; + +typedef struct { + uint8_t data[240]; +} FirmwareUpdateLinePayload; + +typedef struct { + uint8_t clientCount; + uint32_t clientAvaiableBitMask; +} ClientsPayload; + +typedef struct { + uint8_t clientId; + uint8_t mac[6]; +} StatusPayload; + +typedef struct { + uint8_t clientId; + uint32_t ping; +} PongPayload; + +// Union for all the Payloads +typedef union { + RequestPingPayload request_ping; + RequestStatusPayload request_status; + PrepareFirmwareUpdatePayload prepare_firmware_update; + FirmwareUpdateLinePayload firmware_update_line; + ClientsPayload clients; + StatusPayload status; + PongPayload pong; +} PayloadUnion; + +// Base Message that can hold all Payloads +typedef struct { + uint8_t Version; + PC_TO_ESP_MESSAGE_IDS MessageID; + uint8_t Length; + PayloadUnion Payload; +} PCTOESPBaseMessage; + +typedef struct { + uint8_t Version; + ESP_TO_PC_MESSAGE_IDS MessageID; + uint8_t Length; + PayloadUnion Payload; +} ESPTOPCBaseMessage; + +// deklarierte Hook-Signatur +void esp_send_message_hook(ESPTOPCBaseMessage *msg); + +// Generic Send Function Prototype +void send_message(ESP_TO_PC_MESSAGE_IDS msgid, PayloadUnion *payload); + +// Spezific Send Functions Prototype +void send_clients(uint8_t clientCount, uint32_t clientAvaiableBitMask); +void send_status(uint8_t clientId, uint8_t *mac); +void send_pong(uint8_t clientId, uint32_t ping); + +// Prototypes for Message Recieve Handler to be set in user code +void (*on_request_ping)(RequestPingPayload *); +void (*on_request_status)(RequestStatusPayload *); +void (*on_prepare_firmware_update)(PrepareFirmwareUpdatePayload *); +void (*on_firmware_update_line)(FirmwareUpdateLinePayload *); + +#endif