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:
parent
ef9361fca0
commit
bbafc36b1c
36
include/crc7.h
Normal file
36
include/crc7.h
Normal 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
|
|
@ -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
19
lib/crc/crc7_sw.c
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue