From 38d078509ed0951e240210ac727072d25759209b Mon Sep 17 00:00:00 2001 From: Imbus Date: Sun, 24 Aug 2025 12:47:13 +0200 Subject: [PATCH] Message --- message/Makefile | 12 +++++++++++ message/main_demo.c | 14 ++++++++++++ message/message.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ message/message.h | 31 +++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 message/Makefile create mode 100644 message/main_demo.c create mode 100644 message/message.c create mode 100644 message/message.h diff --git a/message/Makefile b/message/Makefile new file mode 100644 index 0000000..2213e3d --- /dev/null +++ b/message/Makefile @@ -0,0 +1,12 @@ +CC ?= gcc +CFLAGS ?= -Wall -O2 + +TARGET = main.elf +SRC = message.c main_demo.c + +$(TARGET): $(SRC) + @echo CC $@ + @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +clean: + rm -f $(TARGET) diff --git a/message/main_demo.c b/message/main_demo.c new file mode 100644 index 0000000..e8a657f --- /dev/null +++ b/message/main_demo.c @@ -0,0 +1,14 @@ +#include "message.h" +#include +#include + +int main(void) { + Message m; + message_create(&m, UI_BATTERY, (MessageData){75}); + + printf("%04X\n", m.crc); + int16_t crc = compute_crc16((const uint8_t *)&m, offsetof(Message, crc)); + printf("%04X\n", crc); + assert(message_validate(&m)); + return 0; +} diff --git a/message/message.c b/message/message.c new file mode 100644 index 0000000..2a52236 --- /dev/null +++ b/message/message.c @@ -0,0 +1,52 @@ +#include "message.h" +#include + +uint16_t compute_crc16(const uint8_t *data, uint16_t len); +bool is_type_valid(MessageType t); + +/** + * @brief Create a message + * + * Use as: create_message(&m1, UI_VOLTAGE, (MessageData){.voltage = 6.3}); + * + * @param m A pointer to the message struct + * @param type The enum type of the message you want to send + * @param data The data corresponding to the message type + */ +void message_create(Message *m, MessageType type, MessageData data) { + m->type = type; + m->data = data; + m->crc = compute_crc16((const uint8_t *)m, offsetof(Message, crc)); +} + +bool message_validate(const Message *m) { + return is_type_valid(m->type) && m->crc == compute_crc16((const uint8_t *)m, offsetof(Message, crc)); +} + +// Standard CRC-16-CCITT (poly 0x1021, init 0xFFFF) +uint16_t compute_crc16(const uint8_t *data, uint16_t len) { + uint16_t crc = 0xFFFF; + for (uint16_t i = 0; i < len; i++) { + crc ^= (uint16_t)data[i] << 8; + for (int j = 0; j < 8; j++) { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + } + return crc; +} + +bool is_type_valid(MessageType t) { + return t >= UI_SPEED_MS && t <= UI_VOLTAGE; +} + +int message_tests(void) { + Message m; + message_create(&m, UI_BATTERY, (MessageData){75}); + + assert(message_validate(&m)); + + return 0; +} diff --git a/message/message.h b/message/message.h new file mode 100644 index 0000000..c81a4e8 --- /dev/null +++ b/message/message.h @@ -0,0 +1,31 @@ +#ifndef MESSAGE_H +#define MESSAGE_H + +#include +#include +#include + +typedef enum { + UI_SPEED_MS, + UI_BATTERY, + UI_VOLTAGE, +} MessageType; + +typedef union { + int battery; + int speed_ms; + float voltage; +} MessageData; + +typedef struct { + MessageType type; + MessageData data; + int16_t crc; +} Message; + +void message_create(Message *m, MessageType type, MessageData data); +bool message_validate(const Message *m); +int message_tests(void); +uint16_t compute_crc16(const uint8_t *data, uint16_t len); + +#endif