cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN not receiving any messages (no ACK?)

csdominik
Associate III

Dear all,

I am working on FDCAN with Nucleo STM32G474RE. And I cannot receive any messages...

Unfortunately I cannot find any examples for this board.

I am able to send messages from the board and receive it on PCAN tool.

Unfortunately when I send message from PCAN to the board I get bus-off error.

Also software is not entering the rx function breakpoint (polled every 4ms).

CAN settings: 24MHz, 500kBit/s, Prescaler 3, tseg1 = 13, tseg2 = 2, syncjump = 1.

I am using HSE 24MHz available on the board for FDCAN - settings are the same.

I have configured FDCAN in CubeMX (using Version: 1.1.0 Build: 4551_20191014-1140 (UTC)).

The configuration is as follows.

/* FDCAN1 init function */
void MX_FDCAN1_Init(void)
{
 
  hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = ENABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 3;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 13;
  hfdcan1.Init.NominalTimeSeg2 = 2;
  hfdcan1.Init.DataPrescaler = 3;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 13;
  hfdcan1.Init.DataTimeSeg2 = 2;
  hfdcan1.Init.StdFiltersNbr = 1;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcanHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(fdcanHandle->Instance==FDCAN1)
  {
  /* USER CODE BEGIN FDCAN1_MspInit 0 */
 
  /* USER CODE END FDCAN1_MspInit 0 */
    /* FDCAN1 clock enable */
    __HAL_RCC_FDCAN_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**FDCAN1 GPIO Configuration    
    PA11     ------> FDCAN1_RX
    PA12     ------> FDCAN1_TX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /* USER CODE BEGIN FDCAN1_MspInit 1 */
 
  /* USER CODE END FDCAN1_MspInit 1 */
  }
}

The additional can_comm_init() is providing the filter settings and configuring the global filter.

void can_comm_init(void)
{
    /* Configure Rx filter */
 
    FDCAN_FilterTypeDef filterSettings;
    HAL_StatusTypeDef sts;
 
    filterSettings.IdType = FDCAN_STANDARD_ID;
    filterSettings.FilterIndex = 0;
    filterSettings.FilterType = FDCAN_FILTER_MASK;
    filterSettings.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
    filterSettings.FilterID1 = 0x111;
    filterSettings.FilterID2 = 0x700;
    sts = HAL_FDCAN_ConfigFilter(&hfdcan1, &filterSettings);
    if(sts != HAL_OK)
    {
        __NOP();
    }
 
    /* Configure global filter to reject all non-matching frames */
    sts = HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
    if(sts != HAL_OK)
    {
        __NOP();
    }
 
    sts = HAL_FDCAN_Start(&hfdcan1);
    if (sts != HAL_OK)
    {
        __NOP();
    }
}

In periodic function I am polling the rx fifo and trying to get message (not entering break point ever):

void can_comm_rx_handler(void)
{
    FDCAN_RxHeaderTypeDef header;
    uint8_t aData[20];
    volatile uint32_t eId = 0;
    volatile uint32_t sId = 0;
 
    if (HAL_FDCAN_GetRxFifoFillLevel(&hfdcan1, FDCAN_RX_FIFO0) > 0)
    {
        HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &header, &aData[0]);
        __NOP();
        eId = header.IdType;
        sId = header.Identifier;
    }
}

I have tried redirecting messages filtered by global filter to RXFIFO1. Unfortunately no success.

Can I have any advise what am I doing wrong?

Kind regards

Dominik

1 ACCEPTED SOLUTION

Accepted Solutions
csdominik
Associate III

The problem was in the CAN filtering and protection circuit and not software...

I have removed few component from the board and sw started working!

This might be reused as working sw example for STM32G4.

Topic closed.

View solution in original post

5 REPLIES 5
csdominik
Associate III

I can add that Internal and external loopback is working.

I am using MCP2551 transceiver.

csdominik
Associate III

The other news is that if using 2 Nucleo STM32G474RE boards connected via CAN (both use MCP2551) the messages are send and received correctly.

This works because I have the same configuration for both Nucleos. SO the HW part looks good, and the problem must be somewhere in the timing...

Still not able to receive message from the other device / PCAN.

Using this code to send message:

void can_comm_tx_handler(void)
{
 
    FDCAN_TxHeaderTypeDef TxMessage;
    uint8_t aData[4] = { 0 };
    //uint32_t usedMailbox = 0;
    static uint32_t successcnt = 0;
    uint32_t ret = 0;
    static uint8_t cnt = 0;
    static volatile uint8_t tx_enable = 1;
 
    if (tx_enable == 1)
    {
        TxMessage.Identifier = 0x124;
        TxMessage.IdType = FDCAN_STANDARD_ID; /* Standard ID *//* FDCAN_EXTENDED_ID? */
        TxMessage.TxFrameType = FDCAN_DATA_FRAME; /* Data Frame, not remote frame */
        TxMessage.DataLength = FDCAN_DLC_BYTES_4; /* 4 Bytes of Data */
        TxMessage.ErrorStateIndicator = FDCAN_ESI_PASSIVE; /* Error passive */
        TxMessage.BitRateSwitch = FDCAN_BRS_OFF; /* Rate switch Off */
        TxMessage.FDFormat = FDCAN_CLASSIC_CAN; /* Classic CAN, not FD_CAN */
        TxMessage.TxEventFifoControl = FDCAN_NO_TX_EVENTS; /* Do not store Tx events */
        TxMessage.MessageMarker = 0; /* Tx marker (event) not tracked */
 
        cnt++;
        aData[0] = 0x12;
        aData[1] = cnt;
        aData[2] = cnt;
        aData[3] = 0x78;
 
        if (HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) > 0)
        {
            HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxMessage, &aData[0]);
            successcnt++;
        }
        else
        {
            __NOP();
            ret = HAL_FDCAN_IsTxBufferMessagePending(&hfdcan1,
            FDCAN_TX_BUFFER0); //hfdcan, TxBufferIndex)
            if (ret > 0)
                HAL_FDCAN_AbortTxRequest(&hfdcan1, FDCAN_TX_BUFFER0);
        {
}

csdominik
Associate III

The problem was in the CAN filtering and protection circuit and not software...

I have removed few component from the board and sw started working!

This might be reused as working sw example for STM32G4.

Topic closed.

Thanks for coming back with the solution.

Please select your post as Best, so that the thread is marked as resolved.

JW

JBere
Associate II

Hi,

Working with G474, having same configuration as you have, and working with Internal and External Loopback, but not receiving ACK (ErrorCode), when configured in Normal Mode, could you detail changes in hardware or filter part, please.