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

@Davaol19 wrote:

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. 


The goal is to confirm if it's a hardware issue or a silicon issue (as you claimed). So this test is important to have come to a clear-cut conclusion: is it an issue in your HW: connections, PCB, the transceiver or something in the MCU..

 


@Davaol19 wrote:

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 don't see any issue on your CAN config (unless I missed something), except the fact you are using HSI as clock source for CAN. 

Try to decrease BS1 in favor of BS2. BS1=12 and BS2=3.

 

For the transceiver, you need to review its datasheet. 

 

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.

I've tried and nothing different happened. But CAN2 works as CAN1 when alone, without errors. I don't understand. I'm forgetting something.

Sorry I didn't understand.

Did you configure CAN1 and CAN2 in loopback mode each and get the same behavior or not?

If yes could you please share this project (two CAN instances in loopback mode) in order to replicate it from my side?

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, i'll try. But i'm not very familiar with loopback mode.


@Davaol19 wrote:

But i'm not very familiar with loopback mode.


Ok. It's time to start to be familiar with it. It's simpler than Normal mode as it doesn't need any external HW and it's needed for cases like yours for debug.

You can inspire from this example provided in the CubeHAL: https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM32446E_EVAL/Examples/CAN/CAN_Loopback

 

 

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.

Hello,

Attached a project I made for Nucleo-F446RE board:

CAN1 and CAN2 are in loopback mode. Nothing connected externally. Activated all the possible CAN errors.

Nothing happened, CAN1 and CAN2 "transceive" both the frames correctly and none of the activated errors has raised.

Please run this FW on your board, open the "Live Expressions" and check especially CAN1_errors and CAN2_errors.

As you can see from my debug session screen shot, CAN1 and CAN2 are receiving messages in loopback mode without errors:

SofLit_0-1725445254952.png

 

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.

Thanks for the code.

But i've been reading the manual and in loopback mode the acknowledge bit is ignore, wich is one of the errors that i've had.

I've tried the code in the nucleo board and the behavior is the same as you explained, tomorrow i will try on the PCB and i'll return here.

But reading your code a think there's no difference with mine in terms of configuration and CAN setup, i think thats the problem maybe can't be sen in this mode due to the fact that acknowledge bit is ignored.

The no direct acces to sram in CAN2 could be a problem?

 


@Davaol19 wrote:

think thats the problem maybe can't be sen in this mode due to the fact that acknowledge bit is ignored.

The no direct acces to sram in CAN2 could be a problem?


You said you have an issue when you enable CAN2 and you suspected an issue with CAN2 implementation in STM32. Loopback mode is the best test to know on which location the issue resides. If you didn't reproduce the behavior on your board with the FW I provided, I'm pretty sure you have an issue with your CAN HW including the transceiver. So please do that in order to converge to a solution.

So please make the test and het back with the result.

Thank you.

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.

I've tried your code in my PCB and the behavior is exactly the same as yours. 

Davaol19_0-1725555097876.png

Tomorrow i will change the mode to normal in your code and try to connect both peripheral between them. 

Thanks you


@Davaol19 wrote:

I've tried your code in my PCB and the behavior is exactly the same as yours. 

Davaol19_0-1725555097876.png

Tomorrow i will change the mode to normal in your code and try to connect both peripheral between them. 

Thanks you


From this, I conclude this is not an issue on the STM32 but in your hardware.

Try to replace the transceiver either the same part number or completely use another part number example SN65HVD230 what we are using in our Eval boards.

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.