Framework for reading and writing variables in real time on any MBED platform.

DistantIO

This is the C implementation of the DistantIO slave framework.

Library is working but slight API breaks may occur in the future. C++ version is also in development.

To get the master-side implementation, see https://github.com/Overdrivr/DistantIO

Committer:
Overdrivr
Date:
Tue Sep 15 15:27:55 2015 +0000
Revision:
0:c4676d32d381
Child:
1:aaffeb93f99b
Version not bug free (especially names should not be longer thant 8 characters or have spaces), but pretty reliable behavior. See github repo for tickets

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Overdrivr 0:c4676d32d381 1 /*
Overdrivr 0:c4676d32d381 2 * serial_protocol.c
Overdrivr 0:c4676d32d381 3 *
Overdrivr 0:c4676d32d381 4 * Created on: Oct 22, 2014
Overdrivr 0:c4676d32d381 5 * Author: B48923
Overdrivr 0:c4676d32d381 6 */
Overdrivr 0:c4676d32d381 7
Overdrivr 0:c4676d32d381 8 #include "protocol.h"
Overdrivr 0:c4676d32d381 9
Overdrivr 0:c4676d32d381 10 enum state
Overdrivr 0:c4676d32d381 11 {
Overdrivr 0:c4676d32d381 12 IDLE,
Overdrivr 0:c4676d32d381 13 IN_PROCESS
Overdrivr 0:c4676d32d381 14 };
Overdrivr 0:c4676d32d381 15 typedef enum state state;
Overdrivr 0:c4676d32d381 16
Overdrivr 0:c4676d32d381 17
Overdrivr 0:c4676d32d381 18 enum ESC_state
Overdrivr 0:c4676d32d381 19 {
Overdrivr 0:c4676d32d381 20 NONE,
Overdrivr 0:c4676d32d381 21 NEXT
Overdrivr 0:c4676d32d381 22 };
Overdrivr 0:c4676d32d381 23 typedef enum ESC_state ESC_state;
Overdrivr 0:c4676d32d381 24
Overdrivr 0:c4676d32d381 25 uint16_t decodingIndex;
Overdrivr 0:c4676d32d381 26 state protocol_state;
Overdrivr 0:c4676d32d381 27 ESC_state escape_state;
Overdrivr 0:c4676d32d381 28
Overdrivr 0:c4676d32d381 29 uint8_t SOF_;
Overdrivr 0:c4676d32d381 30 uint8_t EOF_;
Overdrivr 0:c4676d32d381 31 uint8_t ESC_;
Overdrivr 0:c4676d32d381 32
Overdrivr 0:c4676d32d381 33 static void (*on_encoding_done)(uint8_t* data, uint16_t size);
Overdrivr 0:c4676d32d381 34 static void (*on_decoding_done)(uint8_t* data, uint16_t size);
Overdrivr 0:c4676d32d381 35
Overdrivr 0:c4676d32d381 36
Overdrivr 0:c4676d32d381 37 void init_protocol(void (*encoding_done_callback)(uint8_t*,uint16_t),void (*decoding_done_callback)(uint8_t*,uint16_t))
Overdrivr 0:c4676d32d381 38 {
Overdrivr 0:c4676d32d381 39 protocol_state = IDLE;
Overdrivr 0:c4676d32d381 40 escape_state = NONE;
Overdrivr 0:c4676d32d381 41
Overdrivr 0:c4676d32d381 42 SOF_ = 0xF7;
Overdrivr 0:c4676d32d381 43 EOF_ = 0x7F;
Overdrivr 0:c4676d32d381 44 ESC_ = 0x7D;
Overdrivr 0:c4676d32d381 45
Overdrivr 0:c4676d32d381 46 decodingIndex = 0;
Overdrivr 0:c4676d32d381 47
Overdrivr 0:c4676d32d381 48 on_encoding_done = encoding_done_callback;
Overdrivr 0:c4676d32d381 49 on_decoding_done = decoding_done_callback;
Overdrivr 0:c4676d32d381 50 }
Overdrivr 0:c4676d32d381 51
Overdrivr 0:c4676d32d381 52 void encode(uint8_t* framedata, uint16_t framesize)
Overdrivr 0:c4676d32d381 53 {
Overdrivr 0:c4676d32d381 54 // If frame size is superior than maximum allowed, abort
Overdrivr 0:c4676d32d381 55 if(framesize > ENCODING_BUFFER_SIZE)
Overdrivr 0:c4676d32d381 56 return;
Overdrivr 0:c4676d32d381 57
Overdrivr 0:c4676d32d381 58 // Actual buffer size is twice the data size (for worst case byte stuffing) + SOF + EOF
Overdrivr 0:c4676d32d381 59 static uint8_t encodingBuffer[ENCODING_BUFFER_SIZE * 2 + 2];
Overdrivr 0:c4676d32d381 60
Overdrivr 0:c4676d32d381 61 uint16_t index = 0, i = 0;
Overdrivr 0:c4676d32d381 62
Overdrivr 0:c4676d32d381 63 //Write start of frame / end of frame byte
Overdrivr 0:c4676d32d381 64 encodingBuffer[index++] = SOF_;
Overdrivr 0:c4676d32d381 65
Overdrivr 0:c4676d32d381 66 //Write data
Overdrivr 0:c4676d32d381 67 for(i = 0 ; i < framesize ; i++)
Overdrivr 0:c4676d32d381 68 {
Overdrivr 0:c4676d32d381 69 //See serial_protocols_definition.xlsx
Overdrivr 0:c4676d32d381 70 if(*(framedata + i) == SOF_ ||
Overdrivr 0:c4676d32d381 71 *(framedata + i) == EOF_ ||
Overdrivr 0:c4676d32d381 72 *(framedata + i) == ESC_)
Overdrivr 0:c4676d32d381 73 {
Overdrivr 0:c4676d32d381 74 //If data contains one of the flags, we escape it before
Overdrivr 0:c4676d32d381 75 encodingBuffer[index++] = ESC_;
Overdrivr 0:c4676d32d381 76 }
Overdrivr 0:c4676d32d381 77 encodingBuffer[index++] = framedata[i];
Overdrivr 0:c4676d32d381 78 }
Overdrivr 0:c4676d32d381 79
Overdrivr 0:c4676d32d381 80 encodingBuffer[index++] = EOF_;
Overdrivr 0:c4676d32d381 81
Overdrivr 0:c4676d32d381 82 // Operation is done, call function callback
Overdrivr 0:c4676d32d381 83 on_encoding_done(encodingBuffer,index);
Overdrivr 0:c4676d32d381 84 }
Overdrivr 0:c4676d32d381 85
Overdrivr 0:c4676d32d381 86 void decode(uint8_t received_byte)
Overdrivr 0:c4676d32d381 87 {
Overdrivr 0:c4676d32d381 88 static uint8_t decodingBuffer[DECODING_BUFFER_SIZE];
Overdrivr 0:c4676d32d381 89
Overdrivr 0:c4676d32d381 90 // If a reception was in process
Overdrivr 0:c4676d32d381 91 if(protocol_state == IN_PROCESS)
Overdrivr 0:c4676d32d381 92 {
Overdrivr 0:c4676d32d381 93 // If the character was previously marked as pure data
Overdrivr 0:c4676d32d381 94 if(escape_state == NEXT)
Overdrivr 0:c4676d32d381 95 {
Overdrivr 0:c4676d32d381 96 // If max buffer size was reached, cancel reception to avoid overflowing buffer
Overdrivr 0:c4676d32d381 97 if(decodingIndex + 1 >= DECODING_BUFFER_SIZE)
Overdrivr 0:c4676d32d381 98 {
Overdrivr 0:c4676d32d381 99 decodingIndex = 0;
Overdrivr 0:c4676d32d381 100 protocol_state = IDLE;
Overdrivr 0:c4676d32d381 101 escape_state = NONE;
Overdrivr 0:c4676d32d381 102 }
Overdrivr 0:c4676d32d381 103 else
Overdrivr 0:c4676d32d381 104 {
Overdrivr 0:c4676d32d381 105 decodingBuffer[decodingIndex++] = received_byte;
Overdrivr 0:c4676d32d381 106 escape_state = NONE;
Overdrivr 0:c4676d32d381 107 }
Overdrivr 0:c4676d32d381 108 }
Overdrivr 0:c4676d32d381 109 else
Overdrivr 0:c4676d32d381 110 {
Overdrivr 0:c4676d32d381 111 // End of frame
Overdrivr 0:c4676d32d381 112 if(received_byte == EOF_)
Overdrivr 0:c4676d32d381 113 {
Overdrivr 0:c4676d32d381 114 protocol_state = IDLE;
Overdrivr 0:c4676d32d381 115 // Call the function callback for end of frame
Overdrivr 0:c4676d32d381 116 on_decoding_done(decodingBuffer,decodingIndex);
Overdrivr 0:c4676d32d381 117 }
Overdrivr 0:c4676d32d381 118 else if(received_byte == ESC_)
Overdrivr 0:c4676d32d381 119 {
Overdrivr 0:c4676d32d381 120 escape_state = NEXT;
Overdrivr 0:c4676d32d381 121 }
Overdrivr 0:c4676d32d381 122 else
Overdrivr 0:c4676d32d381 123 {
Overdrivr 0:c4676d32d381 124 // If max buffer size was reached, cancel reception to avoid overflowing buffer
Overdrivr 0:c4676d32d381 125 if(decodingIndex + 1 >= DECODING_BUFFER_SIZE)
Overdrivr 0:c4676d32d381 126 {
Overdrivr 0:c4676d32d381 127 decodingIndex = 0;
Overdrivr 0:c4676d32d381 128 protocol_state = IDLE;
Overdrivr 0:c4676d32d381 129 escape_state = NONE;
Overdrivr 0:c4676d32d381 130 }
Overdrivr 0:c4676d32d381 131 else
Overdrivr 0:c4676d32d381 132 {
Overdrivr 0:c4676d32d381 133 decodingBuffer[decodingIndex++] = received_byte;
Overdrivr 0:c4676d32d381 134 escape_state = NONE;
Overdrivr 0:c4676d32d381 135 }
Overdrivr 0:c4676d32d381 136 }
Overdrivr 0:c4676d32d381 137 }
Overdrivr 0:c4676d32d381 138 }
Overdrivr 0:c4676d32d381 139 else
Overdrivr 0:c4676d32d381 140 {
Overdrivr 0:c4676d32d381 141 if(received_byte == SOF_)
Overdrivr 0:c4676d32d381 142 {
Overdrivr 0:c4676d32d381 143 protocol_state = IN_PROCESS;
Overdrivr 0:c4676d32d381 144 decodingIndex = 0;
Overdrivr 0:c4676d32d381 145 escape_state = NONE;
Overdrivr 0:c4676d32d381 146 }
Overdrivr 0:c4676d32d381 147 else
Overdrivr 0:c4676d32d381 148 {
Overdrivr 0:c4676d32d381 149 //Received character outside a valid frame, ignore it
Overdrivr 0:c4676d32d381 150 }
Overdrivr 0:c4676d32d381 151 }
Overdrivr 0:c4676d32d381 152 }
Overdrivr 0:c4676d32d381 153
Overdrivr 0:c4676d32d381 154
Overdrivr 0:c4676d32d381 155