cancel
Showing results for 
Search instead for 
Did you mean: 

Using CAN2 (slave) without CAN1 (master)?

3pak
Associate II

Hi, I have just received a custom PCB using STM32F413RG (64 pin package) for a university design competition. We are using a single CAN bus (CAN2) for this PCB. I was trying to get CAN communication working and I only managed to get some junk data from the STM32.

Details are below. My questions are:

  • What exactly is the master-slave relationship between CAN1 and CAN2?
  • Is it possible to use CAN2 alone while the CAN1 pins are used for other peripherals?
    • What setup for CAN1 needs to be done in order to use CAN2 alone?
  • If CAN2 cannot be used alone, is it possible to use CAN1 alone?
  • If CAN1 cannot be used alone, then we must use CAN3 only?

I found that when using CAN2, the CAN_TIR register (containing CAN message ID) and CAN_TDTR register (containing CAN message DLC) have junk in them which is NOT overwritten by the AddTxMessage HAL function (except for the TX request bit in TIR register). Thus I get CAN messages, but they have a junk ID and a DLC of 11 (obviously junk). I tried writing directly to the registers in my program and reading back the values, but they did not change.

As an experiment, I tried to write to the CAN1 TIR and TDTR registers with random values and read them back. This worked perfectly fine.

Investigating the reference manual RM0430, I found that CAN2 is a "slave" to CAN1 "master," in dual CAN configuration, while CAN3 is for single CAN configuration. However, the RM0430 document is unclear regarding the exact "master-slave" relationship between CAN1 and CAN2.

7 REPLIES 7

You have basically the logic for 1.5x CAN peripherals, so CAN2 uses a lot of the same logic as CAN1

CAN1 needs to be enabled, and clocking, for the symbiotic relationship to work. I presume it can be idle or mapped to unused pins.

I'd dig through the issues, but don't have time/resources to commit to it.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
3pak
Associate II

I can understand enabling the CAN1 clock, but the main question I have regarding enabling CAN1 is that the initialization procedure requires reading 11 recessive bits on the CAN RX pin as shown in the screenshot below from RM0430 page 1109. However, the CAN1 RX pin is being used for another peripheral already, so how can the initialization be completed?0690X000006CdwvQAC.png

Jeroen3
Senior

The CAN peripheral has a loopback mode you can utilize.

3pak
Associate II

In the CAN MSP init function generated by STM32Cube, there is a macro called __HAL_RCC_CAN2_CLK_ENABLE() that is used. On the line above this, I simply called __HAL_RCC_CAN1_CLK_ENABLE() and that fixed the problem.

I​ found this solution from Google Translation of these forum threads, where it seems that the solution is to set the bit that enables the CAN1 clock:

https://www.fingers-welt.de/phpBB/viewtopic.php?f=14&t=1086

http://forum.easyelectronics.ru/viewtopic.php?f=35&t=27632

Andrew Hazelton
Associate III

This was a stumbling block for myself as I found myself in the same situation as I have designed a custom PCB and am using CAN2 as well. The I spent 1.5 days one this before I realised that i have to include __HAL_RCC_CAN1_CLK_ENABLE(); to get CAN2 to work. I wish this was stated in the reference manual RM0410.

Also, to get receiving filters working on CAN2, "FilterBank" must be greater than "SlaveStartFilterBank".

CAN_FilterTypeDef      sFilterConfig;
 
 
  // Analog Inputs - 0x18FF20xx
 
  sFilterConfig.FilterBank      = 17;
 
  sFilterConfig.FilterMode      = CAN_FILTERMODE_IDMASK;     //   CAN_FILTERMODE_IDLIST;
 
  sFilterConfig.FilterScale      = CAN_FILTERSCALE_32BIT;
 
  sFilterConfig.FilterIdHigh     = ( (0x18FF2000 << 3) >> 16); 
 
  sFilterConfig.FilterIdLow      = ( (0x18FF2000 << 3) & 0xFFFF);
 
  sFilterConfig.FilterMaskIdHigh   = ( (0xFFFFFF00>>3)>>16);
 
  sFilterConfig.FilterMaskIdLow    = ( (0xFFFFFF00 << 3) & 0xFFFF);
 
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
 
  sFilterConfig.FilterActivation   = ENABLE;
 
  sFilterConfig.SlaveStartFilterBank = 15;
 
  HAL_CAN_ConfigFilter(&PowerPlexCAN.CanHandle, &sFilterConfig); 

I just finished also spending more than a day on this until I found this post. The STM32CubeMx software now initializes the __HAL_RCC_CAN1_CLK_ENABLE() correctly if you only enable CAN2. So in this case I forgive for this info not being on the manual.

BUT, the real gotcha was the fact the FilterBank setting had to be higher than the SlaveStartFilterBank setting for CAN2. The whole filter settings could be better explained in the manual.

Hi Rentato,

I tried setting FilterBank higher (17) than SlaveStartFilterBank(15) but still it is not working, of course after having CAN1 clock also enabled. Is there anything I am missing ?

Regards,

Parvez Akhtar