cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN not receive messages from a few particular sensors

Ping1
Associate II

Dear all

I am using STM32H563 and interface with some CAN bus sensors to receive and sometimes send data to them. The CAN bus sensors are developed by a partner company. I developed my software refer to FDCAN_Com_IT example provided in IDE firmware package. They work fine most of time, but there is an issue has been bother me - for a few sensors, tmy software doesn't receive the message form them, it doesn't generate interrupt simply.  Don't think the sensor module is fault as they can be received by a CANUSB dongle, it seems the issues are with a few fixed sensor modules only, so i am wonder what I have done wrong to miss the message, on Logic analyser, message can be seen although sometimes it is with error, but most of time, they are fine, just doesn't reach my ISR.

 

Regards!

Ping

1 ACCEPTED SOLUTION

Accepted Solutions

Try:

  FDCAN_FilterTypeDef        sFilterConfig;
  sFilterConfig.IdType       = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex  = 0U;
  sFilterConfig.FilterType   = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1    = 0;
  sFilterConfig.FilterID2    = 0;
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.

View solution in original post

10 REPLIES 10
Ozone
Principal III

You would need to present that FDCAN configuration settings (code) to check this issue.
Perhaps the message filtering settings are the problem.
Set those to default (no filtering), and implement filters later, once communication works otherwise.

Additionally I would check the TEC and REC fields in the CAN status.

LCE
Principal II

And maybe the messages that you can't receive use bit rate switching (BRS) ?

Ping1
Associate II

Hi, LCE, thanks for reply!

Below is FDCAN configuration - CAN sensor use extended message ID at 500kbps, they are all same.

  hfdcan2.Instance = FDCAN2;
  hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan2.Init.AutoRetransmission = ENABLE;
  hfdcan2.Init.TransmitPause = ENABLE;
  hfdcan2.Init.ProtocolException = ENABLE;
  hfdcan2.Init.NominalPrescaler = 4;
  hfdcan2.Init.NominalSyncJumpWidth = 1;
  hfdcan2.Init.NominalTimeSeg1 = 70;
  hfdcan2.Init.NominalTimeSeg2 = 54;
  hfdcan2.Init.DataPrescaler = 1;
  hfdcan2.Init.DataSyncJumpWidth = 1;
  hfdcan2.Init.DataTimeSeg1 = 1;
  hfdcan2.Init.DataTimeSeg2 = 1;
  hfdcan2.Init.StdFiltersNbr = 1;
  hfdcan2.Init.ExtFiltersNbr = 1;
  hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
  {
    Error_Handler();
  }

Below is the code snap for filter configuration, it accept all message IDs, basically.

  /* USER CODE BEGIN FDCAN2_Init 2 */
  /* Configure standard ID reception filter to Rx FIFO 0. accept any message IDs */
  FDCAN_FilterTypeDef        sFilterConfig;
  sFilterConfig.IdType       = FDCAN_EXTENDED_ID;
  sFilterConfig.FilterIndex  = 0U;
  sFilterConfig.FilterType   = FDCAN_FILTER_RANGE_NO_EIDM;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1    = 0x00000000;
  sFilterConfig.FilterID2    = 0x1FFFFFFF;
  if (HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /**
      *  Configure global filter:
      *    - Filter all remote frames with STD and EXT ID
      *    - Reject non matching frames with STD ID and EXT ID
      */
    if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
                                     FDCAN_REJECT, FDCAN_REJECT,
                                     FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
    {
      Error_Handler();
    }

    /* Activate Rx FIFO 0 new message notification */
    if (HAL_FDCAN_ActivateNotification(&hfdcan2, (FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL), 0U) != HAL_OK)  //enable interrupt
    {
      Error_Handler();
    }

    /*##-2 Start FDCAN controller (continuous listening CAN bus) ##############*/

    if (HAL_FDCAN_Start(&hfdcan2) != HAL_OK)
    {
      Error_Handler();
    }

 I did check BRS from received message , it doesn't use BRS, all sensor modules are programmed with same code.

Regards!

Ping

mƎALLEm
ST Employee

Hello,


@Ping1 wrote:

for a few sensors, tmy software doesn't receive the message form them, it doesn't generate interrupt simply. 


1 - Are these sensors (not working) are same as the others which are working? bitrate issue? connection issue?

You need to sniff the frames at CAN_H/CAN_L of the sensors to confirm the sent frames from STM32H5 are well seen on CAN pins of these sensors.

2- It could be also a filtering issue. But for that you need to be sure of:

 - The frames are well seen on CAN_H/CAN_L

 - The bitrate used by these sensors is the same of what you have configured in STM32H5. 

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.
mƎALLEm
ST Employee

You didn't show the code responsible of sending frames to the sensors.

Also try the filter config:

  FDCAN_FilterTypeDef        sFilterConfig;
  sFilterConfig.IdType       = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex  = 0U;
  sFilterConfig.FilterType   = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1    = 0;
  sFilterConfig.FilterID2    = 0;
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.

Hi, mƎALLEm

Thanks for response!

The ISR code is shown below, as you can see, I am counting 3 messages from 3 different sensors with different message IDs.

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
  if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != 0U)
  {
    /* Retrieve Rx messages from RX FIFO0 */
    if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rxHeader, rxData) != HAL_OK)
    {
      Error_Handler();
    }
	if(rxHeader.Identifier == 0x1f000017) {
		rxed2++;
	}
	if(rxHeader.Identifier == 0x1f00001A) {
		rxed3++;
	}
	if(rxHeader.Identifier == 0x1f000024) {
		rxed6++;
	}
	memcpy(&rxCopy, &rxData, 8);
    tx_semaphore_put(&semaphore_can);  //received a message
  }
}

