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 <patrik.flykt@intel.com>
This commit is contained in:
Patrik Flykt 2017-03-30 12:54:29 +03:00 committed by Jukka Rissanen
parent 70cdaba202
commit bd75219ba0
4 changed files with 103 additions and 0 deletions

View File

@ -30,3 +30,4 @@ obj-$(CONFIG_PINMUX) += pinmux/
obj-$(CONFIG_DMA) += dma/
obj-$(CONFIG_USB) += usb/
obj-$(CONFIG_CRYPTO) += crypto/
obj-y += crc/

1
drivers/crc/Makefile Normal file
View File

@ -0,0 +1 @@
obj-y += crc16_sw.o

35
drivers/crc/crc16_sw.c Normal file
View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2017 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <crc16.h>
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;
}

66
include/crc16.h Normal file
View File

@ -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 <stdint.h>
#include <stddef.h>
/**
* @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