cancel
Showing results for 
Search instead for 
Did you mean: 

Why STM32F407 CAN bus Rx interrupt does not fire in normal mode ?

GLEGR.1
Associate II

Hi, this subject has already been treated with other boards in other forums, but libraries and tools have changed since then so i thougth i could open a new question. 

So i use CAN1 bus in the Discovery STM32F407 in order to share data between 2 discovery. I use a classic transceiver SN65HVD234 from Texas Instruments. I configured the Discovery with CubeMX and used CubeIDE. I'm using the HAL Library.

I use the User button to fire an EXTI interuption that call HAL_CAN_AddTxMessage() an writes on the bus. 

Transmitting data works but not Receiving.

The Hardware is working very well as you can see [in the picture][1]. However the end of the frame bothers me a bit, i don't know if this is nominal.

Here's what I found using the debugger : The interruption enabled for FIFO0 never fires and the function HAL_CAN_RxFifo0MsgPendingCallback() is never called. 

So I think the problem comes frome the Filter and its registers that i don't really understand.

here is the configuration code : It does not rise any error handler during the initialization. 

CAN_HandleTypeDef hcan1;
 
 
 
/* CAN1 init function */
 
void MX_CAN1_Init(void)
 
{
 
 
 
	hcan1.Instance = CAN1;
 
	hcan1.Init.Prescaler = 17;
 
	hcan1.Init.Mode = CAN_MODE_NORMAL;
 
	hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
 
	hcan1.Init.TimeSeg1 = CAN_BS1_6TQ;
 
	hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
 
	hcan1.Init.TimeTriggeredMode = DISABLE;
 
	hcan1.Init.AutoBusOff = DISABLE;
 
	hcan1.Init.AutoWakeUp = DISABLE;
 
	hcan1.Init.AutoRetransmission = DISABLE;
 
	hcan1.Init.ReceiveFifoLocked = DISABLE;
 
	hcan1.Init.TransmitFifoPriority = DISABLE;
 
	if (HAL_CAN_Init(&hcan1) != HAL_OK)
 
	{
 
		Error_Handler();
 
	}
 
 
 
	/* USER CODE BEGIN CAN1_Init */
 
	CAN_FilterTypeDef sFilterConfig;
 
 
 
	/*##-2- Configure the CAN Filter ###########################################*/
 
	sFilterConfig.FilterBank = 1;
 
	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
 
	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
 
	sFilterConfig.FilterIdHigh = 0x0000;
 
	sFilterConfig.FilterIdLow = 0x0000;
 
	sFilterConfig.FilterMaskIdHigh = 0x0000;
 
	sFilterConfig.FilterMaskIdLow = 0x0000;
 
	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
 
	sFilterConfig.FilterActivation = ENABLE;
 
	sFilterConfig.SlaveStartFilterBank = 2;
 
 
 
	if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
 
	{
 
		/* Filter configuration Error */
 
		Error_Handler();
 
	}
 
 
 
	/*##-3- Start the CAN peripheral ###########################################*/
 
	if (HAL_CAN_Start(&hcan1) != HAL_OK)
 
	{
 
		/* Start Error */
 
		Error_Handler();
 
	}
 
	/*##-4- Activate CAN RX notification #######################################*/
 
	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING)
 
			!= HAL_OK) {
 
		/* Notification Error */
 
		Error_Handler();
 
	}
 
	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING)
 
			!= HAL_OK) {
 
		/* Notification Error */
 
		Error_Handler();
 
 
 
	}
 
	/*##-5- Configure Transmission process #####################################*/
 
	TxHeader.StdId = 0x321; // 321 MCU1
 
	TxHeader.ExtId = 0x00;
 
	TxHeader.RTR = CAN_RTR_DATA;
 
	TxHeader.IDE = CAN_ID_STD;
 
	TxHeader.DLC = 2;
 
	TxHeader.TransmitGlobalTime = DISABLE;
 
 
 
	/* USER CODE END CAN1_Init */
 
}
 
 
 
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
 
{
 
 
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};
 
	if(canHandle->Instance==CAN1)
 
	{
 
		/* USER CODE BEGIN CAN1_MspInit 0 */
 
 
 
		/* USER CODE END CAN1_MspInit 0 */
 
		/* CAN1 clock enable */
 
		__HAL_RCC_CAN1_CLK_ENABLE();
 
 
 
		__HAL_RCC_GPIOD_CLK_ENABLE();
 
		/**CAN1 GPIO Configuration
 
  PD0   ------> CAN1_RX
 
  PD1   ------> CAN1_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_VERY_HIGH;
 
		GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
 
		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
 
 
		/* USER CODE BEGIN CAN1_MspInit 1 */
 
 
 
		/* CAN1 interrupt Init */
 
		HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
 
		HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
 
		HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
 
		HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
 
 
 
		/* USER CODE END CAN1_MspInit 1 */
 
	}
 
}

