cancel
Showing results for 
Search instead for 
Did you mean: 

CRC calculation in STM32G4

sireevenkat1
Senior

Hi,

I am working with STM32G491RE in my project. I have to transmit data through UART and I need to calculate CRC for that data.

in my application:

txdata[0] = 0x78;

txdata[1] = 0x04;

txdata[2] = 0x11;

txdata[3] = 0x01;

I have to calculate CRC16 for txdata[1] to txdata[3] and place it in txdata[4]& txdata[5].

 

1.I configured CRC parameters:

hcrc.Instance = CRC;

hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;

hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;

hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;

hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;

hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;

if (HAL_CRC_Init(&hcrc) != HAL_OK)

{

Error_Handler();

}

2. I am using following function to calculate CRC

HAL_CRC_Calculate(&hcrc, (uint8_t *)txdata[1] ,3);
is it correct way to do or need to change anything.
Can anyone suggest.

 

Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

In additional to @Tesla DeLorean 's comments:

> HAL_CRC_Calculate(&hcrc, (uint8_t *)txdata[1] ,3);

You are missing a & sign. It should be this:

HAL_CRC_Calculate(&hcrc, (uint8_t *)&txdata[1], 3);
If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

9 REPLIES 9
Issamos
Lead II

Hello @sireevenkat1 

I suggest you to use this exemple.

Best regards.

II

FBL
ST Employee

Hello @sireevenkat1,

HAL_CRC_Calculate() is used to compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer independently of the previous CRC value. However, HAL_CRC_Accumulate() is being used depending on the combination of the previous CRC value and the new one in order to chain a CRC calculation. For further details check Using the CRC peripheral on STM32 microcontrollers - Application note.

I hope this help!

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi @Issamos,

Thanks for the reply,

It will be helpful but my input data differs every time  based on the other peripheral output.
If I use below api

HAL_CRC_Accumulate(&hcrc, (uint32_t *)&CRC16_DATA8_CHECK, BUFFER_SIZE);
Is it possible to calculate CRC16 for txdata[1] to txdata[3] leaving txdata[0].
Thanks

 

You haven't defined the width of the polynomial, or it's value.

What would be helpful would be to cite what the receiving device is, and then a couple of known good test parameters to confirm its is working properly. There's a lot of critical parameters as they are very sensitive to bit ordering and sequencing.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

In additional to @Tesla DeLorean 's comments:

> HAL_CRC_Calculate(&hcrc, (uint8_t *)txdata[1] ,3);

You are missing a & sign. It should be this:

HAL_CRC_Calculate(&hcrc, (uint8_t *)&txdata[1], 3);
If you feel a post has answered your question, please click "Accept as Solution".

Hi @Tesla DeLorean@TDK 

hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;

Is above statement don't make polynomial enable? Do I need to give value separately?

is below code correct way to do?

CRC_HandleTypeDef hcrc;

MX_CRC_Init();

static void MX_CRC_Init(void)

{

/* USER CODE BEGIN CRC_Init 0 */

/* USER CODE END CRC_Init 0 */

/* USER CODE BEGIN CRC_Init 1 */

/* USER CODE END CRC_Init 1 */

hcrc.Instance = CRC;

hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;

hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;

hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;

hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;

hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;

if (HAL_CRC_Init(&hcrc) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN CRC_Init 2 */

/* USER CODE END CRC_Init 2 */

}

void function()

{

 

txdata[0] = 0x13;

txdata[1] = 0x04;

txdata[2] = 0x15;

txdata[3] = ACK;

// compute CRC to place into last 2 bytes

uint16_t calculatedCRC = HAL_CRC_Calculate(&hcrc,(uint32_t *)&txdata[1], 3);

 

txdata[4] = calculatedCRC & 0xFF; //low CRC byte

txdata[5] = (calculatedCRC >> 8& 0xFF; //high CRC byte

txdata[6] = 0x05;

HAL_UART_Transmit(&huart5, txdata,7, HAL_MAX_DELAY);

}

 

Thanks

@Tesla DeLoreansaid above:

> What would be helpful would be to cite what the receiving device is, and then a couple of known good test parameters to confirm its is working properly. There's a lot of critical parameters as they are very sensitive to bit ordering and sequencing.

JW

So it's using the default 32-bit polynomial?

If you're using you own protocol it would be sufficiently that both ends process the data consistently and generate the same check bytes for the same data.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
sireevenkat1
Senior

Hi @Tesla DeLorean,

1.So it's using the default 32-bit polynomial?-------I think so, not sure.

I am using STM32G4 series .As per CRC application note below tables says polynomial coefficient is programmable. Based on what basis do I need to select polynomial coefficient can you suggest.

I saw some posts in forum they are using below polynomial. Can you suggest how do select value for  polynomial?

1.#define MODBUS_CRC_POLY 0x8005

2.#define MODBUS_CRC_POLY 0xA001

If I define my polynomial below configuration are sufficient?

hcrc.Init.GeneratingPolynomial = MODBUS_CRC_POLY;
hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
hcrc.Init.InitValue = 0xFFFF2.

 

 

sireevenkat1_1-1697174303540.png

 

3.My application is to send the data of  sensors and status of some sensors  to other module using UART. That module receives the data and send it to cloud.

Thanks