cancel
Showing results for 
Search instead for 
Did you mean: 

help! FDCAN does not work in STM32H503.

HKim.23
Associate III

Dear, 

FDCAN does not work.

Please advise if there is any problem in the entire code below.

The set clock of FDCAN is 48Mhz and each setting is as follows.


_legacyfs_online_stmicro_images_0693W00000bi15kQAA.pngWhen the code is executed, Tx is transmitted once every 4 seconds in the while loop.

However, if Tx is entered about 4 times, it always falls into Error_Handler.

Error returns Error at the bottom of HAL_FDCAN_AddMessageToTxFifoQ function.

HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,
 
                        const uint8_t *pTxData)
 
{
 
///////////////////////////////////////////// Skip
 
 if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
 
 {
 
  /* Check that the Tx FIFO/Queue is not full */
 
  if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
 
  {
 
   /* Update error code */
 
   hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;
 
 
 
   return HAL_ERROR;
 
  }
 
///////////////////////////////////////////// Skip
 
}
 

Another important clue is that if you change just one line of frameformat to FDCAN_FRAME_CLASSIC in the entire code, it will operate normally with CAN2.0 (not FDCAN).

hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; -----------> hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;

Important main code is attached.

FDCAN_HandleTypeDef hfdcan1;
 
FDCAN_FilterTypeDef sFilterConfig;
FDCAN_TxHeaderTypeDef TxHeader;
FDCAN_RxHeaderTypeDef RxHeader;
 
uint32_t test_led_timer = 0;
uint8_t TxData[12];
uint8_t RxData[12];
 
int main(void)
{
  HAL_Init();
 
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_FDCAN1_Init();
    uint32_t fdcan_tx_interval_timer = HAL_GetTick();
 
    sFilterConfig.IdType = FDCAN_STANDARD_ID;
    sFilterConfig.FilterIndex = 0;
    sFilterConfig.FilterType = FDCAN_FILTER_MASK;
    sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
    sFilterConfig.FilterID1 = 0x200;
    if(HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
    {
        Error_Handler();
    }
 
    HAL_UARTEx_ReceiveToIdle_IT(&huart2, &Rxch, 1);
 
    //TxHeader.Identifier = 0x1AFAFA00;
    TxHeader.Identifier = 0x100;
    TxHeader.IdType = FDCAN_STANDARD_ID;
    TxHeader.TxFrameType = FDCAN_DATA_FRAME;
    TxHeader.DataLength = FDCAN_DLC_BYTES_12; //FDCAN_DLC_BYTES_48
    TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
    TxHeader.BitRateSwitch = FDCAN_BRS_ON;
    TxHeader.FDFormat = FDCAN_FD_CAN;
    TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
    TxHeader.MessageMarker = 0X00; // Ignore because FDCAN_NO_TX_EVENTS
 
    if(HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
    {
        Error_Handler();
    }
 
    while (1)
    {
        static int indx = 0;
        if((HAL_GetTick() - test_led_timer) > 2000)
        {
            test_led_timer = HAL_GetTick();
            HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
            HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
        }
 
        /* Send Tx FDCAN module */
        if((HAL_GetTick() - fdcan_tx_interval_timer) > 4000)
        {
            fdcan_tx_interval_timer = HAL_GetTick();
            memset(TxData, 0, sizeof(TxData));
            sprintf(TxData, "FDCAN1TX");
            
            if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
            {
                ////!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Errorr occureed .............
                Error_Handler();
            }
        }
    
  }
}
 
 
static void MX_FDCAN1_Init(void)
{
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = ENABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 1;
  hfdcan1.Init.NominalSyncJumpWidth = 12;
  hfdcan1.Init.NominalTimeSeg1 = 83;
  hfdcan1.Init.NominalTimeSeg2 = 12;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 11;
  hfdcan1.Init.DataTimeSeg1 = 12;
  hfdcan1.Init.DataTimeSeg2 = 11;
  hfdcan1.Init.StdFiltersNbr = 1;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
 
}

1 ACCEPTED SOLUTION

Accepted Solutions
LCE
Principal

Not sure if I remember the following correctly from H7 FDCAN:

I think the TX FIFO can hold 4 messages.

The TX FIFO auto-clears with certain settings only if it receives an ACK from any receiver.

So, you sure that the receiver supports bit rate switching at 2 MHz?

If not -> no ACK -> TX FIFO full after 4 messages

View solution in original post

3 REPLIES 3
LCE
Principal

Not sure if I remember the following correctly from H7 FDCAN:

I think the TX FIFO can hold 4 messages.

The TX FIFO auto-clears with certain settings only if it receives an ACK from any receiver.

So, you sure that the receiver supports bit rate switching at 2 MHz?

If not -> no ACK -> TX FIFO full after 4 messages

HKim.23
Associate III

Thank you for your reply.

There was no problem with the code I posted.

However, the message about TX FIFO full was ignored.

And the problem of not reading the message properly was that the CAN analyzer I used had a problem reading CANFD.

That's what I said. :D