I tried to stick to the [STM32F4][2] Ref manual but it didn't work. 

 [1]: https://i.stack.imgur.com/cm3rp.png

 [2]: https://www.st.com/resource/en/reference_manual/dm00031020-stm32f405415-stm32f407417-stm32f427437-and-stm32f429439-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

1 ACCEPTED SOLUTION

Accepted Solutions
GLEGR.1
Associate II

Problem Solved ! 

I did'nt really found why it was not working on my first prototype but I faced the same issue with my final PCB. 

However there was a short circuit between the CAN TX and RX on one MCU due to a thin wire of tin !

Even with that problem i had the RX signal on my scope that's why i did'nt thought it was a hard problem ! 

I removed the bad soldering and modifed the prescalers to have a lower baudrate : 150 Kbits/s .

The design finaly worked with this configuration

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
 
/* USER CODE BEGIN PV */
CAN_HandleTypeDef hcan1;
CAN_TxHeaderTypeDef pHeader; //declare a specific header for message transmittions
CAN_RxHeaderTypeDef pRxHeader; //declare header for message reception
uint32_t TxMailbox;
uint8_t a,r; //declare byte to be transmitted //declare a receive byte
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
 
/* Private user code ---------------------------------------------------------*/
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN1_Init();
  /* USER CODE BEGIN 2 */
  CAN_Config();
  a = 0xff;
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);
	//function to add message for transmition
	if(HAL_CAN_AddTxMessage(&hcan1, &pHeader, &a, &TxMailbox) != HAL_OK){
		Error_Handler();
	}
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
	HAL_Delay(100);
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
 
  }
  /* USER CODE END 3 */
}
 
/**
 * @brief CAN1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_CAN1_Init(void)
{
 
 /* USER CODE BEGIN CAN1_Init 1 */
 /* USER CODE END CAN1_Init 1 */
 hcan1.Instance = CAN1;
 hcan1.Init.Prescaler = 20;
 hcan1.Init.Mode = CAN_MODE_NORMAL;
 hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
 hcan1.Init.TimeSeg1 = CAN_BS1_12TQ;
 hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
 hcan1.Init.TimeTriggeredMode = DISABLE;
 hcan1.Init.AutoBusOff = DISABLE;
 hcan1.Init.AutoWakeUp = DISABLE;
 hcan1.Init.AutoRetransmission = DISABLE;
 hcan1.Init.ReceiveFifoLocked = DISABLE;
 hcan1.Init.TransmitFifoPriority = DISABLE;
 
if (HAL_CAN_Init(&hcan1) != HAL_OK)
 {
  Error_Handler();
 }
 
}
 
/**
 * @brief Configures the CAN.
 * @param None
 * @retval None
 */
 
static void CAN_Config(void)
{
 CAN_FilterTypeDef sFilterConfig;
 
 pHeader.DLC=1; //give message size of 1 byte
 pHeader.IDE=CAN_ID_STD; //set identifier to standard
 pHeader.RTR=CAN_RTR_DATA; //set data type to remote transmission request?
 pHeader.StdId=0x244; //define a standard identifier, used for message identification by filters (switch this for the other microcontroller)
 pHeader.ExtId = 0x01;
 pHeader.TransmitGlobalTime = DISABLE;
 
 //filter one (stack light blink)
 sFilterConfig.FilterFIFOAssignment=CAN_RX_FIFO0; //set fifo assignment
 sFilterConfig.FilterIdHigh = 0x0000;
 sFilterConfig.FilterIdLow = 0x0000;
 sFilterConfig.FilterMaskIdHigh = 0x0000;
 sFilterConfig.FilterMaskIdLow = 0x0000;
 sFilterConfig.FilterScale=CAN_FILTERSCALE_32BIT; //set filter scale
 sFilterConfig.FilterActivation=ENABLE;
 sFilterConfig.FilterBank = 0;
 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
 sFilterConfig.SlaveStartFilterBank = 14;
 if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
 
  {
 
   /* Filter configuration Error */
 
   Error_Handler();
 
  }
 
  if (HAL_CAN_Start(&hcan1) != HAL_OK)
  {
   /* Start Error */
   Error_Handler();
  }
 if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
 
   /* Notification Error */
   Error_Handler();
  }
}
 

So setting all the filters to 0 permits to accept all CAN messages and it is working.

For those who face the same issue (according to my experience) :

  • Make sure your interruptions and the bus are working in LOOPBACK Mode.
  • Visualize your signals on a scope or logic analyser : Bus Line, RX & TX on transceivers and MCU pins.
  • Try in a lower baudrate ( 100 Kbits/s).
  • Use an online example that works as is (if possible).
  • Control your soldering and wiring. 

