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:
Fri Oct 16 16:16:19 2015 +0000
Revision:
6:72d46dbdbe7a
Parent:
1:aaffeb93f99b
removed 'static' keyword in front arrays that just increase RAM usage (premature optimization)

Who changed what in which revision?

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