0

I am designing a CAN Bus with two STM32F4 Discovery boards. I use transceivers SN65HVD234 from Texas Instruments. I configured the Discovery with CubeMX and used CubeIDE. I am using the HAL library.

I use the User button to fire an EXTI interrupt, that calls HAL_CAN_AddTxMessage() and writes on the bus.

Transmitting data works, but not receiving. Only receiving in loopback mode works for a board that self-transmits.

The hardware is working very well (confirmed with scope ) and I saw various people having the same problem on other boards, like in this discussion. As I didn't really understand the solution, here is the configuration of my filter :

CAN_FilterTypeDef  sFilterConfig;
/*## Configure the CAN Filter ###########################################*/
 sFilterConfig.FilterBank = 1; // config seen in [STM32F4 ref manual][2] p1089
 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();
 }

I tried to apply a config seen in the STM32F4 ref manual p1089, but I can't see any way to configure the filter number...

What did I do wrong? I think it could help other people because my design is very classic, using one CAN in normal mode.

SamGibson
  • 17,231
  • 5
  • 37
  • 58

2 Answers2

0

IMO, the FilterIdHigh, FilterIdLow, FilterMaskIdHigh and FilterMaskIdLow shall define the range of devices ID that will be received / ignored. It seems that in your case all IDs are being ignored.

Marko Buršič
  • 23,562
  • 2
  • 20
  • 33
  • Like you said I changed the parameters of the filters : sFilterConfig.FilterIdHigh = 0x320 <<5; //chosing ID 320 sFilterConfig.FilterIdLow = 0; sFilterConfig.FilterMaskIdHigh = 0xFFF <<5; sFilterConfig.FilterMaskIdLow = 0; But Nothing changed. However it works in loopback mode. So the interuption is working. However it might be related to the Rx gpio but it was configured by CubeMX and i have the signals in my scope...So i am clearly lost !! – lordlothard Dec 10 '20 at 14:05
0

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 :

/**
  * @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) :

1. Make sure your interruptions and the bus are working in LOOPBACK Mode.

2. Visualize your signals on a scope or logic analyser : Bus Line, RX & TX on transceivers and MCU pins.

3. Try in a lower baudrate (~100 Kbits/s).

4. Use an online example that works as is (if possible).

5. Control your soldering and wiring.