-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature stm32g4 can support #13565
Feature stm32g4 can support #13565
Conversation
- The FDCAN_clk is calculated on runtime from the according RCC-registers
@m-ecry, thank you for your changes. |
This shall be a patch update, I updated the type and the label. Thanks for the contribution. |
Jenkins CI Test : ❌ FAILEDBuild Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; | ||
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; | ||
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you decrease SystemCoreClock from 170 MHz to 160,
and you get PLLQ frequency at 80 MHz
Could you explain me again the reason ?
Thx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With a core frequency of 170MHz, many CAN-frequencies in my tests could not be setup correctly.
For example I worked at a frequency of 250k. With a core frequency of 170MHz this gave me:
Field | Calculated Value | Register Value |
---|---|---|
ntq1 | 510 (0x1FE) | 253 (0xfd) |
ntq2 | 169 (0xA9) | 40 (0x28) |
sjw | 169 (0xA9) | 40 (0x28) |
So the register could not store the value, the interface could not be setup properly.
The current limitation is the result of the api not using the prescaler (always at 1).
I propose to use the prescaler, calculated this way:
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN) / hz;
int nominalPrescaler = 1;
// !When the sample point should be lower than 50%, this must be changed to
// !IS_FDCAN_NOMINAL_TSEG2(ntq/nominalPrescaler), since
// NTSEG2 and SJW max values are lower. For now the sample point is fix @75%
while (!IS_FDCAN_NOMINAL_TSEG1(ntq/nominalPrescaler)){
nominalPrescaler ++;
if (!IS_FDCAN_NOMINAL_PRESCALER(nominalPrescaler)){
error("Could not determine good nominalPrescaler. Bad clock value\n");
}
}
ntq = ntq/nominalPrescaler;
See commit.
Still there can't be guaranteed, that the resulting timing is within tolerance, so this will still require manual adaptation when using a strange value.
Even with that a frequency of 170MHz caused many setups to fail, so I reduced it to 80MHz, which worked just fine for most (not all) of my test-configurations. Unfortunately I not record my tests properly, I can repeat and record them to show it better, if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx for details.
Maybe we could code like this:
#if DEVICE_CAN
PLLN = 80
#else
PLLN = 85
If you disable CAN, you keep the maximum capability ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That fine by me, I will add this with a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
targets/TARGET_STM/can_api.c
Outdated
@@ -118,7 +179,8 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz | |||
Phase_segment_2 | 30 tq | <nts2> = <n_tq> - 1 - <nts1> | |||
Synchronization_Jump_width | 30 tq | <nsjw> = <nts2> | |||
*/ | |||
int ntq = 10000000 / hz; | |||
|
|||
int ntq = _can_get_core_frequency() / hz; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you could try HAL_RCCEx_GetPeriphCLKFreq with RCC_PERIPHCLK_FDCAN ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmm it seems that STM32H7 doesn't provide the same function... :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note you can try code like this:
#ifdef TARGET_STM32G4
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN)/ hz;
#else
// STM32H7 doesn't support yet HAL_RCCEx_GetPeriphCLKFreq for FDCAN
// Internal ST ticket 92465
int ntq = 10000000 / hz;
#endif
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really nice catch, thank you! I added your proposal in. (35c9e7a)
@@ -491,6 +573,17 @@ void FDCAN2_IT1_IRQHandler(void) | |||
can_irq(CAN_2, 1); | |||
} | |||
|
|||
void FDCAN3_IT0_IRQHandler(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#if defined(FDCAN3_BASE) is missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't add this line, since it was also missing for the FDCAN2 Handlers, which otherwise are also guarded with the #if defined(GDCAN2_BASE).
But I agree, it makes sense to add the guard for both the FDCAN2 and FDCAN3 Handlers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added guards in 35c9e7a
Thanks for your comments, I will look into them and improve the sections until monday! |
Thanks for this! I will be testing this out in the near future :-) |
- Thanks to @jeromecoutant for showing the HAL funtion - Added #ifdef guard to FDCAN2/3 handler functions
- This enables more frequencies, but without regard to the accuracy. May still require manual clock setup, to remain in tolerance window
- Previously a received msg was fixed of data_type
- with 170MHz as can-core-frequency, the accuracy for many baudrates is too low. 160MHz is better for a broad range of frequencies
Added a small fix to support remote-messages (d0c8ad7) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good! I could perform some CAN tests:
- between NUCLEO_H743ZI2 (FDCAN) and NUCLEO_L476RG (CAN) in master branch
- between NUCLEO_H743ZI2 (FDCAN) and NUCLEO_L476RG (CAN) with this pull request (and a small patch, see my comment)
- between NUCLEO_H743ZI2 (FDCAN) and NUCLEO_G474RE (FDCAN) with this pull request
targets/TARGET_STM/can_api.c
Outdated
#else | ||
// STM32H7 doesn't support yet HAL_RCCEx_GetPeriphCLKFreq for FDCAN | ||
// Internal ST ticket 92465 | ||
int ntq = 10000000 / hz; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not hz in this function but f...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for that slip-up, I have no H7 to test, but should have noticed it anyway. Thanks for testing!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed in 73493b9
Pull request has been modified.
b280255
to
d4e22e2
Compare
- can_frequency uses f instead of hz for can frequency - Also added comment to system_clock
d4e22e2
to
73493b9
Compare
Jenkins CI Test : ✔️ SUCCESSBuild Number: 2 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
CI restarted (to get the status again) |
Jenkins CI Test : ✔️ SUCCESSBuild Number: 3 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Summary of changes
Added CAN support for the STM32G4.
Added support of FDCAN3 interface for the STM32 family.
Added fdcan_core_clk calculation instead of basing the calculation on a fixed 10MHz.
Impact of changes
Migration actions required
Documentation
None.
Pull request type
Test results
I've tested it with the NUCLEO-G474RE board & FDCAN-Adapter, don't know exactly how to do this section.
Reviewers
@jeromecoutant