cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446RET6R TWO CAN PERIPHERALS

Davaol19
Associate III

Hello!!

I'm trying to use both CAN peripherals in an STM32F446RET6R on a custom PCB, but something is not going well enough.

I've done the basic configuration using the STMCubeIDE platform (I'll add the code later, but first I want to know if someone has had similar issues with this microcontroller).

The problem is that if I only configure one peripheral, CAN1 (the Master), everything works okay—no error bits in SFRs, no BUSOFFs or anything like that, everything is transmitted and received well.

But when I configure CAN2 (SLAVE), CAN1 continues working perfectly, but CAN2 starts sending frames with CRC errors and corrupted data (I'm using CANoe to read the messages). The TEC bit starts incrementing until the node gets stopped.

The flags raised when the transmission stops are TEC, EPVF, and EWGF.

I also want to add that if I configure everything without a reception interrupt in CAN2, the transmission and reception in CAN1 and transmission in CAN2 work fine without any flags raised.

If anyone can help me with this topic, I’d appreciate it a lot. I've done similar configurations with other microcontrollers, and they worked well.

 

THANKS!!

 

 

30 REPLIES 30

But if i only use CAN2 works perfectly. The problem comes when i use both at the same time.

Ok.. let’s be fact based on that. 

Make a very simple project where CAN1 and CAN2 are communicating together. Just a communication between the two CAN instances nothing else and you need to test that without any other node connected on the bus: only CAN1 and CAN2 on the bus you need to activate the errors on both sides. You need to reproduce the behavior and detect erros on CAN1.

Then attach it here so I will do the test next week on a Nucleo board.

 

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

¿Do you know any example were both CAN peripherals are used? Maybe can help me.

I think that maybe i have to try writing my code using registers but i'm not at that level yet.

An example I made years ago on STM32F217. You can inspire from it. 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Okey, to make it clear for me.


@SofLit wrote:

 

Make a very simple project where CAN1 and CAN2 are communicating together. Just a communication between the two CAN instances nothing else and you need to test that without any other node connected on the bus:

 

 

 

 


Basically is a code were both peripherals are configured to transmit and receive, can configuration is in normal mode like the project that i shared yesterday i understand. 


@SofLit wrote:

 

 only CAN1 and CAN2 on the bus you need to activate the errors on both sides. You need to reproduce the behavior and detect erros on CAN1.

 

 


¿By activating the errors you mean activating SCE interrupt? I usually read bit errors in SFRs while debugging.



Basically is a code were both peripherals are configured to transmit and receive, can configuration is in normal mode like the project that i shared yesterday i understand. 


I need a project where CAN1 and CAN2 are communicating together on the bus without any other node. So disconnect CANoe etc:

SofLit_0-1725029046981.png

 



¿By activating the errors you mean activating SCE interrupt? I usually read bit errors in SFRs while debugging.


You can read the errors in the registers but better let them raise as soon as they are detected using interrupt.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Okey, understood.

I tested it and it worked without errors for 3 minutes. After that, TEC in CAN2 and REC in CAN1 started increasing until EWGF was triggered, followed by EPVF, causing the bus to stop.

Additionally, LEC shows 010, which indicates a form error.

 

Ok. I suspect a HW issue here.. It could be something related to the transceiver.

If you configure CAN1 and CAN2 each in one of the test modes (loopback mode for example), and disconnect CAN1 from CAN2. do you face the same behavior?

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

But is really difficult to me think that is hardware because i'm sure that it's right, is the same as the CAN1, which works perfectly when alone. 

I've tried to configure only CAN2 and the behavior is the same when connected to CAN1 or CANoe. Are you sure that my code is good? i'm not missing anything?

Here is all the code related to setup CAN2 peripheral:

 

 

 

static void MX_CAN2_Init(void) {

	/* USER CODE BEGIN CAN2_Init 0 */
	CAN_FilterTypeDef canfilterconfig;
	/* USER CODE END CAN2_Init 0 */

	/* USER CODE BEGIN CAN2_Init 1 */

	/* USER CODE END CAN2_Init 1 */
	hcan2.Instance = CAN2;
	hcan2.Init.Prescaler = 2;
	hcan2.Init.Mode = CAN_MODE_NORMAL;
	hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
	hcan2.Init.TimeSeg1 = CAN_BS1_13TQ;
	hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
	hcan2.Init.TimeTriggeredMode = DISABLE;
	hcan2.Init.AutoBusOff = DISABLE;
	hcan2.Init.AutoWakeUp = DISABLE;
	hcan2.Init.AutoRetransmission = ENABLE;
	hcan2.Init.ReceiveFifoLocked = DISABLE;
	hcan2.Init.TransmitFifoPriority = ENABLE;
	if (HAL_CAN_Init(&hcan2) != HAL_OK) {
		Error_Handler();
	}
	/* USER CODE BEGIN CAN2_Init 2 */
	// Configurar la prioridad para CAN2_RX0
	canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
	canfilterconfig.FilterBank = 21; // which filter bank to use from the assigned ones
	canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
	canfilterconfig.FilterIdHigh = 0x000 << 5;
	canfilterconfig.FilterIdLow = 0;
	canfilterconfig.FilterMaskIdHigh = 0x000 << 5;
	canfilterconfig.FilterMaskIdLow = 0x0000;
	canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
	canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
	canfilterconfig.SlaveStartFilterBank = 20;
	HAL_CAN_ConfigFilter(&hcan2, &canfilterconfig);

	/* USER CODE END CAN2_Init 2 */

}
	MX_CAN1_Init();
	MX_CAN2_Init();
	/* USER CODE BEGIN 2 */
	HAL_CAN_Start(&hcan1);
	HAL_CAN_Start(&hcan2);

	HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
	HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING);

 

 

 

 

 

 

 

void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hcan->Instance==CAN1)
  {
  /* USER CODE BEGIN CAN1_MspInit 0 */

  /* USER CODE END CAN1_MspInit 0 */
    /* Peripheral clock enable */
    HAL_RCC_CAN1_CLK_ENABLED++;
    if(HAL_RCC_CAN1_CLK_ENABLED==1){
      __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, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
  /* USER CODE BEGIN CAN1_MspInit 1 */

  /* USER CODE END CAN1_MspInit 1 */
  }
  else if(hcan->Instance==CAN2)
  {
  /* USER CODE BEGIN CAN2_MspInit 0 */

  /* USER CODE END CAN2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_CAN2_CLK_ENABLE();
    HAL_RCC_CAN1_CLK_ENABLED++;
    if(HAL_RCC_CAN1_CLK_ENABLED==1){
      __HAL_RCC_CAN1_CLK_ENABLE();
    }

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN2 GPIO Configuration
    PB12     ------> CAN2_RX
    PB13     ------> CAN2_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
    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_CAN2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* CAN2 interrupt Init */
    HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 1);
    HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
  /* USER CODE BEGIN CAN2_MspInit 1 */

  /* USER CODE END CAN2_MspInit 1 */
  }

}

 

Do you think that all the initialitzation is right? I'm not missing anything? 

 

I also add the schematic:

Davaol19_0-1725310823048.png