First class data visualization and communication library with embedded devices. Code is maintained at github.com/Overdrivr/Telemetry
Dependents: telemetry_car_demo telemetry_demo_FRDM-TFC telemetry_example_01 telemetry_indexed_data_demo ... more
Diff: c_api/framing.c
- Revision:
- 5:cd94bb58e096
- Parent:
- 3:37d2d127bc83
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c_api/framing.c Wed Mar 09 12:15:13 2016 +0000 @@ -0,0 +1,183 @@ +#include "framing.h" + +typedef enum _state +{ + IDLE, // No incoming frame is in process + ESCAPING, // incoming frame in process, next character to be escaped + ACTIVE // frame in process +} _state ; + +typedef struct storage storage; +struct storage +{ + uint8_t * ptr; + uint32_t size; + uint32_t cursor; + +}; + +static storage incomingStorage; +static storage outgoingStorage; + +int8_t safe_append(storage * s, uint8_t byte); + +static uint8_t SOF_; +static uint8_t EOF_; +static uint8_t ESC_; + +static _state incoming_state; + +void (*on_incoming_frame_cb)(uint8_t * storage, uint32_t occupiedSize); +void (*on_error_cb)(int32_t errCode); + +void initialize_framing() +{ + incomingStorage.ptr = NULL; + outgoingStorage.ptr = NULL; + + incomingStorage.size = 0; + outgoingStorage.size = 0; + + incomingStorage.cursor = 0; + incomingStorage.cursor = 0; + + SOF_ = 0xF7; + EOF_ = 0x7F; + ESC_ = 0x7D; + + incoming_state = IDLE; +} + +void outgoing_storage(uint8_t * buf, uint32_t bufSize) +{ + outgoingStorage.ptr = buf; + outgoingStorage.size = bufSize; +} + +void begin() +{ + if(outgoingStorage.size == 0 || outgoingStorage.ptr == NULL) + return; + + outgoingStorage.cursor = 0; + + // Should not fail + safe_append(&outgoingStorage,SOF_); +} + +void append(uint8_t byte) +{ + if(outgoingStorage.size == 0 || outgoingStorage.ptr == NULL) + return; + + // byte == to flag, need to escape it + if(byte == SOF_ || byte == EOF_ || byte == ESC_) + { + if(!safe_append(&outgoingStorage,ESC_)) + return; + } + + if(!safe_append(&outgoingStorage,byte)) + return; +} + +void append2(uint16_t twobytes) +{ + uint8_t * ptr = (uint8_t*)(&twobytes); + append(ptr[0]); + append(ptr[1]); +} + +void append4(uint32_t fourbytes) +{ + uint8_t * ptr = (uint8_t*)(&fourbytes); + append(ptr[0]); + append(ptr[1]); + append(ptr[2]); + append(ptr[3]); +} + +uint32_t end() +{ + if(outgoingStorage.size == 0 || outgoingStorage.ptr == NULL) + return 0; + + if(!safe_append(&outgoingStorage,EOF_)) + return 0; + + return outgoingStorage.cursor; +} + +void incoming_storage(uint8_t * buf, uint32_t bufSize) +{ + incomingStorage.ptr = buf; + incomingStorage.size = bufSize; +} + +void set_on_incoming_frame(void (*callback)(uint8_t * storage, uint32_t occupiedSize)) +{ + on_incoming_frame_cb = callback; +} + +void set_on_incoming_error(void (*callback)(int32_t errCode)) +{ + on_error_cb = callback; +} + +void feed(uint8_t byte) +{ + if(incomingStorage.size == 0 || incomingStorage.ptr == NULL) + return; + + if(incoming_state == ESCAPING) + { + if(!safe_append(&incomingStorage,byte)) + { + incoming_state = IDLE; + return; + } + incoming_state = ACTIVE; + return; + } + + if(byte == SOF_) + { + incoming_state = ACTIVE; + incomingStorage.cursor = 0; + return; + } + + if(incoming_state == ACTIVE) + { + if(byte == EOF_) + { + incoming_state = IDLE; + on_incoming_frame_cb(incomingStorage.ptr, incomingStorage.cursor); + } + // Escape next character + else if(byte == ESC_) + { + incoming_state = ESCAPING; + } + else + { + if(!safe_append(&incomingStorage,byte)) + { + incoming_state = IDLE; + return; + } + incoming_state = ACTIVE; + } + } +} + +int8_t safe_append(storage * s, uint8_t byte) +{ + // Not enough space for 1 more character + if(s->cursor + 1 >= s->size) + return 0; + + s->ptr[s->cursor++] = byte; + + return 1; +}