CRC32

Hi, please help with CRC32 on an RA6M2 MCU.

I am trying to generate a CRC32 value for a 21-byte input data. I am using the r_crc FSP module with the CRC interface. The module documentation mentions that the r_crc32 has a limitation of only accepting the 32-bit words for calculating a CRC32 value. 

I have checked the r_crc module code and it is clear that last byte, of my 21-byte input data, is not considered when generating the CRC-32 value. 

Is there any way to get the r_crc32 module to work with data input that does end on a 32-bit boundary? if not, is there a different FSP module or library available that I can use to generate CRC32 values?

  • Hello,

    Thanks for reaching out Renesas Engineering Community!

    Could you please provide us more info about what are you trying to do? 

    Regarding CRC module, CRC module supports all these algorithms:

    So it supports CRC-8 calculations for 8-bit input data, CRC-16 and CRC-CCITT for 16-bit data, CRC-32 and CRC-32C for 32-bit data.

    In case you have an array with 21 bytes maybe you should consider using CRC-8 polynomial.

    You can select it from FSP Configurator as shown here:

    Hope it helps!

    Best Regards,

    IK

  • The short answer is no - you pad a CRC-32 out to 32 bits to do the calculation.  Read about CRC-32 and you understand why. Or you could do a CRC-8 as the other post suggests.

  • I found someones solution using anther manufacturers CRC generator where they did some magic to handle the last few bytes.

    I was about to brute force it using a bit oriented algorithm. Seems to work.

    uint32_t RenesasCRC32UpdateLastBytes(uint32_t crc32, void *data, size_t bytes)
    {
    	uint8_t *data_ptr8 = data;        // 8 bit pointer to data
    	size_t bytes_left = bytes & 0x3;  // number of bytes left to process
    	uint8_t *last_bytes = &data_ptr8[bytes & ~0x3]; // ptr to them
    
    	// copy remaining bits
    	uint32_t bits = 0;
    	memcpy(&bits, last_bytes, bytes_left);
    
    	// slowly grind out the crc bit by bit
    	for (size_t bit_indx = 0; bit_indx < (bytes_left*8); bit_indx++ )
    	{
    		if ( ( crc32 ^ bits ) & 1 )
    		{
    			crc32 = ( crc32 >> 1 ) ^ 0xEDB88320;
    		}
    		else
    		{
    			crc32  >>= 1 ;
    		}
    
    		bits >>= 1;
    	}
    
    	return crc32;
    }
    
    
    uint32_t RenesasCRC32(void *data, uint32_t bytes)
    {
    	uint32_t crc32;
    
    	R_CRC_Open(&g_crc0_ctrl, &g_crc0_cfg);
    
    	crc_input_t crc_input =
    	{
    		.num_bytes = bytes & ~0x3,              // Length of input buffer
    		.crc_seed = 0xffffffff,                 // CRC seed value
    		.p_input_buffer = data           // Pointer to input buffer
    	};
    
    	R_CRC_Calculate(&g_crc0_ctrl, &crc_input, &crc32);
    
    	R_CRC_Close(&g_crc0_ctrl);
    
    	// bit oriented update last 0 to 3 bytes
    	crc32 = RenesasCRC32UpdateLastBytes(crc32, data, bytes);
    
    	return ~crc32;
    }