-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpacketserial.cpp
167 lines (134 loc) · 3.13 KB
/
packetserial.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "Serial.h"
#include "packetserial.h"
typedef enum {
IdleWait,
ReadLength,
Receiving,
CheckSum,
SendAck,
SendNack,
HandlePacket,
ResetBuffer
}
PacketSerialState;
#define ACK 0xFD
#define NACK 0xFE
#define STARTBYTE 0x02
#define PACKET_SERIAL_BUFFER_LENGTH 32
static PacketSerialState currentState;
static byte buffer[PACKET_SERIAL_BUFFER_LENGTH];
static byte length;
static byte position;
static boolean validate_checksum(byte checksum);
void packet_serial_send(byte* payload, byte length);
//extern void handle_packet(byte* payload, byte length);
void packet_serial_run(){
switch(currentState){
//States
case IdleWait:
//check for bytes waiting
if (Serial.available()){
if (Serial.read() == STARTBYTE)
currentState=ReadLength;
else
currentState=SendNack;
}
//if first byte = x02, state = ReadLength
//else send reject //ignore?
break;
case ReadLength:
//if byte waiting, packet length = byte value, state = receiving
if (Serial.available()){
length = Serial.read();
currentState=Receiving;
}
break;
case Receiving:
//if byte waiting
if (Serial.available()){
buffer[position++] = Serial.read(); //byte
//if position reachse length, state = checksum
if (position >= length){ //check this, is checksum part of length?
currentState=CheckSum;
}
}
break;
case CheckSum:
//if byte waiting,
if (Serial.available()){
byte checksum = Serial.read();
boolean valid = validate_checksum(checksum);
if (valid)
currentState=SendAck;
else
currentState=SendNack;
}
break;
case SendAck:
//send ack
Serial.write(ACK);
currentState=HandlePacket;
break;
case SendNack:
//send nack
Serial.write(NACK);
currentState=ResetBuffer;
break;
case HandlePacket:
//call process packet function
handle_packet(buffer,length);
currentState = ResetBuffer;
break;
case ResetBuffer:
//reset buffer and length/position vars
int i;
for (i = 0; i < PACKET_SERIAL_BUFFER_LENGTH; i++){
buffer[i] = 0;
}
position = 0;
length = 0;
currentState = IdleWait;
break;
default:
//something terrible happened
currentState=ResetBuffer;
break;
}
}
static boolean validate_checksum(byte checksum){
byte bytesum = 0;
bytesum += length;
byte i;
for (i=0; i < length; i++){
bytesum = (byte) (bytesum + buffer[i]);
}
bytesum = (byte) (256 - bytesum);
if (bytesum == checksum){
return true;
}
else {
//log_debug("invalid packet checksum");
return false;
}
}
void packet_serial_send(byte* payload, byte length){
//Send start byte
Serial.write(STARTBYTE);
//Send Length
Serial.write(length);
//Send payload
byte i;
for (i = 0; i < length; i++){
Serial.write(payload[i]);
}
//Send checksum byte
byte bytesum = 0;
bytesum += length;
for (i=0; i < length; i++){
bytesum = (byte) (bytesum + payload[i]);
}
bytesum = (byte) (256 - bytesum);
Serial.write(bytesum);
//check response byte
byte resp = Serial.read();
}