From bd75219ba00ca0f41be773c3dbbf5fa0bff0d908 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Thu, 30 Mar 2017 12:54:29 +0300 Subject: [PATCH] crc16: Create function for computing CRC 16 Add the simplest possible CRC 16 function that computes the CRC value without the help of lookup tables. Change-Id: I9163389adaa4a70c4e8ce8ce6d5f0661f40c7871 Signed-off-by: Patrik Flykt --- drivers/Makefile | 1 + drivers/crc/Makefile | 1 + drivers/crc/crc16_sw.c | 35 ++++++++++++++++++++++ include/crc16.h | 66 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 drivers/crc/Makefile create mode 100644 drivers/crc/crc16_sw.c create mode 100644 include/crc16.h diff --git a/drivers/Makefile b/drivers/Makefile index 4bf578b86c4..8fe8bbcfefe 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_PINMUX) += pinmux/ obj-$(CONFIG_DMA) += dma/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_CRYPTO) += crypto/ +obj-y += crc/ diff --git a/drivers/crc/Makefile b/drivers/crc/Makefile new file mode 100644 index 00000000000..9968597cc2e --- /dev/null +++ b/drivers/crc/Makefile @@ -0,0 +1 @@ +obj-y += crc16_sw.o diff --git a/drivers/crc/crc16_sw.c b/drivers/crc/crc16_sw.c new file mode 100644 index 00000000000..ee9da073bb9 --- /dev/null +++ b/drivers/crc/crc16_sw.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +uint16_t crc16(const uint8_t *src, size_t len, uint16_t polynomial, + uint16_t initial_value) +{ + uint16_t crc = initial_value; + size_t i, b; + + /* src length + crc width of zeros appended */ + for (i = 0; i < len + sizeof(crc); i++) { + + for (b = 0; b < 8; b++) { + uint16_t divide = crc & 0x8000; + + crc = (crc << 1); + + /* choose input bytes or implicit trailing zeros */ + if (i < len) { + crc |= !!(src[i] & (0x80 >> b)); + } + + if (divide) { + crc = crc ^ polynomial; + } + } + } + + return crc; +} diff --git a/include/crc16.h b/include/crc16.h new file mode 100644 index 00000000000..cd29b130aa7 --- /dev/null +++ b/include/crc16.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief CRC 16 computation function + */ + +#ifndef __CRC16_H +#define __CRC16_H + +#include +#include + +/** + * @brief Generic function for computing CRC 16 + * + * Compute CRC 16 by passing in the address of the input, the input length + * and polynomial used in addition to the initial value. + * + * @param src Input bytes for the computation + * @param len Length of the input in bytes + * @param polynomial The polynomial to use omitting the leading x^16 + * coefficient + * @param initial_value Initial value for the CRC computation + * + * @return The computed CRC16 value + */ +uint16_t crc16(const uint8_t *src, size_t len, uint16_t polynomial, + uint16_t initial_value); + +/** + * @brief Compute CCITT variant of CRC 16 + * + * CCITT variant of CRC 16 is using 0x1021 as its polynomial with the initial + * value set to 0xffff. + * + * @param src Input bytes for the computation + * @param len Length of the input in bytes + * + * @return The computed CRC16 value + */ +static inline uint16_t crc16_ccitt(const uint8_t *src, size_t len) +{ + return crc16(src, len, 0x1021, 0xffff); +} + +/** + * @brief Compute ANSI variant of CRC 16 + * + * ANSI variant of CRC 16 is using 0x8005 as its polynomial with the initial + * value set to 0xffff. + * + * @param src Input bytes for the computation + * @param len Length of the input in bytes + * + * @return The computed CRC16 value + */ +static inline uint16_t crc16_ansi(const uint8_t *src, size_t len) +{ + return crc16(src, len, 0x8005, 0xffff); +} + +#endif