Skip to main content
Graduate II
December 16, 2023
Solved

How to generate CRC-16 in javascript and validate the checksum on STM32F373

  • December 16, 2023
  • 2 replies
  • 6296 views

I need to generate a simple CRC16 checksum from a unit8_t array[64] in javascript and validate the checksum on the STM32F373.

I have been looking at the CRC unit and all of its options.  I see STM32 use a non-standard scheme.

Does anyone know of a sample library or function examples showing how it can be done in javascript with matching c function?  

Here is the javascript function i could potentially use if I can match up a c function or STM32 CRC config settings to match:

function calculateCRC(data) {
    const polynomial = 0xEDB88320;
    let crc = 0xFFFFFFFF;
    // Iterate through each character in the data
    for (let i = 0; i < data.length; i++) {
        // XOR the current character
        // with the current CRC value
        crc ^= data.charCodeAt(i);
 
        // Perform bitwise operations
        // to calculate the new CRC value
        for (let j = 0; j < 8; j++) {
            crc = (crc >>> 1) ^ (crc & 1 ? polynomial : 0);
        }
    }
    // Perform a final XOR operation and return the CRC value
    return crc ^ 0xFFFFFFFF;
}
 
    This topic has been closed for replies.
    Best answer by JamesHome

    The CRC16 checksum calculation is commonly used for error-checking purposes. The JavaScript function you provided is a CRC32 implementation, not CRC16. Here's a CRC16 implementation in JavaScript that matches a common CRC16-CCITT polynomial (0x1021) and its corresponding C function:

    Javascript&colon;

     

    function calculateCRC16(data) {
     const polynomial = 0x1021;
     let crc = 0xFFFF;
    
     for (let i = 0; i < data.length; i++) {
     crc ^= (data[i] << 8);
    
     for (let j = 0; j < 8; j++) {
     crc = (crc & 0x8000) ? ((crc << 1) ^ polynomial) : (crc << 1);
     }
     }
    
     return crc & 0xFFFF;
    }

     

    You can use this JavaScript function to calculate the CRC16 checksum for your unit8_t array[64] in JavaScript. Now, let's create a corresponding C function for STM32.

    C (STM32):

     

    #include <stdint.h>
    
    uint16_t calculateCRC16(const uint8_t *data, uint32_t length) {
     const uint16_t polynomial = 0x1021;
     uint16_t crc = 0xFFFF;
    
     for (uint32_t i = 0; i < length; i++) {
     crc ^= (data[i] << 8);
    
     for (uint8_t j = 0; j < 8; j++) {
     crc = (crc & 0x8000) ? ((crc << 1) ^ polynomial) : (crc << 1);
     }
     }
    
     return crc & 0xFFFF;
    }

     

    You can use this C function on your STM32F373 to validate the CRC16 checksum. Make sure to pass the same array of data and its length to both the JavaScript and C functions.

    Note: CRC16 settings can vary, so it's important to ensure that both the JavaScript and C implementations use the same polynomial and initial CRC value for compatibility. The implementations provided use the common CRC16-CCITT polynomial (0x1021) and initial value (0xFFFF).

     

    2 replies

    Graduate II
    December 17, 2023

    Depends on the polynomial, shift direction, endianess, etc there are lots of ways to implement a 16-bit CRC, even a "standard" one

    // left shift, 0x1021 polynomial
    uint16_t crc16_byte(uint16_t crc, uint8_t data)
    {
    	int i;
    	crc ^= (uint16_t)crc << 8; // Apply byte to high order
    
    	for(i=0; i<8; i++)
    		crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
    
    	return(crc);
    }

     

    ST's 32-bit uses a "standard" polynomial, but assumes data is applied 32-bit at a time in Big Endian

    uint32_t crc32_word(uint32_t crc, uint32_t data)
    {
    	int i;
    	crc ^= data;
    
    	for(i=0; i<32; i++)
    		crc = (crc << 1) ^ ((crc & 0x80000000) ? 0x04C11DB7 : 0);
    
    	return(crc);
    }
    JamesHomeAnswer
    Visitor II
    December 17, 2023

    The CRC16 checksum calculation is commonly used for error-checking purposes. The JavaScript function you provided is a CRC32 implementation, not CRC16. Here's a CRC16 implementation in JavaScript that matches a common CRC16-CCITT polynomial (0x1021) and its corresponding C function:

    Javascript&colon;

     

    function calculateCRC16(data) {
     const polynomial = 0x1021;
     let crc = 0xFFFF;
    
     for (let i = 0; i < data.length; i++) {
     crc ^= (data[i] << 8);
    
     for (let j = 0; j < 8; j++) {
     crc = (crc & 0x8000) ? ((crc << 1) ^ polynomial) : (crc << 1);
     }
     }
    
     return crc & 0xFFFF;
    }

     

    You can use this JavaScript function to calculate the CRC16 checksum for your unit8_t array[64] in JavaScript. Now, let's create a corresponding C function for STM32.

    C (STM32):

     

    #include <stdint.h>
    
    uint16_t calculateCRC16(const uint8_t *data, uint32_t length) {
     const uint16_t polynomial = 0x1021;
     uint16_t crc = 0xFFFF;
    
     for (uint32_t i = 0; i < length; i++) {
     crc ^= (data[i] << 8);
    
     for (uint8_t j = 0; j < 8; j++) {
     crc = (crc & 0x8000) ? ((crc << 1) ^ polynomial) : (crc << 1);
     }
     }
    
     return crc & 0xFFFF;
    }

     

    You can use this C function on your STM32F373 to validate the CRC16 checksum. Make sure to pass the same array of data and its length to both the JavaScript and C functions.

    Note: CRC16 settings can vary, so it's important to ensure that both the JavaScript and C implementations use the same polynomial and initial CRC value for compatibility. The implementations provided use the common CRC16-CCITT polynomial (0x1021) and initial value (0xFFFF).

     

    LMorr.3Author
    Graduate II
    December 18, 2023

    Thank you!