aboutsummaryrefslogtreecommitdiff
path: root/quantum/serial_link/protocol/byte_stuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/serial_link/protocol/byte_stuffer.c')
-rw-r--r--quantum/serial_link/protocol/byte_stuffer.c135
1 files changed, 0 insertions, 135 deletions
diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c
deleted file mode 100644
index d3a91d828..000000000
--- a/quantum/serial_link/protocol/byte_stuffer.c
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2The MIT License (MIT)
3
4Copyright (c) 2016 Fred Sundvik
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
25#include "serial_link/protocol/byte_stuffer.h"
26#include "serial_link/protocol/frame_validator.h"
27#include "serial_link/protocol/physical.h"
28#include <stdbool.h>
29
30// This implements the "Consistent overhead byte stuffing protocol"
31// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing
32// http://www.stuartcheshire.org/papers/COBSforToN.pdf
33
34typedef struct byte_stuffer_state {
35 uint16_t next_zero;
36 uint16_t data_pos;
37 bool long_frame;
38 uint8_t data[MAX_FRAME_SIZE];
39} byte_stuffer_state_t;
40
41static byte_stuffer_state_t states[NUM_LINKS];
42
43void init_byte_stuffer_state(byte_stuffer_state_t* state) {
44 state->next_zero = 0;
45 state->data_pos = 0;
46 state->long_frame = false;
47}
48
49void init_byte_stuffer(void) {
50 int i;
51 for (i = 0; i < NUM_LINKS; i++) {
52 init_byte_stuffer_state(&states[i]);
53 }
54}
55
56void byte_stuffer_recv_byte(uint8_t link, uint8_t data) {
57 byte_stuffer_state_t* state = &states[link];
58 // Start of a new frame
59 if (state->next_zero == 0) {
60 state->next_zero = data;
61 state->long_frame = data == 0xFF;
62 state->data_pos = 0;
63 return;
64 }
65
66 state->next_zero--;
67 if (data == 0) {
68 if (state->next_zero == 0) {
69 // The frame is completed
70 if (state->data_pos > 0) {
71 validator_recv_frame(link, state->data, state->data_pos);
72 }
73 } else {
74 // The frame is invalid, so reset
75 init_byte_stuffer_state(state);
76 }
77 } else {
78 if (state->data_pos == MAX_FRAME_SIZE) {
79 // We exceeded our maximum frame size
80 // therefore there's nothing else to do than reset to a new frame
81 state->next_zero = data;
82 state->long_frame = data == 0xFF;
83 state->data_pos = 0;
84 } else if (state->next_zero == 0) {
85 if (state->long_frame) {
86 // This is part of a long frame, so continue
87 state->next_zero = data;
88 state->long_frame = data == 0xFF;
89 } else {
90 // Special case for zeroes
91 state->next_zero = data;
92 state->data[state->data_pos++] = 0;
93 }
94 } else {
95 state->data[state->data_pos++] = data;
96 }
97 }
98}
99
100static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) {
101 send_data(link, &num_non_zero, 1);
102 if (end > start) {
103 send_data(link, start, end - start);
104 }
105}
106
107void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) {
108 const uint8_t zero = 0;
109 if (size > 0) {
110 uint16_t num_non_zero = 1;
111 uint8_t* end = data + size;
112 uint8_t* start = data;
113 while (data < end) {
114 if (num_non_zero == 0xFF) {
115 // There's more data after big non-zero block
116 // So send it, and start a new block
117 send_block(link, start, data, num_non_zero);
118 start = data;
119 num_non_zero = 1;
120 } else {
121 if (*data == 0) {
122 // A zero encountered, so send the block
123 send_block(link, start, data, num_non_zero);
124 start = data + 1;
125 num_non_zero = 1;
126 } else {
127 num_non_zero++;
128 }
129 ++data;
130 }
131 }
132 send_block(link, start, data, num_non_zero);
133 send_data(link, &zero, 1);
134 }
135}