From c2b2f2c14d69a97ca73f5392db5e659dbcf1fb96 Mon Sep 17 00:00:00 2001 From: Penguin Date: Mon, 11 Apr 2022 17:01:54 -0500 Subject: [PATCH] adding protocol stuff for rs485 bus --- .clang-format | 10 +- shared/drivers/p_serial_mgr.c | 96 ++++++++++-- shared/drivers/p_serial_mgr.h | 11 ++ shared/util/PCircularBuffer.c | 286 ++-------------------------------- shared/util/PCircularBuffer.h | 130 ++-------------- 5 files changed, 123 insertions(+), 410 deletions(-) diff --git a/.clang-format b/.clang-format index d6b48de..12e9c1f 100644 --- a/.clang-format +++ b/.clang-format @@ -20,7 +20,7 @@ AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortLambdasOnASingleLine: All AllowShortIfStatementsOnASingleLine: Never -AllowShortLoopsOnASingleLine: false +AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false @@ -30,7 +30,7 @@ AttributeMacros: BinPackArguments: true BinPackParameters: true BraceWrapping: - AfterCaseLabel: false + AfterCaseLabel: true AfterClass: true AfterControlStatement: Always AfterEnum: true @@ -38,14 +38,14 @@ BraceWrapping: AfterNamespace: true AfterObjCDeclaration: true AfterStruct: true - AfterUnion: false + AfterUnion: true AfterExternBlock: true BeforeCatch: true BeforeElse: true BeforeLambdaBody: false BeforeWhile: false IndentBraces: false - SplitEmptyFunction: true + SplitEmptyFunction: false SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None @@ -95,7 +95,7 @@ IncludeCategories: IncludeIsMainRegex: '(Test)?$' IncludeIsMainSourceRegex: '' IndentAccessModifiers: false -IndentCaseLabels: false +IndentCaseLabels: true IndentCaseBlocks: false IndentGotoLabels: true IndentPPDirectives: None diff --git a/shared/drivers/p_serial_mgr.c b/shared/drivers/p_serial_mgr.c index a80e029..01d820c 100644 --- a/shared/drivers/p_serial_mgr.c +++ b/shared/drivers/p_serial_mgr.c @@ -1,15 +1,93 @@ #include "p_serial_mgr.h" #include "PCircularBuffer.h" -#define MAX_SERIAL_BUFFER_SIZE (256) -static uint8_t buffer[MAX_SERIAL_BUFFER_SIZE]; -static p_cb_u8 serial_cb; +#include "stm32l4xx_hal_uart.h" + +#define MAX_SERIAL_BUFFER_SIZE (262) // Actually 261, add 1 for padding + +// 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 +// [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_FRAME = 2, // get byte + SS_ESC = 3, // get byte, dont increment number left + SS_CHECKSUM = 4 // done +} serial_state_t; static UART_HandleTypeDef *_serial_huart_inst = NULL; -static uint8_t serial_cb_rxc = '\0'; +static serial_state_t sstate = SS_IDLE; +static uint8_t rxc = '\0'; + +static serial_pkt_t pkt_bank[10]; +static p_cb_serial_pkt_t serial_pkt_cb; + +static volatile uint8_t index_tracker = 0; void UART1_RxCpltCallback(UART_HandleTypeDef *huart) { - serial_cb.push(&serial_cb, serial_cb_rxc); + switch (sstate) + { + case SS_IDLE: // packet start + { + if (rxc == 0x7E) + { + sstate = SS_START; + } + } + break; + case SS_START: + { + switch (index_tracker) + { + case 0: // source addr + { + serial_pkt_cb.buffer[serial_pkt_cb.head].src_addr = rxc; + } + break; + case 1: + { + serial_pkt_cb.buffer[serial_pkt_cb.head].dest_addr = rxc; + } + break; + case 2: + { + serial_pkt_cb.buffer[serial_pkt_cb.head].len = rxc; + } + break; + default: + { + // shouldnt get here + for (;;) + {} + } + }; + } + break; + case SS_ESC: + { + } + break; + case SS_CHECKSUM: + { + } + break; + default: + { + PDEBUG("Shouldn't have hit this!\n"); + } + }; + HAL_UART_Receive_IT(_serial_huart_inst, &rxc, 1); + // serial_cb.push(&serial_cb, serial_cb_rxc); // HAL_GPIO_WritePin(USART1_DE_GPIO_Port, USART1_DE_Pin, 1); // huart2_rxc = huart1_rxc; @@ -22,15 +100,13 @@ void p_serial_mgr_init(UART_HandleTypeDef *huart) _serial_huart_inst = huart; _serial_huart_inst->RxCpltCallback = UART1_RxCpltCallback; - memset(buffer, 0, MAX_SERIAL_BUFFER_SIZE); - p_cb_u8_init(&serial_cb, buffer, MAX_SERIAL_BUFFER_SIZE); + p_cb_serial_pkt_init(&serial_pkt_cb, pkt_bank, 10); } void p_serial_mgr_service(void) -{ -} +{} void p_serial_mgr_start() { - HAL_UART_Receive_IT(_serial_huart_inst, &serial_cb_rxc, 1); + HAL_UART_Receive_IT(_serial_huart_inst, &rxc, 1); } diff --git a/shared/drivers/p_serial_mgr.h b/shared/drivers/p_serial_mgr.h index 65aa5e9..2a024e6 100644 --- a/shared/drivers/p_serial_mgr.h +++ b/shared/drivers/p_serial_mgr.h @@ -2,6 +2,17 @@ #define _P_SERIAL_MGR_H_ #include "stm32l4xx_hal.h" +#include + +typedef struct serial_pkt_t +{ + uint8_t src_addr; + uint8_t dest_addr; + int len; + uint8_t frame_data[256]; + uint8_t checksum; +} serial_pkt_t; + void p_serial_mgr_init(UART_HandleTypeDef *huart); void p_serial_mgr_service(void); diff --git a/shared/util/PCircularBuffer.c b/shared/util/PCircularBuffer.c index ef98696..4d8177b 100644 --- a/shared/util/PCircularBuffer.c +++ b/shared/util/PCircularBuffer.c @@ -1,3 +1,4 @@ +#include "putil.h" #include // Error handler used for debugging only @@ -7,73 +8,20 @@ static void handle_status(const char *func, PB_CB_STATUS status_code) { if (status_code != PB_CB_GOOD) { - printf("%s failed: error code: %d\r\n", func, status_code); + PDEBUG("%s failed: error code: %d\r\n", func, status_code); } } #endif // Circular Buffer Prototypes -- uint8_t -#if PB_CB_U8 static PB_CB_STATUS p_cb_u8_push(p_cb_u8 *cbuffer, uint8_t value); static PB_CB_STATUS p_cb_u8_empty(p_cb_u8 *cbuffer); -#endif - -// Circular Buffer Prototypes -- uint16_t -#if PB_CB_U16 -static PB_CB_STATUS p_cb_u16_push(p_cb_double *cbuffer, uint16_t value); -static PB_CB_STATUS p_cb_u16_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- uint32_t -#if PB_CB_U32 -static PB_CB_STATUS p_cb_u32_push(p_cb_double *cbuffer, uint32_t value); -static PB_CB_STATUS p_cb_u32_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- uint64_t -#if PB_CB_U64 -static PB_CB_STATUS p_cb_u64_push(p_cb_double *cbuffer, uint64_t value); -static PB_CB_STATUS p_cb_u64_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- int8_t -#if PB_CB_I8 -static PB_CB_STATUS p_cb_i8_push(p_cb_double *cbuffer, int8_t value); -static PB_CB_STATUS p_cb_i8_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- int16_t -#if PB_CB_I16 -static PB_CB_STATUS p_cb_i16_push(p_cb_double *cbuffer, int16_t value); -static PB_CB_STATUS p_cb_i16_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- int32_t -#if PB_CB_I32 -static PB_CB_STATUS p_cb_i32_push(p_cb_double *cbuffer, int32_t value); -static PB_CB_STATUS p_cb_i32_empty(p_cb_double *cbuffer); -#endif -// Circular Buffer Prototypes -- int64_t -#if PB_CB_I64 -static PB_CB_STATUS p_cb_i64_push(p_cb_double *cbuffer, int64_t value); -static PB_CB_STATUS p_cb_i64_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- Float -#if PB_CB_FLOAT -static PB_CB_STATUS p_cb_float_push(p_cb_double *cbuffer, float value); -static PB_CB_STATUS p_cb_float_empty(p_cb_double *cbuffer); -#endif - -// Circular Buffer Prototypes -- Double -#if PB_CB_DOUBLE -static PB_CB_STATUS p_cb_double_push(p_cb_double *cbuffer, double value); -static PB_CB_STATUS p_cb_double_empty(p_cb_double *cbuffer); -#endif +// serial_pkt +static PB_CB_STATUS p_cb_serial_pkt_push(p_cb_serial_pkt_t *cbuffer, serial_pkt_t value); +static PB_CB_STATUS p_cb_serial_pkt_empty(p_cb_serial_pkt_t *cbuffer); // Circular Buffer Definitions -- uint8_t -#if PB_CB_U8 PB_CB_STATUS p_cb_u8_init(p_cb_u8 *circ_buffer, uint8_t *buff, uint32_t max_length) { PB_CB_STATUS ret = PB_CB_GOOD; @@ -123,6 +71,7 @@ PB_CB_STATUS p_cb_u8_push(p_cb_u8 *cbuffer, uint8_t value) return ret; } + PB_CB_STATUS p_cb_u8_empty(p_cb_u8 *cbuffer) { PB_CB_STATUS ret = PB_CB_GOOD; @@ -153,214 +102,9 @@ PB_CB_STATUS p_cb_u8_empty(p_cb_u8 *cbuffer) return ret; } -#endif -// Circular Buffer Definitions -- uint16_t -#if PB_CB_U16 -PB_CB_STATUS p_cb_u16_init(p_cb_u16 *circ_buffer, uint16_t *buff, uint32_t max_length) -{ - PB_CB_STATUS ret = PB_CB_GOOD; - do - { - // Make sure the buffer isn't bad (null) - if (!buff) - { - ret = PB_CB_NULL_BUFFER; - break; - } - - // Make sure the max buffer is a useable size - if (max_length > PB_CB_MAX_BUFFER_SIZE || max_length <= 0) - { - ret = PB_CB_BAD_BUFFER_SIZE; - break; - } - } while (0); - -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} - -PB_CB_STATUS p_cb_u16_push(p_cb_double *cbuffer, uint16_t value) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -PB_CB_STATUS p_cb_u16_empty(p_cb_double *cbuffer) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -#endif - -// Circular Buffer Definitions -- uint32_t -#if PB_CB_U32 -PB_CB_STATUS p_cb_u32_init(p_cb_u32 *circ_buffer, uint32_t *buff, uint32_t max_length) -{ - PB_CB_STATUS ret = PB_CB_GOOD; - do - { - // Make sure the buffer isn't bad (null) - if (!buff) - { - ret = PB_CB_NULL_BUFFER; - break; - } - - // Make sure the max buffer is a useable size - if (max_length > PB_CB_MAX_BUFFER_SIZE || max_length <= 0) - { - ret = PB_CB_BAD_BUFFER_SIZE; - break; - } - } while (0); - -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -PB_CB_STATUS p_cb_u32_push(p_cb_double *cbuffer, uint32_t value) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - return ret; -} -PB_CB_STATUS p_cb_u32_empty(p_cb_double *cbuffer) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -#endif - -// Circular Buffer Definitions -- uint64_t -#if PB_CB_U64 -PB_CB_STATUS p_cb_u64_init(p_cb_u64 *circ_buffer, uint64_t *buff, uint32_t max_length) -{ - PB_CB_STATUS ret = PB_CB_GOOD; - do - { - // Make sure the buffer isn't bad (null) - if (!buff) - { - ret = PB_CB_NULL_BUFFER; - break; - } - - // Make sure the max buffer is a useable size - if (max_length > PB_CB_MAX_BUFFER_SIZE || max_length <= 0) - { - ret = PB_CB_BAD_BUFFER_SIZE; - break; - } - } while (0); - -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -PB_CB_STATUS p_cb_u64_push(p_cb_double *cbuffer, uint64_t value) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -PB_CB_STATUS p_cb_u64_empty(p_cb_double *cbuffer) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -#endif - -#if PB_CB_FLOAT -PB_CB_STATUS p_cb_float_init(p_cb_float *circ_buffer, float *buff, uint32_t max_length) -{ - PB_CB_STATUS ret = PB_CB_GOOD; - do - { - // Make sure the buffer isn't bad (null) - if (!buff) - { - ret = PB_CB_NULL_BUFFER; - break; - } - - // Make sure the max buffer is a useable size - if (max_length > PB_CB_MAX_BUFFER_SIZE || max_length <= 0) - { - ret = PB_CB_BAD_BUFFER_SIZE; - break; - } - } while (0); - -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -PB_CB_STATUS p_cb_float_push(p_cb_double *cbuffer, float value) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -PB_CB_STATUS p_cb_float_empty(p_cb_double *cbuffer) -{ - PB_CB_STATUS ret = PB_CB_GOOD; -// Debugging -#ifdef PB_CB_DEBUG - handle_status(__func__, ret); -#endif - - return ret; -} -#endif - -// Circular Buffer Definitions -- double -#if PB_CB_DOUBLE -PB_CB_STATUS p_cb_double_init(p_cb_double *circ_buffer, double *buff, uint32_t max_length) +// Circular Buffer Definitions -- uint8_t +PB_CB_STATUS p_cb_serial_pkt_init(p_cb_serial_pkt_t *inst, serial_pkt_t *buff, uint32_t max_length) { PB_CB_STATUS ret = PB_CB_GOOD; do @@ -378,12 +122,6 @@ PB_CB_STATUS p_cb_double_init(p_cb_double *circ_buffer, double *buff, uint32_t m ret = PB_CB_BAD_BUFFER_SIZE; break; } - circ_buffer->buffer = buff; - circ_buffer->max_len = (uint16_t)max_length; - circ_buffer->head = 0; - circ_buffer->push = p_cb_double_push; - circ_buffer->empty = p_cb_double_empty; - circ_buffer->empty(circ_buffer); } while (0); // Debugging @@ -394,7 +132,7 @@ PB_CB_STATUS p_cb_double_init(p_cb_double *circ_buffer, double *buff, uint32_t m return ret; } -PB_CB_STATUS p_cb_double_push(p_cb_double *cbuffer, double value) +PB_CB_STATUS p_cb_serial_pkt_push(p_cb_serial_pkt_t *cbuffer, serial_pkt_t value) { PB_CB_STATUS ret = PB_CB_GOOD; @@ -415,7 +153,8 @@ PB_CB_STATUS p_cb_double_push(p_cb_double *cbuffer, double value) return ret; } -PB_CB_STATUS p_cb_double_empty(p_cb_double *cbuffer) + +PB_CB_STATUS p_cb_serial_pkt_empty(p_cb_serial_pkt_t *cbuffer) { PB_CB_STATUS ret = PB_CB_GOOD; @@ -432,7 +171,7 @@ PB_CB_STATUS p_cb_double_empty(p_cb_double *cbuffer) ret = PB_CB_NULL_BUFFER; break; } - memset(cbuffer->buffer, 0, sizeof(double) * cbuffer->max_len); + memset(cbuffer->buffer, 0, sizeof(serial_pkt_t) * cbuffer->max_len); cbuffer->head = 0; cbuffer->b_empty = true; cbuffer->b_filled = false; @@ -445,4 +184,3 @@ PB_CB_STATUS p_cb_double_empty(p_cb_double *cbuffer) return ret; } -#endif diff --git a/shared/util/PCircularBuffer.h b/shared/util/PCircularBuffer.h index 073ed2d..eff2410 100644 --- a/shared/util/PCircularBuffer.h +++ b/shared/util/PCircularBuffer.h @@ -31,43 +31,18 @@ #ifndef _PCIRCULARBUFFER_H_ #define _PCIRCULARBUFFER_H_ +#include "p_serial_mgr.h" #include #include -// comment this out for release builds -//#define PB_CB_DEBUG - -// Making these PB_EN/DIS rather than just ENABLE/DISABLE because -// some enable/disable definition might already exist that is -// inversely active (enabled = 0, disable = 1) -// this way our en/dis definitions are explicit -#ifndef PB_ENABLE -#define PB_ENABLE (1) -#endif - -#ifndef PB_DISABLE -#define PB_DISABLE (0) +#ifdef _DEBUG +#define PC_CB_DEBUG #endif // Max size is 65535 (2^16 - 1) so variables can be safely set 16 bits (unsigned) // If you want to change this, you'll need to change the sizes of all heads and max lengths #define PB_CB_MAX_BUFFER_SIZE (65535) -// Config -// Disable or Enable types needed here -// We can save code size this way -// While there are better ways to do this, this is the most accessible for anyone imo -#define PB_CB_FLOAT PB_DISABLE -#define PB_CB_DOUBLE PB_DISABLE -#define PB_CB_U8 PB_ENABLE -#define PB_CB_U16 PB_DISABLE -#define PB_CB_U32 PB_DISABLE -#define PB_CB_U64 PB_DISABLE -#define PB_CB_I8 PB_DISABLE -#define PB_CB_I16 PB_DISABLE -#define PB_CB_I32 PB_DISABLE -#define PB_CB_I64 PB_DISABLE - typedef enum PB_CB_STATUS { PB_CB_GOOD = 0, @@ -77,7 +52,6 @@ typedef enum PB_CB_STATUS PB_CB_NULL_CBUFFER = 4 } PB_CB_STATUS; -#if PB_CB_U8 typedef struct p_cb_u8 { uint8_t *buffer; @@ -95,106 +69,20 @@ typedef struct p_cb_u8 } p_cb_u8; PB_CB_STATUS p_cb_u8_init(p_cb_u8 *circ_buffer, uint8_t *buff, uint32_t max_length); -#endif - -#if PB_CB_U16 -typedef struct p_cb_u16 -{ - uint16_t *buffer; - uint16_t head; - uint16_t max_len; - // Signifies the buffer being filled at least once. - // Useful for initializing sensor data - bool b_filled; - // Signifies the buffer being empty - // Useful for knowing if data is being received - bool b_empty; - - PB_CB_STATUS (*push)(struct p_cb_u16 *cbuffer, uint16_t value); - PB_CB_STATUS (*empty)(struct p_cb_u16 *cbuffer); -} p_cb_u16; -PB_CB_STATUS p_cb_u16_init(p_cb_u16 *circ_buffer, uint16_t *buff, uint32_t max_length); -#endif - -#if PB_CB_U32 -typedef struct p_cb_u32 +typedef struct p_cb_serial_pkt_t { - uint32_t *buffer; + serial_pkt_t *buffer; uint16_t head; uint16_t max_len; - // Signifies the buffer being filled at least once. - // Useful for initializing sensor data bool b_filled; // Signifies the buffer being empty // Useful for knowing if data is being received bool b_empty; - PB_CB_STATUS (*push)(struct p_cb_u32 *cbuffer, uint32_t value); - PB_CB_STATUS (*empty)(struct p_cb_u32 *cbuffer); -} p_cb_u32; - -PB_CB_STATUS p_cb_u32_init(p_cb_u32 *circ_buffer, uint32_t *buff, uint32_t max_length); -#endif - -#if PB_CB_U64 -typedef struct p_cb_u64 -{ - uint64_t *buffer; - uint16_t head; - uint16_t max_len; - // Signifies the buffer being filled at least once. - // Useful for initializing sensor data - bool b_filled; - // Signifies the buffer being empty - // Useful for knowing if data is being received - bool b_empty; - - PB_CB_STATUS (*push)(struct p_cb_u64 *cbuffer, uint64_t value); - PB_CB_STATUS (*empty)(struct p_cb_u64 *cbuffer); -} p_cb_u64; - -PB_CB_STATUS p_cb_u64_init(p_cb_u64 *circ_buffer, uint64_t *buff, uint32_t max_length); -#endif - -#if PB_CB_FLOAT -typedef struct p_cb_float -{ - float *buffer; - uint16_t head; - uint16_t max_len; - // Signifies the buffer being filled at least once. - // Useful for initializing sensor data - bool b_filled; - // Signifies the buffer being empty - // Useful for knowing if data is being received - bool b_empty; - - PB_CB_STATUS (*push)(struct p_cb_float *cbuffer, float value); - PB_CB_STATUS (*empty)(struct p_cb_float *cbuffer); -} p_cb_float; - -PB_CB_STATUS p_cb_float_init(p_cb_float *circ_buffer, float *buff, uint32_t max_length); -#endif - -#if PB_CB_DOUBLE -typedef struct p_cb_double -{ - double *buffer; - uint16_t head; - uint16_t max_len; - // Signifies the buffer being filled at least once. - // Useful for initializing sensor data - bool b_filled; - // Signifies the buffer being empty - // Useful for knowing if data is being received - bool b_empty; - - PB_CB_STATUS (*push)(struct p_cb_double *cbuffer, double value); - PB_CB_STATUS (*empty)(struct p_cb_double *cbuffer); -} p_cb_double; - -PB_CB_STATUS p_cb_double_init(p_cb_double *circ_buffer, double *buff, uint32_t max_length); -#endif + PB_CB_STATUS (*push)(struct p_cb_u8 *cbuffer, uint8_t value); + PB_CB_STATUS (*empty)(struct p_cb_u8 *cbuffer); +} p_cb_serial_pkt_t; +PB_CB_STATUS p_cb_serial_pkt_init(p_cb_serial_pkt_t *inst, serial_pkt_t *buff, uint32_t max_length); #endif