cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743ZIT6 fdcan works at 100,125 and 1000 kbps but it doesn't at 250 and 500kbps

ACots.2
Associate

Hi everyone,

I'm using an STM32H743ZIT6, Revision Y.

I'm trying to test the fdcan peripheral by sending packets from fdcan1 to fdcan2 and checking the received packets.

I wrote a test function that performs both Init and Tx/Rx.

I'm only using the TX in FIFO mode and RX_FIFO0 and I'm using Classic Can Frame.

I tried to inizialize the FIFOs with only one element, and it works with all my desired baudrates [100, 125, 250, 500, 1000]kbps

When I try to increase che FIFO elements number to 32, it works for baud 100, 125 and 1000. 

But with baudrate 250 and 500 I have a reception problem. 

The HAL_FDCAN_GetRxMessage(&hfdcan2, FDCAN_RX_FIFO0, &RxHeader, RxData) returns HAL_ERROR and 

hfdcan2.ErrorCode == 0x100 that is HAL_FDCAN_ERROR_FIFO_EMPTY.

I don't understand how it's possible that works at 1Mbps but not at 250 and 500kbps!

Any help would be much appreciated.

Best Regards

Aléxandros

	//Test_FDCAN_Can_4_5_Npkt(1, 100);		// OK
	//Test_FDCAN_Can_4_5_Npkt(1, 125);		// OK
	//Test_FDCAN_Can_4_5_Npkt(1, 250);		// OK
	//Test_FDCAN_Can_4_5_Npkt(1, 500);		// OK
	//Test_FDCAN_Can_4_5_Npkt(1, 1000);	// OK
	//Test_FDCAN_Can_4_5_Npkt(32, 100);	// OK
	//Test_FDCAN_Can_4_5_Npkt(32, 125);	// OK
	//Test_FDCAN_Can_4_5_Npkt(32, 250);	// NO !!!!!!!!!!!!
	//Test_FDCAN_Can_4_5_Npkt(32, 500);	// NO !!!!!!!!!!!!
	//Test_FDCAN_Can_4_5_Npkt(32, 1000);	// OK
 
