Skip to main content
LMorr.3
Senior
December 16, 2023
Solved

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

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.
JamesHomeBest answer
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).

 

3 replies

Tesla DeLorean
Guru
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);
}
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
JamesHomeBest answer
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.3
LMorr.3Author
Senior
December 18, 2023

Thank you!