Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
pprz_transport.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Pascal Brisset, Antoine Drouin
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
41 #ifndef PPRZ_TRANSPORT_H
42 #define PPRZ_TRANSPORT_H
43 
44 #include <inttypes.h>
45 #include "std.h"
46 #ifndef PPRZ_DATALINK_EXPORT
49 #else /* PPRZ_DATALINK_EXPORT defined */
50 #include "datalink.h"
51 #include "transport.h"
52 #endif
53 
54 /* PPRZ Transport
55  * downlink macros
56  */
57 extern uint8_t ck_a, ck_b;
58 
59 #define STX 0x99
60 
62 #define PprzTransportSizeOf(_dev, _payload) (_payload+4)
63 
64 #define PprzTransportCheckFreeSpace(_dev, _x) TransportLink(_dev, CheckFreeSpace(_x))
65 #define PprzTransportPut1Byte(_dev, _x) TransportLink(_dev, Transmit(_x))
66 #define PprzTransportSendMessage(_dev) TransportLink(_dev, SendMessage())
67 
68 #define PprzTransportHeader(_dev, payload_len) { \
69  PprzTransportPut1Byte(_dev, STX); \
70  uint8_t msg_len = PprzTransportSizeOf(_dev, payload_len); \
71  PprzTransportPut1Byte(_dev, msg_len); \
72  ck_a = msg_len; ck_b = msg_len; \
73 }
74 
75 #define PprzTransportTrailer(_dev) { \
76  PprzTransportPut1Byte(_dev, ck_a); \
77  PprzTransportPut1Byte(_dev, ck_b); \
78  PprzTransportSendMessage(_dev); \
79 }
80 
81 #define PprzTransportPutUint8(_dev, _byte) { \
82  ck_a += _byte; \
83  ck_b += ck_a; \
84  PprzTransportPut1Byte(_dev, _byte); \
85  }
86 
87 #define PprzTransportPutNamedUint8(_dev, _name, _byte) PprzTransportPutUint8(_dev, _byte)
88 
89 #define PprzTransportPut1ByteByAddr(_dev, _byte) { \
90  uint8_t _x = *(_byte); \
91  PprzTransportPutUint8(_dev, _x); \
92  }
93 
94 #define PprzTransportPut2ByteByAddr(_dev, _byte) { \
95  PprzTransportPut1ByteByAddr(_dev, _byte); \
96  PprzTransportPut1ByteByAddr(_dev, (const uint8_t*)_byte+1); \
97  }
98 
99 #define PprzTransportPut4ByteByAddr(_dev, _byte) { \
100  PprzTransportPut2ByteByAddr(_dev, _byte); \
101  PprzTransportPut2ByteByAddr(_dev, (const uint8_t*)_byte+2); \
102  }
103 
104 #ifdef __IEEE_BIG_ENDIAN /* From machine/ieeefp.h */
105 #define PprzTransportPutDoubleByAddr(_dev, _byte) { \
106  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte+4); \
107  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte); \
108  }
109 #define PprzTransportPutUint64ByAddr(_dev, _byte) { \
110  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte+4); \
111  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte); \
112  }
113 #define PprzTransportPutInt64ByAddr(_dev, _byte) { \
114  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte+4); \
115  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte); \
116  }
117 #else
118 #define PprzTransportPutDoubleByAddr(_dev, _byte) { \
119  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte); \
120  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte+4); \
121  }
122 #define PprzTransportPutUint64ByAddr(_dev, _byte) { \
123  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte); \
124  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte+4); \
125  }
126 #define PprzTransportPutInt64ByAddr(_dev, _byte) { \
127  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte); \
128  PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_byte+4); \
129  }
130 #endif
131 
132 
133 #define PprzTransportPutInt8ByAddr(_dev, _x) PprzTransportPut1ByteByAddr(_dev, _x)
134 #define PprzTransportPutUint8ByAddr(_dev, _x) PprzTransportPut1ByteByAddr(_dev, (const uint8_t*)_x)
135 #define PprzTransportPutInt16ByAddr(_dev, _x) PprzTransportPut2ByteByAddr(_dev, (const uint8_t*)_x)
136 #define PprzTransportPutUint16ByAddr(_dev, _x) PprzTransportPut2ByteByAddr(_dev, (const uint8_t*)_x)
137 #define PprzTransportPutInt32ByAddr(_dev, _x) PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_x)
138 #define PprzTransportPutUint32ByAddr(_dev, _x) PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_x)
139 #define PprzTransportPutFloatByAddr(_dev, _x) PprzTransportPut4ByteByAddr(_dev, (const uint8_t*)_x)
140 #define PprzTransportPutCharByAddr(_dev, _x) PprzTransportPut1ByteByAddr(_dev, (const uint8_t*)_x)
141 
142 #define PprzTransportPutArray(_dev, _put, _n, _x) { \
143  uint8_t _i; \
144  PprzTransportPutUint8(_dev, _n); \
145  for(_i = 0; _i < _n; _i++) { \
146  _put(_dev, &_x[_i]); \
147  } \
148 }
149 
150 #define PprzTransportPutInt8Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutInt8ByAddr, _n, _x)
151 #define PprzTransportPutUint8Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutUint8ByAddr, _n, _x)
152 
153 #define PprzTransportPutCharArray(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutCharByAddr, _n, _x)
154 
155 #define PprzTransportPutInt16Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutInt16ByAddr, _n, _x)
156 #define PprzTransportPutUint16Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutUint16ByAddr, _n, _x)
157 
158 #define PprzTransportPutInt32Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutInt32ByAddr, _n, _x)
159 #define PprzTransportPutUint32Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutUint32ByAddr, _n, _x)
160 
161 #define PprzTransportPutFloatArray(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutFloatByAddr, _n, _x)
162 
163 #define PprzTransportPutInt64Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutInt64ByAddr, _n, _x)
164 #define PprzTransportPutUint64Array(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutUint64ByAddr, _n, _x)
165 
166 #define PprzTransportPutDoubleArray(_dev, _n, _x) PprzTransportPutArray(_dev, PprzTransportPutDoubleByAddr, _n, _x)
167 
168 #define PprzTransportPutFixedArray(_dev, _put, _n, _x) { \
169  uint8_t _i; \
170  for(_i = 0; _i < _n; _i++) { \
171  _put(_dev, &_x[_i]); \
172  } \
173 }
174 
175 #define PprzTransportPutInt8FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutInt8ByAddr, _n, _x)
176 #define PprzTransportPutUint8FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutUint8ByAddr, _n, _x)
177 
178 #define PprzTransportPutCharFixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutCharByAddr, _n, _x)
179 
180 #define PprzTransportPutInt16FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutInt16ByAddr, _n, _x)
181 #define PprzTransportPutUint16FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutUint16ByAddr, _n, _x)
182 
183 #define PprzTransportPutInt32FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutInt32ByAddr, _n, _x)
184 #define PprzTransportPutUint32FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutUint32ByAddr, _n, _x)
185 
186 #define PprzTransportPutFloatFixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutFloatByAddr, _n, _x)
187 
188 #define PprzTransportPutInt64FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutInt64ByAddr, _n, _x)
189 #define PprzTransportPutUint64FixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutUint64ByAddr, _n, _x)
190 
191 #define PprzTransportPutDoubleFixedArray(_dev, _n, _x) PprzTransportPutFixedArray(_dev, PprzTransportPutDoubleByAddr, _n, _x)
192 
195 // PPRZ parsing state machine
196 #define UNINIT 0
197 #define GOT_STX 1
198 #define GOT_LENGTH 2
199 #define GOT_PAYLOAD 3
200 #define GOT_CRC1 4
201 
203  // generic interface
204  struct transport trans;
205  // specific pprz transport variables
209 };
210 
211 extern struct pprz_transport pprz_tp;
212 
213 static inline void parse_pprz(struct pprz_transport * t, uint8_t c ) {
214  switch (t->status) {
215  case UNINIT:
216  if (c == STX)
217  t->status++;
218  break;
219  case GOT_STX:
220  if (t->trans.msg_received) {
221  t->trans.ovrn++;
222  goto error;
223  }
224  t->trans.payload_len = c-4; /* Counting STX, LENGTH and CRC1 and CRC2 */
225  t->ck_a = t->ck_b = c;
226  t->status++;
227  t->payload_idx = 0;
228  break;
229  case GOT_LENGTH:
230  t->trans.payload[t->payload_idx] = c;
231  t->ck_a += c; t->ck_b += t->ck_a;
232  t->payload_idx++;
233  if (t->payload_idx == t->trans.payload_len)
234  t->status++;
235  break;
236  case GOT_PAYLOAD:
237  if (c != t->ck_a)
238  goto error;
239  t->status++;
240  break;
241  case GOT_CRC1:
242  if (c != t->ck_b)
243  goto error;
244  t->trans.msg_received = TRUE;
245  goto restart;
246  default:
247  goto error;
248  }
249  return;
250  error:
251  t->trans.error++;
252  restart:
253  t->status = UNINIT;
254  return;
255 }
256 
257 static inline void pprz_parse_payload(struct pprz_transport * t) {
258  uint8_t i;
259  for(i = 0; i < t->trans.payload_len; i++)
260  dl_buffer[i] = t->trans.payload[i];
262 }
263 
264 
265 #define PprzBuffer(_dev) TransportLink(_dev,ChAvailable())
266 #define ReadPprzBuffer(_dev,_trans) { while (TransportLink(_dev,ChAvailable())&&!(_trans.trans.msg_received)) parse_pprz(&(_trans),TransportLink(_dev,Getch())); }
267 #define PprzCheckAndParse(_dev,_trans) { \
268  if (PprzBuffer(_dev)) { \
269  ReadPprzBuffer(_dev,_trans); \
270  if (_trans.trans.msg_received) { \
271  pprz_parse_payload(&(_trans)); \
272  _trans.trans.msg_received = FALSE; \
273  } \
274  } \
275 }
276 
277 
278 #endif /* PPRZ_TRANSPORT_H */
279 
generic transport header
#define GOT_PAYLOAD
static void parse_pprz(struct pprz_transport *t, uint8_t c)
Generic transport header.
Definition: transport.h:39
struct transport trans
#define GOT_STX
bool_t dl_msg_available
Definition: main_demo5.c:56
uint8_t ck_a
volatile uint8_t payload_len
Definition: transport.h:43
uint8_t payload[TRANSPORT_PAYLOAD_LEN]
Definition: transport.h:41
#define UNINIT
Receiving pprz messages.
#define TRUE
Definition: imu_chimu.h:144
unsigned char uint8_t
Definition: types.h:14
#define STX
#define GOT_CRC1
volatile bool_t msg_received
Definition: transport.h:45
uint8_t dl_buffer[MSG_SIZE]
Definition: main_demo5.c:59
uint8_t ck_b
uint8_t ovrn
Definition: transport.h:47
#define GOT_LENGTH
static void pprz_parse_payload(struct pprz_transport *t)
uint8_t error
Definition: transport.h:47
struct pprz_transport pprz_tp