cancel
Showing results for 
Search instead for 
Did you mean: 

Extended CANBUS example L4 or H7

Linas L
Senior II

Hello,

In my project I must use extended CANBUS protocol on STM32L496 and STM32H743 microcontrollers.

Does any one have example how to use it ? None on STM examples comes with extended canbus demo, googling also did not give any results.

I have working setup for regular canbus

Any examples would be welcome !

Thank you

3 REPLIES 3
Kraal
Senior III

Hi,

Please show us some actual code as a first step to help you.

Can you tell us what do you mean by "extended CAN bus protocol" ?

Best regards.

It is 2.0B Version. Nearly all examples or projects on the internet use 2.0A version.

Its extended address space can bus protocol.

This is typical 2.0A implementation:

FDCAN_HandleTypeDef hfdcan;
FDCAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
FDCAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8];
 
 
static void FDCAN_Config(void)
{
  FDCAN_FilterTypeDef sFilterConfig;
 
  /* Bit time configuration:
    fdcan_ker_ck               = 40 MHz
    Time_quantum (tq)          = 25 ns
    Synchronization_segment    = 1 tq
    Propagation_segment        = 23 tq
    Phase_segment_1            = 8 tq
    Phase_segment_2            = 8 tq
    Synchronization_Jump_width = 8 tq
    Bit_length                 = 40 tq = 1 µs
    Bit_rate                   = 1 MBit/s
  */
  hfdcan.Instance = FDCANx;
  hfdcan.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan.Init.AutoRetransmission = DISABLE;
  hfdcan.Init.TransmitPause = DISABLE;
  hfdcan.Init.ProtocolException = ENABLE;
  hfdcan.Init.NominalPrescaler = 0x1; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
  hfdcan.Init.NominalSyncJumpWidth = 0x8;
  hfdcan.Init.NominalTimeSeg1 = 0x1F; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
  hfdcan.Init.NominalTimeSeg2 = 0x8;
  hfdcan.Init.MessageRAMOffset = 0;
  hfdcan.Init.StdFiltersNbr = 1;
  hfdcan.Init.ExtFiltersNbr = 0;
  hfdcan.Init.RxFifo0ElmtsNbr = 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 = 1;
  hfdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
  hfdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
  if (HAL_FDCAN_Init(&hfdcan) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
 
  /* Configure Rx filter */
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1 = 0x321;
  sFilterConfig.FilterID2 = 0x7FF;
  if (HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
    Error_Handler();
  }
 
  /* Start the FDCAN module */
  if (HAL_FDCAN_Start(&hfdcan) != HAL_OK)
  {
    /* Start Error */
    Error_Handler();
  }
 
  if (HAL_FDCAN_ActivateNotification(&hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
    /* Notification Error */
    Error_Handler();
  }
 
  /* Prepare Tx Header */
  TxHeader.Identifier = 0x321;
  TxHeader.IdType = FDCAN_STANDARD_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;
}
 
 
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
  if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
  {
    /* Retreive Rx messages from RX FIFO0 */
    if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
    {
    /* Reception Error */
    Error_Handler();
    }
 
    /* Display LEDx */
    if ((RxHeader.Identifier == 0x321) && (RxHeader.IdType == FDCAN_STANDARD_ID) && (RxHeader.DataLength == FDCAN_DLC_BYTES_2))
    {
     // LED_Display(RxData[0]);
      ubKeyNumber = RxData[0];
    }
 
    if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
    {
      /* Notification Error */
      Error_Handler();
    }
  }
}
 
#define FDCANx                      FDCAN1
#define FDCANx_CLK_ENABLE()         __HAL_RCC_FDCAN_CLK_ENABLE()
#define FDCANx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define FDCANx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
 
#define FDCANx_FORCE_RESET()   __HAL_RCC_FDCAN_FORCE_RESET()
#define FDCANx_RELEASE_RESET() __HAL_RCC_FDCAN_RELEASE_RESET()
 
/* Definition for FDCANx Pins */
#define FDCANx_TX_PIN       GPIO_PIN_9
#define FDCANx_TX_GPIO_PORT GPIOB
#define FDCANx_TX_AF        GPIO_AF9_FDCAN1
#define FDCANx_RX_PIN       GPIO_PIN_8
#define FDCANx_RX_GPIO_PORT GPIOB
#define FDCANx_RX_AF        GPIO_AF9_FDCAN1
 
/* Definition for FDCANx's NVIC IRQ and IRQ Handlers */
#define FDCANx_IRQn       FDCAN1_IT0_IRQn
#define FDCANx_IRQHandler FDCAN1_IT0_IRQHandler
 
 
 
 
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.Pull      = GPIO_PULLUP;
  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, 1);
  HAL_NVIC_EnableIRQ(FDCANx_IRQn);
}
 
void FDCANx_IRQHandler(void)
{
  HAL_FDCAN_IRQHandler(&hfdcan);
}

Great. So you want to use extended ID.

I'm not using HAL, but if your IDE is eclipse based (like Atollic TrueStudio or STM CubeIDE), you can CTRL+CLICK on any constant or variable and you will be redirected to its definition.

In your case I would CTRL+CLICK on FDCAN_STANDARD_ID (line 52 and 79) to see if FDCAN_EXTENDED_ID exists or not (I think it does). Replace all occurence of FDCAN_STANDARD_ID with its extended equivalent in the above code. Line 34 should be set to 0 (no standard ID filters) and line 35 to 1 (we want to filter the extended IDs).

The last step is too change the IDs to the actual value you want to use.

Best regards.