Skip to main content
Visitor II
December 7, 2020
Solved

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

  • December 7, 2020
  • 3 replies
  • 5920 views

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

    This topic has been closed for replies.
    Best answer by GLEGR.1

    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. 

    3 replies

    Visitor II
    December 16, 2020

    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.1Author
    Visitor II
    December 29, 2020

    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.1AuthorAnswer
    Visitor II
    January 5, 2021

    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.