lock irq when retrieving time
[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 int8_t rc_proto_send_hello(uint64_t addr, void *data, uint8_t data_len)
82 {
83         struct rc_proto_echo_req hdr;
84         struct xbee_msg msg;
85
86         hdr.type = RC_PROTO_HELLO;
87         hdr.datalen = data_len;
88
89         msg.iovlen = 2;
90         msg.iov[0].buf = &hdr;
91         msg.iov[0].len = sizeof(hdr);
92         msg.iov[1].buf = data;
93         msg.iov[1].len = data_len;
94
95         return xbeeapp_send_msg(addr, &msg, 1);
96 }
97
98
99 #if 0
100 #define N_SERVO 6
101 #define SERVO_NBITS 10
102 uint16_t servos[N_SERVO] = { 0x123, 0x234, 0x321, 0x123, 0x234, 0x321 };
103
104 int8_t servo2buf(uint8_t *buf, uint8_t len, uint8_t servo_mask,
105                   uint8_t pow, uint8_t seq)
106 {
107         uint8_t i = 0, num;
108         uint8_t remain_bits;
109         uint8_t servo_bits = 0;
110         uint16_t servo_val;
111         uint8_t tmp;
112
113         if (len < 2)
114                 return -1;
115
116         memset(buf, 0, len);
117         buf[i++] = servo_mask;
118         buf[i++] = ((seq & 0x1f) << 3) | (pow & 0x7);
119         remain_bits = 8;
120
121         for (num = 0; num < N_SERVO; num++) {
122                 if (!(servo_mask & (1 << num)))
123                         continue;
124                 servo_val = servos[num];
125                 servo_bits = SERVO_NBITS;
126
127                 tmp = (servo_val >> (servo_bits - remain_bits));
128                 tmp &= ((1 << remain_bits) - 1);
129                 if (i >= len)
130                         return -1;
131                 buf[i++] |= tmp;
132
133                 servo_bits = 10 - remain_bits;
134                 tmp = servo_val & ((1 << servo_bits) - 1);
135                 tmp <<= (8 - servo_bits);
136                 if (i >= len)
137                         return -1;
138                 buf[i] = tmp;
139
140                 if (servo_bits == 8) {
141                         i++;
142                         remain_bits = 8;
143                 }
144                 else
145                         remain_bits = 8 - servo_bits;
146         }
147
148         if (remain_bits != 8)
149                 i++;
150
151         return i;
152 }
153
154 int8_t buf2servo(uint8_t *buf, uint8_t len)
155 {
156         uint8_t mask, count = 0;
157         uint8_t num = 0;
158         uint8_t pow, seq;
159         uint16_t val;
160
161         if (len < 2)
162                 return -1;
163
164         mask = buf[0];
165         if (mask > 0x3f)
166                 return -1;
167         pow = buf[1] & 0x07;
168         seq = buf[1] >> 5;
169
170         for (num = 0; num < N_SERVO; num++) {
171                 if ((1<<num) & mask)
172                         count++;
173         }
174         switch (count) {
175                 case 1: if (len != 4) return -1; break;
176                 case 2: if (len != 5) return -1; break;
177                 case 3: if (len != 6) return -1; break;
178                 case 4: if (len != 7) return -1; break;
179                 case 5: if (len != 9) return -1; break;
180                 case 6: if (len != 10) return -1; break;
181                 default: return -1;
182         }
183
184         for (num = 0; ((1<<num) & mask) == 0; num++) {
185                 if (num >= N_SERVO)
186                         return 0;
187         }
188
189         val = buf[2];
190         val <<= 2;
191         val |= (buf[3] >> 6);
192
193         for (num++; ((1<<num) & mask) == 0; num++) {
194                 if (num >= N_SERVO)
195                         return 0;
196         }
197
198         val = buf[3] & 0x3f;
199         val <<= 4;
200         val |= (buf[4] >> 4);
201
202         for (num++; ((1<<num) & mask) == 0; num++) {
203                 if (num >= N_SERVO)
204                         return 0;
205         }
206
207         val = buf[4] & 0xf;
208         val <<= 6;
209         val |= (buf[5] >> 2);
210
211         for (num++; ((1<<num) & mask) == 0; num++) {
212                 if (num >= N_SERVO)
213                         return 0;
214         }
215
216         val = buf[5] & 0x3;
217         val <<= 8;
218         val |= (buf[6]);
219
220         for (num++; ((1<<num) & mask) == 0; num++) {
221                 if (num >= N_SERVO)
222                         return 0;
223         }
224
225         val = buf[7];
226         val <<= 2;
227         val |= (buf[8] >> 6);
228
229         for (num++; ((1<<num) & mask) == 0; num++) {
230                 if (num >= N_SERVO)
231                         return 0;
232         }
233
234         val = buf[8];
235         val <<= 4;
236         val |= (buf[9] >> 4);
237
238         return 0;
239 }
240 #endif