Files
MSE-SoftwEng/pico-sensor/McuLib/src/McuCRC_Generator.h
2025-05-06 13:07:01 +00:00

174 lines
5.9 KiB
C

/**
* Copyright Ivo Gärtner
* \file
* \author Ivo Gärtner
* \copyright Ivo Gärtner
* \date 9.11.2018
* SPDX-License-Identifier: BSD-3-Clause
*
* This program code does very closely rely on the example code
* of Ross Williams' article "A Painless Guide to CRC Error
* Detection Algorithms".
*
*
* How to use this code:
*
* First: Define the McuCRC_Generator_t structure, e.g. like this:
*
* McuCRC_Generator_t crcGen;
* crcGen.McuCRC_InitialValue = 0xFFFFFFFF;
* crcGen.McuCRC_Polynomial = 0x04C11DB7;
* crcGen.McuCRC_ReflectedInput = 0;
* crcGen.McuCRC_ReflectedOutput = 0;
* crcGen.McuCRC_Width = McuCRC_WIDTH_32_BIT;
* crcGen.McuCRC_XorOutput = 0xFFFFFFFF;
* crcGen.McuCRC_Table = NULL;
*
* Second: Run the McuCRC_Init function on the McuCRC_Generator_t structure:
*
* McuCRC_Init( &crcGen );
*
* Third: For the shift register implementation call McuCRC_CalculateBlock() and then McuCRC_GetCrcValue(), e.g. like this:
*
* uint32_t crc;
* uint8_t byteArray[] = {0x01, 0x01, 0x12, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
*
* McuCRC_CalculateBlock( &crcGen, byteArray, 8 );
* crc = McuCRC_GetCrcValue( &crcGen );
*
* Or for the LUT implementation call McuCRC_CalculateWithTableCRC32(), or the 8 / 16 bit versions of it, like this:
*
* crc = McuCRC_CalculateWithTableCRC8( &crcGen, byteArray, 8 );
*
*
* happy crc'ing
*/
#ifndef McuCRC_GENERATOR_H_INCLUDED
#define McuCRC_GENERATOR_H_INCLUDED
#include <stdint.h>
#include <stddef.h>
#define McuCRC_BIT_PER_BYTE 8
enum McuCRC_WIDTH_BITS
{
McuCRC_WIDTH_8_BIT = 8,
McuCRC_WIDTH_16_BIT = 16,
McuCRC_WIDTH_32_BIT = 32
};
typedef struct
{
enum McuCRC_WIDTH_BITS McuCRC_Width; /**< PARAMETER: Width of the CRC in bits - 16 or 32 */
uint32_t McuCRC_Polynomial; /**< PARAMETER: The CRC algorithm's polynomial */
uint32_t McuCRC_InitialValue; /**< PARAMETER: Initial register value */
uint32_t McuCRC_ReflectedInput; /**< PARAMETER: Reflect input - 0: no, >=1: yes */
uint32_t McuCRC_ReflectedOutput; /**< PARAMETER: Reflect output - 0: no, >=1: yes */
uint32_t McuCRC_XorOutput; /**< PARAMETER: XOR this to the output of the CRC calculation */
uint32_t McuCRC_WidthMask; /**< CONTEXT: Mask for the crc width */
uint32_t McuCRC_Register; /**< CONTEXT: Storage for the crc value */
void *McuCRC_Table; /**< PARAMETER: Pointer to a LUT if no shift register implementation is used */
} McuCRC_Generator_t;
/**
* \fn McuCRC_Init()
*
* \brief Sets the initial value of the crc calculation and calculates the width mask
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
*/
void McuCRC_Init ( McuCRC_Generator_t *crcGen );
/**
* \fn McuCRC_CalculateBlock()
*
* \brief Calculates a crc from a block of data (uint8_t array)
*
* This function calculates the crc but does not Xor the output. To get the
* Xor'd output use the function \a McuCRC_GetCrcValue() which returns the Xor'd
* crc value.
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
* \param uint8_t *data_pu8 Pointer to the data to be crc'd
* \param size_t length Number of bytes in the data array
*/
void McuCRC_CalculateBlock (McuCRC_Generator_t *crcGen, uint8_t *data_pu8, size_t length );
/**
* \fn McuCRC_CalculateNextValue()
*
* \brief Calculates the crc of one byte in a data stream
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
* \param uint8_t data_u8 Byte to be crc'd
*
*/
void McuCRC_CalculateNextValue ( McuCRC_Generator_t *crcGen, uint8_t data_u8 );
/**
* \fn McuCRC_GetCrcValue()
*
* \brief Returns you the Xor'd crc
*
* When you ran the functions \a McuCRC_CalculateBlock or \a McuCRC_CalculateNextValue over
* the data which you want to CRC, this function Xor's the calculated crc and returns
* this Xor'd value.
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
* \return The value in crcGen->McuCRC_Register XOR^d with the crcGen->McuCRC_XorOut parameter
*/
uint32_t McuCRC_GetCrcValue ( McuCRC_Generator_t *crcGen );
/**
* \fn McuCRC_CalculateWithTableCRC32()
*
* \brief Calculates a 32 bit crc of a byte array using a LUT
*
* The LUT used for this function can be calculated using the function \a McuCRC_GenerateLookUpTable()
* The pointer the LUT has to be casted to (void*)
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
* \return The calculated crc, XOR^d with the crcGen->McuCRC_XorOut parameter
*/
uint32_t McuCRC_CalculateWithTableCRC32 ( McuCRC_Generator_t *crcGen, uint8_t *data_pu8, size_t length );
/**
* \fn McuCRC_CalculateWithTableCRC16()
*
* \brief Calculates a 16 bit crc of a byte array using a LUT
*
* The LUT used for this function can be calculated using the function \a McuCRC_GenerateLookUpTable()
* The pointer the LUT has to be casted to (void*)
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
* \return The calculated crc, XOR^d with the crcGen->McuCRC_XorOut parameter
*/
uint16_t McuCRC_CalculateWithTableCRC16 ( McuCRC_Generator_t *crcGen, uint8_t *data_pu8, size_t length );
/**
* \fn McuCRC_CalculateWithTableCRC8()
*
* \brief Calculates a 8 bit crc of a byte array using a LUT
*
* The LUT used for this function can be calculated using the function \a McuCRC_GenerateLookUpTable()
* The pointer the LUT has to be casted to (void*)
*
* \param McuCRC_Generator_t *crcGen Pointer to a \a McuCRC_Generator_t structure
* \return The calculated crc, XOR^d with the crcGen->McuCRC_XorOut parameter
*/
uint8_t McuCRC_CalculateWithTableCRC8 ( McuCRC_Generator_t *crcGen, uint8_t *data_pu8, size_t length );
/**
* \fn McuCRC_Reflect()
*
* \brief Returns the bottom \a noOfBits_u32 bits of \a value_u32 in revered order
*
* \param uint32_t value_u32 Value on which to perform the bit reversal
* \param uint32_t noOfBits_u32 Number of bits to reverse
*/
uint32_t McuCRC_Reflect ( uint32_t value_u32, uint32_t noOfBits_u32);
#endif // McuCRC_GENERATOR_H_INCLUDED