cancel
Showing results for 
Search instead for 
Did you mean: 

Developing FDCAN on FPGA: problem with CRC of FDCAN with STM32

Salomé
Associate

Hello,

I m trying to establish a CANFD communication with an FPGA and an STM32 NUCLEO-H7A3ZI-Q. I just want the stm32 to transmit data to the FPGA. My colleague did the code for the STM32 and for standard CAN, everything works. I can receive the data and my CRC calculation is the same as the one that i had sent to me. 

 

For the CANFD, the trame is all good until the CRC. He just sends me 1 byte data and the CRC that i can observe is to big for an FDCAN (supposed to be 17 and 21 for more than 16 bytes). 

Here is the frame that he sent me:

ID : 00000010001

RTR : 0

IDE : 0

CONTROL: 10000001

DATA : 01001000

All the frame : 00000010001001000000101001000

Here is an image of what i can observe :

Trame_CAN_FD.png

The frame that we can observe is (Start bit in black, stuff_bit :(

  • 0000010010001001000001010100100010110111110111010100110001011111111111111111

If i remove bitstuffing, the begining is the same

  • 00000010001001000000101001000 (frame)    10110111111110101001100010 (crc maybe bigger with other '1')

As you can see, the CRC seems to be bigger than 17 or 21. I made a test file that calculate CRC and tried everything :

- Using CRC17 with and without stuff in calculation

- Using CRC21 with and without stuff in calculation

- Using CRC32 with and without stuff in calculation

I tested every polynomial I could find :

- CRC-17 : 0x1685B (Wikipedia) /  0x3685B (CAN with Flexible Data-Rate, BOSH) 

- CRC-21:  0x102899 (Wikipedia) /  0x302899 (CAN with Flexible Data-Rate, BOSH) 

- CRC-32: 0x04C11DB7(Wikipedia /   0x302899(CAN with Flexible Data-Rate, BOSH) / 0x4C11DB7 (RM0455
Reference manual)

I can't find anything about the CRC of the CANFD in the manual of the STM32 (RM0455 Reference manual STM32H7A3/7B3 and STM32H7B0 Value line) and there is nothing on the internet so if anyone has an idea or knows what is the polynomial for CANFD, could you please help me. 

Thank you.

Here is the code that my colleague wrote and that seems to work correctly:

 

 

 

/* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FDCAN1_Init();
  /* USER CODE BEGIN 2 */
 
  if(HAL_FDCAN_Start(&hfdcan1) != HAL_OK){
  	  Error_Handler();
    }
 
  if(HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK){
	  Error_Handler();
  }
 
 
  TxHeader1.Identifier = 0x11;
  TxHeader1.IdType = FDCAN_STANDARD_ID;
  TxHeader1.TxFrameType = FDCAN_DATA_FRAME;
  TxHeader1.DataLength = FDCAN_DLC_BYTES_1;
  TxHeader1.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  TxHeader1.BitRateSwitch = FDCAN_BRS_OFF;
  TxHeader1.FDFormat = FDCAN_FD_CAN;
  TxHeader1.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
  TxHeader1.MessageMarker = 0;
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
 
	 sprintf((char*) TxData1, "H", idx);
 
	 if(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader1, TxData1) != HAL_OK){
		 Error_Handler();
	 }
	 while(tmp < 10000){
		 tmp++;
	 }
	 tmp =0;
	 idx++;
 
  }
  /* USER CODE END 3 */
}

 
 
 
static void MX_FDCAN1_Init(void)
{
 
  /* USER CODE BEGIN FDCAN1_Init 0 */
 
	/* USER CODE END FDCAN1_Init 0 */
 
  /* USER CODE BEGIN FDCAN1_Init 1 */
 
 
  /* USER CODE END FDCAN1_Init 1 */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
  hfdcan1.Init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK;
  hfdcan1.Init.AutoRetransmission = ENABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 4;
  hfdcan1.Init.NominalSyncJumpWidth = 19;
  hfdcan1.Init.NominalTimeSeg1 = 105;
  hfdcan1.Init.NominalTimeSeg2 = 19;
  hfdcan1.Init.DataPrescaler = 4;
  hfdcan1.Init.DataSyncJumpWidth = 19;
  hfdcan1.Init.DataTimeSeg1 = 105;
  hfdcan1.Init.DataTimeSeg2 = 19;
  hfdcan1.Init.MessageRAMOffset = 0;
  hfdcan1.Init.StdFiltersNbr = 0;
  hfdcan1.Init.ExtFiltersNbr = 1;
  hfdcan1.Init.RxFifo0ElmtsNbr = 1;
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_12;
  hfdcan1.Init.RxFifo1ElmtsNbr = 0;
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxBuffersNbr = 0;
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.TxEventsNbr = 0;
  hfdcan1.Init.TxBuffersNbr = 1;
  hfdcan1.Init.TxFifoQueueElmtsNbr = 1;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN1_Init 2 */
 
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1 = 0x11;
  sFilterConfig.FilterID2 = 0x11;
  sFilterConfig.RxBufferIndex = 0;
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
  {
	Error_Handler();
  }
}

 

 

 

 

4 REPLIES 4
SofLit
ST Employee

Hello,

I don't think CRC polynomial config is an important information that's why it was not provided in the STM32 documentation.

Look at this whitepaper: https://datasheet.datasheetarchive.com/originals/crawler/bosch-semiconductors.de/d86e094dd180575f847791e56fe3d1f5.pdf

Also I've attached an article "CAN with Flexible Data-Rate" by Florian Hartwich, Robert Bosch GmbH

See section "4. Cyclic Redundancy Check"

 

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.

Hello, 

Thank you for your answer.

The thing is, i'm coding an FPGA where i m programing all fields of FDCAN protocol manually. I created a block called CRC where i put the input and calculate the crc. I can enable bit_stuffing or not in calculation wich is usefull. 

In my Can process, when i come to the Ack part, i ask to the CRC block if the CRC is equal to 0 wich means that i have the same CRC as the STM32 and what i received is correct. But since i have no idea what polynome is used and how on the STM32, I can't acquit the frame. 

Plus, i don't even know the size of the CRC field so i don't know when to acquit...

So for me it is important to know what polynomial is used because i need to put it in my CRC block so i can made the division.

 

I have read the document that you have sent and i noticed that for the transmition of the CRC, there is "fixed bit stuff"  after every four bits of data. I made an excel of different CRC for different messages and i conclued that it seems to be the case:

CRC.png

The thing is, i don't understand why the crc is 21 bits ( i only have 1 byte of data) and , when i play a simulation, i still can't find the same CRC if i remove all the fixed bit stuffing (in yellow).

The polynomial that i use is x21+x20+x13+x11+x7+x4+x3+1 (the same as in the doc you sent)

Hello,

Just to point out that this is a very specific question related to the FDCAN peripheral implementation which I think you can contact Bosch as it's the provider. 


The thing is, i don't understand why the crc is 21 bits ( i only have 1 byte of data) and , when i play a simulation, i still can't find the same CRC if i remove all the fixed bit stuffing (in yellow).

The polynomial that i use is x21+x20+x13+x11+x7+x4+x3+1 (the same as in the doc you sent)


Meanwhile, I'm not expert of that subject, but didn't understand your feedback because this paragraph tells you how to calculate the CRC: the three CRC types (CRC_15/CRC_17/CRC_21) are calculated at the same time and one CRC type will be selected and transmitted based on the control bit and the DLC value.

SofLit_0-1719408137535.png

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.
SofLit
ST Employee

+

SofLit_0-1719409697602.png

 

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.