2022-03-28 3:15 AM
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;
		}
	}
}