Below is the sending message thread: after it receives different type so message, for now reply with an initial TYPE_CONFIG_REQUEST message, and then for all TYPE_OCC_DATA message, I just sent it on bus for test only.

VOID FDCAN_thread_entry(ULONG initial_input)
{
	ULONG current_value;
	TX_THREAD *first_suspended;
	ULONG suspended_count;
	TX_SEMAPHORE *next_semaphore;
	HAL_StatusTypeDef sendStatus;
	//uint8_t rxed = 0;
	FDCAN_TxHeaderTypeDef        txHeader;
	while(1) {
		can_TS = HAL_GPIO_ReadPin(FDCAN_TS_GPIO_Port, FDCAN_TS_Pin);  //SET means it is in normal mode,
		/* Check one message is received in Rx FIFO 0 */
		tx_semaphore_get(&semaphore_can, TX_WAIT_FOREVER);

		UINT status = _tx_semaphore_info_get(&semaphore_can, NULL, &current_value, &first_suspended, &suspended_count, &next_semaphore);
		if(status == TX_SUCCESS) {
			//send a reply message with what rxed content ID and data
			if(rxData[7] == TYPE_CONFIG_REQUEST) {
				txData[0] = 0x01;  //enable indicator
				txData[5] = 0x64;  //0.2s, 0x64~1s, 0xC8 data packet every 2s for now
				txData[7] = TYPE_CONFIG_REPLY;
				txHeader.Identifier          = rxHeader.Identifier - 0x1f000000;//unicast one //   //broadcast to all
				txHeader.IdType              = FDCAN_EXTENDED_ID;
				txHeader.TxFrameType         = FDCAN_DATA_FRAME;
				txHeader.DataLength          = FDCAN_DLC_BYTES_8;
				txHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
				txHeader.BitRateSwitch       = FDCAN_BRS_OFF;
				txHeader.FDFormat            = FDCAN_CLASSIC_CAN;  //classic works, FD works too
				txHeader.TxEventFifoControl  = FDCAN_STORE_TX_EVENTS;
				txHeader.MessageMarker       = 0x11U;
				sendStatus = HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &txHeader, txData);
				if(sendStatus != HAL_OK)
				{
				  FDCAN_Error_Handler();
				}
			}
			else if(rxData[7] == TYPE_OCC_DATA){
				rxedCnt++;
				/* this is for test only - send out a can msg to confirm we received it */
				txHeader.Identifier          = rxHeader.Identifier + 0x800000;  //rxHeader.Identifier means send from Mother board 0x1f800005 for test
				txHeader.IdType              = FDCAN_EXTENDED_ID;
				txHeader.TxFrameType         = FDCAN_DATA_FRAME;
				txHeader.DataLength          = FDCAN_DLC_BYTES_8;
				txHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
				txHeader.BitRateSwitch       = FDCAN_BRS_OFF;
				txHeader.FDFormat            = FDCAN_CLASSIC_CAN;  //classic works, FD works too
				txHeader.TxEventFifoControl  = FDCAN_STORE_TX_EVENTS;
				txHeader.MessageMarker       = 0x12U;

				sendStatus = HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &txHeader, rxCopy);
				if(sendStatus != HAL_OK)
				{
					FDCAN_Error_Handler();
				}
			}
		}
		tx_thread_sleep(10);
	}
}

 Also, tried your filter config, no difference, BTW, I am using extended message ID, that is the only change from your suggestion.

Thank for your attention.

Ping

 

Ping1
Associate II

Hi, regarding

"You need to sniff the frames at CAN_H/CAN_L of the sensors to confirm the sent frames from STM32H5 are well seen on CAN pins of these sensors."

I am not sure how to sniff CAN_H/CAN_L, I am only sniff CAN_RX and CAN_TX between MCU and CAN Transceiver. Sometime, RX pins with message errors, sometimes not, but in ant case, I don't get it from my ISR, while it works for other 2 on same bus.

Regards!

Ping

LCE
Principal II

Filter:

Just to make sure it's not the filter, comment out the call to HAL_FDCAN_ConfigGlobalFilter() or change it from FDCAN_REJECT to FDCAN_ACCEPT_IN_RX_FIFO0 or FDCAN_ACCEPT_IN_RX_FIFO1 .

Surely only if you have set up the according RX FIFO...

Ping1
Associate II

Hi, ICE

Thank you for reply.

Tried first to remove it and seems no difference made, then tried to change to below - i am receiving extended ID only.

      FDCAN_FilterTypeDef        sFilterConfig;
      sFilterConfig.IdType       = FDCAN_EXTENDED_ID;
      sFilterConfig.FilterIndex  = 0U;
      sFilterConfig.FilterType   = FDCAN_FILTER_RANGE; 
      sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; 
      sFilterConfig.FilterID1    = 0x00000000;
      sFilterConfig.FilterID2    = 0x1FFFFFFF;
      if (HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig) != HAL_OK)
      {
        Error_Handler();
      }
	if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
			FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0,
			FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
  	{
  		Error_Handler();
  	}

Still makes no difference, I hope I made the change correct, let me know if i misunderstand anything.

Thank you!

Ping