MCUXpresso SDK API Reference Manual  Rev. 0
NXP Semiconductors
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
CRC: Cyclic Redundancy Check Driver

Overview

MCUXpresso SDK provides the Peripheral driver for the Cyclic Redundancy Check (CRC) module of MCUXpresso SDK devices.

The cyclic redundancy check (CRC) module generates 16/32-bit CRC code for error detection. The CRC module provides three variants of polynomials, a programmable seed and other parameters required to implement a 16-bit or 32-bit CRC standard.

CRC Driver Initialization and Configuration

CRC_Init() function enables the clock for the CRC module in the LPC SYSCON block and fully (re-)configures the CRC module according to configuration structure. It also starts checksum computation by writing the seed.

The seed member of the configuration structure is the initial checksum for which new data can be added to. When starting new checksum computation, the seed shall be set to the initial checksum per the CRC protocol specification. For continued checksum operation, the seed shall be set to the intermediate checksum value as obtained from previous calls to CRC_GetConfig() function. After CRC_Init(), one or multiple CRC_WriteData() calls follow to update checksum with data, then CRC_Get16bitResult() or CRC_Get32bitResult() follows to read the result. CRC_Init() can be called as many times as required, thus, allows for runtime changes of CRC protocol.

CRC_GetDefaultConfig() function can be used to set the module configuration structure with parameters for CRC-16/CCITT-FALSE protocol.

CRC_Deinit() function disables clock to the CRC module.

CRC_Reset() performs hardware reset of the CRC module.

CRC Write Data

The CRC_WriteData() function is used to add data to actual CRC. Internally it tries to use 32-bit reads and writes for all aligned data in the user buffer and it uses 8-bit reads and writes for all unaligned data in the user buffer. This function can update CRC with user supplied data chunks of arbitrary size, so one can update CRC byte by byte or with all bytes at once. Prior call of CRC configuration function CRC_Init() fully specifies the CRC module configuration for CRC_WriteData() call.

CRC Get Checksum

The CRC_Get16bitResult() or CRC_Get32bitResult() function is used to read the CRC module checksum register. The bit reverse and 1's complement operations are already applied to the result if previously configured. Use CRC_GetConfig() function to get the actual checksum without bit reverse and 1's complement applied so it can be used as seed when resuming calculation later.

CRC_Init() / CRC_WriteData() / CRC_Get16bitResult() to get final checksum.

CRC_Init() / CRC_WriteData() / ... / CRC_WriteData() / CRC_Get16bitResult() to get final checksum.

CRC_Init() / CRC_WriteData() / CRC_GetConfig() to get intermediate checksum to be used as seed value in future.

CRC_Init() / CRC_WriteData() / ... / CRC_WriteData() / CRC_GetConfig() to get intermediate checksum.

Comments about API usage in RTOS

If multiple RTOS tasks share the CRC module to compute checksums with different data and/or protocols, the following needs to be implemented by the user:

The triplets

CRC_Init() / CRC_WriteData() / CRC_Get16bitResult() or CRC_Get32bitResult() or CRC_GetConfig()

shall be protected by RTOS mutex to protect CRC module against concurrent accesses from different tasks. Example:

CRC_Module_RTOS_Mutex_Lock;
CRC_Module_RTOS_Mutex_Unlock;

Alternatively, the context switch handler could read original configuration and restore it when switching back to original task/thread:

CRC_GetConfig(base, &originalConfig);
/* ... other task using CRC engine... */
CRC_Init(base, &originalConfig);

Comments about API usage in interrupt handler

All APIs can be used from interrupt handler although execution time shall be considered (interrupt latency of equal and lower priority interrupts increases). Protection against concurrent accesses from different interrupt handlers and/or tasks shall be assured by the user.

CRC Driver Examples

Simple examples

Simple example with default CRC-16/CCITT-FALSE protocol

crc_config_t config;
CRC_Type *base;
uint8_t data[] = {0x00, 0x01, 0x02, 0x03, 0x04};
uint16_t checksum;
base = CRC0;
CRC_GetDefaultConfig(base, &config); /* default gives CRC-16/CCITT-FALSE */
CRC_Init(base, &config);
CRC_WriteData(base, data, sizeof(data));
checksum = CRC_Get16bitResult(base);
CRC_Deinit(base);

Simple example with CRC-32 protocol configuration

