cancel
Showing results for 
Search instead for 
Did you mean: 

H723 FDCAN1 and FDCAN2

PGrif.2
Associate III

Hi there,

I am using two STM32H723ZGT communicating via FDCAN2 instance (FDCAN, no bit rate switch, 12500 bit/s). Both controller use the same FDCAN initialization code, but different filter IDs.

As shown below, the message is transfered on receiver CAN_Rx (upper trace) and acknowledged on sender CAN_Rx (lower trace), but neither the HAL_FDCAN_RxFifo0Callback() nor HAL_FDCAN_RxFifo1Callback() is triggered. When the receiver is shut down, the ackowledge disapears, so the message seems stuck in the the CAN peripherial.

FDCAN messageFDCAN message

CAN instance 1 (CAN2.0) is used for communication with other periperhial devices an works as expected.

What am I missing?

Thanks in advance!

 

CAN2 initialization FDCAN for both controller

 

/* USER CODE END FDCAN2_Init 1 */
  hfdcan2.Instance = FDCAN2;
  hfdcan2.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
  hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan2.Init.AutoRetransmission = DISABLE;
  hfdcan2.Init.TransmitPause = DISABLE;
  hfdcan2.Init.ProtocolException = ENABLE;
  hfdcan2.Init.NominalPrescaler = 32;
  hfdcan2.Init.NominalSyncJumpWidth = 5;
  hfdcan2.Init.NominalTimeSeg1 = 32;
  hfdcan2.Init.NominalTimeSeg2 = 7;
  hfdcan2.Init.DataPrescaler = 1;
  hfdcan2.Init.DataSyncJumpWidth = 16;
  hfdcan2.Init.DataTimeSeg1 = 20;
  hfdcan2.Init.DataTimeSeg2 = 16;
  hfdcan2.Init.MessageRAMOffset = 196;
  hfdcan2.Init.StdFiltersNbr = 1;
  hfdcan2.Init.ExtFiltersNbr = 1;
  hfdcan2.Init.RxFifo0ElmtsNbr = 16;
  hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
  hfdcan2.Init.RxFifo1ElmtsNbr = 16;
  hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
  hfdcan2.Init.RxBuffersNbr = 0;
  hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_64;
  hfdcan2.Init.TxEventsNbr = 0;
  hfdcan2.Init.TxBuffersNbr = 0;
  hfdcan2.Init.TxFifoQueueElmtsNbr = 16;
  hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_64;
  if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN2_Init 2 */

 

CAN2 Filter configuration

 

uint8_t CAN_ConfigCAN02Filter(uint8_t own_address)
{
	//
	uint8_t result = 0;
	FDCAN_FilterTypeDef canFilterConfig = { 0 };
	uint8_t filterindex  = 0;

	//
	canFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;

	//
	canFilterConfig.IdType = FDCAN_EXTENDED_ID;

	//
	canFilterConfig.FilterType = FDCAN_FILTER_MASK;

	//
	canFilterConfig.FilterID1 = own_address;	// canIdentifier
	canFilterConfig.FilterID2 = 0;				// mask: 0 => accept all messages

	//
	canFilterConfig.RxBufferIndex = 0;			// set to 0 if using FIFO
	//	canFilterConfig.IsCalibrationMsg = 0;

	//
	canFilterConfig.FilterIndex = filterindex;

	// configure the FDCAN reception filter
	result += HAL_FDCAN_ConfigFilter(&hfdcan2, &canFilterConfig);

	//
	filterindex += 2;

	// enable Rx interrupts
	result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
	result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);

	// enable Tx interrupts
	result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_TX_COMPLETE, FDCAN_TX_BUFFER0);
	result += HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_TX_FIFO_EMPTY, 0);

	// configure global filter to reject all non-matching frames
	HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
			FDCAN_REJECT,
			FDCAN_REJECT,
			FDCAN_REJECT_REMOTE,
			FDCAN_REJECT_REMOTE);

	//
	return result;
}

 

CAN1 initialization CAN2.0 

 

 /* USER CODE END FDCAN1_Init 1 */
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = ENABLE;
  hfdcan1.Init.NominalPrescaler = 40;
  hfdcan1.Init.NominalSyncJumpWidth = 5;
  hfdcan1.Init.NominalTimeSeg1 = 10;
  hfdcan1.Init.NominalTimeSeg2 = 9;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 16;
  hfdcan1.Init.DataTimeSeg1 = 20;
  hfdcan1.Init.DataTimeSeg2 = 16;
  hfdcan1.Init.MessageRAMOffset = 0;
  hfdcan1.Init.StdFiltersNbr = 1;
  hfdcan1.Init.ExtFiltersNbr = 1;
  hfdcan1.Init.RxFifo0ElmtsNbr = 16;
  hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxFifo1ElmtsNbr = 0;
  hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.RxBuffersNbr = 0;
  hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
  hfdcan1.Init.TxEventsNbr = 0;
  hfdcan1.Init.TxBuffersNbr = 0;
  hfdcan1.Init.TxFifoQueueElmtsNbr = 32;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN FDCAN1_Init 2 */

 

 

 

 

