add cksum
[aversive.git] / projects / microb2010 / sensorboard / i2c_protocol.c
1 /*
2  *  Copyright Droids Corporation (2007)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: i2c_protocol.c,v 1.3 2009-05-27 20:04:07 zer0 Exp $
19  *
20  */
21
22 #include <string.h>
23
24 #include <aversive.h>
25 #include <aversive/list.h>
26 #include <aversive/error.h>
27
28 #include <scheduler.h>
29
30 #include <i2c.h>
31 #include <ax12.h>
32 #include <uart.h>
33 #include <pwm_ng.h>
34 #include <time.h>
35 #include <spi.h>
36
37 #include <pid.h>
38 #include <quadramp.h>
39 #include <control_system_manager.h>
40 #include <blocking_detection_manager.h>
41
42 #include <rdline.h>
43 #include <parse.h>
44 #include <parse_string.h>
45 #include <parse_num.h>
46
47 #include "../common/i2c_commands.h"
48 #include "main.h"
49 #include "actuator.h"
50 #include "beacon.h"
51 #include "scanner.h"
52
53 void i2c_protocol_init(void)
54 {
55 }
56
57 /*** LED CONTROL ***/
58 void i2c_led_control(uint8_t l, uint8_t state)
59 {
60         switch(l) {
61         case 1:
62                 state? LED1_ON():LED1_OFF();
63                 break;
64         case 2:
65                 state? LED2_ON():LED2_OFF();
66                 break;
67         default:
68                 break;
69         }
70 }
71
72 void i2c_send_status(void)
73 {
74         struct i2c_ans_sensorboard_status ans;
75         i2c_flush();
76         ans.hdr.cmd =  I2C_ANS_SENSORBOARD_STATUS;
77         ans.status = 0x55; /* XXX */
78         ans.opponent_x = beacon.opponent_x;
79         ans.opponent_y = beacon.opponent_y;
80         ans.opponent_a = beacon.opponent_angle;
81         ans.opponent_d = beacon.opponent_dist;
82
83         ans.scan_status = 0;
84         ans.scan_status |= scan_params.working ? 0 : I2C_SCAN_DONE; 
85         ans.scan_status |= scan_params.max_column_detected ? I2C_SCAN_MAX_COLUMN : 0;
86
87
88         ans.dropzone_x = scan_params.dropzone_x;
89         ans.dropzone_y = scan_params.dropzone_y;
90         ans.dropzone_h = scan_params.dropzone_h;
91
92         i2c_send(I2C_ADD_MASTER, (uint8_t *) &ans,
93                  sizeof(ans), I2C_CTRL_GENERIC);
94 }
95
96
97 void i2c_scanner_calibre_laser(void* dummy)
98 {
99         scanner_calibre_laser();
100 }
101
102 void i2c_scanner_end_process(void* dummy)
103 {
104         scanner_end_process();
105 }
106
107 void i2c_recvevent(uint8_t * buf, int8_t size)
108 {
109         void *void_cmd = buf;
110         static uint8_t a=0;
111         a=!a;
112         if (a)
113                 LED2_ON();
114         else
115                 LED2_OFF();
116
117         if (size <= 0) {
118                 goto error;
119         }
120         
121         switch (buf[0]) {
122
123         /* Commands (no answer needed) */
124         case I2C_CMD_GENERIC_LED_CONTROL: 
125                 {
126                         struct i2c_cmd_led_control *cmd = void_cmd;
127                         if (size != sizeof (*cmd))
128                                 goto error;
129                         i2c_led_control(cmd->led_num, cmd->state);
130                         break;
131                 }
132                 
133         case I2C_CMD_GENERIC_SET_COLOR:
134                 {
135                         struct i2c_cmd_generic_color *cmd = void_cmd;
136                         if (size != sizeof (*cmd))
137                                 goto error;
138                         sensorboard.our_color = cmd->color;
139                         break;
140                 }
141
142         case I2C_CMD_SENSORBOARD_SET_BEACON:
143                 {
144                         struct i2c_cmd_sensorboard_start_beacon *cmd = void_cmd;
145                         if (size != sizeof (*cmd))
146                                 goto error;
147
148                         if (cmd->enable)
149                                 beacon_start();
150                         else
151                                 beacon_stop();
152                                 
153                         break;
154                 }
155
156         case I2C_CMD_SENSORBOARD_SET_SCANNER:
157                 {
158                         struct i2c_cmd_sensorboard_scanner *cmd = void_cmd;
159                         if (size != sizeof (*cmd))
160                                 goto error;
161
162                         scanner_set_mode(cmd->mode);
163                         break;
164
165                 }
166
167
168         case I2C_CMD_SENSORBOARD_SCANNER_ALGO:
169                 {
170                         struct i2c_cmd_sensorboard_scanner_algo *cmd = void_cmd;
171                         if (size != sizeof (*cmd))
172                                 goto error;
173
174                         scan_params.algo = cmd->algo;
175
176                         if (cmd->algo == I2C_SCANNER_ALGO_COLUMN_DROPZONE){
177                                 scan_params.drop_zone.working_zone = cmd->drop_zone.working_zone;
178                                 scan_params.drop_zone.center_x = cmd->drop_zone.center_x;
179                                 scan_params.drop_zone.center_y = cmd->drop_zone.center_y;
180                         }
181                         else if (cmd->algo == I2C_SCANNER_ALGO_CHECK_TEMPLE) {
182                                 scan_params.check_temple.level = cmd->check_temple.level;
183                                 scan_params.check_temple.temple_x = cmd->check_temple.temple_x;
184                                 scan_params.check_temple.temple_y = cmd->check_temple.temple_y;                         
185                         } 
186                         else if (cmd->algo == I2C_SCANNER_ALGO_TEMPLE_DROPZONE){
187                                 scan_params.drop_zone.working_zone = cmd->drop_zone.working_zone;
188                                 scan_params.drop_zone.center_x = cmd->drop_zone.center_x;
189                                 scan_params.drop_zone.center_y = cmd->drop_zone.center_y;
190                         }
191                         else{
192                                 /* new command */
193                         }
194
195                         scan_params.working = 1;
196                         scheduler_add_single_event_priority(i2c_scanner_end_process, NULL, 
197                                                             1,
198                                                             CS_PRIO-1);
199                         break;
200
201                 }
202
203         case I2C_CMD_SENSORBOARD_CALIB_SCANNER:
204                 {
205                         struct i2c_cmd_sensorboard_calib_scanner *cmd = void_cmd;
206                         if (size != sizeof (*cmd))
207                                 goto error;
208                         
209                         scheduler_add_single_event_priority(i2c_scanner_calibre_laser, NULL, 
210                                                             1,
211                                                             CS_PRIO-1);
212                         break;
213                 }
214
215
216
217         /* Add other commands here ...*/
218
219
220         case I2C_REQ_SENSORBOARD_STATUS:
221                 {
222                         struct i2c_req_sensorboard_status *cmd = void_cmd;                      
223                         if (size != sizeof (*cmd))
224                                 goto error;
225
226                         beacon.robot_x = cmd->x;
227                         beacon.robot_y = cmd->y;
228                         beacon.robot_angle = cmd->a;
229
230                         if (cmd->enable_pickup_wheels)
231                                 pickup_wheels_on();
232                         else
233                                 pickup_wheels_off();
234                                 
235                         i2c_send_status();
236                         break;
237                 }
238
239         default:
240                 goto error;
241         }
242
243  error:
244         /* log error on a led ? */
245         return;
246 }
247
248 void i2c_recvbyteevent(uint8_t hwstatus, uint8_t i, uint8_t c)
249 {
250 }
251
252 void i2c_sendevent(int8_t size)
253 {
254 }
255
256