cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H757-EVAL doesn't work at FDCAN_MODE_NORMAL

PCape.1
Associate

Hello everyone, I am working on our project based on STM32H757I-EVAL board (or NUCLEO-H755ZI-Q). I have already tested several parts that we expect to use Ethernet, UART, I2C, IOs, LCD, LEDs, etc. I have troubles with LwIP TCP/IP stack and finally I use CycloneTCP stack with a success. Last problem is CAN 2.0A communication at FDCAN1.

I was starting with FDCAN_Classic_Frame_Networking example for STM32HT43I-EVAL and adopted to our STM32H757I-EVAL board. The communication works well in a mode set to FDCAN_MODE_EXTERNAL_LOOPBACK and doesn't work in FDCAN_MODE_NORMAL. FDCAN parameters are set for 500 kbps (fdcan_ker_ck to 40 MHz, CPU M7 clock to 400 MHz, AXI and AHB clocks to 200 MHz and finally APB clocks to 100 MHz). The code is same for both modes except one parameter hfdcan.Init.Mode.

  • FDCAN_MODE_EXTERNAL_LOOPBACK works well:
    •    I think TX-RX delay is low about 70 ns (see 01TransitionDelay = 70ns.png and 10TransitionDelay = 70ns.png).
    •    SOF and arbitration with ID 0x555 is OK (see SOF+Arbitration ID=0x555.png) and the bit length 2us is OK.
    •    Complete CAN frame sent by CAN unit is OK (see Complete CAN Frame - OK.png) and also last ACK dominant bit sent by USB-CAN adapter is OK.
    •    The frames are acknowledged and logged by USB-CAN adapter (see FDCAN_MODE_EXTERNAL_LOOPBACK Log - OK.png).
    •    There is no error in an SFR FDCAN_PSR.LEC during debugging.
    •    LED2 is toggled after each reception of a valid frame (interrupt, callback and message filters are OK).

  • FDCAN_MODE_NORMAL doesn't work:
    •    First message sent after reset is SOF and probably signalisation of any error (17 dominant bits, see SOF+Error Flags - First message after reset.png). There is no arbitration, RTR, DLC, data, etc.
    •    Next messages is SOF and probably Passive Error Flag (6 recessive bits, sent by CAN unit ?) followed by Active Error Flag (6 dominant bits sent by USB-CAN adapter) (see SOF+Error Flags - following messages after first one.png).
    •    USB-CAN adapter doesn't log any valid message, only registered errors (see FDCAN_MODE_NORMAL Log - NOK.png).
    •    There is Error0Bit, 5 (101b) in the SFR FDCAN_PSR.LEC during debugging. Detailed description is at the page 2713 in a ST reference manual RM0399 Rev 3.

I was checking CAN point to point profibus cable, 2x 120 Ohm termination resistors, transceiver MCP2562FD and also verified all relevant parameters with ST documentation (clocks, bit time segments, filters, TX/RX pin settings).

I am using STMCubeIDE 1.7.0 and STM32Cube_FW_H7_V1.9.0.

Similar problem was reported in a question https://community.st.com/s/question/0D53W00000j5m6SSAQ/stm32-can-bus-not-sending-the-messages but finally with no solution :(

Any solution or advice will be very appreciate.

Best regards

Capek

