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