current limit on shovel
[aversive.git] / projects / microb2010 / mainboard / i2c_protocol.c
index 403decd..3354e39 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright Droids Corporation (2009)
- * 
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
@@ -53,6 +53,9 @@
 #include "main.h"
 #include "sensor.h"
 #include "i2c_protocol.h"
+#ifdef HOST_VERSION
+#include "robotsim.h"
+#endif
 
 #define I2C_STATE_MAX 4
 
@@ -70,16 +73,19 @@ static volatile uint16_t i2c_errors = 0;
 static volatile uint8_t running_op = OP_READY;
 
 #define I2C_MAX_LOG 3
+#ifndef HOST_VERSION
 static uint8_t error_log = 0;
 
+static int8_t i2c_req_cobboard_status(void);
+static int8_t i2c_req_ballboard_status(void);
+
+#endif
+
 /* used for commands */
 uint8_t command_buf[I2C_SEND_BUFFER_SIZE];
 volatile int8_t command_dest=-1;
 volatile uint8_t command_size=0;
 
-static int8_t i2c_req_cobboard_status(void);
-static int8_t i2c_req_ballboard_status(void);
-
 #define I2C_ERROR(args...) do {                                                \
                if (error_log < I2C_MAX_LOG) {                          \
                        ERROR(E_USER_I2C_PROTO, args);                  \
@@ -99,6 +105,9 @@ void i2c_protocol_init(void)
 
 void i2c_protocol_debug(void)
 {
+#ifdef HOST_VERSION
+       return;
+#else
        printf_P(PSTR("I2C protocol debug infos:\r\n"));
        printf_P(PSTR("  i2c_state=%d\r\n"), i2c_state);
        printf_P(PSTR("  i2c_errors=%d\r\n"), i2c_errors);
@@ -106,8 +115,10 @@ void i2c_protocol_debug(void)
        printf_P(PSTR("  command_size=%d\r\n"), command_size);
        printf_P(PSTR("  command_dest=%d\r\n"), command_dest);
        printf_P(PSTR("  i2c_status=%x\r\n"), i2c_status());
+#endif
 }
 
+#ifndef HOST_VERSION
 static void i2cproto_next_state(uint8_t inc)
 {
        i2c_state += inc;
@@ -131,11 +142,11 @@ void i2c_poll_slaves(void *dummy)
        uint8_t flags;
        int8_t err;
        static uint8_t a = 0;
-       
+
        a++;
        if (a & 0x4)
                LED2_TOGGLE();
-       
+
        /* already running */
        IRQ_LOCK(flags);
        if (running_op != OP_READY) {
@@ -168,8 +179,8 @@ void i2c_poll_slaves(void *dummy)
 
 #define I2C_ANS_COBBOARD 1
        case I2C_ANS_COBBOARD:
-               if ((err = i2c_recv(I2C_COBBOARD_ADDR, 
-                                   sizeof(struct i2c_ans_cobboard_status), 
+               if ((err = i2c_recv(I2C_COBBOARD_ADDR,
+                                   sizeof(struct i2c_ans_cobboard_status),
                                    I2C_CTRL_GENERIC)))
                        goto error;
                break;
@@ -183,8 +194,8 @@ void i2c_poll_slaves(void *dummy)
 
 #define I2C_ANS_BALLBOARD 3
        case I2C_ANS_BALLBOARD:
-               if ((err = i2c_recv(I2C_BALLBOARD_ADDR, 
-                                   sizeof(struct i2c_ans_ballboard_status), 
+               if ((err = i2c_recv(I2C_BALLBOARD_ADDR,
+                                   sizeof(struct i2c_ans_ballboard_status),
                                    I2C_CTRL_GENERIC)))
                        goto error;
                break;
@@ -203,7 +214,7 @@ void i2c_poll_slaves(void *dummy)
        IRQ_UNLOCK(flags);
        i2c_errors++;
        if (i2c_errors > I2C_MAX_ERRORS) {
-               I2C_ERROR("I2C send is_cmd=%d proto_state=%d " 
+               I2C_ERROR("I2C send is_cmd=%d proto_state=%d "
                      "err=%d i2c_status=%x", !!command_size, i2c_state, err, i2c_status());
                i2c_reset();
                i2c_errors = 0;
@@ -229,7 +240,7 @@ void i2c_sendevent(int8_t size)
                        i2c_reset();
                        i2c_errors = 0;
                }
-               
+
                if (running_op == OP_POLL) {
                        /* skip associated answer */
                        i2cproto_next_state(2);
@@ -246,7 +257,7 @@ void i2c_recvevent(uint8_t * buf, int8_t size)
 
        /* recv is only trigged after a poll */
        running_op = OP_READY;
-       
+
        if (size < 0) {
                goto error;
        }
@@ -254,15 +265,16 @@ void i2c_recvevent(uint8_t * buf, int8_t size)
        switch (buf[0]) {
 
        case I2C_ANS_COBBOARD_STATUS: {
-               struct i2c_ans_cobboard_status * ans = 
+               struct i2c_ans_cobboard_status * ans =
                        (struct i2c_ans_cobboard_status *)buf;
-               
+
                if (size != sizeof (*ans))
                        goto error;
 
                /* status */
                cobboard.mode = ans->mode;
                cobboard.status = ans->status;
+               cobboard.cob_count = ans->cob_count;
                cobboard.left_cobroller_speed = ans->left_cobroller_speed;
                cs_set_consign(&mainboard.left_cobroller.cs, cobboard.left_cobroller_speed);
                cobboard.right_cobroller_speed = ans->right_cobroller_speed;
@@ -272,7 +284,8 @@ void i2c_recvevent(uint8_t * buf, int8_t size)
        }
 
        case I2C_ANS_BALLBOARD_STATUS: {
-               struct i2c_ans_ballboard_status * ans = 
+               uint8_t tmp;
+               struct i2c_ans_ballboard_status * ans =
                        (struct i2c_ans_ballboard_status *)buf;
 
                if (size != sizeof (*ans))
@@ -280,6 +293,12 @@ void i2c_recvevent(uint8_t * buf, int8_t size)
                ballboard.mode = ans->mode;
                ballboard.status = ans->status;
                ballboard.ball_count = ans->ball_count;
+               tmp = ans->lcob;
+               if (tmp != I2C_COB_NONE)
+                       ballboard.lcob = tmp;
+               tmp = ans->rcob;
+               if (tmp != I2C_COB_NONE)
+                       ballboard.rcob = tmp;
                break;
        }
 
@@ -290,7 +309,7 @@ void i2c_recvevent(uint8_t * buf, int8_t size)
        return;
  error:
        i2c_errors++;
-       NOTICE(E_USER_I2C_PROTO, "recv error state=%d op=%d", 
+       NOTICE(E_USER_I2C_PROTO, "recv error state=%d op=%d",
               i2c_state, running_op);
        if (i2c_errors > I2C_MAX_ERRORS) {
                I2C_ERROR("I2C error, slave not ready");
@@ -302,6 +321,7 @@ void i2c_recvevent(uint8_t * buf, int8_t size)
 void i2c_recvbyteevent(uint8_t hwstatus, uint8_t i, uint8_t c)
 {
 }
+#endif /* !HOST_VERSION */
 
 /* ******** ******** ******** ******** */
 /* commands */
@@ -309,8 +329,11 @@ void i2c_recvbyteevent(uint8_t hwstatus, uint8_t i, uint8_t c)
 
 
 static int8_t
-i2c_send_command(uint8_t addr, uint8_t * buf, uint8_t size) 
+i2c_send_command(uint8_t addr, uint8_t * buf, uint8_t size)
 {
+#ifdef HOST_VERSION
+       return robotsim_i2c(addr, buf, size);
+#else
        uint8_t flags;
         microseconds us = time_get_us2();
 
@@ -329,14 +352,18 @@ i2c_send_command(uint8_t addr, uint8_t * buf, uint8_t size)
         * interrupt context, but it's forbidden */
        I2C_ERROR("I2C command send failed");
        return -EBUSY;
+#endif
 }
 
+#ifndef HOST_VERSION
 static int8_t i2c_req_cobboard_status(void)
 {
        struct i2c_req_cobboard_status buf;
        int8_t err;
 
        buf.hdr.cmd = I2C_REQ_COBBOARD_STATUS;
+       buf.lspickle = cobboard.lspickle;
+       buf.rspickle = cobboard.rspickle;
        err = i2c_send(I2C_COBBOARD_ADDR, (uint8_t*)&buf,
                        sizeof(buf), I2C_CTRL_GENERIC);
 
@@ -346,11 +373,12 @@ static int8_t i2c_req_cobboard_status(void)
 static int8_t i2c_req_ballboard_status(void)
 {
        struct i2c_req_ballboard_status buf;
-       
+
        buf.hdr.cmd = I2C_REQ_BALLBOARD_STATUS;
        return i2c_send(I2C_BALLBOARD_ADDR, (uint8_t*)&buf,
                        sizeof(buf), I2C_CTRL_GENERIC);
 }
+#endif /* !HOST_VERSION */
 
 int8_t i2c_set_color(uint8_t addr, uint8_t color)
 {
@@ -372,70 +400,61 @@ int8_t i2c_led_control(uint8_t addr, uint8_t led, uint8_t state)
        return i2c_send_command(addr, (uint8_t*)&buf, sizeof(buf));
 }
 
-int8_t i2c_cobboard_mode_eject(void)
+int8_t i2c_cobboard_set_mode(uint8_t mode)
 {
+#ifdef HOST_VERSION
+       cobboard.mode = mode;
+       return 0;
+#else
        struct i2c_cmd_cobboard_set_mode buf;
        buf.hdr.cmd = I2C_CMD_COBBOARD_SET_MODE;
-       buf.mode = cobboard.mode | I2C_COBBOARD_MODE_EJECT;
+       buf.mode = mode;
        return i2c_send_command(I2C_COBBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
+#endif
 }
 
-int8_t i2c_cobboard_mode_harvest(uint8_t side)
+static int8_t i2c_cobboard_set_spickle(uint8_t side, uint8_t flags)
 {
-       struct i2c_cmd_cobboard_set_mode buf;
-       uint8_t mode = cobboard.mode;
-
-       buf.hdr.cmd = I2C_CMD_COBBOARD_SET_MODE;
-       if (side == I2C_LEFT_SIDE) {
-               mode |= I2C_COBBOARD_MODE_L_DEPLOY;
-               mode |= I2C_COBBOARD_MODE_L_HARVEST;
-       }
-       else {
-               mode |= I2C_COBBOARD_MODE_R_DEPLOY;
-               mode |= I2C_COBBOARD_MODE_R_HARVEST;
-       }
-       buf.mode = mode;
-       return i2c_send_command(I2C_COBBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
+#ifdef HOST_VERSION
+       return robotsim_i2c_cobboard_set_spickles(side, flags);
+#else
+       if (side == I2C_LEFT_SIDE)
+               cobboard.lspickle = flags;
+       else
+               cobboard.rspickle = flags;
+       return 0;
+#endif
 }
 
-int8_t i2c_cobboard_mode_deploy(uint8_t side)
+int8_t i2c_cobboard_pack(uint8_t side)
 {
-       struct i2c_cmd_cobboard_set_mode buf;
-       uint8_t mode = cobboard.mode;
+       return i2c_cobboard_set_spickle(side, 0);
+}
 
-       buf.hdr.cmd = I2C_CMD_COBBOARD_SET_MODE;
-       if (side == I2C_LEFT_SIDE) {
-               mode &= ~(I2C_COBBOARD_MODE_L_DEPLOY | I2C_COBBOARD_MODE_L_HARVEST);
-               mode |= I2C_COBBOARD_MODE_L_DEPLOY;
-       }
-       else {
-               mode &= ~(I2C_COBBOARD_MODE_R_DEPLOY | I2C_COBBOARD_MODE_R_HARVEST);
-               mode |= I2C_COBBOARD_MODE_R_DEPLOY;
-       }
-       buf.mode = mode;
-       return i2c_send_command(I2C_COBBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
+int8_t i2c_cobboard_autoharvest(uint8_t side)
+{
+       return i2c_cobboard_set_spickle(side,
+                                       I2C_COBBOARD_SPK_DEPLOY |
+                                       I2C_COBBOARD_SPK_AUTOHARVEST);
 }
 
-int8_t i2c_cobboard_mode_pack(uint8_t side)
+int8_t i2c_cobboard_deploy(uint8_t side)
 {
-       struct i2c_cmd_cobboard_set_mode buf;
-       uint8_t mode = cobboard.mode;
+       return i2c_cobboard_set_spickle(side, I2C_COBBOARD_SPK_DEPLOY);
+}
 
-       buf.hdr.cmd = I2C_CMD_COBBOARD_SET_MODE;
-       if (side == I2C_LEFT_SIDE)
-               mode &= ~(I2C_COBBOARD_MODE_L_DEPLOY | I2C_COBBOARD_MODE_L_HARVEST);
-       else
-               mode &= ~(I2C_COBBOARD_MODE_R_DEPLOY | I2C_COBBOARD_MODE_R_HARVEST);
-       buf.mode = mode;
-       return i2c_send_command(I2C_COBBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
+int8_t i2c_cobboard_autoharvest_nomove(uint8_t side)
+{
+       return i2c_cobboard_set_spickle(side,
+                                       I2C_COBBOARD_SPK_DEPLOY |
+                                       I2C_COBBOARD_SPK_AUTOHARVEST |
+                                       I2C_COBBOARD_SPK_NO_MOVE);
 }
 
-int8_t i2c_cobboard_mode_init(void)
+int8_t i2c_cobboard_deploy_nomove(uint8_t side)
 {
-       struct i2c_cmd_cobboard_set_mode buf;
-       buf.hdr.cmd = I2C_CMD_COBBOARD_SET_MODE;
-       buf.mode = I2C_COBBOARD_MODE_INIT;
-       return i2c_send_command(I2C_COBBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
+       return i2c_cobboard_set_spickle(side, I2C_COBBOARD_SPK_DEPLOY |
+                                       I2C_COBBOARD_SPK_NO_MOVE);
 }
 
 int8_t i2c_ballboard_set_mode(uint8_t mode)
@@ -443,6 +462,6 @@ int8_t i2c_ballboard_set_mode(uint8_t mode)
        struct i2c_cmd_ballboard_set_mode buf;
        buf.hdr.cmd = I2C_CMD_BALLBOARD_SET_MODE;
        buf.mode = mode;
-       return i2c_send_command(I2C_COBBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
+       return i2c_send_command(I2C_BALLBOARD_ADDR, (uint8_t*)&buf, sizeof(buf));
 }