Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/modm/math/utils/crc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ crc8_ccitt_update(uint8_t crc, uint8_t data)
data ^= crc;
for (uint8_t ii = 0; ii < 8; ii++)
{
const bool msb = (data & 0x80) != 0;
data <<= 1;
if (data & 0x80) data ^= 0x07;
if (msb) data ^= 0x07;
}
return data;
#endif
Expand Down
61 changes: 61 additions & 0 deletions test/modm/math/utils/crc_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2026, Tudor Fanaru
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/math/utils/crc.hpp>

#include "crc_test.hpp"

namespace
{
// "123456789" is the input the CRC catalogue publishes check values against,
// so the expectations below are external references.
const uint8_t check_input[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
}

void
CrcTest::testCrc8CcittCheckValue()
{
// CRC-8 with polynomial 0x07 and init 0xFF.
TEST_ASSERT_EQUALS(modm::math::crc8_ccitt(check_input, sizeof(check_input)), 0xFBU);
}

void
CrcTest::testCrc8CcittUsesEveryInputBit()
{
// Regression: shifting before testing bit 7 discards it, leaving the MSB of
// every input byte unexamined. That made crc8_ccitt_update(crc, d) equal
// crc8_ccitt_update(crc, d ^ 0x80) for all 32768 (crc, d) pairs, put only
// 128 of 256 outputs in reach, and left single-bit errors in that position
// undetectable.
for (uint16_t crc = 0; crc < 256; ++crc)
{
for (uint16_t data = 0; data < 128; ++data)
{
const uint8_t a = modm::math::crc8_ccitt_update(uint8_t(crc), uint8_t(data));
const uint8_t b = modm::math::crc8_ccitt_update(uint8_t(crc), uint8_t(data ^ 0x80));
TEST_ASSERT_TRUE(a != b);
}
}
}

void
CrcTest::testCrc16CcittCheckValue()
{
// CRC-16/MCRF4XX: reflected polynomial 0x8408, init 0xFFFF, no final xor.
TEST_ASSERT_EQUALS(modm::math::crc16_ccitt(check_input, sizeof(check_input)), 0x6F91U);
}

void
CrcTest::testCrc32CheckValue()
{
// CRC-32/ISO-HDLC, as used by zlib and PNG.
TEST_ASSERT_EQUALS(modm::math::crc32(check_input, sizeof(check_input)), 0xCBF43926UL);
}
29 changes: 29 additions & 0 deletions test/modm/math/utils/crc_test.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2026, Tudor Fanaru
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <unittest/testsuite.hpp>

/// @ingroup modm_test_test_math
class CrcTest : public unittest::TestSuite
{
public:
void
testCrc8CcittCheckValue();

void
testCrc8CcittUsesEveryInputBit();

void
testCrc16CcittCheckValue();

void
testCrc32CheckValue();
};
Loading