From 90691eb6a2065d2c49e3e45f26f1f564132594f8 Mon Sep 17 00:00:00 2001 From: nvt-se Date: Tue, 11 Nov 2008 12:24:43 +0000 Subject: [PATCH] crc calculation contributed by Carlo Alberto Buano + some refactoring. --- platform/msb430/dev/cc1020.c | 88 +++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/platform/msb430/dev/cc1020.c b/platform/msb430/dev/cc1020.c index 00889652a..6f23cea70 100644 --- a/platform/msb430/dev/cc1020.c +++ b/platform/msb430/dev/cc1020.c @@ -57,11 +57,14 @@ Berlin, 2006 #include "cc1020-internal.h" #include "cc1020.h" #include "lib/random.h" +#include "lib/crc16.h" #include "net/rime/rimestats.h" #include "dev/irq.h" #include "dev/dma.h" #include "energest.h" +#define CRC_LEN 2 // CHECKSUM + static int cc1020_calibrate(void); static int cc1020_setupTX(int); static int cc1020_setupRX(int); @@ -113,6 +116,20 @@ dma_callback(void) dma_done = 1; } +static +reset_receiver(void) +{ + // reset receiver + cc1020_rxlen = 0; + + if ((cc1020_state & CC1020_TURN_OFF) && (cc1020_txlen == 0)) { + cc1020_off(); + } else { + CC1020_SET_OPSTATE(CC1020_RX | CC1020_RX_SEARCHING); + ENABLE_RX_IRQ(); + } +} + void cc1020_init(const uint8_t *config) { @@ -214,8 +231,10 @@ cc1020_set_power(uint8_t pa_power) int cc1020_send(const void *buf, unsigned short len) { - int try; - + int try; + int normal_header = HDRSIZE + len; + uint16_t rxcrc = 0xFFFF; // For checksum purposes + if (cc1020_state == CC1020_OFF) return -2; @@ -226,16 +245,29 @@ cc1020_send(const void *buf, unsigned short len) cc1020_txlen = PREAMBLESIZE + SYNCWDSIZE; // header - cc1020_txbuf[cc1020_txlen++] = 0x00; - cc1020_txbuf[cc1020_txlen++] = HDRSIZE + len; - + cc1020_txbuf[cc1020_txlen++] = 0x00; + cc1020_txbuf[cc1020_txlen++] = normal_header + CRC_LEN; + + // Adding the checksum on header and data + rxcrc = crc16_add((uint8_t) (normal_header & 0xff), rxcrc); + rxcrc = crc16_add((uint8_t) ((normal_header >> 8)& 0xff), rxcrc); + + int i=0; + for(i=0;i> 8) & 0xff), + expected_crc); + + int i = 0; + for(i = HDRSIZE; i < cc1020_rxlen; i++){ + expected_crc = crc16_add(cc1020_rxbuf[i], expected_crc); + } + + if(expected_crc == actual_crc){ + receiver_callback(&cc1020_driver); + } else { + RIMESTATS_ADD(badcrc); + reset_receiver(); + } } } @@ -430,9 +474,10 @@ interrupt(UART0RX_VECTOR) cc1020_rxhandler(void) } else { return; } - /* Update RSSI. - TODO: add sampling/averaging of several RSSI to get - more reliable RSSI values + /* + * Update RSSI. + * TODO: add sampling/averaging of several RSSI to get + * more reliable RSSI values. */ rssi = cc1020_read_reg(CC1020_RSS); CC1020_SET_OPSTATE(CC1020_RX | CC1020_RX_RECEIVING); @@ -452,6 +497,7 @@ interrupt(UART0RX_VECTOR) cc1020_rxhandler(void) } cc1020_rxlen++; + if (cc1020_rxlen == HDRSIZE) { pktlen = ((struct cc1020_header *)cc1020_rxbuf)->length; if (pktlen == 0 || pktlen > sizeof (cc1020_rxbuf)) {