b04e18cc1e63814119c19c19b888472d7f69e1d8
[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 <scheduler.h>
38 #include <clock_time.h>
39 #include <parse.h>
40 #include <rdline.h>
41 #include <timer.h>
42 #include <xbee.h>
43
44 #include "callout.h"
45 #include "rc_proto.h"
46 #include "main.h"
47
48 /* */
49 struct rc_proto_power_levels {
50         uint8_t ttl;
51         uint16_t power_db;
52 };
53 static struct rc_proto_power_levels power_levels[MAX_POWER_LEVEL];
54
55 /* update power level when we receive the answer from DB */
56 static int update_power_level(void *frame, unsigned len, void *arg)
57 {
58         struct xbee_atresp_hdr *atresp = (struct xbee_atresp_hdr *)frame;
59         int level = (intptr_t)arg;
60         uint8_t db;
61
62         /* XXX check if this test is correct */
63         if (len < sizeof(struct xbee_atresp_hdr) + sizeof(uint8_t)) {
64                 /* XXX stats */
65                 return -1;
66         }
67
68         db = atresp->data[0];
69         power_levels[level].power_db = db;
70         power_levels[level].ttl = 2;
71         return 0;
72 }
73
74 /* when we receive a power probe, ask the DB value to the xbee */
75 void rc_proto_rx_power_probe(int power_level)
76 {
77         (void)power_level;
78         xbeeapp_send_atcmd("DB", NULL, 0, 0, update_power_level, NULL);
79 }
80
81 /* send a hello message */
82 // XXX iovec for xbee ?
83 int8_t rc_proto_send_hello(uint64_t addr, void *data, uint8_t data_len)
84 {
85         struct {
86                 struct rc_proto_echo_req hdr;
87                 char buf[XBEE_MAX_FRAME_LEN - sizeof(struct rc_proto_echo_req)];
88         } frame;
89
90         if (data_len > sizeof(frame.buf))
91                 return -1;
92
93         frame.hdr.type = RC_PROTO_HELLO;
94         frame.hdr.datalen = data_len;
95         memcpy(frame.buf, data, data_len);
96         return xbeeapp_send_msg(addr, &frame,
97                                 data_len + sizeof(struct rc_proto_echo_req), 1);
98 }
99
100
101 #if 0
102 #define N_SERVO 6
103 #define SERVO_NBITS 10
104 uint16_t servos[N_SERVO] = { 0x123, 0x234, 0x321, 0x123, 0x234, 0x321 };
105
106 int8_t servo2buf(uint8_t *buf, uint8_t len, uint8_t servo_mask,
107                   uint8_t pow, uint8_t seq)
108 {
109         uint8_t i = 0, num;
110         uint8_t remain_bits;
111         uint8_t servo_bits = 0;
112         uint16_t servo_val;
113         uint8_t tmp;
114
115         if (len < 2)
116                 return -1;
117
118         memset(buf, 0, len);
119         buf[i++] = servo_mask;
120         buf[i++] = ((seq & 0x1f) << 3) | (pow & 0x7);
121         remain_bits = 8;
122
123         for (num = 0; num < N_SERVO; num++) {
124                 if (!(servo_mask & (1 << num)))
125                         continue;
126                 servo_val = servos[num];
127                 servo_bits = SERVO_NBITS;
128
129                 tmp = (servo_val >> (servo_bits - remain_bits));
130                 tmp &= ((1 << remain_bits) - 1);
131                 if (i >= len)
132                         return -1;
133                 buf[i++] |= tmp;
134
135                 servo_bits = 10 - remain_bits;
136                 tmp = servo_val & ((1 << servo_bits) - 1);
137                 tmp <<= (8 - servo_bits);
138                 if (i >= len)
139                         return -1;
140                 buf[i] = tmp;
141
142                 if (servo_bits == 8) {
143                         i++;
144                         remain_bits = 8;
145                 }
146                 else
147                         remain_bits = 8 - servo_bits;
148         }
149
150         if (remain_bits != 8)
151                 i++;
152
153         return i;
154 }
155
156 int8_t buf2servo(uint8_t *buf, uint8_t len)
157 {
158         uint8_t mask, count = 0;
159         uint8_t num = 0;
160         uint8_t pow, seq;
161         uint16_t val;
162
163         if (len < 2)
164                 return -1;
165
166         mask = buf[0];
167         if (mask > 0x3f)
168                 return -1;
169         pow = buf[1] & 0x07;
170         seq = buf[1] >> 5;
171
172         for (num = 0; num < N_SERVO; num++) {
173                 if ((1<<num) & mask)
174                         count++;
175         }
176         switch (count) {
177                 case 1: if (len != 4) return -1; break;
178                 case 2: if (len != 5) return -1; break;
179                 case 3: if (len != 6) return -1; break;
180                 case 4: if (len != 7) return -1; break;
181                 case 5: if (len != 9) return -1; break;
182                 case 6: if (len != 10) return -1; break;
183                 default: return -1;
184         }
185
186         for (num = 0; ((1<<num) & mask) == 0; num++) {
187                 if (num >= N_SERVO)
188                         return 0;
189         }
190
191         val = buf[2];
192         val <<= 2;
193         val |= (buf[3] >> 6);
194
195         for (num++; ((1<<num) & mask) == 0; num++) {
196                 if (num >= N_SERVO)
197                         return 0;
198         }
199
200         val = buf[3] & 0x3f;
201         val <<= 4;
202         val |= (buf[4] >> 4);
203
204         for (num++; ((1<<num) & mask) == 0; num++) {
205                 if (num >= N_SERVO)
206                         return 0;
207         }
208
209         val = buf[4] & 0xf;
210         val <<= 6;
211         val |= (buf[5] >> 2);
212
213         for (num++; ((1<<num) & mask) == 0; num++) {
214                 if (num >= N_SERVO)
215                         return 0;
216         }
217
218         val = buf[5] & 0x3;
219         val <<= 8;
220         val |= (buf[6]);
221
222         for (num++; ((1<<num) & mask) == 0; num++) {
223                 if (num >= N_SERVO)
224                         return 0;
225         }
226
227         val = buf[7];
228         val <<= 2;
229         val |= (buf[8] >> 6);
230
231         for (num++; ((1<<num) & mask) == 0; num++) {
232                 if (num >= N_SERVO)
233                         return 0;
234         }
235
236         val = buf[8];
237         val <<= 4;
238         val |= (buf[9] >> 4);
239
240         return 0;
241 }
242 #endif