View solution in original post

3 REPLIES 3
SPati.7
Associate III

I am also facing same issue in case of STM32F107x as well. Transmit is working and Recieve is not working. I tried in Loop back mode as well, but no use.

If you got any update, Please let me know.

GLEGR.1
Associate II

So we tried with the old library std but it does not work either. We also tried with STM32F405 microcontrolers . We will keep debugging, maybe it has something to do with the baudrate or internal registers ... I would be very happy if someone had experience with this kind of issues !

GLEGR.1
Associate II

Problem Solved ! 

I did'nt really found why it was not working on my first prototype but I faced the same issue with my final PCB. 

However there was a short circuit between the CAN TX and RX on one MCU due to a thin wire of tin !

Even with that problem i had the RX signal on my scope that's why i did'nt thought it was a hard problem ! 

I removed the bad soldering and modifed the prescalers to have a lower baudrate : 150 Kbits/s .

The design finaly worked with this configuration

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
 
/* USER CODE BEGIN PV */
CAN_HandleTypeDef hcan1;
CAN_TxHeaderTypeDef pHeader; //declare a specific header for message transmittions
CAN_RxHeaderTypeDef pRxHeader; //declare header for message reception
uint32_t TxMailbox;
uint8_t a,r; //declare byte to be transmitted //declare a receive byte
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
 
/* Private user code ---------------------------------------------------------*/
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN1_Init();
  /* USER CODE BEGIN 2 */
  CAN_Config();
  a = 0xff;
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);
	//function to add message for transmition
	if(HAL_CAN_AddTxMessage(&hcan1, &pHeader, &a, &TxMailbox) != HAL_OK){
		Error_Handler();
	}
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
	HAL_Delay(100);
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
 
  }
  /* USER CODE END 3 */
}
 
/**
 * @brief CAN1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_CAN1_Init(void)
{
 
 /* USER CODE BEGIN CAN1_Init 1 */
 /* USER CODE END CAN1_Init 1 */
 hcan1.Instance = CAN1;
 hcan1.Init.Prescaler = 20;
 hcan1.Init.Mode = CAN_MODE_NORMAL;
 hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
 hcan1.Init.TimeSeg1 = CAN_BS1_12TQ;
 hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
 hcan1.Init.TimeTriggeredMode = DISABLE;
 hcan1.Init.AutoBusOff = DISABLE;
 hcan1.Init.AutoWakeUp = DISABLE;
 hcan1.Init.AutoRetransmission = DISABLE;
 hcan1.Init.ReceiveFifoLocked = DISABLE;
 hcan1.Init.TransmitFifoPriority = DISABLE;
 
if (HAL_CAN_Init(&hcan1) != HAL_OK)
 {
  Error_Handler();
 }
 
}
 
/**
 * @brief Configures the CAN.
 * @param None
 * @retval None
 */
 
static void CAN_Config(void)
{
 CAN_FilterTypeDef sFilterConfig;
 
 pHeader.DLC=1; //give message size of 1 byte
 pHeader.IDE=CAN_ID_STD; //set identifier to standard
 pHeader.RTR=CAN_RTR_DATA; //set data type to remote transmission request?
 pHeader.StdId=0x244; //define a standard identifier, used for message identification by filters (switch this for the other microcontroller)
 pHeader.ExtId = 0x01;
 pHeader.TransmitGlobalTime = DISABLE;
 
 //filter one (stack light blink)
 sFilterConfig.FilterFIFOAssignment=CAN_RX_FIFO0; //set fifo assignment
 sFilterConfig.FilterIdHigh = 0x0000;
 sFilterConfig.FilterIdLow = 0x0000;
 sFilterConfig.FilterMaskIdHigh = 0x0000;
 sFilterConfig.FilterMaskIdLow = 0x0000;
 sFilterConfig.FilterScale=CAN_FILTERSCALE_32BIT; //set filter scale
 sFilterConfig.FilterActivation=ENABLE;
 sFilterConfig.FilterBank = 0;
 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
 sFilterConfig.SlaveStartFilterBank = 14;
 if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
 
  {
 
   /* Filter configuration Error */
 
   Error_Handler();
 
  }
 
  if (HAL_CAN_Start(&hcan1) != HAL_OK)
  {
   /* Start Error */
   Error_Handler();
  }
 if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
 
   /* Notification Error */
   Error_Handler();
  }
}
 

So setting all the filters to 0 permits to accept all CAN messages and it is working.

For those who face the same issue (according to my experience) :

  • Make sure your interruptions and the bus are working in LOOPBACK Mode.
  • Visualize your signals on a scope or logic analyser : Bus Line, RX & TX on transceivers and MCU pins.
  • Try in a lower baudrate ( 100 Kbits/s).
  • Use an online example that works as is (if possible).
  • Control your soldering and wiring.