9.2. CRC-CCITT Source Code

The checksum algorithm implements a CRC-CCITT using initialization values equal to 0x1D0F and 0x1021 (normal representation) as the poly.

9.2.1. Header file

/**
 * @file
 * Functions for calculation of CRC.
 * @copyright 2018 Silicon Laboratories Inc.
 */
#ifndef _CRC_H_
#define _CRC_H_

/****************************************************************************/
/*                              INCLUDE FILES                               */
/****************************************************************************/

#include <stdint.h>

/****************************************************************************/
/*                     EXPORTED TYPES and DEFINITIONS                       */
/****************************************************************************/

/****************************************************************************/
/*                              EXPORTED DATA                               */
/****************************************************************************/

/****************************************************************************/
/*                           EXPORTED FUNCTIONS                             */
/****************************************************************************/

#define CRC_INITAL_VALUE                    0x1D0Fu

/**
 * Returns a CRC calculation using the CCITT polynomial (0x1021).
 *
 * @param crc Initial value set to CRC_INITAL_VALUE unless calculating multiple parts of a frame. In that case
 *            the value should be set to the result of the previous calculation.
 * @param pDataAddr Pointer to the array of data.
 * @param bDataLen Length of the data.
 * @return CRC value
 */
uint16_t CRC_CheckCrc16(
  uint16_t crc,
  uint8_t *pDataAddr,
  uint16_t bDataLen
);

#endif /* _CRC_H_ */

9.2.2. Implementation

/**
 * @file
 * Functions for calculation of CRC.
 * @copyright 2018 Silicon Laboratories Inc.
 */
#include <CRC.h>

#define POLY 0x1021          /* crc-ccitt mask */

uint16_t CRC_CheckCrc16(
  uint16_t crc,
  uint8_t *pDataAddr,
  uint16_t bDataLen)
{
  uint8_t WorkData;
  uint8_t bitMask;
  uint8_t NewBit;

  while(bDataLen--)
  {
    WorkData = *pDataAddr;
    pDataAddr++;
    for (bitMask = 0x80; bitMask != 0; bitMask >>= 1)
    {
      /* Align test bit with next bit of the message byte, starting with msb. */
      NewBit = ((WorkData & bitMask) != 0) ^ ((crc & 0x8000) != 0);
      crc <<= 1;
      if (NewBit)
      {
        crc ^= POLY;
      }
    } /* for (bitMask = 0x80; bitMask != 0; bitMask >>= 1) */
  }
  return crc;
}