crc_config_t config;
uint32_t checksum;
config.reverseIn = true;
config.complementIn = false;
config.reverseOut = true;
config.complementOut = true;
config.seed = 0xFFFFFFFFu;
CRC_Init(base, &config);
/* example: update by 1 byte at time */
while (dataSize)
{
uint8_t c = GetCharacter();
CRC_WriteData(base, &c, 1);
dataSize--;
}
checksum = CRC_Get32bitResult(base);
CRC_Deinit(base);

Advanced examples

Per-partes data updates with context switch between. Assuming we have 3 tasks/threads, each using CRC module to compute checksums of different protocol, with context switches.

Firstly, we prepare 3 CRC configurations for 3 different protocols: CRC-16 (ARC), CRC-16/CCITT-FALSE and CRC-32. Table below lists the individual protocol specifications. See also: http://reveng.sourceforge.net/crc-catalogue/

CRC-16/CCITT-FALSE CRC-16 CRC-32
Width 16 bits 16 bits 32 bits
Polynomial 0x1021 0x8005 0x04C11DB7
Initial seed 0xFFFF 0x0000 0xFFFFFFFF
Complement checksum No No Yes
Reflect In No Yes Yes
Reflect Out No Yes Yes

Corresponding functions to get configurations:

void GetConfigCrc16Ccitt(CRC_Type *base, crc_config_t *config)
{
config->reverseIn = false;
config->complementIn = false;
config->reverseOut = false;
config->complementOut = false;
config->seed = 0xFFFFU;
}
void GetConfigCrc16(CRC_Type *base, crc_config_t *config)
{
config->reverseIn = true;
config->complementIn = false;
config->reverseOut = true;
config->complementOut = false;
config->seed = 0x0U;
}
void GetConfigCrc32(CRC_Type *base, crc_config_t *config)
{
config->reverseIn = true;
config->complementIn = false;
config->reverseOut = true;
config->complementOut = true;
config->seed = 0xFFFFFFFFU;
}

The following context switches show possible API usage:

uint16_t checksumCrc16;
uint32_t checksumCrc32;
uint16_t checksumCrc16Ccitt;
crc_config_t configCrc16;
crc_config_t configCrc32;
crc_config_t configCrc16Ccitt;
GetConfigCrc16(base, &configCrc16);
GetConfigCrc32(base, &configCrc32);
GetConfigCrc16Ccitt(base, &configCrc16Ccitt);
/* Task A bytes[0-3] */
CRC_Init(base, &configCrc16);
CRC_WriteData(base, &data[0], 4);
CRC_GetConfig(base, &configCrc16);
/* Task B bytes[0-3] */
CRC_Init(base, &configCrc16Ccitt);
CRC_WriteData(base, &data[0], 4);
CRC_GetConfig(base, &configCrc16Ccitt);
/* Task C 4 bytes[0-3] */
CRC_Init(base, &configCrc32);
CRC_WriteData(base, &data[0], 4);
CRC_GetConfig(base, &configCrc32);
/* Task B add final 5 bytes[4-8] */
CRC_Init(base, &configCrc16Ccitt);
CRC_WriteData(base, &data[4], 5);
checksumCrc16Ccitt = CRC_Get16bitResult(base);
/* Task C 3 bytes[4-6] */
CRC_Init(base, &configCrc32);
CRC_WriteData(base, &data[4], 3);
CRC_GetConfig(base, &configCrc32);
/* Task A 3 bytes[4-6] */
CRC_Init(base, &configCrc16);
CRC_WriteData(base, &data[4], 3);
CRC_GetConfig(base, &configCrc16);
/* Task C add final 2 bytes[7-8] */
CRC_Init(base, &configCrc32);
CRC_WriteData(base, &data[7], 2);
checksumCrc32 = CRC_Get32bitResult(base);
/* Task A add final 2 bytes[7-8] */
CRC_Init(base, &configCrc16);
CRC_WriteData(base, &data[7], 2);
checksumCrc16 = CRC_Get16bitResult(base);

Files

file  fsl_crc.h
 

Data Structures

struct  crc_config_t
 CRC protocol configuration. More...
 

Macros

#define CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT   1
 Default configuration structure filled by CRC_GetDefaultConfig(). More...
 

Enumerations

enum  crc_polynomial_t {
  kCRC_Polynomial_CRC_CCITT = 0U,
  kCRC_Polynomial_CRC_16 = 1U,
  kCRC_Polynomial_CRC_32 = 2U
}
 CRC polynomials to use. More...
 

Functions