// num_of_packets between 1 and 32
// uiBaudRate [100, 125, 250, 500, 1000]
static void Test_FDCAN_Can_4_5_Npkt(uint8_t num_of_packets, uint32_t uiBaudRate)
{
	extern FDCAN_HandleTypeDef hfdcan1;
	extern FDCAN_HandleTypeDef hfdcan2;
	HAL_StatusTypeDef HALRes;
	uint8_t nOfRxPkts = 0;
 
	HwWriteLedGreenDS3(1);//GREEN LED ON 
 
 
	/************************
	*      Init FDCAN1      *
	************************/
	
	hfdcan1.Instance = FDCAN1;
	hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
	hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
	hfdcan1.Init.AutoRetransmission = ENABLE;
	hfdcan1.Init.TransmitPause = DISABLE;
	hfdcan1.Init.ProtocolException = DISABLE;
	
	//40MHz
	switch ( uiBaudRate ) {
			case 100:
					hfdcan1.Init.NominalPrescaler = 2;
					hfdcan1.Init.NominalSyncJumpWidth = 8;
					hfdcan1.Init.NominalTimeSeg1 = 159;
					hfdcan1.Init.NominalTimeSeg2 = 40;
					break;
			case 125:
					hfdcan1.Init.NominalPrescaler = 1;
					hfdcan1.Init.NominalSyncJumpWidth = 8;
					hfdcan1.Init.NominalTimeSeg1 = 255;
					hfdcan1.Init.NominalTimeSeg2 = 64;
					break;
			case 250:
					hfdcan1.Init.NominalPrescaler = 1;
					hfdcan1.Init.NominalSyncJumpWidth = 8;
					hfdcan1.Init.NominalTimeSeg1 = 127;
					hfdcan1.Init.NominalTimeSeg2 = 32;
					break;
			case 500:
					hfdcan1.Init.NominalPrescaler = 1;
					hfdcan1.Init.NominalSyncJumpWidth = 8;
					hfdcan1.Init.NominalTimeSeg1 = 63;
					hfdcan1.Init.NominalTimeSeg2 = 16;
					break;
			case 1000:
					hfdcan1.Init.NominalPrescaler = 1;
					hfdcan1.Init.NominalSyncJumpWidth = 8;
					hfdcan1.Init.NominalTimeSeg1 = 31;
					hfdcan1.Init.NominalTimeSeg2 = 8;
					break;
			default:
					break;
	}
	
	hfdcan1.Init.DataPrescaler = 1;
	hfdcan1.Init.DataSyncJumpWidth = 1;
	hfdcan1.Init.DataTimeSeg1 = 1;
	hfdcan1.Init.DataTimeSeg2 = 1;
	hfdcan1.Init.MessageRAMOffset = 0;
	hfdcan1.Init.StdFiltersNbr = 1;
	hfdcan1.Init.ExtFiltersNbr = 0;
	hfdcan1.Init.RxFifo0ElmtsNbr = num_of_packets;//<--------
	hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
	hfdcan1.Init.RxFifo1ElmtsNbr = 0;
	hfdcan1.Init.RxBuffersNbr = 0;
	hfdcan1.Init.TxEventsNbr = 0;
	hfdcan1.Init.TxBuffersNbr = 0;
	hfdcan1.Init.TxFifoQueueElmtsNbr = num_of_packets;//<--------
	hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
	hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
	
	HALRes = HAL_FDCAN_Init ( &hfdcan1 );
	if ( HALRes != HAL_OK ) {
		__NOP();
	}
	
	/************************
	*      Init FDCAN2      *
	************************/
	
	hfdcan2.Instance = FDCAN2;
	hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
	hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
	hfdcan2.Init.AutoRetransmission = ENABLE;
	hfdcan2.Init.TransmitPause = DISABLE;
	hfdcan2.Init.ProtocolException = DISABLE;
	
	// Preparazione registri per baud rate
	switch ( uiBaudRate ) {
			case 100:
					hfdcan2.Init.NominalPrescaler = 2;
					hfdcan2.Init.NominalSyncJumpWidth = 8;
					hfdcan2.Init.NominalTimeSeg1 = 159;
					hfdcan2.Init.NominalTimeSeg2 = 40;
					break;
			case 125:
					hfdcan2.Init.NominalPrescaler = 1;
					hfdcan2.Init.NominalSyncJumpWidth = 8;
					hfdcan2.Init.NominalTimeSeg1 = 255;
					hfdcan2.Init.NominalTimeSeg2 = 64;
					break;
			case 250:
					hfdcan2.Init.NominalPrescaler = 1;
					hfdcan2.Init.NominalSyncJumpWidth = 8;
					hfdcan2.Init.NominalTimeSeg1 = 127;
					hfdcan2.Init.NominalTimeSeg2 = 32;
					break;
			case 500:
					hfdcan2.Init.NominalPrescaler = 1;
					hfdcan2.Init.NominalSyncJumpWidth = 8;
					hfdcan2.Init.NominalTimeSeg1 = 63;
					hfdcan2.Init.NominalTimeSeg2 = 16;
					break;
			case 1000:
					hfdcan2.Init.NominalPrescaler = 1;
					hfdcan2.Init.NominalSyncJumpWidth = 8;
					hfdcan2.Init.NominalTimeSeg1 = 31;
					hfdcan2.Init.NominalTimeSeg2 = 8;
					break;
			default:
					break;
	}
	
	hfdcan2.Init.DataPrescaler = 1;
	hfdcan2.Init.DataSyncJumpWidth = 1;
	hfdcan2.Init.DataTimeSeg1 = 1;
	hfdcan2.Init.DataTimeSeg2 = 1;
	hfdcan2.Init.MessageRAMOffset = 0;
	hfdcan2.Init.StdFiltersNbr = 1;
	hfdcan2.Init.ExtFiltersNbr = 0;
	hfdcan2.Init.RxFifo0ElmtsNbr = num_of_packets;//<--------
	hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
	hfdcan2.Init.RxFifo1ElmtsNbr = 0;
	hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
	hfdcan2.Init.RxBuffersNbr = 0;
	hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
	hfdcan2.Init.TxEventsNbr = 0;
	hfdcan2.Init.TxBuffersNbr = 0;
	hfdcan2.Init.TxFifoQueueElmtsNbr = num_of_packets;//<--------
	hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
	hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
	
	HALRes = HAL_FDCAN_Init ( &hfdcan2 );
	if ( HALRes != HAL_OK ) {
		__NOP();
	}
	/************************
	*        Filters        *
	************************/
	
	FDCAN_FilterTypeDef FDCanFilter;
	
	/* Configure Rx filter */
	FDCanFilter.IdType = FDCAN_STANDARD_ID;
	FDCanFilter.FilterIndex = 0;
	FDCanFilter.FilterType = FDCAN_FILTER_MASK;
	FDCanFilter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
	FDCanFilter.FilterID2 = 0x7FF;
	
	// FILTER FDCAN1
	FDCanFilter.FilterID1 = 0x321;
	HALRes = HAL_FDCAN_ConfigFilter ( &hfdcan1 , &FDCanFilter );
	if ( HALRes != HAL_OK ) {
		__NOP();
	}
	/* Configure global filter to reject all non-matching frames */
	HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
	
	// FILTER FDCAN2
	FDCanFilter.FilterID1 = 0x322;
	HALRes = HAL_FDCAN_ConfigFilter ( &hfdcan2 , &FDCanFilter );
	if ( HALRes != HAL_OK ) {
		__NOP();
	}
	/* Configure global filter to reject all non-matching frames */
	HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
	
	
	/************************
	*        Start         *
	************************/
	
	HALRes = HAL_FDCAN_Start ( &hfdcan1 );
	if ( HALRes != HAL_OK ) {
		__NOP();
	}
	
	HALRes = HAL_FDCAN_Start ( &hfdcan2 );
	if ( HALRes != HAL_OK ) {
		__NOP();
	}
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// INIT COMPLETE
	// INFINITE LOOP
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	while(1)
	{
	FDCAN_TxHeaderTypeDef TxHeader;
	FDCAN_RxHeaderTypeDef RxHeader;
	uint8_t TxData[8];
	uint8_t RxData[8];
	
		/* Configure Tx buffer message */
		TxHeader.Identifier = 0x322;			//filter for fdcan2
		TxHeader.IdType = FDCAN_STANDARD_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;
		TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
		TxHeader.MessageMarker = 0;
	
		for(uint8_t i=0 ; i<num_of_packets ;i++){
			TxData[0] = i;
			TxData[1] = i;
			TxData[2] = i;
			TxData[3] = i;
			TxData[4] = i;
			TxData[5] = i;
			TxData[6] = i;
			TxData[7] = i;
 
			/* Add message to Tx FIFO */
			HALRes = HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData);
 
			if(HALRes){
				__NOP();//breakpoint  --> Tx error
			}
		}
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
		/* Wait for messages received */
//    	do{
//    		nOfRxPkts = HAL_FDCAN_GetRxFifoFillLevel(&hfdcan2, FDCAN_RX_FIFO0);
//    	}while (nOfRxPkts < num_of_packets);
		HAL_Delay(50);
	
		for(uint8_t i=0 ; i<num_of_packets ; i++){
			/* Retrieve message from Rx FIFO 0 */
			HALRes = HAL_FDCAN_GetRxMessage(&hfdcan2, FDCAN_RX_FIFO0, &RxHeader, RxData);
	
			if(HALRes)
			{
				__NOP();//breakpoint --> hfdcan2.ErrorCode == HAL_FDCAN_ERROR_FIFO_EMPTY	((uint32_t)0x00000100U)
			}
			else
			{
				// CHECK RECEIVED PACKETS
				for(uint8_t j=0 ; j<8 ; j++){
					if (RxData[j] != i) {
						HwWriteLedSxRedDS2(1);//breakpoint --> CORRUPTED PACKET
					}
				}
			}
	
		}
	
	
		//CANCEL RxData
		for(uint8_t j=0 ; j<8 ; j++){
			RxData[j] = 0;
		}
	}
}

0 REPLIES 0