2025-12-17 1:32 AM - last edited on 2025-12-19 2:03 AM by mƎALLEm
Hi guys i have a nucleo h7A3Zi-q dev board . i am trying to receive CAN messges sent from ESP32 borads . esp is sending can frame by using SN65HVD232D. and i configured the FDCAN to receive the can messages . esp can is set at 500 kbits , and my stm configurations is like this
static void MX_FDCAN1_Init(void)
{
/* USER CODE BEGIN FDCAN1_Init 0 */
/* USER CODE END FDCAN1_Init 0 */
FDCAN_ClkCalUnitTypeDef sCcuConfig = {0};
/* USER CODE BEGIN FDCAN1_Init 1 */
/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = DISABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 8;
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 = 1;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.RxFifo0ElmtsNbr = 0;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
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 = 0;
hfdcan1.Init.TxFifoQueueElmtsNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
sCcuConfig.ClockDivider = FDCAN_CLOCK_DIV1;
sCcuConfig.MinOscClkPeriods = 0x00;
sCcuConfig.CalFieldLength = FDCAN_CALIB_FIELD_LENGTH_32;
sCcuConfig.TimeQuantaPerBitTime = 4;
sCcuConfig.WatchdogStartValue = 0x0000;
if (HAL_FDCAN_ConfigClockCalibration(&hfdcan1, &sCcuConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */
/* USER CODE END FDCAN1_Init 2 */
}
void can_init(void)
{
if(can_h == NULL)
Error_Handler();
CanRxQueue = xQueueCreateStatic(16,sizeof(can_frame_t),ucQueueStorageArea,&xStaticQueue);
if (CanRxQueue == NULL)
Error_Handler();
sFilter.IdType = FDCAN_STANDARD_ID;
sFilter.FilterIndex = 0u;
sFilter.FilterID1 = 0;
sFilter.FilterID2 = 0x1FFFFFFF;
sFilter.FilterType = FDCAN_FILTER_RANGE;
sFilter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
//sFilter.RxBufferIndex = FDCAN_FILTER_TO_RXBUFFER;
if(HAL_FDCAN_ConfigFilter(can_h,&sFilter)!= HAL_OK){
Error_Handler();
}
if(HAL_FDCAN_Start(can_h) != HAL_OK){
Error_Handler();
}
if(HAL_FDCAN_ActivateNotification(can_h,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0)!=HAL_OK){
Error_Handler();
}
printf("can initialized \n");
}
void HAL_FDCAN_RxFifoCallback(FDCAN_HandleTypeDef *hfdcan,uint32_t RxFifo0ITs)
{
printf("can callback \n");
Error_Handler();
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
if(HAL_FDCAN_GetRxMessage(can_h, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
/* Reception Error */
Error_Handler();
rxdata.can_id = RxHeader.Identifier;
rxdata.can_dlc = RxHeader.DataLength;
memcpy(rxdata.data , RxData , CAN_MAX_DATA);
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(CanRxQueue,&rxdata,&xHigherPriorityTaskWoken);
if(xHigherPriorityTaskWoken)
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
/* Notification Error */
Error_Handler();
}
}
.
what i need is the can should work in interrupt mode . and i have to set up multiple esp and receive those messges.
edit : currently working with internal loopback mode still not reciving anything , i am not sure if sending is working but defintely sure that not reciving anything.
Solved! Go to Solution.
2025-12-23 12:19 AM - edited 2025-12-23 12:36 AM
I don't know about ESP, you need to check your ESP CAN configuration. You should have the same CAN bitrate.
For the timing and as you are using Classical CAN, you can refer to this knowledge base, it was written for bxCAN but the principle is the same: select a sample point at about 87.5%: CAN (bxCAN) bit time configuration on STM32 MCUs
2025-12-19 1:57 AM
You are using a standard ID filter while ID2 is an extended ID!
Use Mask ID with all filters IDs set to 0 if you want to receive all the CAN messages.
Did you enable the NVIC interrupt line for FDCAN?
Refer also to the following knowledge base articles:
STM32 FDCAN running at 8 Mb/s on NUCLEO boards
How to use FDCAN to create a simple communication with a basic filter
2025-12-20 9:42 AM - edited 2025-12-20 9:44 AM
yeah now i tried one of your example with the loop back mode . almost got it working but with one issue. i can read from RX_FIFO0 while in debug mode , because of breakpoints , but if i try to run it in normal i am not getting anything inside my rxbuffer . can is running at 500 kbits . any idea to fix this issue or whats causing it
MX_GPIO_Init();
MX_FDCAN2_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
/* Configure standard ID reception filter to Rx buffer 0 */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
sFilterConfig.FilterID1 = 0x000;
sFilterConfig.FilterID2 = 0x000;
sFilterConfig.RxBufferIndex = 0;
if(HAL_FDCAN_ConfigFilter(&CAN_USED, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure extended ID reception filter to Rx FIFO 1 */
sFilterConfig.IdType = FDCAN_EXTENDED_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
sFilterConfig.FilterID1 = 0x1111111;
sFilterConfig.FilterID2 = 0x2222222;
if(HAL_FDCAN_ConfigFilter(&CAN_USED, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
HAL_FDCAN_GetRxFifoFillLevel(&hfdcan2,FDCAN_RX_FIFO0);
/* Start the FDCAN module */
if(HAL_FDCAN_Start(&CAN_USED) != HAL_OK)
{
Error_Handler();
}
HAL_FDCAN_ActivateNotification(
&hfdcan2,
FDCAN_IT_RX_FIFO0_NEW_MESSAGE,
0
);
/* Configure Tx buffer message */
TxHeader.Identifier = 0x111;
TxHeader.IdType = FDCAN_STANDARD_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_8;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
TxHeader.MessageMarker = 0x52;
if(HAL_FDCAN_AddMessageToTxBuffer(&CAN_USED, &TxHeader, TxData0, FDCAN_TX_BUFFER0) !=HAL_OK)
{
Error_Handler();
}
/* Send Tx buffer message */
HAL_FDCAN_EnableTxBufferRequest(&CAN_USED, FDCAN_TX_BUFFER0);
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE)
{
HAL_FDCAN_GetRxMessage(&hfdcan2,
FDCAN_RX_FIFO0,
&RxHeader,
RxData);
// Process data here
// (toggle LED, set flag, copy buffer, etc.)
}
}
2025-12-22 12:40 AM
yes got that working now, now the main issue , reading message from esp32 through CAN bus. since i am in STM32H7A3VIT6 anything should i take care of ?
2025-12-22 12:57 AM
@b1aze wrote:
yes got that working now, now the main issue , reading message from esp32 through CAN bus. since i am in STM32H7A3VIT6 anything should i take care of ?
Sorry I didn't understand, what worked for you till now?
+ what are the differences between CAN_USED and hfdcan2 are they the same instance?
2025-12-22 8:33 AM - edited 2025-12-22 8:44 AM
okay i tested with the example code from an another post . i that they used FDCAN2 to run can in internal loopback mode . i had issues earlier but that worked when i properly configured the FDCAN2 . but my main goal was to enable can communication between different boards like from esp or another stm32 and recive it . and for can transceiver i am using SN65HVD232D. so my test setup is esp ->SN65HVD232D ->CAN_H | CAN_L ->SN65HVD232D -> stm32
thank you for your resposne @mƎALLEm .
And also whats the use of data prescaler timeseg1,timeseg2 . how to cofigure them , and is that improtant
2025-12-23 12:19 AM - edited 2025-12-23 12:36 AM
I don't know about ESP, you need to check your ESP CAN configuration. You should have the same CAN bitrate.
For the timing and as you are using Classical CAN, you can refer to this knowledge base, it was written for bxCAN but the principle is the same: select a sample point at about 87.5%: CAN (bxCAN) bit time configuration on STM32 MCUs