void CRC_Init (CRC_Type *base, const crc_config_t *config)
 Enables and configures the CRC peripheral module. More...
 
static void CRC_Deinit (CRC_Type *base)
 Disables the CRC peripheral module. More...
 
void CRC_Reset (CRC_Type *base)
 resets CRC peripheral module. More...
 
void CRC_GetDefaultConfig (crc_config_t *config)
 Loads default values to CRC protocol configuration structure. More...
 
void CRC_GetConfig (CRC_Type *base, crc_config_t *config)
 Loads actual values configured in CRC peripheral to CRC protocol configuration structure. More...
 
void CRC_WriteData (CRC_Type *base, const uint8_t *data, size_t dataSize)
 Writes data to the CRC module. More...
 
static uint32_t CRC_Get32bitResult (CRC_Type *base)
 Reads 32-bit checksum from the CRC module. More...
 
static uint16_t CRC_Get16bitResult (CRC_Type *base)
 Reads 16-bit checksum from the CRC module. More...
 

Driver version

#define FSL_CRC_DRIVER_VERSION   (MAKE_VERSION(2, 0, 1))
 CRC driver version. More...
 

Data Structure Documentation

struct crc_config_t

This structure holds the configuration for the CRC protocol.

Data Fields

crc_polynomial_t polynomial
 CRC polynomial. More...
 
bool reverseIn
 Reverse bits on input. More...
 
bool complementIn
 Perform 1's complement on input. More...
 
bool reverseOut
 Reverse bits on output. More...
 
bool complementOut
 Perform 1's complement on output. More...
 
uint32_t seed
 Starting checksum value. More...
 

Field Documentation

crc_polynomial_t crc_config_t::polynomial
bool crc_config_t::reverseIn
bool crc_config_t::complementIn
bool crc_config_t::reverseOut
bool crc_config_t::complementOut
uint32_t crc_config_t::seed

Macro Definition Documentation

#define FSL_CRC_DRIVER_VERSION   (MAKE_VERSION(2, 0, 1))

Version 2.0.1.

Current version: 2.0.1

Change log:

  • Version 2.0.0
    • initial version
  • Version 2.0.1
    • add explicit type cast when writing to WR_DATA
#define CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT   1

Uses CRC-16/CCITT-FALSE as default.

Enumeration Type Documentation

Enumerator
kCRC_Polynomial_CRC_CCITT 

x^16+x^12+x^5+1

kCRC_Polynomial_CRC_16 

x^16+x^15+x^2+1

kCRC_Polynomial_CRC_32 

x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1

Function Documentation

void CRC_Init ( CRC_Type *  base,
const crc_config_t config 
)

This functions enables the CRC peripheral clock in the LPC SYSCON block. It also configures the CRC engine and starts checksum computation by writing the seed.

Parameters
baseCRC peripheral address.
configCRC module configuration structure.
static void CRC_Deinit ( CRC_Type *  base)
inlinestatic

This functions disables the CRC peripheral clock in the LPC SYSCON block.

Parameters
baseCRC peripheral address.
void CRC_Reset ( CRC_Type *  base)
Parameters
baseCRC peripheral address.
void CRC_GetDefaultConfig ( crc_config_t config)

Loads default values to CRC protocol configuration structure. The default values are:

* config->reverseIn = false;
* config->complementIn = false;
* config->reverseOut = false;
* config->complementOut = false;
* config->seed = 0xFFFFU;
*
Parameters
configCRC protocol configuration structure
void CRC_GetConfig ( CRC_Type *  base,
crc_config_t config 
)

The values, including seed, can be used to resume CRC calculation later.

Parameters
baseCRC peripheral address.
configCRC protocol configuration structure
void CRC_WriteData ( CRC_Type *  base,
const uint8_t *  data,
size_t  dataSize 
)

Writes input data buffer bytes to CRC data register.

Parameters
baseCRC peripheral address.
dataInput data stream, MSByte in data[0].
dataSizeSize of the input data buffer in bytes.
static uint32_t CRC_Get32bitResult ( CRC_Type *  base)
inlinestatic

Reads CRC data register.

Parameters
baseCRC peripheral address.
Returns
final 32-bit checksum, after configured bit reverse and complement operations.
static uint16_t CRC_Get16bitResult ( CRC_Type *  base)
inlinestatic

Reads CRC data register.

Parameters
baseCRC peripheral address.
Returns
final 16-bit checksum, after configured bit reverse and complement operations.