Nucleo-H743ZI2 FDCAN: late trigger of Rx interrupts
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-15 04:08 AM - last edited on ‎2024-11-18 02:19 AM by SofLit
(Moved to appropriate forum from 'Feedback')
Hi,
I'm using Nuleo-H743Zi2 hardware. I have configured FDCAN1 with below configurations,
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
hfdcan1.Init.NominalPrescaler = prescaler;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 13;
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1;
hfdcan1.Init.MessageRAMOffset = 0;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.RxFifo0ElmtsNbr = 8;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxFifo1ElmtsNbr = 8;
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxBuffersNbr = 8;
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.TxEventsNbr = 8;
hfdcan1.Init.TxBuffersNbr = 8;
hfdcan1.Init.TxFifoQueueElmtsNbr = 8;
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 */
FDCAN_FilterTypeDef sFilterConfig;
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x400;
sFilterConfig.FilterID2 = 0x5FF;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK) {
// Filter configuration Error
Error_Handler();
}
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK) {
// Start Error
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(&hfdcan1,
FDCAN_IT_TX_COMPLETE | FDCAN_IT_RX_FIFO0_NEW_MESSAGE
| FDCAN_IT_BUS_OFF | FDCAN_IT_ERROR_PASSIVE
| FDCAN_IT_ERROR_WARNING, 0) != HAL_OK) {
// Notification Error
Error_Handler();
}
*****************************************************************************************************
*****************************************************************************************************
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hfdcan->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspInit 0 */
/* USER CODE END FDCAN1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInitStruct.PLL2.PLL2M = 8;
PeriphClkInitStruct.PLL2.PLL2N = 48;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 8;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_FDCAN_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**FDCAN1 GPIO Configuration
PD0 ------> FDCAN1_RX
PD1 ------> FDCAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* FDCAN1 interrupt Init */
HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
/* USER CODE BEGIN FDCAN1_MspInit 1 */
/* USER CODE END FDCAN1_MspInit 1 */
}
The FDCAN Reception interrupts are triggered late >500ms sometimes more than a second. So the requests from master gets timed out.
a. Is the above configuration is correct?
b. If yes, what can be done to improve the performance?
- Labels:
-
CAN
-
FDCAN
-
STM32H7 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-15 04:23 AM - edited ‎2024-11-15 04:34 AM
Hello @KT_Matt,
To share your code please use </> button. Tips on posting.
At a first glance and according to you config, you are using FDCAN mode and these data phase parameter timings are bad: BS1 = 1, BS2 = 1.
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1;
Need to increase BS1 and BS2 as much as possible and decrease the prescaler to match your data phase bitrate.
Please refer to this article. It gives an example of FDCAN communication on Nucleo-H7 with Nominal phase bitrate = 1Mb/s and the data phase at 8Mb/s. And provided an example of calculation.
Are you sure the other node is in FDCAN mode not in classic mode?
What is the bitrate you are using for both nominal and data phase?
Could you please share your ioc file?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-17 10:43 PM - edited ‎2024-11-17 10:51 PM
Hi @SofLit,
Thanks for responding.
My requirement is for Classic Mode only and the bitrate needed is 125, 250, 500Kbps. For classic mode, the recommended changes are needed?
Attached the ioc file.
Thanks and Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-17 11:55 PM
I would suggest to use a CAN trace tool (or a scope), to check what is really happening on the bus, and when.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-18 12:01 AM
Hi @Ozone ,
We used CAN trace, the CAN messages are received at the Hardware queue, but the interrupt is not triggered or triggered late(>500ms). If the interrupt not triggered means, later when interrupt triggers, the previous message gets handled.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-18 12:33 AM
Hello @KT_Matt ,
I would suggest these timings @500kb/s for FDCAN in classic mode/ MCU running at 400MHz with an extarnal precise crystal (in your case 8MHz using STLINK MCO in Bypass mode):
I've attached the updated ioc file.
Hope it helps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-18 12:35 AM
Ok, I understand.
Occasionally, some poster here need to be reminded that CAN is not a deterministic bus, and a CAN trace or such is necessary.
> ... the CAN messages are received at the Hardware queue, but the interrupt is not triggered or triggered late(>500ms).
This suggests it is an issue with the H743's CAN peripheral, which I have no actual experience with.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-18 01:52 AM
Hi @SofLit ,
I tried the recommended configuration. Looks like the FDCAN is not working with this clock speed(100Mhz). It works only with 48MHz.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-18 01:59 AM
Hello @KT_Matt ,
It should work at 100MHz / System clock at 400MHz/VOS1:
Did you try Loopback mode first? Try External Loopback mode and probe with an oscilloscope or analyzer on FDCAN_Tx pin. Do you receive the sent frame?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-11-18 02:15 AM
Also could you please check if the HSE is 8MHz?
For that you need to check that on MCO1 (PA8). I've attached the ioc file where I've added the output of HSE on PA8.
Could you please check with an oscilloscope if you have 8MHz on PA8?