X-Git-Url: http://git.droids-corp.org/?p=aversive.git;a=blobdiff_plain;f=projects%2Fmicrob2010%2Fmainboard%2Fi2c_protocol.c;h=49b707bdca892570d373d85eddd7330f0717a815;hp=403decd0cc63d56f77bb8730ade7adcb7e24cecb;hb=HEAD;hpb=09e0cfb842943982e9fa3c4792c097bf4be25360 diff --git a/projects/microb2010/mainboard/i2c_protocol.c b/projects/microb2010/mainboard/i2c_protocol.c index 403decd..49b707b 100644 --- a/projects/microb2010/mainboard/i2c_protocol.c +++ b/projects/microb2010/mainboard/i2c_protocol.c @@ -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,16 @@ 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; + ballboard.opponent_x = ans->opponent_x; + ballboard.opponent_y = ans->opponent_y; + ballboard.opponent_a = ans->opponent_a; + ballboard.opponent_d = ans->opponent_d; break; } @@ -290,7 +313,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 +325,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 +333,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 +356,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 +377,16 @@ 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; + /* robot position */ + buf.x = position_get_x_s16(&mainboard.pos); + buf.y = position_get_y_s16(&mainboard.pos); + buf.a = position_get_a_deg_s16(&mainboard.pos); 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 +408,64 @@ 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; +#endif 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)); } -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; +#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 +} - 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)); +int8_t i2c_cobboard_pack(uint8_t side) +{ + return i2c_cobboard_set_spickle(side, 0); } -int8_t i2c_cobboard_mode_deploy(uint8_t side) +int8_t i2c_cobboard_pack_weak(uint8_t side) { - struct i2c_cmd_cobboard_set_mode buf; - uint8_t mode = cobboard.mode; + return i2c_cobboard_set_spickle(side, I2C_COBBOARD_SPK_WEAK); +} - 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 +473,14 @@ 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)); +} + +int8_t i2c_ballboard_set_beacon(uint8_t enable) +{ + struct i2c_cmd_ballboard_start_beacon buf; + buf.hdr.cmd = I2C_CMD_BALLBOARD_SET_BEACON; + buf.enable = enable; + return i2c_send_command(I2C_BALLBOARD_ADDR, (uint8_t*)&buf, sizeof(buf)); }