cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN (Classic, Normal) STM32H753 STM32CubeMX HAL

Jack3
Senior II

I am new to FDCAN on STM32H7.

Using STM32H753VIT6, STM32CubeMX , and HAL, I configured both FDCAN1 (master) and FDCAN2 (slave) at 250 kbps, and all seems to work fine.

To check it, I used a MicroChip CAN Bus Analyzer Tool (BTW a very limited and buggy product, but not expensive).

I calculated the nominal bit time for 250kbps, which should be 4uS.

  

This is how configured it. I switched the FDCAN clock to PLL2Q which I have set to 80, to get a clock of 10MHz.

PeriphClkInitStruct.PLL2.PLL2Q = 80;    // fdcan_ker_ck = 800MHz / 80 = 10MHz
PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL2;

Then I configured values in the function MX_FDCAN1_Init.

 My calculations:

* Bit time configuration:
 * ************************
 * Bit time parameter         | Nominal      | Data
 * ---------------------------|--------------|------------------
 * fdcan_ker_ck               | 10 MHz       | 10 MHz
 * Time_quantum (tq)          | 100 ns       | 100 ns
 * Synchronization_segment    | 1 tq         | 1 tq
 * Propagation_segment        | 23 tq        | 23 tq
 * Phase_segment_1            | 8 tq         | 8 tq
 * Phase_segment_2            | 8 tq         | 8 tq
 * Synchronization_Jump_width | 8 tq         | 8 tq
 * Sample (80%)               | 32 tq        | 32 tq
 * Bit_length                 | 40 tq = 4 µs | 40 tq = 4 µs
 * Bit_rate                   | 250 kBit/s   | 250 kBit/s

 Some of the important values: 

/* Specifies the value by which the oscillator frequency is
   * divided for generating the nominal bit time quanta.
   * This parameter must be a number between 1 and 512
   * 800MHz / PLL2@80 = 10MHz / 250kHz = 40
   */
  hfdcan1.Init.NominalPrescaler = 1;          /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
 
  /* Specifies the maximum number of time quanta the FDCAN
   * hardware is allowed to lengthen or shorten a bit to perform
   * re-synchronization.
   * This parameter must be a number between 1 and 128
   */
  hfdcan1.Init.NominalSyncJumpWidth = 0x08;
 
  /* Specifies the number of time quanta in Bit Segment 1.
   * This parameter must be a number between 2 and 256
   */
  hfdcan1.Init.NominalTimeSeg1 = 31;        /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
 
  /* Specifies the number of time quanta in Bit Segment 2.
   * This parameter must be a number between 2 and 128
   */
  hfdcan1.Init.NominalTimeSeg2 = 8;
 
  /* Specifies the value by which the oscillator frequency is
   * divided for generating the data bit time quanta.
   * This parameter must be a number between 1 and 32
   */
  hfdcan1.Init.DataPrescaler = 1;
 
  /* Specifies the maximum number of time quanta the FDCAN
   * hardware is allowed to lengthen or shorten a data bit to
   * perform re-synchronization.
   * This parameter must be a number between 1 and 16
   */
  hfdcan1.Init.DataSyncJumpWidth = 0x08;
 
  /* Specifies the number of time quanta in Data Bit Segment 1.
   * This parameter must be a number between 1 and 32
   */
  hfdcan1.Init.DataTimeSeg1 = 31;
 
  /* Specifies the number of time quanta in Data Bit Segment 2.
   * This parameter must be a number between 1 and 16
   */
  hfdcan1.Init.DataTimeSeg2 = 8;

I am not sure DataPrescaler is the same as NominalPrescaler, and same for DataTimeSeg1 = NominalTimeSeg1 and DataTimeSeg2 = DataTimeSeg1. But all works.

I transmit a message using the following code:

uint8_t ubKeyNumber = 0x0;
FDCAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
FDCAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8];
 
void dmc_canbus_transmit_1(void)
{
  /* Prepare Tx Header */
  TxHeader.Identifier = 0x321;
  TxHeader.IdType = FDCAN_EXTENDED_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;
 
  /* Set the data to be transmitted */
  TxData[0] = ubKeyNumber++;
  TxData[1] = 0xAD;
  TxData[2] = 0xDE;
  TxData[3] = 0xAD;
  TxData[4] = 0xBE;
  TxData[5] = 0xEF;
  TxData[6] = 0xFA;
  TxData[7] = 0xCE;
 
  /* Start the Transmission process */
  dmc_puts("HAL_FDCAN_AddMessageToTxFifoQ: ");
  if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK)
  {
    /* Transmission request Error */
    Error_Handler();
  }
}
 
 
// This function is called after  MX_FDCAN1_Init(); to configure the filter
void dmc_canbus_init_1(void)
{
//  FDCAN_FilterTypeDef sFilterConfig;
 
//  /* Configure Rx filter */
//  sFilterConfig.IdType = FDCAN_EXTENDED_ID;
//  sFilterConfig.FilterIndex = 0;
//  sFilterConfig.FilterType = FDCAN_FILTER_MASK;
//  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
//  sFilterConfig.FilterID1 = 0x321;
//  sFilterConfig.FilterID2 = 0x1FFFFFFF;
//  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
//  {
//    /* Filter configuration Error */
//    Error_Handler();
//  }
 
  /* Configure global filter to reject all non-matching frames */
//  HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
 
  /* Start the FDCAN module */
  if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
  {
    /* Start Error */
    Error_Handler();
  }
 
  if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }
}

When I use the out-commented filtering, the hardware filtering does not seem to work, I will not receive data.

If using it, in MX_FDCAN1_Init I also specify

  hfdcan1.Init.ExtFiltersNbr = 1;

What can be the problem?

Any help would be appreciated.

0 REPLIES 0