Skip to main content
Jack3
Senior
June 12, 2019
Question

FDCAN (Classic, Normal) STM32H753 STM32CubeMX HAL

  • June 12, 2019
  • 0 replies
  • 1126 views

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.

This topic has been closed for replies.