µTasker Forum

µTasker Forum => NXPTM M522XX, KINETIS and i.MX RT => Topic started by: mark on February 21, 2021, 06:04:20 AM

Title: Kinetis CRC HW Module
Post by: mark on February 21, 2021, 06:04:20 AM
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).

Code: [Select]
              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:

Code: [Select]
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:

Code: [Select]
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