-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProtocol.cpp
More file actions
238 lines (208 loc) · 7.96 KB
/
Protocol.cpp
File metadata and controls
238 lines (208 loc) · 7.96 KB
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#include "Arduino.h"
#include "config.h"
#include "def.h"
#include "types.h"
#include "EEPROM.h"
#include "LCD.h"
#include "Serial.h"
#include "Protocol.h"
/************************************** MultiWii Serial Protocol *******************************************************/
// Multiwii Serial Protocol 0
#define MSP_VERSION 0
//to multiwii developpers/committers : do not add new MSP messages without a proper argumentation/agreement on the forum
#define MSP_IDENT 100 //out message multitype + multiwii version + protocol version + capability variable
#define MSP_STATUS 101 //out message cycletime & errors_count & sensor present & box activation & current setting number
#define MSP_RAW_IMU 102 //out message 9 DOF
#define MSP_SERVO 103 //out message 8 servos
#define MSP_MOTOR 104 //out message 8 motors
#define MSP_RC 105 //out message 8 rc chan and more
#define MSP_RAW_GPS 106 //out message fix, numsat, lat, lon, alt, speed, ground course
#define MSP_COMP_GPS 107 //out message distance home, direction home
#define MSP_ATTITUDE 108 //out message 2 angles 1 heading
#define MSP_ALTITUDE 109 //out message altitude, variometer
#define MSP_ANALOG 110 //out message vbat, powermetersum, rssi if available on RX
#define MSP_RC_TUNING 111 //out message rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID
#define MSP_PID 112 //out message P I D coeff (9 are used currently)
#define MSP_BOX 113 //out message BOX setup (number is dependant of your setup)
#define MSP_MISC 114 //out message powermeter trig
#define MSP_MOTOR_PINS 115 //out message which pins are in use for motors & servos, for GUI
#define MSP_BOXNAMES 116 //out message the aux switch names
#define MSP_PIDNAMES 117 //out message the PID names
#define MSP_WP 118 //out message get a WP, WP# is in the payload, returns (WP#, lat, lon, alt, flags) WP#0-home, WP#16-poshold
#define MSP_BOXIDS 119 //out message get the permanent IDs associated to BOXes
#define MSP_SERVO_CONF 120 //out message Servo settings
#define MSP_SET_RAW_RC 200 //in message 8 rc chan
#define MSP_SET_RAW_GPS 201 //in message fix, numsat, lat, lon, alt, speed
#define MSP_SET_PID 202 //in message P I D coeff (9 are used currently)
#define MSP_SET_BOX 203 //in message BOX setup (number is dependant of your setup)
#define MSP_SET_RC_TUNING 204 //in message rc rate, rc expo, rollpitch rate, yaw rate, dyn throttle PID
#define MSP_ACC_CALIBRATION 205 //in message no param
#define MSP_MAG_CALIBRATION 206 //in message no param
#define MSP_SET_MISC 207 //in message powermeter trig + 8 free for future use
#define MSP_RESET_CONF 208 //in message no param
#define MSP_SET_WP 209 //in message sets a given WP (WP#,lat, lon, alt, flags)
#define MSP_SELECT_SETTING 210 //in message Select Setting Number (0-2)
#define MSP_SET_HEAD 211 //in message define a new heading hold direction
#define MSP_SET_SERVO_CONF 212 //in message Servo settings
#define MSP_SET_MOTOR 214 //in message PropBalance function
#define MSP_BIND 240 //in message no param
#define MSP_EEPROM_WRITE 250 //in message no param
#define MSP_DEBUGMSG 253 //out message debug string buffer
#define MSP_DEBUG 254 //out message debug1,debug2,debug3,debug4
#ifdef DEBUGMSG
#define DEBUG_MSG_BUFFER_SIZE 128
static char debug_buf[DEBUG_MSG_BUFFER_SIZE];
static uint8_t head_debug;
static uint8_t tail_debug;
static uint8_t debugmsg_available();
static void debugmsg_serialize(uint8_t l);
#endif
static uint8_t CURRENTPORT=0;
#define INBUF_SIZE 64
static uint8_t inBuf[INBUF_SIZE][UART_NUMBER];
static uint8_t checksum[UART_NUMBER];
static uint8_t indRX[UART_NUMBER];
static uint8_t cmdMSP[UART_NUMBER];
void evaluateOtherData(uint8_t sr);
#ifndef SUPPRESS_ALL_SERIAL_MSP
void evaluateCommand();
#endif
#define BIND_CAPABLE 0; //Used for Spektrum today; can be used in the future for any RX type that needs a bind and has a MultiWii module.
#if defined(SPEK_BIND)
#define BIND_CAPABLE 1;
#endif
// Capability is bit flags; next defines should be 2, 4, 8...
const uint32_t capability = 0+BIND_CAPABLE;
uint8_t read8() {
return inBuf[indRX[CURRENTPORT]++][CURRENTPORT]&0xff;
}
uint16_t read16() {
uint16_t t = read8();
t+= (uint16_t)read8()<<8;
return t;
}
uint32_t read32() {
uint32_t t = read16();
t+= (uint32_t)read16()<<16;
return t;
}
void serialize8(uint8_t a) {
SerialSerialize(CURRENTPORT,a);
checksum[CURRENTPORT] ^= a;
}
void serialize16(int16_t a) {
serialize8((a ) & 0xFF);
serialize8((a>>8) & 0xFF);
}
void serialize32(uint32_t a) {
serialize8((a ) & 0xFF);
serialize8((a>> 8) & 0xFF);
serialize8((a>>16) & 0xFF);
serialize8((a>>24) & 0xFF);
}
void headSerialResponse(uint8_t err, uint8_t s) {
serialize8('$');
serialize8('M');
serialize8(err ? '!' : '>');
checksum[CURRENTPORT] = 0; // start calculating a new checksum
serialize8(s);
serialize8(cmdMSP[CURRENTPORT]);
}
void headSerialReply(uint8_t s) {
headSerialResponse(0, s);
}
void inline headSerialError(uint8_t s) {
headSerialResponse(1, s);
}
void tailSerialReply() {
UartSendData(CURRENTPORT);
}
void serializeNames(PGM_P s) {
headSerialReply(strlen_P(s));
for (PGM_P c = s; pgm_read_byte(c); c++) {
serialize8(pgm_read_byte(c));
}
}
void serialCom() {
uint8_t c,n;
static uint8_t offset[UART_NUMBER];
static uint8_t dataSize[UART_NUMBER];
static enum _serial_state {
IDLE,
HEADER_START,
HEADER_M,
HEADER_ARROW,
HEADER_SIZE,
HEADER_CMD,
} c_state[UART_NUMBER];// = IDLE;
for(n=0;n<UART_NUMBER;n++) {
#if !defined(PROMINI)
CURRENTPORT=n;
#endif
#define GPS_COND
#if defined(GPS_SERIAL)
#if defined(GPS_PROMINI)
#define GPS_COND
#else
#undef GPS_COND
#define GPS_COND && (GPS_SERIAL != CURRENTPORT)
#endif
#endif
#define SPEK_COND
#if defined(SPEKTRUM) && (UART_NUMBER > 1)
#define SPEK_COND && (SPEK_SERIAL_PORT != CURRENTPORT)
#endif
#define SBUS_COND
#if defined(SBUS) && (UART_NUMBER > 1)
#define SBUS_COND && (SBUS_SERIAL_PORT != CURRENTPORT)
#endif
evaluateCommand();
}
}
void s_struct(uint8_t *cb,uint8_t siz) {
headSerialReply(siz);
while(siz--) serialize8(*cb++);
}
void s_struct_w(uint8_t *cb,uint8_t siz) {
headSerialReply(0);
while(siz--) *cb++ = read8();
}
#ifndef SUPPRESS_ALL_SERIAL_MSP
void evaluateCommand() {
uint8_t size = debugmsg_available();
if (size > 16) size = 16;
debugmsg_serialize(size);
tailSerialReply();
}
#endif // SUPPRESS_ALL_SERIAL_MSP
#ifdef DEBUGMSG
void debugmsg_append_str(const char *str) {
while(*str) {
debug_buf[head_debug++] = *str++;
if (head_debug == DEBUG_MSG_BUFFER_SIZE) {
head_debug = 0;
}
}
}
static uint8_t debugmsg_available() {
if (head_debug >= tail_debug) {
return head_debug-tail_debug;
} else {
return head_debug + (DEBUG_MSG_BUFFER_SIZE-tail_debug);
}
}
static void debugmsg_serialize(uint8_t l) {
for (uint8_t i=0; i<l; i++) {
if (head_debug != tail_debug) {
serialize8(debug_buf[tail_debug++]);
if (tail_debug == DEBUG_MSG_BUFFER_SIZE) {
tail_debug = 0;
}
} else {
//serialize8('\0');
}
}
}
#else
void debugmsg_append_str(const char *str) {};
#endif