outline text with black
[fpv.git] / mainboard / rc_proto.h
1 #ifndef RC_PROTO_H
2 #define RC_PROTO_H
3
4 /* generic header */
5 struct rc_proto_hdr {
6         uint8_t type;
7 } __attribute__((packed));
8
9
10 /* send a hello message, no answer is expected from the peer */
11 #define RC_PROTO_HELLO 0x00
12 struct rc_proto_hello {
13         uint8_t type;
14         uint8_t datalen; /* len of data excluding header */
15         uint8_t data[];
16 } __attribute__((packed));
17
18 /* send an echo request, expect an echo reply from the peer */
19 #define RC_PROTO_ECHO_REQ 0x01
20 struct rc_proto_echo_req {
21         uint8_t type;
22         int8_t power;
23         uint16_t timestamp; /* copied as-is in answer */
24         uint8_t datalen; /* len of data excluding header */
25         uint8_t data[];
26 } __attribute__((packed));
27
28 /* reply to an echo request */
29 #define RC_PROTO_ECHO_ANS 0x02
30 struct rc_proto_echo_ans {
31         uint8_t type;
32         uint16_t timestamp;
33         uint8_t datalen; /* len of data excluding header */
34         uint8_t data[];
35 } __attribute__((packed));
36
37 /* send a power level probe to the peer: no answer is expected, but the peer
38  * will know that a packet with this power-level is received. It can also ask
39  * the RSSI of this packet. */
40 #define RC_PROTO_POWER_PROBE 0x03
41 struct rc_proto_power_probe {
42         uint8_t type;
43         uint8_t power_level;
44 } __attribute__((packed));
45
46 /* acknowledge a servo command */
47 #define RC_PROTO_ACK 0x04
48 struct rc_proto_ack {
49         uint8_t type;
50         uint8_t seq;
51 } __attribute__((packed));
52
53 /*
54  * If type < 0x3f, it's a servo command. The size of the message is critical
55  * because it's send very often. The "type" field contains the bitfield of
56  * servos present in the body of the message. A sequence number (5bits) and the
57  * power level (3 bits) are also sent. The servos are listed as 10bits fields,
58  * without padding.
59  *
60  * Example: we send servo 0 (=0x123) and servo 3 (=0x234). Power = 2.
61  *   command type (RC_PROTO_SERVO)
62  *   power_level = 0 (3 bits, LSB)  \
63  *   bypass = 0 (1 bit)              > one byte
64  *   seq = 1 (4 bits, MSB)          /
65  *   servo_val[0]=0x123
66  *   servo_val[1]=0x234
67  *   servo_val[2]=0x321
68  *   servo_val[3]=0x123
69  *   servo_val[4]=0x234
70  *   servo_val[5]=0x321
71  *
72  * -> 0x05 0x10 0x48 0xe3 0x4c 0x85 0x23 0x8d 0x32 0x10
73  *    type psb  |ser0  ser1  ser2  ser3  |ser4  ser5
74  */
75 #define RC_PROTO_SERVO 0x05
76 #define RC_PROTO_SERVO_LEN 10 /* len of frame */
77 struct rc_proto_servo {
78         uint8_t type;
79         uint8_t data[];
80 };
81
82 /* send stats */
83 #define RC_PROTO_STATS 0x06
84 struct rc_proto_stats {
85         uint8_t type;
86         uint8_t stats[]; /* format is struct rc_proto_stats_data */
87 } __attribute__((packed));
88
89 /*
90  * GPS position
91  */
92 #define RC_PROTO_GPS_POS 0x07
93 struct rc_proto_gps_pos {
94         uint8_t type;
95
96         uint8_t valid;     /* 1 if position is valid */
97         int32_t latitude;  /* between -90e7 and 90e7, in 1/1e-7 degrees,
98                             * positive means north hemisphere */
99         int32_t longitude; /* between -180e7 and 180e7, in 1/1e-7 degrees,
100                             * positive means east */
101         uint32_t altitude; /* altitude from elipsoid, in 1/100 meters */
102 };
103
104 /*
105  * IMU position
106  */
107 #define RC_PROTO_IMU_POS 0x08
108 struct rc_proto_imu_pos {
109         uint8_t type;
110
111         uint8_t valid;
112         uint16_t roll;     /* XXX unit ? */
113         uint16_t pitch;
114         uint16_t yaw;
115 };
116
117
118 /* rc_proto timers configuration (default values in rc_proto.c) */
119 struct rc_proto_timers {
120         uint16_t send_servo_min_ms;
121         uint16_t send_servo_max_ms;
122         uint16_t send_power_probe_ms;
123         uint16_t send_gps_pos_ms;
124         uint16_t send_imu_pos_ms;
125         uint16_t autobypass_ms;
126 };
127 extern struct rc_proto_timers rc_proto_timers;
128
129 /* send a Hello message to a peer */
130 int8_t rc_proto_send_hello(uint64_t addr, void *data, uint8_t data_len,
131         int8_t power);
132
133 int8_t rc_proto_send_echo_req(uint64_t addr, void *data, uint8_t data_len,
134         int8_t power);
135
136 /* reception of a xbee message */
137 int rc_proto_rx(struct xbee_recv_hdr *recvframe, unsigned len);
138
139 /* dump statistics related to rc_proto */
140 void rc_proto_dump_stats(void);
141
142 /* reset statistics related to rc_proto */
143 void rc_proto_reset_stats(void);
144
145 /* set the peer xbee address */
146 void rc_proto_set_dstaddr(uint64_t addr);
147
148 /* get the peer xbee address */
149 uint64_t rc_proto_get_dstaddr(void);
150
151 void rc_proto_dump_servos(void);
152
153 /* tx mode */
154 #define RC_PROTO_FLAGS_TX_OFF        0x0000
155 #define RC_PROTO_FLAGS_TX_BYPASS     0x0001
156 #define RC_PROTO_FLAGS_TX_COPY_SPI   0x0002
157 #define RC_PROTO_FLAGS_TX_RESERVED   0x0003
158 #define RC_PROTO_FLAGS_TX_MASK       0x0003
159
160 /* if set, copy received servo values to SPI */
161 #define RC_PROTO_FLAGS_RX_COPY_SPI   0x0004
162
163 /* if set, switch to bypass when no servo is received during some time */
164 #define RC_PROTO_FLAGS_RX_AUTOBYPASS 0x0008
165
166 /* if set, send stats periodically to the peer (1 sec) */
167 #define RC_PROTO_FLAGS_TX_STATS      0x0010
168
169 /* if set, send power probe periodically to the peer (500 ms) */
170 #define RC_PROTO_FLAGS_TX_POW_PROBE  0x0020
171
172 /* if set, send GPS position to the peer (500 ms) */
173 #define RC_PROTO_FLAGS_TX_GPS_POS    0x0040
174
175 /* if set, send IMU position to the peer (100 ms) */
176 #define RC_PROTO_FLAGS_TX_IMU_POS    0x0080
177
178 /* if set, use received probes to compute best power level */
179 #define RC_PROTO_FLAGS_COMPUTE_BEST_POW  0x0100
180
181 void rc_proto_set_mode(uint16_t flags);
182
183 uint16_t rc_proto_get_mode(void);
184
185 /* initialize rc_proto module */
186 void rc_proto_init(void);
187
188 #endif