23 REPLIES 23

No. This is not the right way to use CAN in Normal mode.

You need to use transceivers to connect two nodes. 

CAN is not UART nor SPI nor something else. You need to use transceivers even with only two nodes on the bus. 

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 SofLit,

I know, also tested it with a CAN driver on both sides, same issue. 

The CAN bus driver provides the differential bus signal, the power to send longer distances and sharpens the received signals.

There would be either a CAN error on the sender side (not observed in any mentioned case) or no CAN ACK on the receiver side (also not observed in any case).

The used 10$ logic anlayser used to provide the shown logs shows clear signals in all cases (so the physical layer is OK) and is able to read and display the send values as the ID/data in a correct way.

Just changing the FilterID2 and global filter as in case 1 and case 2 provides this issue of no interrupt/callback.

 

Cheers!  

Hi SofLit,

 so i relay just need the right filter setting for FDCAN Extended ID Filter one ID with one mask.

 

As playing around with the code shows, that using 

 

//
canFilterConfig.IdType = FDCAN_EXTENDED_ID;	// extended ID
canFilterConfig.FilterType = FDCAN_FILTER_MASK; // second ID is the mask
canFilterConfig.FilterID1 = own_address;	// set the CAN ID to be filtered
canFilterConfig.FilterID2 = 0;			// mask: 0 => accept all messages

 

with

 

 

HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
		FDCAN_REJECT,
		FDCAN_REJECT,
		FDCAN_FILTER_REMOTE,
		FDCAN_FILTER_REMOTE);

 

 

rejects everything, even the matching frames, which is not the way HAL_FDCAN_ConfigGlobalFilter suposed to work. But I have to call HAL_FDCAN_ConfigGlobalFilter() otherwise it dosen't work either ...

SofLit
ST Employee

Refer to this thread, it may help you:

https://community.st.com/t5/stm32-mcus-products/how-to-configure-fdcan-receive-filter-configuration-for-multiple/td-p/622174

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.

As far as I know cross-connection CAN RxTx is not the recommended solution - it depends on the internal logic of the CAN frontend. See https://community.st.com/t5/stm32-mcus-products/on-board-communication-via-can-without-transceiver/td-p/152684 for a clean and proven solution (without using transceivers). 

The solution can work but with very limited bus distance and not recommended for a final design.

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 SofLit,

The issue still exists at my side, could somebody confirm or contradict it using the attached project? 

I managed to setup a minimum project using 2 NUCLEO-144-H723 boards and two jumper wires (<150 mm), where H723A is the sender and H723B is the receiver. FDCAN2 is used for communication and FDCAN1 is only setup for consistency of this thread.

 

The sender will send an extended FDCAN message every second, indicated by the RED on-board LED toggling. Every successful received extended FDCAN message at the receiver will be indicated by a toggled GREEN on-board LED. Both H723A/B use the same project code, two  #defines select the task.

 

Setup the sender H723A

uncomment line 105 at the main.c

 

 

#define sender			// use this definition for the sender H723A

 

 

compile, program and run.

 

Setup the receiver H723B

comment out line 105 at the main.c

 

 

//#define sender			// use this definition for the sender H723A

 

 

 

1. setup for successful receiving

uncomment line 188 at the ProcessCAN.c

 

 

#define RECEIVE_SUCCSEFUL

 

 

compile, program and run.

The receiver will use the following global CAN filter setup

 

 

// EITHER uncomment this and GREEN BOARD LED toggles -> receiving
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
			FDCAN_ACCEPT_IN_RX_FIFO1,
			FDCAN_ACCEPT_IN_RX_FIFO1,
			FDCAN_FILTER_REMOTE,
			FDCAN_FILTER_REMOTE);

 

 

 

2. setup for unsuccessful receiving

comment out line 188 at the ProcessCAN.c

 

 

//#define RECEIVE_SUCCSEFUL

 

 

compile, program and run.

The receiver will use the following global CAN filter setup, which should allow the message to pass the filter, but it doesn't.

 

 

// OR uncomment this and GREEN BOARD LED does not toggle -> not receiving
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2,
			FDCAN_REJECT,
			FDCAN_REJECT,
			FDCAN_FILTER_REMOTE,
			FDCAN_FILTER_REMOTE);

 

 

 

Cheers!

Hi SofLit,

I found an related but also unresolved issue:

Help with FD-CAN filter - STMicroelectronics Community

 

Cheers!

It is not true. It is possible to connect 2 nodes via CAN without the transceiver. A resistor net is needed. 

 

Purifier.2 What is your hw configuration?


@STDoom wrote:

It is not true. It is possible to connect 2 nodes via CAN without the transceiver. A resistor net is needed. 


Not recommended configuration. This could be used just for test and with low bitrate and with a very low distance between nodes.

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.