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?
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 !
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.
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
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.
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.