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
protocol.cpp@1:aaffeb93f99b, 2015-10-08 (annotated)
- Committer:
- Overdrivr
- Date:
- Thu Oct 08 12:27:20 2015 +0000
- Revision:
- 1:aaffeb93f99b
- Parent:
- 0:c4676d32d381
- Child:
- 6:72d46dbdbe7a
commit for publish
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:c4676d32d381 | 84 | static 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 |