move xbee user code in a separate file
[protos/xbee-avr.git] / rc_proto.c
1 /*
2  * Copyright (c) 2013, Olivier MATZ <zer0@droids-corp.org>
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <string.h>
29
30 #include <aversive.h>
31 #include <aversive/queue.h>
32
33 #include <stdint.h>
34
35 #include <uart.h>
36
37 #include <parse.h>
38 #include <rdline.h>
39 #include <timer.h>
40 #include <xbee.h>
41
42 #include "callout.h"
43 #include "rc_proto.h"
44 #include "xbee_user.h"
45 #include "main.h"
46
47 /* */
48 struct rc_proto_power_levels {
49         uint8_t ttl;
50         uint16_t power_db;
51 };
52 static struct rc_proto_power_levels power_levels[MAX_POWER_LEVEL];
53
54 /* update power level when we receive the answer from DB */
55 static int update_power_level(void *frame, unsigned len, void *arg)
56 {
57         struct xbee_atresp_hdr *atresp = (struct xbee_atresp_hdr *)frame;
58         int level = (intptr_t)arg;
59         uint8_t db;
60
61         /* XXX check if this test is correct */
62         if (len < sizeof(struct xbee_atresp_hdr) + sizeof(uint8_t)) {
63                 /* XXX stats */
64                 return -1;
65         }
66
67         db = atresp->data[0];
68         power_levels[level].power_db = db;
69         power_levels[level].ttl = 2;
70         return 0;
71 }
72
73 /* when we receive a power probe, ask the DB value to the xbee */
74 void rc_proto_rx_power_probe(int power_level)
75 {
76         (void)power_level;
77         xbeeapp_send_atcmd("DB", NULL, 0, 0, update_power_level, NULL);
78 }
79
80 /* send a hello message */
81 // XXX iovec for xbee ?
82 int8_t rc_proto_send_hello(uint64_t addr, void *data, uint8_t data_len)
83 {
84         struct {
85                 struct rc_proto_echo_req hdr;
86                 char buf[XBEE_MAX_FRAME_LEN - sizeof(struct rc_proto_echo_req)];
87         } frame;
88
89         if (data_len > sizeof(frame.buf))
90                 return -1;
91
92         frame.hdr.type = RC_PROTO_HELLO;
93         frame.hdr.datalen = data_len;
94         memcpy(frame.buf, data, data_len);
95         return xbeeapp_send_msg(addr, &frame,
96                                 data_len + sizeof(struct rc_proto_echo_req), 1);
97 }
98
99
100 #if 0
101 #define N_SERVO 6
102 #define SERVO_NBITS 10
103 uint16_t servos[N_SERVO] = { 0x123, 0x234, 0x321, 0x123, 0x234, 0x321 };
104
105 int8_t servo2buf(uint8_t *buf, uint8_t len, uint8_t servo_mask,
106                   uint8_t pow, uint8_t seq)
107 {
108         uint8_t i = 0, num;
109         uint8_t remain_bits;
110         uint8_t servo_bits = 0;
111         uint16_t servo_val;
112         uint8_t tmp;
113
114         if (len < 2)
115                 return -1;
116
117         memset(buf, 0, len);
118         buf[i++] = servo_mask;
119         buf[i++] = ((seq & 0x1f) << 3) | (pow & 0x7);
120         remain_bits = 8;
121
122         for (num = 0; num < N_SERVO; num++) {
123                 if (!(servo_mask & (1 << num)))
124                         continue;
125                 servo_val = servos[num];
126                 servo_bits = SERVO_NBITS;
127
128                 tmp = (servo_val >> (servo_bits - remain_bits));
129                 tmp &= ((1 << remain_bits) - 1);
130                 if (i >= len)
131                         return -1;
132                 buf[i++] |= tmp;
133
134                 servo_bits = 10 - remain_bits;
135                 tmp = servo_val & ((1 << servo_bits) - 1);
136                 tmp <<= (8 - servo_bits);
137                 if (i >= len)
138                         return -1;
139                 buf[i] = tmp;
140
141                 if (servo_bits == 8) {
142                         i++;
143                         remain_bits = 8;
144                 }
145                 else
146                         remain_bits = 8 - servo_bits;
147         }
148
149         if (remain_bits != 8)
150                 i++;
151
152         return i;
153 }
154
155 int8_t buf2servo(uint8_t *buf, uint8_t len)
156 {
157         uint8_t mask, count = 0;
158         uint8_t num = 0;
159         uint8_t pow, seq;
160         uint16_t val;
161
162         if (len < 2)
163                 return -1;
164
165         mask = buf[0];
166         if (mask > 0x3f)
167                 return -1;
168         pow = buf[1] & 0x07;
169         seq = buf[1] >> 5;
170
171         for (num = 0; num < N_SERVO; num++) {
172                 if ((1<<num) & mask)
173                         count++;
174         }
175         switch (count) {
176                 case 1: if (len != 4) return -1; break;
177                 case 2: if (len != 5) return -1; break;
178                 case 3: if (len != 6) return -1; break;
179                 case 4: if (len != 7) return -1; break;
180                 case 5: if (len != 9) return -1; break;
181                 case 6: if (len != 10) return -1; break;
182                 default: return -1;
183         }
184
185         for (num = 0; ((1<<num) & mask) == 0; num++) {
186                 if (num >= N_SERVO)
187                         return 0;
188         }
189
190         val = buf[2];
191         val <<= 2;
192         val |= (buf[3] >> 6);
193
194         for (num++; ((1<<num) & mask) == 0; num++) {
195                 if (num >= N_SERVO)
196                         return 0;
197         }
198
199         val = buf[3] & 0x3f;
200         val <<= 4;
201         val |= (buf[4] >> 4);
202
203         for (num++; ((1<<num) & mask) == 0; num++) {
204                 if (num >= N_SERVO)
205                         return 0;
206         }
207
208         val = buf[4] & 0xf;
209         val <<= 6;
210         val |= (buf[5] >> 2);
211
212         for (num++; ((1<<num) & mask) == 0; num++) {
213                 if (num >= N_SERVO)
214                         return 0;
215         }
216
217         val = buf[5] & 0x3;
218         val <<= 8;
219         val |= (buf[6]);
220
221         for (num++; ((1<<num) & mask) == 0; num++) {
222                 if (num >= N_SERVO)
223                         return 0;
224         }
225
226         val = buf[7];
227         val <<= 2;
228         val |= (buf[8] >> 6);
229
230         for (num++; ((1<<num) & mask) == 0; num++) {
231                 if (num >= N_SERVO)
232                         return 0;
233         }
234
235         val = buf[8];
236         val <<= 4;
237         val |= (buf[9] >> 4);
238
239         return 0;
240 }
241 #endif