Developing FDCAN on FPGA: problem with CRC of FDCAN with STM32
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 :

The frame that we can observe is (Start bit in black, stuff_bit :(
- 00000
10010001001000001010100100010110111110111010100110001011111111111111111
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();
}
}

