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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers framing.cpp Source File

framing.cpp

00001 #include "framing.h"
00002 
00003 typedef enum _state
00004 {
00005   IDLE, // No incoming frame is in process
00006   ESCAPING, // incoming frame in process, next character to be escaped
00007   ACTIVE // frame in process
00008 } _state ;
00009 
00010 typedef struct storage storage;
00011 struct storage
00012 {
00013    uint8_t * ptr;
00014    uint32_t size;
00015    uint32_t cursor;
00016 
00017 };
00018 
00019 static storage incomingStorage;
00020 static storage outgoingStorage;
00021 
00022 int8_t safe_append(storage * s, uint8_t byte);
00023 
00024 static uint8_t SOF_;
00025 static uint8_t EOF_;
00026 static uint8_t ESC_;
00027 
00028 static _state incoming_state;
00029 
00030 void (*on_incoming_frame_cb)(uint8_t * storage, uint32_t occupiedSize);
00031 void (*on_error_cb)(int32_t errCode);
00032 
00033 void initialize_framing()
00034 {
00035   incomingStorage.ptr = NULL;
00036   outgoingStorage.ptr = NULL;
00037 
00038   incomingStorage.size = 0;
00039   outgoingStorage.size = 0;
00040 
00041   incomingStorage.cursor = 0;
00042   incomingStorage.cursor = 0;
00043 
00044   SOF_ = 0xF7;
00045   EOF_ = 0x7F;
00046   ESC_ = 0x7D;
00047 
00048   incoming_state = IDLE;
00049 }
00050 
00051 void outgoing_storage(uint8_t * buf, uint32_t bufSize)
00052 {
00053   outgoingStorage.ptr = buf;
00054   outgoingStorage.size = bufSize;
00055 }
00056 
00057 void begin()
00058 {
00059   if(outgoingStorage.size == 0 || outgoingStorage.ptr == NULL)
00060     return;
00061 
00062   outgoingStorage.cursor = 0;
00063 
00064   // Should not fail
00065   safe_append(&outgoingStorage,SOF_);
00066 }
00067 
00068 void append(uint8_t byte)
00069 {
00070   if(outgoingStorage.size == 0 || outgoingStorage.ptr == NULL)
00071     return;
00072 
00073   // byte == to flag, need to escape it
00074   if(byte == SOF_ || byte == EOF_ || byte == ESC_)
00075   {
00076     if(!safe_append(&outgoingStorage,ESC_))
00077       return;
00078   }
00079 
00080   if(!safe_append(&outgoingStorage,byte))
00081     return;
00082 }
00083 
00084 void append2(uint16_t twobytes)
00085 {
00086   uint8_t * ptr = (uint8_t*)(&twobytes);
00087   append(ptr[0]);
00088   append(ptr[1]);
00089 }
00090 
00091 void append4(uint32_t fourbytes)
00092 {
00093   uint8_t * ptr = (uint8_t*)(&fourbytes);
00094   append(ptr[0]);
00095   append(ptr[1]);
00096   append(ptr[2]);
00097   append(ptr[3]);
00098 }
00099 
00100 uint32_t end()
00101 {
00102   if(outgoingStorage.size == 0 || outgoingStorage.ptr == NULL)
00103     return 0;
00104 
00105   if(!safe_append(&outgoingStorage,EOF_))
00106     return 0;
00107 
00108   return outgoingStorage.cursor;
00109 }
00110 
00111 void incoming_storage(uint8_t * buf, uint32_t bufSize)
00112 {
00113   incomingStorage.ptr = buf;
00114   incomingStorage.size = bufSize;
00115 }
00116 
00117 void set_on_incoming_frame(void (*callback)(uint8_t * storage, uint32_t occupiedSize))
00118 {
00119   on_incoming_frame_cb = callback;
00120 }
00121 
00122 void set_on_incoming_error(void (*callback)(int32_t errCode))
00123 {
00124   on_error_cb = callback;
00125 }
00126 
00127 void feed(uint8_t byte)
00128 {
00129   if(incomingStorage.size == 0 || incomingStorage.ptr == NULL)
00130     return;
00131 
00132   if(incoming_state == ESCAPING)
00133   {
00134     if(!safe_append(&incomingStorage,byte))
00135     {
00136       incoming_state = IDLE;
00137       return;
00138     }
00139     incoming_state = ACTIVE;
00140     return;
00141   }
00142 
00143   if(byte == SOF_)
00144   {
00145       incoming_state = ACTIVE;
00146       incomingStorage.cursor = 0;
00147       return;
00148   }
00149 
00150   if(incoming_state == ACTIVE)
00151   {
00152     if(byte == EOF_)
00153     {
00154         incoming_state = IDLE;
00155         on_incoming_frame_cb(incomingStorage.ptr, incomingStorage.cursor);
00156     }
00157     // Escape next character
00158     else if(byte == ESC_)
00159     {
00160         incoming_state = ESCAPING;
00161     }
00162     else
00163     {
00164       if(!safe_append(&incomingStorage,byte))
00165       {
00166         incoming_state = IDLE;
00167         return;
00168       }
00169       incoming_state = ACTIVE;
00170     }
00171   }
00172 }
00173 
00174 int8_t safe_append(storage * s, uint8_t byte)
00175 {
00176   // Not enough space for 1 more character
00177   if(s->cursor + 1 >= s->size)
00178     return 0;
00179 
00180   s->ptr[s->cursor++] = byte;
00181 
00182   return 1;
00183 }