From 2f60068f2c03084942a6965a58960f27d23d32af Mon Sep 17 00:00:00 2001 From: Jérémy Dufour Date: Sat, 16 May 2009 01:23:09 +0200 Subject: * digital/avr/io, digital/avr/asserv: - use CRC over TWI communication between the asserv and io boards. --- digital/asserv/src/asserv/twi_proto.c | 24 ++++++++++++++++++++---- digital/io/src/asserv.c | 25 ++++++++++++++++++------- digital/io/src/avrconfig.h | 5 ++++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/digital/asserv/src/asserv/twi_proto.c b/digital/asserv/src/asserv/twi_proto.c index 6168f245..df41efaa 100644 --- a/digital/asserv/src/asserv/twi_proto.c +++ b/digital/asserv/src/asserv/twi_proto.c @@ -27,6 +27,7 @@ #include "modules/utils/utils.h" #include "modules/utils/byte.h" +#include "modules/utils/crc.h" #include "modules/twi/twi.h" #include "io.h" @@ -70,11 +71,13 @@ void twi_proto_update (void) { u8 buf[AC_TWI_SL_RECV_BUFFER_SIZE]; + u8 read_data; /* Handle incoming command. */ - while (twi_sl_poll (buf, sizeof (buf))) - twi_proto_callback (buf, sizeof (buf)); + while ((read_data = twi_sl_poll (buf, sizeof (buf)))) + twi_proto_callback (buf, read_data); /* Update status. */ - u8 status[15]; + u8 status_with_crc[16]; + u8 *status = &status_with_crc[1]; status[0] = 0 | (state_aux[1].blocked << 7) | (state_aux[1].finished << 6) @@ -98,13 +101,26 @@ twi_proto_update (void) status[12] = v16_to_v8 (aux[0].pos, 0); status[13] = v16_to_v8 (aux[1].pos, 1); status[14] = v16_to_v8 (aux[1].pos, 0); - twi_sl_update (status, sizeof (status)); + /* Compute CRC. */ + status_with_crc[0] = crc_compute (&status_with_crc[1], + sizeof (status_with_crc) - 1); + twi_sl_update (status_with_crc, sizeof (status_with_crc)); } /** Handle one command. */ static void twi_proto_callback (u8 *buf, u8 size) { + /* Check CRC. */ + if (crc_compute (buf + 1, size - 1) != buf[0]) + return; + else + { + /* Remove the CRC of the buffer. */ + buf += 1; + size -= 1; + } + if (buf[0] == twi_proto.seq) return; #define c(cmd, size) (cmd) diff --git a/digital/io/src/asserv.c b/digital/io/src/asserv.c index b35c436c..eb241e65 100644 --- a/digital/io/src/asserv.c +++ b/digital/io/src/asserv.c @@ -29,6 +29,7 @@ #include "modules/twi/twi.h" /* twi_* */ #include "modules/utils/byte.h" /* v*_to_v* */ #include "modules/math/fixed/fixed.h" +#include "modules/utils/crc.h" #include "giboulee.h" /* BOT_* */ #include "io.h" @@ -77,12 +78,12 @@ static uint8_t asserv_twi_seq; /** * Shared buffer used to send commands to the asserv. */ -static uint8_t asserv_twi_buffer[14]; +static uint8_t asserv_twi_buffer[15]; /** * Pointer to access the buffer to put the parameters list. */ -static uint8_t *asserv_twi_buffer_param = &asserv_twi_buffer[2]; +static uint8_t *asserv_twi_buffer_param = &asserv_twi_buffer[3]; /** * Status structure maintains by the update command. @@ -195,12 +196,15 @@ asserv_twi_send_command (uint8_t command, uint8_t length) assert (asserv_last_cmd_ack ()); /* Put the sequence number */ - asserv_twi_buffer[0] = ++asserv_twi_seq; + asserv_twi_buffer[1] = ++asserv_twi_seq; /* Put the command into the buffer */ - asserv_twi_buffer[1] = command; + asserv_twi_buffer[2] = command; + + /* Compute CRC. */ + asserv_twi_buffer[0] = crc_compute (&asserv_twi_buffer[1], length + 2); /* Send the prepared command */ - return asserv_twi_send (length + 2); + return asserv_twi_send (length + 3); } /* Send a prepared command to the asserv board using TWI module. */ @@ -242,11 +246,18 @@ void asserv_update_status (void) { /* Status buffer used to receive data from the asserv */ - static uint8_t status_buffer[AC_ASSERV_STATUS_LENGTH]; + static uint8_t buffer[AC_ASSERV_STATUS_LENGTH + 1]; + uint8_t *status_buffer = &buffer[1]; + /* Read data from the asserv card */ - twi_ms_read (AC_ASSERV_TWI_ADDRESS, status_buffer, AC_ASSERV_STATUS_LENGTH); + twi_ms_read (AC_ASSERV_TWI_ADDRESS, buffer, AC_ASSERV_STATUS_LENGTH + 1); /* Update until done */ asserv_twi_update (); + /* Check CRC. */ + uint8_t crc = crc_compute (status_buffer, AC_ASSERV_STATUS_LENGTH); + if (crc != buffer[0]) + return; + /* Parse received data and store them */ asserv_status.status = status_buffer[0]; asserv_status.input_port = status_buffer[1]; diff --git a/digital/io/src/avrconfig.h b/digital/io/src/avrconfig.h index 4b676c96..74ceb238 100644 --- a/digital/io/src/avrconfig.h +++ b/digital/io/src/avrconfig.h @@ -104,7 +104,10 @@ #define AC_IO_TWI_ADDRESS 2 /** TWI address of the asserv board. */ #define AC_ASSERV_TWI_ADDRESS 4 -/** Length of the status buffer maintains by the asserv board. */ +/** + * Length of the status buffer maintains by the asserv board. + * This length should not include the CRC byte! + */ #define AC_ASSERV_STATUS_LENGTH 15 #endif /* avrconfig_h */ -- cgit v1.2.3