2024-08-19 12:36 AM - last edited on 2024-08-19 02:23 AM by SofLit
Hello,
I am trying to make FDCAN work but I am not receiving any messages. The TX is working fine but when trying to receive messages the interrupt is not triggered. I am using STM32H7 series with freertos.
I have set the filter, started FDCAN, enabled interrupts, activated notifications,.. Any idea what I have missed?
Even when using external loopback, I can see the messages being sent but the interrupt is not triggering.
This is my code:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fdcan.c
* @brief This file provides code for the configuration
* of the FDCAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os2.h"
#include "fdcan.h"
#include "stm32h7rsxx_it.h"
/* USER CODE BEGIN 0 */
#define TX_TIMEOUT (1000U) /* Transmission timeout in ms */
/* Hardware related, can't be changed */
#define NB_RX_FIFO (3U) /* Number of RX FIFO Elements available */
FDCAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[12U];
static const uint8_t txData0[] = {0x10, 0x32, 0x54, 0x76, 0x98, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
static const uint8_t txData1[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
static const uint8_t txData2[] = {0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00};
/* USER CODE END 0 */
FDCAN_HandleTypeDef hfdcan1;
/* FDCAN1 init function */
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.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 8;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 8;
hfdcan1.Init.NominalTimeSeg2 = 3;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */
/* USER CODE END FDCAN1_Init 2 */
}
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcanHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(fdcanHandle->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspInit 0 */
/* USER CODE END FDCAN1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_HSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* FDCAN1 clock enable */
__HAL_RCC_FDCAN_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**FDCAN1 GPIO Configuration
PD1 ------> FDCAN1_TX
PD0 ------> FDCAN1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* FDCAN1 interrupt Init */
HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
/* USER CODE BEGIN FDCAN1_MspInit 1 */
/* USER CODE END FDCAN1_MspInit 1 */
}
}
void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcanHandle)
{
if(fdcanHandle->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspDeInit 0 */
/* USER CODE END FDCAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_FDCAN_CLK_DISABLE();
/**FDCAN1 GPIO Configuration
PD1 ------> FDCAN1_TX
PD0 ------> FDCAN1_RX
*/
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_1|GPIO_PIN_0);
/* FDCAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);
/* USER CODE BEGIN FDCAN1_MspDeInit 1 */
/* USER CODE END FDCAN1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
void FDCAN_Task(void *argument)
{
/* USER CODE BEGIN FDCAN_Task */
// Activate the notification for new data in FIFO0 for FDCAN1
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
// Start FDCAN
/*##-1 Configure the FDCAN filters ########################################*/
/* Configure standard ID reception filter to Rx FIFO 0. Only accept ID = FilterID1 */
FDCAN_FilterTypeDef sFilterConfig;
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0U;
sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x444;
sFilterConfig.FilterID2 = 0x444; /* For acceptance, MessageID and FilterID1 must match exactly */
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure extended ID reception filter to Rx FIFO 1. Only accept ID between FilterID1 and FilterID2. */
sFilterConfig.IdType = FDCAN_EXTENDED_ID;
sFilterConfig.FilterIndex = 0U;
sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
sFilterConfig.FilterID1 = 0x1111111;
sFilterConfig.FilterID2 = 0x2222222;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/**
* Configure global filter:
* - Filter all remote frames with STD and EXT ID
* - Reject non matching frames with STD ID and EXT ID
*/
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1,
FDCAN_REJECT, FDCAN_REJECT,
FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
Error_Handler();
}
/*##-2 Start FDCAN controller (continuous listening CAN bus) ##############*/
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
// Activate the notification for new data in FIFO0 for FDCAN1
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
/* Infinite loop */
for(;;)
{
// /*##-3 Transmit messages ##################################################*/
//
FDCAN_TxHeaderTypeDef txHeader;
/* Add message to Tx FIFO */
txHeader.Identifier = 0x444;
txHeader.IdType = FDCAN_STANDARD_ID;
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = FDCAN_DLC_BYTES_12;
txHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
txHeader.BitRateSwitch = FDCAN_BRS_ON;
txHeader.FDFormat = FDCAN_FD_CAN;
txHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
txHeader.MessageMarker = 0x52U;
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txHeader, txData0) != HAL_OK)
{
Error_Handler();
}
/* Add second message to Tx FIFO */
txHeader.Identifier = 0x1111112;
txHeader.IdType = FDCAN_EXTENDED_ID;
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = FDCAN_DLC_BYTES_12;
txHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
txHeader.BitRateSwitch = FDCAN_BRS_ON;
txHeader.FDFormat = FDCAN_FD_CAN;
txHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
txHeader.MessageMarker = 0xCCU;
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txHeader, txData1) != HAL_OK)
{
Error_Handler();
}
/* Add third message to Tx FIFO */
txHeader.Identifier = 0x1111113;
txHeader.IdType = FDCAN_EXTENDED_ID;
txHeader.TxFrameType = FDCAN_DATA_FRAME;
txHeader.DataLength = FDCAN_DLC_BYTES_12;
txHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
txHeader.BitRateSwitch = FDCAN_BRS_OFF;
txHeader.FDFormat = FDCAN_FD_CAN;
txHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
txHeader.MessageMarker = 0xDDU;
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txHeader, txData2) != HAL_OK)
{
Error_Handler();
}
/* Get tick */
uint32_t tickstart = HAL_GetTick();
/* Wait transmission complete */
while (HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) != NB_RX_FIFO)
{
/* Timeout handling */
if ((HAL_GetTick() - tickstart) > TX_TIMEOUT)
{
Error_Handler();
}
}
/*##-4 Receive messages ###################################################*/
/* Check one message is received in Rx FIFO 0 */
HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0);
/* Retrieve message from Rx FIFO 0 */
HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &rxHeader, rxData);
osDelay(1);
}
/* USER CODE END FDCAN_Task */
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
/* Retreive Rx messages from RX FIFO0 */
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rxHeader, &rxData) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
}
}
/* USER CODE END 1 */
Solved! Go to Solution.
2024-08-19 03:22 AM
Thank you for your help. I have found the issue. I had filter definition but in the .ioc file my Std Filter Nbr was set to 0 since I forgot to set it. It works fine now!
2024-08-19 02:22 AM
Hello,
First, why are you posting this thread in "TouchGFX and GUI" forum? need to be posted in "STM32 MCUs products" forum. --> will be moved then.
Second, why are you calling this in the FDCAN_Task():
HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &rxHeader, rxData);
and at the same time using FDCAN RX Callback where you are calling the same API HAL_FDCAN_GetRxMessage() ?
As you are using RTOS, I suggest first to make your example in baremetal before using an RTOS.
Also please read this article: https://community.st.com/t5/stm32-mcus/can-reception-issues-reasons-and-general-troubleshooting/ta-p/689741
2024-08-19 02:50 AM
Hello,
since I am using TouchGFX i figured it seems appropriate.
I was calling it in the task and in the callback because I wanted to test it since it never gets to the callback because interrupt doesnt trigger. I have later removed it from the task and left it only in the callback.
Clock source selection: TIM6 with HSE crystal/ceramic resonator
Filter configuration:
/* Configure standard ID reception filter to Rx FIFO 0. Only accept ID = FilterID1 */
FDCAN_FilterTypeDef sFilterConfig;
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0U;
sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x444;
sFilterConfig.FilterID2 = 0x444; /* For acceptance, MessageID and FilterID1 must match exactly */
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure extended ID reception filter to Rx FIFO 1. Only accept ID between FilterID1 and FilterID2. */
sFilterConfig.IdType = FDCAN_EXTENDED_ID;
sFilterConfig.FilterIndex = 0U;
sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
sFilterConfig.FilterID1 = 0x1111111;
sFilterConfig.FilterID2 = 0x2222222;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
Im trying to receive a standard ID 0x444 message.
Bus overload: Since I'm using freeRTOS and sending message TX every 1 ms , could that overload the bus so It wont be able to receive anything?
2024-08-19 03:04 AM - edited 2024-08-19 03:09 AM
Bus overload: Since I'm using freeRTOS and sending message TX every 1 ms , could that overload the bus so It wont be able to receive anything?
You need simply to increase the delay to get the answer.
But you need also to remove the call of:
HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &rxHeader, rxData);
from FDCAN_Task().
2024-08-19 03:12 AM
It actuall worsen everything by increasing it now it stops sending data after about 300 tries. Still nothing with the receiving part. When using external loopback the interrupt is not triggered. What could I be doing wrong ?
The message Im trying to send to trigger the interrupt looks like this:
The filter seems to be correct and data is being sent to the PCAN-View so I know that hardware communication is fine
2024-08-19 03:22 AM
Thank you for your help. I have found the issue. I had filter definition but in the .ioc file my Std Filter Nbr was set to 0 since I forgot to set it. It works fine now!