2025-11-28 2:13 AM
Hello there
I am struggling with receiving interrupts on my microcontroller project. I am currently developing a CAN bus logging device; the following code therefore sets up the CAN peripheral in silent mode. I test my device in a CAN network with two other devices that are constantly communicating with each other. I have verified that the CAN messages appear at the CAN Rx pin of my MCU using an oscilloscope.
However, my CAN Rx interrupts won't fire. I tried some fixes from other posts, but unfortunately, neither of them worked for me.
My setup is as follows:
>> MCU: STM32L432KCU
>> CAN receiver ISO1044BD
>> Vdd = 1.8 V (the MCU and the CAN transceiver are both running on this level).
>> IDE = CubeIDE
Have any of you ever had to tackle this problem?
## Here is the can.c file that was automatically generated by the CubeIDE, in which you can see the CAN initialisation.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.c
* @brief This file provides code for the configuration
* of the CAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 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 "can.h"
/* USER CODE BEGIN 0 */
#include "hal_handles.h"
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 5;
hcan1.Init.Mode = CAN_MODE_SILENT;
hcan1.Init.SyncJumpWidth = CAN_SJW_2TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
hal_handles_setCanHandle(&hcan1);
/* USER CODE END CAN1_Init 2 */
}
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_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
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(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
### and here you can see, how i set up my filter (supposed to accept all filters)
static void set_filter_configuration(void)
{
CAN_FilterTypeDef filter;
filter.FilterMode = CAN_FILTERMODE_IDMASK;
filter.FilterScale = CAN_FILTERSCALE_32BIT;
filter.FilterIdHigh = 0x0000;
filter.FilterIdLow = 0x0000;
filter.FilterMaskIdHigh = 0x0000;
filter.FilterMaskIdLow = 0x0000;
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter.FilterActivation = ENABLE;
filter.FilterBank = 0;
filter.SlaveStartFilterBank = 0;
HAL_CAN_ConfigFilter(hal_handles_getCanHandle(), &filter);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
// ... handling isr
}
void pl_can_init(void)
{
CAN_HandleTypeDef *hcan = hal_handles_getCanHandle();
// some other inits...
set_filter_configuration();
if (HAL_CAN_Start(hcan) != HAL_OK)
{
for (;;)
;
}
}
Solved! Go to Solution.
2025-11-28 2:39 PM
I was able to get the interrupts working; it was just a case of activating the notifications. After making the following call, the interrupts came on in both loopback and silent mode.
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
Thank you for your time, and for your quick support and responses!
2025-11-28 2:19 AM
Welcome to the forum.
You haven't given much information about your setup - please see:
How to write your question to maximize your chances to find a solution
In particular, details of the board you are using (schematics, etc) and your CAN bus configuration...
2025-11-28 2:41 AM - edited 2025-11-28 2:48 AM
Hello @julian_bischof and welcome to the ST community,
Why are you setting Slave start bank to 0? With this configuration you didn't allocate any filter resource for CAN1.
filter.SlaveStartFilterBank = 0;
Please set it to 14 (I think it's the default value of CAN2SB bit field) or at least set it to 1.
Please read this knowledge base article:
2025-11-28 2:43 AM
@Andrew Neil wrote:
In particular, details of the board you are using (schematics, etc) and your CAN bus configuration...
Indeed.
2025-11-28 4:37 AM
Thanks for the quick response!
The CAN interface looks like as following:
The CAN Bus configuration is supposed to be in silent mode, so that my logging device only listens to the bus.
The settings shown below unfortunately did not solve my interrupt problem.
filter.FilterBank = 0;
filter.SlaveStartFilterBank = 14;
2025-11-28 4:39 AM - edited 2025-11-28 4:48 AM
@julian_bischof wrote:
The settings shown below unfortunately did not solve my interrupt problem.
filter.FilterBank = 0; filter.SlaveStartFilterBank = 14;
Even all are OK, that cannot work if you didn't set SlaveStartBank > 0.
Try first the Loopback mode to test the interrupts and filters before moving to the Silent mode.
@julian_bischof wrote:
The CAN Bus configuration is supposed to be in silent mode, so that my logging device only listens to the bus.
"listens to the bus": That's why you need to share the schematics as it was requested and as you did.
2025-11-28 5:22 AM
Okay, all right — I set up the CAN in loopback mode to test my interrupts, but they still don't run. Which settings do I need to configure to start the CAN interrupts correctly?
My board only runs on the mcu-internal clock – do I need to consider any special configurations to get these interrupts to work? I set the baud rate to 500 kbps using the STM32 CubeMX GUI.
2025-11-28 5:26 AM - edited 2025-11-28 5:29 AM
@julian_bischof wrote:
My board only runs on the mcu-internal clock
That's not recommended. You need to use a crystal (XTAL) or crystal oscillator (XO) with CAN communication.
As the Loopback mode is not working that means you have an issue in your software. Could you please share the complete project? If not possible in public, share it with me in private.
2025-11-28 2:39 PM
I was able to get the interrupts working; it was just a case of activating the notifications. After making the following call, the interrupts came on in both loopback and silent mode.
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
Thank you for your time, and for your quick support and responses!