lib: add crc7.

Used as a checksum on command messages when talking with MMC cards.

Implemented using the unwound bytewise implementation from
https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
which is a good mix of size and speed.

The API and naming matches lib/crc7.c in Linux.

Signed-off-by: Michael Hope <mlhx@google.com>
This commit is contained in:
Michael Hope 2018-02-11 18:07:39 +01:00 committed by Anas Nashif
parent ef9361fca0
commit bbafc36b1c
4 changed files with 70 additions and 2 deletions

36
include/crc7.h Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2018 Google LLC.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __CRC7_H_
#define __CRC7_H_
#include <zephyr/types.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Compute the CRC-7 checksum of a buffer.
*
* See JESD84-A441. Used by the MMC protocol. Uses 0x09 as the
* polynomial with no reflection. The CRC is left
* justified, so bit 7 of the result is bit 6 of the CRC.
*
* @param seed Value to seed the CRC with
* @param src Input bytes for the computation
* @param len Length of the input in bytes
*
* @return The computed CRC7 value
*/
u8_t crc7_be(u8_t seed, const u8_t *src, size_t len);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1 +1 @@
zephyr_sources(crc32_sw.c crc16_sw.c crc8_sw.c)
zephyr_sources(crc32_sw.c crc16_sw.c crc8_sw.c crc7_sw.c)

19
lib/crc/crc7_sw.c Normal file
View file

@ -0,0 +1,19 @@
/*
* Copyright (c) 2018 Google LLC.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <crc7.h>
u8_t crc7_be(u8_t seed, const u8_t *src, size_t len)
{
while (len--) {
u8_t e = seed ^ *src++;
u8_t f = e ^ (e >> 4) ^ (e >> 7);
seed = (f << 1) ^ (f << 4);
}
return seed;
}

View file

@ -9,6 +9,7 @@
#include <lib/crc/crc32_sw.c>
#include <lib/crc/crc16_sw.c>
#include <lib/crc/crc8_sw.c>
#include <lib/crc/crc7_sw.c>
void test_crc32_ieee(void)
{
@ -109,6 +110,17 @@ void test_crc8_ccitt(void)
sizeof(test2)) == 0xFB, "pass", "fail");
}
void test_crc7_be(void)
{
u8_t test0[] = { 0 };
u8_t test1[] = { 'A' };
u8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
zassert_equal(crc7_be(0, test0, sizeof(test0)), 0, NULL);
zassert_equal(crc7_be(0, test1, sizeof(test1)), 0xDA, NULL);
zassert_equal(crc7_be(0, test2, sizeof(test2)), 0xEA, NULL);
}
void test_main(void)
{
ztest_test_suite(test_crc,
@ -118,6 +130,7 @@ void test_main(void)
ztest_unit_test(test_crc16_ccitt),
ztest_unit_test(test_crc16_ccitt_for_ppp),
ztest_unit_test(test_crc16_itu_t),
ztest_unit_test(test_crc8_ccitt));
ztest_unit_test(test_crc8_ccitt),
ztest_unit_test(test_crc7_be));
ztest_run_test_suite(test_crc);
}