19.4.3.5 CRC Operation

A Cyclic Redundancy Check (CRC) is an error detection technique used to identify errors in data. It is commonly used to determine whether data transmitted or stored in data and program memories has been corrupted. A CRC takes a data stream or a block of data as input and generates a 16- or 32-bit output that can be appended to the data and used as a checksum.

When the data is received, the device or application repeats the CRC calculation. If the new CRC result does not match the one calculated earlier, the block contains a data error. The application will then detect this and may take a corrective action, such as requesting the data to be sent again or simply discarding the incorrect data.

The CRC engine in the DMAC supports two commonly used CRC polynomials: CRC-16 (CRC-CCITT) and CRC-32 (IEEE 802.3).

  • CRC-16:
    • Polynomial: x16 + x12 + x5 + 1
    • Hex value: 0x1021
  • CRC-32:
    • Polynomial: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
    • Hex value: 0x04C11DB7

The data source for the CRC engine can be either one of the DMA channels or the APB bus interface, and must be selected by writing to the CRC Input Source bits in the CRC Control (CRCCTRL.CRCSRC) register. The CRC engine then takes data input from the selected source and generates a checksum based on these data. The checksum is available in the CRC Checksum (CRCCHKSUM) register. When CRC-32 polynomial is used, the final checksum read is bit-reversed and complemented, as shown in the following figure.

The CRC polynomial is selected by writing to the CRC Polynomial Type bit in the CRC Control (CRCCTRL.CRCPOLY) register, the default is CRC-16. The CRC engine operates on byte only. When the DMA is used as the data source for the CRC engine, the DMA channel beat size setting will be used. When the APB bus interface is used, the application must configure the CRC Beat Size bit field of the CRC Control (CRCCTRL.CRCBEATSIZE) register. 8-, 16-, or 32-bit bus transfer access types are supported. The corresponding number of bytes will be written in the CRCDATAIN, register and the CRC engine will operate on the input data in a byte-by-byte manner.

Figure 19-11. CRC Generator Block Diagram
CRC on DMA data
CRC-16 or CRC-32 calculations can be performed on data passing through any DMA channel. Once a DMA channel is selected as the source, the CRC engine will continuously generate the CRC on the data passing through that channel. The checksum is available for readout once the DMA transaction is completed or aborted. A CRC can also be generated on SRAM, Flash or I/O memory by passing these data through a DMA channel. In this case, the destination register for the DMA data can be the data input CRC Data Input (CRCDATAIN) register in the CRC engine.
CRC using the I/O interface
Before using the CRC engine with the I/O interface, the application must set the CRC Beat Size bit field in the CRC Control (CRCCTRL.CRCBEATSIZE) register. 8/16/32-bit bus transfer type can be selected.

CRC can be performed on any data by loading it into the CRC engine using the CPU and writing the data to the CRCDATAIN register. Using this method, an arbitrary number of bytes can be written to the register by the CPU, and the CRC is calculated continuously for each byte, starting with the lowest byte. When the CRC engine is loaded by word or half-word, the CRC calculation also starts with the lowest byte of each word.

The completion of the CRC checksum calculation is signaled by the DMAC setting the CRC Busy bit in the CRC Status (CRCSTATUS.CRCBUSY) register. Before reading the checksum, CRCSTATUS.CRCBUSY must be cleared, as the ‘bit-reverse + complement’ operation is not performed while this bit is set.

CRCSTATUS.CRCBUSY will be set by the hardware when the first byte of data is loaded. Once all the data has been loaded, CRCSTATUS.CRCBUSY must be cleared in software for the ‘bit-reverse + complement’ operation to be performed, ensuring that the CRCCHKSUM register is ready to be read.

Manual writes to the CRC must be performed while CRCSTATUS.CRCBUSY is set.