Hi All
The following details concern the CRC HW module in the Kinetis parts and is valid as from 21st Feb. 2021 in the developers version.
1. The driver can be enabled with (in app_hw_kinetis.h) SUPPORT_HW_CRC
2. These are the modes that are implemented:
CRC16_CCITT_FALSE_CALCULATION
CRC16_AUG_CCITT_CALCULATION
CRC16_CDMA2000_CALCULATION
CRC16_DDS110_CALCULATION
CRC16_DECTR_CALCULATION
CRC16_DECTX_CALCULATION
CRC16_T10_DIF_CALCULATION
CRC16_TELEDISK_CALCULATION
CRC16_XMODEM_CALCULATION
CRC16_EN_13757_CALCULATION
CRC16_GENIBUS_CALCULATION
CRC16_MAXIM_CALCULATION
CRC16_TMS37157_CALCULATION
CRC16_MCRF4XX_CALCULATION
CRC16_RIELLO_CALCULATION
CRC16_USB_CALCULATION
CRC16_ARC_CALCULATION
CRC16_MODBUS_CALCULATION
CRC16_MCRF4XX_CALCULATION
CRC16_RIELLO_CALCULATION
CRC16_TMS37157_CALCULATION
CRC16_A_CALCULATION
CRC16_KERMIT_CALCULATION
CRC16_BUYPASS_CALCULATION
CRC16_X25_CALCULATION
CRC16_DNP_CALCULATION
CRC32_IEEE_CALCULATION
CRC32_BZIP2_CALCULATION
CRC32_MPEG2_CALCULATION
CRC32_POSIX_CALCULATION
CRC32_Q_CALCULATION
CRC32_C_CALCULATION
CRC32_D_CALCULATION
CRC32_JAMCRC_CALCULATION
CRC32_XFER_CALCULATION
3. In debug.c are some test commands in the I/O menu which allow testing two CRC16 and two CRC32 types to be verified
{"crc16", "Check CRC-16-Maxim", DO_HARDWARE, DO_CRC_16_MAXIM},
{"crc16b", "Check CRC-16-Buypass", DO_HARDWARE, DO_CRC_16_BUYPASS},
{"crc32", "Check CRC-32-IEEE", DO_HARDWARE, DO_CRC_32_IEEE},
{"crc32m", "Check CRC-32-Mpeg-2", DO_HARDWARE, DO_CRC_32_MPEG2},
4. This is how to use it (see also the code in debug.c which verifies the result with reference values).
static const unsigned char ucRefData[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B'};
fnCalculateCRC(ucRefData, sizeof(ucRefData), (CRC16_MAXIM_CALCULATION)); // configure the calculation and calculate the first buffer
fnCalculateCRC(ucRefData, sizeof(ucRefData), 0); // recalculate without reseeding
ulCalculated = fnCalculateCRC(ucRefData, sizeof(ucRefData), 0); // recalculate without reseeding
fnDebugHex(ulCalculated, (WITH_LEADIN | sizeof(unsigned short) | WITH_CR_LF)); // display the result
if (ulCalculated == 0xf0bc) { // recalculate without reseeding and terminate (power down hardware CRC module)
fnDebugMsg("Pass\r\n");
}
else {
fnDebugMsg("Failed\r\n");
}
Terminal output example:
#crc16
0xf0bc
Pass
The example shows the input being passed 3 times.
If one only needs to calculate a single buffer it is used like this:
usCalculated = (unsigned short)fnCalculateCRC(ucRefData, sizeof(ucRefData), (CRC16_MAXIM_CALCULATION));
CRC16_MAXIM_CALCULATION selects the standard to use (internally it uses 0x8005 polynomial, 0x0000 seed value and the result is inverted).
The result returned is always 32 bits in length but in the case of the CRC16 (as shown) it can be cast to a 16 bit result.
If the calculation is to be performed over multiple input buffers without resetting the seed in between following calls can be done with:
fnCalculateCRC(ucRefData, sizeof(ucRefData), (0)); // continue calculating the CRC over multiple buffers
fnCalculateCRC(ucRefData, sizeof(ucRefData), (0));
fnCalculateCRC(ucRefData, sizeof(ucRefData), (0));
usCalculated = (unsigned short)fnCalculateCRC(ucRefData, sizeof(ucRefData), (0)); // use the final result
The mode parameter is simply set to 0 so that the mode is retained without setting a new seed value. Intermediate results are returned but don't need to be used until all buffers have been handled.
5. After each calculation the CRC module is automatically powered down.
6. The API should be very easy to use and can be used for a wide range of standard CRC16 and CRC32 calculations just by passing the desired mode parameter (without needing to know all setup details to achieve the mode)
7. The function works in on the Kinetis HW when it has a CRC module integrated. It also works in the simulator when using this command. The simulator emulates the way that the module operates and produces the equivalent output for all of the modes.
Regards
Mark