cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750XBHX - CANFD Callback problem

sqwerize
Associate II

Hey, I have a problem with the callback for FDCAN1. I am sending frames through ucandevices converter but the callback for FIFO0 is not called. The frames are definitely arriving, I added a test FreeRTOS and a task to receive and send frames to CAN1 and it worked very well, frames were received and sent back to the bus.
I have NVIC interrupts set up, I fiddled with the clock for CANFD and speeds, also with no effect.

Is anyone able to help me?
I am sending my project as an attachment

16 REPLIES 16
Karl Yamashita
Lead II

 

Maybe your sample point could be an issue?  Try these values which is at 87%

KarlYamashita_0-1713404977482.png

 

You've already defined your variables as global. When you call HAL_FDCAN_GetRxMessage, the values are save into the local variables. The local variables inside the callback will get destroyed when it returns from the callback. The global variables won't get updated.

void HAL_FDCAN_RxFifo0MsgPendingCallback(FDCAN_HandleTypeDef *hfdcan)
{
	LED1_ON();
  if(hfdcan->Instance == FDCAN1)
  {
    // already defined as global
    //FDCAN_RxHeaderTypeDef RxHeader;
    //uint8_t RxData[8];

    // Pobierz ramkę
    if(HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
    {

    }
  }
}

 

You sure that the UCAN has the same baud rate of 100kbs?

 

SofLit
ST Employee

Hello,


I added a test FreeRTOS and a task to receive and send frames to CAN1 and it worked very well, frames were received and sent back to the bus.

I'm confused about this statement. You said that the callback is not called but you're receiving well the frames.

Could you please clarify this point?

Moreover, as I see from your clock configuration, FDCAN clock is provided by PLL1Q having the clock source HSI.

It's not recommended to use HSI for CAN/FDCAN communication. Use HSE with an external crystal instead.

PS: You are setting your bitrate at 100kb/s. Are you sure it's not 1Mb/s?

SofLit_0-1713439149778.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
SofLit
ST Employee

Another question came to my mind: are you using STM32H750B-DK board?

If yes, there is a discrepancy with your GPIOs settings: PB8/PB9 in CubeMx vs PH13/PH14 in the schematics.

SofLit_0-1713439742373.png

SofLit_0-1713439961006.png

PS: FDCAN2 GPIOs are correct.

 

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hello, I am using the ART-PI development board, I am sending the output schematic and documentation. I'll be back from work in 2 hours and I'll still try to change the configuration as my colleague above wrote, currently I'm at a loss.... I need to make a bridge between CAN1 and CAN2, the FreeRTOS task will not be a good solution here to transmit frames in real time. As I mentioned, such code in RTOS task works fine and I can receive and send back to the bus frames.... :(

@EDIT
@SofLit 
The canbus communication works, I can receive and send frames on the can bus, but only through the RTOS task or through the while() loop in the main class. I have a problem with the callback I am creating. It is not called despite the NVIC interrupt setting :(
I've been testing different speeds, ultimately I need to work on 500 kBit/s speed, because that's the bus I'll be plugging into in my BMW.

My RTOS task (this example is working):

void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN 5 */
  FDCAN_RxHeaderTypeDef RxHeader;
  uint8_t RxData[8];
  FDCAN_TxHeaderTypeDef TxHeader;
  uint8_t TxData[8];
  HAL_StatusTypeDef rxStatus;
 
  /* Infinite loop */
  for(;;)
  {
    
    rxStatus = HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, RxData);
 
    if(rxStatus == HAL_OK) {
      LED1_ON();
      printf("frame received: ID = 0x%X, DLC = %d, Data = ", RxHeader.Identifier, RxHeader.DataLength);
      for(int i = 0; i < 8; i++) {
        printf("0x%X ", RxData[i]);
    
        TxData[i] = RxData[i];
      }
      printf("\n");
 
      TxHeader.Identifier = RxHeader.Identifier; // Echo the same ID
      TxHeader.IdType = RxHeader.IdType;
      TxHeader.TxFrameType = FDCAN_DATA_FRAME;
      TxHeader.DataLength = RxHeader.DataLength;
      TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
      TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
      TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
      TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
      TxHeader.MessageMarker = 0;
 
 
      if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
      {
        // Obsługa błędów transmisji
        printf("Błąd wysyłania ramki!\n");
      }
  
  LED1_OFF();
    }
 
    osDelay(10); // Czas na przetwarzanie innych zadań
  }
  /* USER CODE END 5 */
}


