diff --git a/libuavcan/include/uavcan/internal/transport/crc.hpp b/libuavcan/include/uavcan/internal/transport/crc.hpp index eab0a34e58..f3aece90d9 100644 --- a/libuavcan/include/uavcan/internal/transport/crc.hpp +++ b/libuavcan/include/uavcan/internal/transport/crc.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include namespace uavcan @@ -11,8 +12,16 @@ namespace uavcan /** * CRC-16-CCITT - * Initial value: 0x0000 - * Coefficient: 0x1021 + * Initial value: 0xFFFF + * Poly: 0x1021 + * Reverse: no + * Output xor: 0 + * + * import crcmod + * crc = crcmod.predefined.Crc('crc-ccitt-false') + * crc.update('123456789') + * crc.hexdigest() + * '29B1' */ class TransportCRC { @@ -23,17 +32,26 @@ public: enum { NumBytes = 2 }; TransportCRC() - : value_(0x0000) + : value_(0xFFFF) { } TransportCRC(const uint8_t* bytes, unsigned int len) - : value_(0x0000) + : value_(0xFFFF) { add(bytes, len); } - uint16_t add(uint8_t byte); - uint16_t add(const uint8_t* bytes, unsigned int len); + void add(uint8_t byte) + { + value_ = ((value_ << 8) ^ Table[((value_ >> 8) ^ byte) & 0xFF]) & 0xFFFF; + } + + void add(const uint8_t* bytes, unsigned int len) + { + assert(bytes); + while (len--) + add(*bytes++); + } uint16_t get() const { return value_; } }; diff --git a/libuavcan/src/transport/crc.cpp b/libuavcan/src/transport/crc.cpp index 5ecdadd0a1..c0056ab268 100644 --- a/libuavcan/src/transport/crc.cpp +++ b/libuavcan/src/transport/crc.cpp @@ -45,18 +45,4 @@ const uint16_t TransportCRC::Table[256] = 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; -uint16_t TransportCRC::add(uint8_t byte) -{ - value_ = (value_ << 8) ^ Table[((value_ >> 8) ^ byte) & 0xFF]; - return value_; -} - -uint16_t TransportCRC::add(const uint8_t* bytes, unsigned int len) -{ - assert(bytes); - while (len--) - add(*bytes++); - return value_; -} - } diff --git a/libuavcan/test/transport/crc.cpp b/libuavcan/test/transport/crc.cpp index d76d1d7fe3..aa61b86cce 100644 --- a/libuavcan/test/transport/crc.cpp +++ b/libuavcan/test/transport/crc.cpp @@ -2,25 +2,34 @@ * Copyright (C) 2014 Pavel Kirienko */ -#include #include #include +/* + import crcmod + crc = crcmod.predefined.Crc('crc-ccitt-false') + crc.update('123') + crc.hexdigest() +'5BCE' + crc.update('456789') + crc.hexdigest() +'29B1' + */ TEST(TransportCRC, Correctness) { uavcan::TransportCRC crc; - ASSERT_EQ(0x0000, crc.get()); + ASSERT_EQ(0xFFFF, crc.get()); crc.add('1'); crc.add('2'); crc.add('3'); - ASSERT_EQ(38738, crc.get()); + ASSERT_EQ(0x5BCE, crc.get()); - crc.add(reinterpret_cast("Foobar"), 6); - ASSERT_EQ(53881, crc.get()); + crc.add(reinterpret_cast("456789"), 6); + ASSERT_EQ(0x29B1, crc.get()); // Initializing constructor - ASSERT_EQ(crc.get(), uavcan::TransportCRC(reinterpret_cast("123Foobar"), 9).get()); + ASSERT_EQ(crc.get(), uavcan::TransportCRC(reinterpret_cast("123456789"), 9).get()); }