void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan)
{
  GPIO_InitTypeDef  GPIO_InitStruct;
  
  RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  FDCANx_TX_GPIO_CLK_ENABLE();
  FDCANx_RX_GPIO_CLK_ENABLE();
  
  /* Select PLL1Q as source of FDCANx clock */
  RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
  RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
  HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
  
  /* Enable FDCANx clock */
  FDCANx_CLK_ENABLE();
  
  /*##-2- Configure peripheral GPIO ##########################################*/
  /* FDCANx TX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = FDCANx_TX_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = FDCANx_TX_AF;
  HAL_GPIO_Init(FDCANx_TX_GPIO_PORT, &GPIO_InitStruct);
  
  /* FDCANx RX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = FDCANx_RX_PIN;
  GPIO_InitStruct.Alternate = FDCANx_RX_AF;
  HAL_GPIO_Init(FDCANx_RX_GPIO_PORT, &GPIO_InitStruct);
  
  /*##-3- Configure the NVIC #################################################*/   
  /* NVIC for FDCANx */
  HAL_NVIC_SetPriority(FDCANx_IRQn, 0, 0); // bylo 0, 1, někde je 5, 0
  HAL_NVIC_EnableIRQ(FDCANx_IRQn);
}
static void FDCAN_Config(void)
{
  FDCAN_FilterTypeDef sFilterConfig;
  //FDCAN_ClkCalUnitTypeDef sCcuConfig;
 
  /* Bit time configuration:
    fdcan_ker_ck               = 40 MHz
    Data_prescaler             = 2
    Time_quantum (tq)          = 50 ns
    Synchronization_segment    = 1 tq
    Propagation_segment        = 23 tq
    Phase_segment_1            = 8 tq
    Phase_segment_2            = 8 tq
    Synchronization_Jump_width = 4 tq
    Bit_length                 = 40 tq = 2 µs
    Bit_rate                   = 500 kBit/s
  */
  hfdcan.Instance = FDCANx;
  hfdcan.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan.Init.Mode = FDCAN_MODE_NORMAL; // FDCAN_MODE_NORMAL , FDCAN_MODE_EXTERNAL_LOOPBACK
  hfdcan.Init.AutoRetransmission = DISABLE;
  hfdcan.Init.TransmitPause = DISABLE;
  hfdcan.Init.ProtocolException = ENABLE;
  hfdcan.Init.NominalPrescaler = 2; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
  hfdcan.Init.NominalSyncJumpWidth = 4; // 0x8 is wrong, max. is 4
  hfdcan.Init.NominalTimeSeg1 = 31; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
  hfdcan.Init.NominalTimeSeg2 = 8;
  hfdcan.Init.DataPrescaler = hfdcan.Init.NominalPrescaler;
  hfdcan.Init.DataSyncJumpWidth = hfdcan.Init.NominalSyncJumpWidth;
  hfdcan.Init.DataTimeSeg1 = hfdcan.Init.NominalTimeSeg1;
  hfdcan.Init.DataTimeSeg2 = hfdcan.Init.NominalTimeSeg2;
  hfdcan.Init.MessageRAMOffset = 0;
  hfdcan.Init.StdFiltersNbr = 1;
  hfdcan.Init.ExtFiltersNbr = 0;
  hfdcan.Init.RxFifo0ElmtsNbr = 10; // was 1
  hfdcan.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
  hfdcan.Init.RxFifo1ElmtsNbr = 0;
  hfdcan.Init.RxBuffersNbr = 0;
  hfdcan.Init.TxEventsNbr = 0;
  hfdcan.Init.TxBuffersNbr = 0;
  hfdcan.Init.TxFifoQueueElmtsNbr = 10; // was 1
  hfdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan) != HAL_OK)
  {
      //Debug message
      TRACE_ERROR("FDCAN - Initialization Error!\r\n");
  }
 
  /*
  //Debug message
  TRACE_ERROR("FDCAN - GetClockCalibrationState %lu\r\n", HAL_FDCAN_GetClockCalibrationState(&hfdcan));
  sCcuConfig.ClockCalibration = FDCAN_CLOCK_CALIBRATION_DISABLE;
  sCcuConfig.ClockDivider = FDCAN_CLOCK_DIV1;
  if (HAL_FDCAN_ConfigClockCalibration(&hfdcan, &sCcuConfig) != HAL_OK)
  {
      //Debug message
      TRACE_ERROR("FDCAN - ConfigClockCalibration Error!\r\n");
  }
  */
 
  /* Configure Rx filter */
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; // bylo FDCAN_FILTER_TO_RXFIFO0, FDCAN_FILTER_DISABLE;
  sFilterConfig.FilterID1 = 0x555;
  sFilterConfig.FilterID2 = 0x7FF;
  if (HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig) != HAL_OK)
  {
      //Debug message
      TRACE_ERROR("FDCAN - Filter configuration Error!\r\n");
  }
 
  /* Configure global filter to reject all non-matching frames */
  HAL_FDCAN_ConfigGlobalFilter(&hfdcan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE); // bylo FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
 
  /* Start the FDCAN module */
  if (HAL_FDCAN_Start(&hfdcan) != HAL_OK)
  {
      //Debug message
      TRACE_ERROR("FDCAN - Failed start!\r\n");
  }
 
  if (HAL_FDCAN_ActivateNotification(&hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
      //Debug message
      TRACE_ERROR("FDCAN - Notification Error!\r\n");
  }
 
  /* Prepare Tx Header */
  TxHeader.Identifier = 0x555;
  TxHeader.IdType = FDCAN_STANDARD_ID;
  TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  TxHeader.DataLength = FDCAN_DLC_BYTES_2;
  TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
  TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
  TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
  TxHeader.MessageMarker = 0;
}
 
/**
  * @brief  Rx FIFO 0 callback.
  * @param  hfdcan: pointer to an FDCAN_HandleTypeDef structure that contains
  *         the configuration information for the specified FDCAN.
  * @param  RxFifo0ITs: indicates which Rx FIFO 0 interrupts are signalled.
  *                     This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts.
  * @retval None
  */
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
  if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
  {
    /* Retrieve Rx messages from RX FIFO0 */
    if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
    {
        //Debug message
        TRACE_ERROR("FDCAN - Reception Error!\r\n");
    }
 
    /* Display LEDx */
    if ((RxHeader.Identifier == 0x555) && (RxHeader.IdType == FDCAN_STANDARD_ID) && (RxHeader.DataLength == FDCAN_DLC_BYTES_2))
    {
      //LED_Display(RxData[0]);
      ubKeyNumber = RxData[0];
      BSP_LED_Toggle(LED2);
    }
 
    if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
    {
        //Debug message
        TRACE_ERROR("FDCAN - Notification Error!\r\n");
    }
  }
}
 

1 ACCEPTED SOLUTION

Accepted Solutions
PCape.1
Associate

Hello everyone, the problem was solved. There was missing JP2 jumper at STM32H757I-EVAL board for connecting RX signal at CAN transceiver to PA11 pin at MCU. It was my mistake.

Best regards

Capek

View solution in original post

1 REPLY 1
PCape.1
Associate

Hello everyone, the problem was solved. There was missing JP2 jumper at STM32H757I-EVAL board for connecting RX signal at CAN transceiver to PA11 pin at MCU. It was my mistake.

Best regards

Capek