I'm using TJA1050 from this site:
Transceiver CAN TJA1050 - Sklep msalamon

sqwerize
Associate II

I come back to you with answers. I have switched the clock for FDCAN to HSE, it is set to 25MHz.
I switched the prescaller and Time seg1, Time seg2 to as the colleague above wrote. This unfortunately had no effect. When debugging, HAL_FDCAN_ActivateNotification does not return errors. Sending to can works or receiving when I do it in the main while loop in the main() method.
In the HAL_FDCAN_RxFifo0MsgPendingCallback method I set the LED to light up as a signal that it has been called, no other operations there for the time being, as it makes no sense. I am sending in the attachment once again my project. The speed is scaled to 100kBit/s. I have UCAN set to 100k, so the speeds agree, besides I can see the frames sent by the stm32 from the while loop on it.

Hello,

System clock is not yet set to HSE (25MHz) in your latest attached project. Still set to HSI.

SofLit_0-1713454368462.png

+ You lost some user code from this latest version.

But I would understand more the case. So, let's summarize:

You are sending frames @100kb/s from a CAN node called "ucan" to FDCAN1 of your STM32H750 MCU.

The callback is not called (using interrupt) but when you are in polling mode (FreeRTOS / without interrupt) you are well receiving messages.

Could you please confirm?

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Suggestion:

Could you please make a very simple project no RTOS no other stuff and peripherals. Just FDCAN1 in loopback mode. So FDCAN1 will send receive his own frames.

Could you please do this test?

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

@SofLit wrote:

+ You lost some user code from this latest version.

But I would understand more the case. So, let's summarize:

You are sending frames @100kb/s from a CAN node called "ucan" to FDCAN1 of your STM32H750 MCU.

The callback is not called (using interrupt) but when you are in polling mode (FreeRTOS / without interrupt) you are well receiving messages.

Could you please confirm?

 


To begin with, I would like to confirm that, exactly that. In the FreeRTOS task, I can receive and send frames.



Now the funniest thing !
I rewrote the clock and inserted a method:
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
This method gets called!!! BUT... It gives me an error when trying to read a message from the FIFO.

I previously inserted the method, without the uint32_t RxFifo0ITs parameter:
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan)

sqwerize_0-1713458566846.pngsqwerize_1-1713458603404.png

/* Update error code */

hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;



sqwerize
Associate II

@SofLit  Problem solved!!! I don't know what I would have done without your help, in truth you have guided me to this solution.
I found in another topic on the forum information to add in the file stm32h7xx_hal_msp.c
HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn;)

Now the callback receives frames and sends back to the bus without any problems.

One more question, as I mentioned earlier.
I want to build a bridge between CAN1 and CAN2, I understand that for CAN1 I define FIFO0 and for CAN2 I define FIFO1 and based on the callback I transfer data between them, however, one thing bothers me that I am not completely familiar with.... Clock configuration and prescaller for 500kB/s. Can you help me still in this thread with the correct configuration of Prescaller, Time seg 1 and Time seg 2? I am very much asking...

 

void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

if(hfdcan->Instance==FDCAN1)

{

/* USER CODE BEGIN FDCAN1_MspInit 0 */

 

/* USER CODE END FDCAN1_MspInit 0 */

 

/** Initializes the peripherals clock

*/

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;

PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_HSE;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/* Peripheral clock enable */

__HAL_RCC_FDCAN_CLK_ENABLE();

 

__HAL_RCC_GPIOB_CLK_ENABLE();

/**FDCAN1 GPIO Configuration

PB9 ------> FDCAN1_TX

PB8 ------> FDCAN1_RX

*/

GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8;

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(GPIOB, &GPIO_InitStruct);

 

/* FDCAN1 interrupt Init */

HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 5, 0);

HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);

/* USER CODE BEGIN FDCAN1_MspInit 1 */

 

HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 5, 0);

HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);

/* USER CODE END FDCAN1_MspInit 1 */

}

 

}