0
\$\begingroup\$

I have a source of can messages connected to the SN65HVD232D CAN controller, which is then wired to a NUCLEO-G431KB via the FDCAN1 TX and RX pins. I confirmed with an oscilloscope/digital decoder that the transceiver does indeed output valid CAN messages, but the interrupt never triggers. This is the setup I use in an attempt to receive classic CAN messages using the hardware I have:

enter image description here

These are the settings in STM32CubeMX:

enter image description here

This is the code these settings generate in the form of an init function that is called in the init section for those who don't use the "wizard", but still use the STM32 HAL:

hfdcan1.Instance = FDCAN1;
  hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV24;
  hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  hfdcan1.Init.AutoRetransmission = DISABLE;
  hfdcan1.Init.TransmitPause = DISABLE;
  hfdcan1.Init.ProtocolException = DISABLE;
  hfdcan1.Init.NominalPrescaler = 1;
  hfdcan1.Init.NominalSyncJumpWidth = 1;
  hfdcan1.Init.NominalTimeSeg1 = 2;
  hfdcan1.Init.NominalTimeSeg2 = 2;
  hfdcan1.Init.DataPrescaler = 1;
  hfdcan1.Init.DataSyncJumpWidth = 1;
  hfdcan1.Init.DataTimeSeg1 = 1;
  hfdcan1.Init.DataTimeSeg2 = 1;
  hfdcan1.Init.StdFiltersNbr = 0;
  hfdcan1.Init.ExtFiltersNbr = 0;
  hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_QUEUE_OPERATION;
  if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }

I then initialize the filters that should allow every packet to get through (which doesn't print any errors):

FDCAN_FilterTypeDef sFilterConfig;
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_RANGE;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0;
sFilterConfig.FilterID2 = 0x1FFFFFFF;

if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK) {
    /* Filter configuration Error */
    printf("[CAN] Unable to configure!\n");
}

if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK) {
    /* Start Error */
    printf("[CAN] Unable to start!\n");
}

if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) {
    /* Notification Error */
    printf("[CAN] Unable to activate the CAN interrupt!\n");
}

As well as the interrupt function with a simple breakpoint (in Keil) to indicate any interrupt calls:

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) {
  __breakpoint(0);
}

From what I've read in the brief FDCAN peripheral overview by ST, there should be no problem receiving CAN 2.0 packets, yet my attempts don't seem to yield any results. Any help would be greatly appreciated!

\$\endgroup\$
2
  • \$\begingroup\$ Where's your baudrate setup? You need to know the CAN bus speed and microcontroller bus speed in order to correctly set timing parameters. \$\endgroup\$
    – Ben Voigt
    May 24, 2022 at 20:28
  • \$\begingroup\$ Thank you @BenVoigt. This is the first time I'm working with CAN so I wasn't sure which parameters are important, but yes, setting the correct timing is probably what will fix my issue. I'll try it later and if successful report here for others that might have a similar issue. \$\endgroup\$ May 25, 2022 at 9:03

2 Answers 2

0
\$\begingroup\$

The solution was to simply set the correct timings. In case anyone else comes across this thread, you can use http://www.bittiming.can-wiki.info/ for CAN messages and https://www.kvaser.com/support/calculators/can-fd-bit-timing-calculator/ to easily calculate FD CAN timings.

\$\endgroup\$
0
\$\begingroup\$

To add to your solution (yes the bit timings have to be correct first);

You initialise the CAN peripheral to have 0 filters:

  hfdcan1.Init.StdFiltersNbr = 0;
  hfdcan1.Init.ExtFiltersNbr = 0;

Then set up a filter:

FDCAN_FilterTypeDef sFilterConfig;
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_RANGE;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0;
sFilterConfig.FilterID2 = 0x1FFFFFFF;

if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK) {
    /* Filter configuration Error */
    printf("[CAN] Unable to configure!\n");
}

Just a heads-up that if you do want to use filters at some point you will need to set the StdFiltersNbr to 1 (or more, depending how many filters you add) and also add a call to configure the global filter:

HAL_FDCAN_ConfigGlobalFilter(prv_hcan_pt, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.