FDCAN Support for STM32G474 Nucleo

Hello everyone, I’m working on a project using Mbed OS 6.2.1 and an STM32G474RE-Nucleo.

The board is listed as a target and Mbed compiles fine and works with the simple blinky example.

I’m trying to utilize CAN bus with this board, however when I attempt to compile anything related to CAN I end up with numerous errors. I think I’ve tracked this down to the board utilizing FDCAN instead of the traditional CAN used by STM32 boards.

So far I’ve added an override to mbed_app.json for “has can” which solved a few issues but I’m still having problems with can_api.c which i’ll show in the picture below…

Is there a different API for FDCAN, or something different I should be doing here? Or is it simply not supported yet?

I appreciate any help offered! Thanks!
Dan

Hi

Note first that FDCAN has been ported in MBED with STM32H7.
It has not been checked at all with STM32G4 yet.

I spoke with some ST CAN expert.
Seems that G4 FDCAN is the light version of STM32H7 FDCAN…
So it’s worth to try to remove lines that doesn’t compile and tests !

Jerome

Hello,

I’m currently also working on this and the removal of these lines makes the can useable.
Be aware of that the frequency of the fdcan-peripheral is hard coded in the can_api to 10MHz, while the normal PLLQ frequency is 170MHz.

You can manipulate the system_clock to set the PLLQ to 10MHz or, what I prefer, change the frequency in the can_api.c (in dir TARGET_STM)

I’m wondering, why this frequency is hard coded and changed it to be calculated like this:

In Function _can_init_freq_direct exchange
int ntq = 10000000 / hz;

with

    /** Calculate the fdcan clk value for accurate calculation of the quantum timing
     * !Attention Not all bitrates can be covered with all fdcan clk values. When a clk
     * does not work for the desired bitrate, change system_clock settings for PLLQ
     */
    int pll_source_clk;

    int pll_source = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC_Msk);
    if (pll_source == RCC_PLLCFGR_PLLSRC_HSE){
        pll_source_clk = HSE_VALUE;
    } else if (pll_source == RCC_PLLCFGR_PLLSRC_HSI){
        pll_source_clk = HSI_VALUE;
    } else {
        MBED_ERROR(
                MBED_MAKE_ERROR(MBED_MODULE_DRIVER_CAN, MBED_ERROR_CODE_CONFIG_UNSUPPORTED),
                "PLL source must be HSI or HSE");
    }

    int pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM_Msk) >> RCC_PLLCFGR_PLLM_Pos) + 1;
    int plln = (RCC->PLLCFGR & RCC_PLLCFGR_PLLN_Msk) >> RCC_PLLCFGR_PLLN_Pos;
    int pllq = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ_Msk) >> RCC_PLLCFGR_PLLQ_Pos) + 1;
    pllq = pllq * 2;
    int fdcan_freq = ((pll_source_clk / pllm) * plln) / pllq;

    int ntq = fdcan_freq/ hz;

This enables the Classic Can, there is no support for real FDCAN as far as I’m aware of.

Greetings,
Martin.

Thanks for the info to both of you.

I was able to get it to compile by commenting out the lines in can_api.c that had errors.

I couldn’t get the frequency code working that you posted Martin, I may have missed something though so will look again after I take a break.

However, I was able to get FDCAN1 and FDCAN2 both working at the same time by hard-coding the bit timings and whatnot in can_api.c to values I had used previously that worked in stm32cubeide.

Just for reference, the values I used… They may not be perfect, but they worked for 500kbit.
FDCAN Frequency default of 170mhz
Baud Rate: 500k
NominalPrescaler = 20
NominalTimeSeg1 = 14
NominalTimeSeg2 = 2
NominalSyncJumpWidth = 1

Hey, happy that you made it work.

Not so happy, that my solution did not work for you. Some points to notice:

The assumed configuration for my code is no further changes in the can_api, so the prescaler is fixed to 1, the sample-point is 75%. The SJW and the TSEG2 are the same. This could be improved obviously, but I didn’t want to make to big changes.

From what I can tell, your configuration has a different sample-point and a (slightly) different sjw.

My setup is a socketcan with default sample-point connected to the nucleo-board. I tested it with a clock frequency of 170 MHz and 500k and it worked, so the configuration is ok in theory.

Hi
I would be happy to review and accept a mbed-os pull request from you enabling CAN in STM32G4!

Regards,
Jerome

I’m still new to all of this including using git for things much outside of git clone. Learning slowly and have set up a local git server so that i can learn without messing anyone elses projects up haha.

Martins work above will probably work, I’m sure i screwed something up on my end modifying the mbed library.

I’m using a website that calculates the bit timing for different speeds and such to derive the values. http://www.bittiming.can-wiki.info/ is the site. It doesn’t have an option for FDCAN, so I’ve been using BXCAN with success. I need to use my scope to see what the signals look like still.

I apologize, I’m pretty new to all of the programming side of things.

1 Like

Hello Jerome,

I added my changes and opened a pull request (#13565). This is my first one in this project, I would be thankful for advise.

With best regards,
Martin.