Hardware and Software CRC implementation for K64F

Fork of FastCRC by tom dunigan

CRC_HW.cpp

Committer:
pkozyra
Date:
2016-11-23
Revision:
2:8741619dfd64
Child:
3:1a167cf7f3bb

File content as of revision 2:8741619dfd64:


#include "CRC_HW.h"

// ===============================================

typedef struct {
  union {
      uint32_t CRC; //CRC Data register
      struct {
          uint16_t CRC16;
          uint16_t CRC16_1;
      };
      struct {
          uint8_t CRC8;
          uint8_t CRC8_1;
          uint8_t CRC8_2;
          uint8_t CRC8_3;
      };
  };
  uint32_t GPOLY; //CRC Polynomial register
  uint32_t CTRL;  //CRC Control register
} CRC_T;

static volatile CRC_T * const rCRC = (CRC_T *)0x40032000;

#define CRC_CTRL_WAS   25 // Write CRC Data Register As Seed(1) / Data(0)
#define CRC_CTRL_TCRC  24 // Width of CRC protocol (0=16 BIT, 1=32 BIT)
#define CRC_CTRL_TOTR1 29 // TOTR[1]

// ================= 16-BIT CRC ===================

/** Constructor
 * Enables CRC-clock
 */
FastCRC16::FastCRC16(){
  SIM_SCGC6 |= SIM_SCGC6_CRC_MASK;
}

/** XMODEM
 * @param data Pointer to Data
 * @param datalen Length of Data
 * @return CRC value
 */
uint16_t FastCRC16::xmodem(uint16_t poly, uint16_t data)
{
  //width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 
  return generic(poly, 0, CRC_FLAG_TOT00_TOTR00, data);
}

/** Update
 * Call for subsequent calculations with previous seed
 * @param data Pointer to Data
 * @param datalen Length of Data
 * @return CRC value
 */
uint16_t FastCRC16::update(uint16_t data)
{
    uint16_t src = data;
    rCRC->CRC16_1 = src; //Write 16 Bit

    return rCRC->CRC16_1;
}

/** generic function for all 16-Bit CRCs
 * @param polynom Polynom
 * @param seed Seed
 * @param flags Flags
 * @param data Pointer to Data
 * @param datalen Length of Data
 * @return CRC value
 */
uint16_t FastCRC16::generic(const uint16_t polynom, const uint16_t seed, const uint32_t flags, uint16_t data)
{

  rCRC->CTRL  = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS);// 32-Bit Mode, prepare to write seed(25)
  rCRC->GPOLY = ((uint32_t)polynom)<<16;                       // set polynom
  rCRC->CRC   = ((uint32_t)seed<<16);                          // this is the seed
  rCRC->CTRL  = flags | (1<<CRC_CTRL_TCRC);                    // Clear WAS Bit - prepare to write data

  return update(data);
}

// ================= 32-BIT CRC ===================

/** Constructor
 * Enables CRC-clock
 */
FastCRC32::FastCRC32(){
  SIM_SCGC6 |= SIM_SCGC6_CRC_MASK;
}

/** CRC32
 * @param data Pointer to Data
 * @param datalen Length of Data
 * @return CRC value
 */
uint32_t FastCRC32::crc32(const uint8_t *data, const uint16_t datalen)
{
  // poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0xffffffff 
  return generic(0x04C11DB7L, 0XFFFFFFFFL, CRC_FLAG_TOT00_TOTR00, data, datalen);
}

/** Update
 * Call for subsequent calculations with previous seed
 * @param data Pointer to Data
 * @param datalen Length of Data
 * @return CRC value
 */
//#pragma GCC diagnostic ignored "-Wpointer-arith"
uint32_t FastCRC32::update(const uint8_t *data, const uint16_t datalen)
{

  const uint8_t *src = data;

    rCRC->CRC8_3 = *src++; //Write 8 BIT

  return rCRC->CRC;
}

/** generic function for all 32-Bit CRCs
 * @param polynom Polynom
 * @param seed Seed
 * @param flags Flags
 * @param data Pointer to Data
 * @param datalen Length of Data
 * @return CRC value
 */
uint32_t FastCRC32::generic(const uint32_t polynom, const uint32_t seed, const uint32_t flags, const uint8_t *data, const uint16_t datalen)
{

  rCRC->CTRL  = flags | (1<<CRC_CTRL_TCRC) | (1<<CRC_CTRL_WAS); // 32Bit Mode, prepare to write seed(25)
  rCRC->GPOLY = polynom;                                        // Set polynom
  rCRC->CRC   = seed;                                           // This is the seed
  rCRC->CTRL  = flags | (1<<CRC_CTRL_TCRC);                     // Clear WAS Bit - prepare to write data

  return update(data, datalen);
}