-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
stm32: Add support for all STM32L43x/L44x/L45x/L462/L47x/L486/L4A6. #16523
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
base: master
Are you sure you want to change the base?
Conversation
Code size report:
|
Adds all STM32L4 80 MHz parts with at least 256 KiB Flash, including non-USB and crypto parts. There are only preprocessor directive changes, no code changes. Signed-off-by: Chris Mason <c.mason@inchipdesign.com.au>
2376c39
to
a0943ed
Compare
stm32/boards/stm32l432_af.csv Fix errors and omission. stm32/boards/stm32l452_af.csv Fix omission. stm32/boards/stm32l433_af.csv Add. Signed-off-by: Chris Mason <c.mason@inchipdesign.com.au>
stm32/boards/stm32l43x_12kFS.ld stm32/boards/stm32l43x_26kFS.ld Replace stm32l432.ld with tunable versions for all stm32l43x parts. The LENGTH(FLASH_FS) needs to be tuned for each board port to squeeze in drivers (eg USB, CANbus). These changes allow editing one number (FS_SIZE) and all regions are calculated automatically. stm32l43x_26kFS.ld provides a 26 KiB file system for minimal ports, eg NUCLEO_L432KC. stm32l43x_12kFS.ld provides a 12 KiB file system for ports with USB. stm32/boards/NUCLEO_L432KC/mpconfigboard.mk Use new stm32l43x_26kFS.ld. Signed-off-by: Chris Mason <c.mason@inchipdesign.com.au>
a0943ed
to
1665595
Compare
This is the first of three PRs to replace #7123 |
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.
Thanks for submitting this PR, @chrismas9!
I have a few comments, all about trying to avoid the "rightward creep" of needing to name the many subtly different variants of STM32L4! Sounds like you've used the STM32L4 family a lot, and I haven't, so please let me know if you think any of the proposed changes are too risky. (It's probably worth also waiting to see what @dpgeorge thinks about going in that direction before we commit to it.)
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 230K /* sectors 0-114 */ | ||
FLASH_FS (r) : ORIGIN = 0x08039800, LENGTH = 26K /* sectors 115-127 */ | ||
ALL_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K | ||
FS_SIZE (r) : ORIGIN = 0, LENGTH = 12K /* Adjust the File System size here */ |
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 like this trick... it'd be good to use it consistently across all the stm32 linker scripts, but there are 49 more of them...
I guess it's fine to have it just for these two, although @dpgeorge might have a different opinion.
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 think you can just use variables in ORIGIN and LENGTH? See how mimxrt does it, eg ports/mimxrt/boards/common.ld
. @robert-hh has done a good job making that port quite configurable with the linker scripts.
#elif defined(STM32L0) || \ | ||
defined(STM32L432xx) || defined(STM32L442xx) || \ | ||
defined(STM32L433xx) || defined(STM32L443xx) || \ | ||
defined(STM32L452xx) || defined(STM32L462xx) |
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.
Can this one be defined(STM32L4)
? If MICROPY_HW_USB_FS
is unset, it won't include any code.
@@ -93,7 +93,8 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { | |||
const uint32_t otg_alt = GPIO_AF10_OTG1_FS; | |||
#elif defined(STM32L0) | |||
const uint32_t otg_alt = GPIO_AF0_USB; | |||
#elif defined(STM32L432xx) || defined(STM32L452xx) | |||
#elif defined(STM32L432xx) || defined(STM32L442xx) || defined(STM32L433xx) || defined(STM32L443xx) || \ | |||
defined(STM32L452xx) || defined(STM32L462xx) |
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.
Confused about why we set otg_alt
here anyway, if these are parts that only have USB device support?
But that's preexisting... How about using defined(STM32L4)
here and same at line 160? We can always split it up again if a new STM32L4 board is added that behaves differently.
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.
The STM32 HAL uses GPIO_AF0_USB
, GPIO_AF10_USB_FS
, GPIO_AF10_USB
, GPIO_AF10_OTG_FS
, GPIO_AF10_OTG1_FS
, etc depending on the capabilities of each chip and which AF the USB is allocated to. The L432/L452 names differ to all other L4s because they don't support OTG. I think these need to stay as they are.
As for using otg_alt
the pyboard hardware supports OTG, it has an OTG connector and provision for a power switch. I'm not sure what software support there is.
@@ -133,7 +133,7 @@ static void dac_deinit(uint32_t dac_channel) { | |||
|
|||
void dac_deinit_all(void) { | |||
dac_deinit(DAC_CHANNEL_1); | |||
#if !defined(STM32L452xx) | |||
#if !defined(STM32L451xx) && !defined(STM32L452xx) && !defined(STM32L462xx) |
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 think all of the clauses in this file can be #if !defined(DAC_CHANNEL2_SUPPORT)
(another CMSIS header define).
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.
Hmm, looking at CMSIS some more this macro might be inconsistently defined. 🙄
I think a safe (but ugly) variant will be #if !defined(STM32L4) || !defined(DAC_CHANNEL2_SUPPORT))
#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32L432xx) || defined(STM32L452xx) || defined(STM32WB) | ||
#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || \ | ||
defined(STM32L432xx) || defined(STM32L442xx) || defined(STM32L433xx) || defined(STM32L443xx) || \ | ||
defined(STM32L452xx) || defined(STM32L462xx) || defined(STM32WB) |
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 bit of a deviation from how we've done this until now, but I think we can replace this increasingly long line of #if clauses with
#if defined(USB_OTG_FS)
This peripheral address is defined in the CMSIS headers for all the chips which contain an OTG peripheral, as far as I can tell...
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.
The L332 and L452 families use USB_FS
, so using USB_FS
and USB_OTG_FS
I can greatly simplify this.
@@ -90,7 +90,8 @@ void mp_hal_ticks_cpu_enable(void) { | |||
#endif | |||
|
|||
void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) { | |||
#if defined(STM32L476xx) || defined(STM32L496xx) | |||
#if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L486xx) || \ | |||
defined(STM32L496xx) || defined(STM32L4A6xx) |
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.
There are too many datasheets to read them all, but it seems like all of the STM32L4s that have a GPIOG also have a VDDIO2:
❯ rg -c --include-zero "define PWR_CR2_IOSV" | sort
stm32l412xx.h:0
stm32l422xx.h:0
stm32l431xx.h:0
stm32l432xx.h:0
stm32l433xx.h:0
stm32l442xx.h:0
stm32l443xx.h:0
stm32l451xx.h:0
stm32l452xx.h:0
stm32l462xx.h:0
stm32l471xx.h:3
stm32l475xx.h:3
stm32l476xx.h:3
stm32l485xx.h:3
stm32l486xx.h:3
stm32l496xx.h:3
stm32l4a6xx.h:3
stm32l4p5xx.h:3
stm32l4q5xx.h:3
stm32l4r5xx.h:3
stm32l4r7xx.h:3
stm32l4r9xx.h:3
stm32l4s5xx.h:3
stm32l4s7xx.h:3
stm32l4s9xx.h:3
stm32l4xx.h:0
system_stm32l4xx.h:0
❯ rg -c --include-zero "define GPIOG" | sort
stm32l412xx.h:0
stm32l422xx.h:0
stm32l431xx.h:0
stm32l432xx.h:0
stm32l433xx.h:0
stm32l442xx.h:0
stm32l443xx.h:0
stm32l451xx.h:0
stm32l452xx.h:0
stm32l462xx.h:0
stm32l471xx.h:2
stm32l475xx.h:2
stm32l476xx.h:2
stm32l485xx.h:2
stm32l486xx.h:2
stm32l496xx.h:2
stm32l4a6xx.h:2
stm32l4p5xx.h:2
stm32l4q5xx.h:2
stm32l4r5xx.h:2
stm32l4r7xx.h:2
stm32l4r9xx.h:2
stm32l4s5xx.h:2
stm32l4s7xx.h:2
stm32l4s9xx.h:2
stm32l4xx.h:0
system_stm32l4xx.h:0
... Do you think it's safe to make this #if defined(STM32L4) && defined(GPIOG)
?
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 have checked one datasheet from each family (L432/33/5/7/9/P/R) and this look safe. Only L47x and above have GPIOG
and they also have VDDIO2
defined(STM32L476xx) || defined(STM32L496xx) || \ | ||
defined(STM32L462xx) || defined(STM32L471xx) || \ | ||
defined(STM32L475xx) || defined(STM32L476xx) || \ | ||
defined(STM32L486xx) || defined(STM32L496xx) || \ | ||
defined(STM32L4A6xx) || \ |
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.
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's what I did in #7123
@projectgus Thanks for the review and helpful comments. I agree using STM32L4 in many places would simplify things and improve readability. I did that in my previous PR in some places. I looked for precedent from other commits and thought listing all parts was preferred . However with so many parts it is messy. When I first started I thought there might be newer parts coming with different features, but now I think that is unlikely. ST have moved on with newer families like G4 and I think L4 is stable. I will review your suggestions when I get a chance. I also wanted to be careful not to touch anything that affects other families due to the amount of testing, especially for families I am not familiar with and don't have dev boards for. I will still consider your suggestions. I'm happy to update all the linker scripts for parts with 2K sectors. It's a bit more complicated for parts with non uniform sectors sizes. I have another PR coming for them. It reduces the FS cache to 48K, moves the stack into CCRAM, increases the heap size and the FS by using more sectors. I would do the non uniform linker scripts in that PR. I have been using this for years, but it needs a bit of cleanup and a big rebase first. |
Sounds good. Feel free to ignore any/all of the suggestions which might impact other chips, I will make a note to take a look at them later on. (I think I can write a script that builds all of the stm32 boards and verifies no differences in the binaries, and then get stuck in cleaning up macros without fear...)
That sounds great to me, if you're up for it! |
On this, @dpgeorge may disagree, but I think what's happened is most source files have gradually grown from only a few chips supported to a lot of chips now, without it necessarily being the intention to list them all out. We've had good luck cleaning up the esp32 port to use capability-based macros rather than listing every chip, but that's an order of magnitude fewer chips with a lot less differences so I'm not sure how viable it will turn out to be on stm32. (To be clear, this is not a problem I'm suggesting you should tackle in this PR - except for maybe the few places where the lines were growing by a large proportion.) |
Another possible way to simplify the long list of parts would be to define family sub groups in
There are only six sub groups of STM32L4 compared with over twenty individual parts. The main differences between parts in a sub group are USB, LCD and crypto support. |
Summary
This adds support for all 80 MHz STM32L4 parts.
There are no code changes, only preprocessor directives, af, ld and mk file changes.
L431 and L433 are higher pincount versions of L432 with more peripherals.
All other variants are identical to existing parts except for USB, LCD and crypto.
The 256 kiB parts are short on Flash for File System and the FS size needs tuning depending on
enabled features (eg USB requires 14 KiB). The stm32l43x*.ld linker scripts simplify FS_SIZE tuning.
Testing
The L431, L432, L433, L442 and L443 have been tested on NUCLEO boards with and without USB. Only REPL, USB and FS have been tested. Other peripherals are the same as similar parts.
All parts have been compiled error free using modified board files from existing ports.
After these tests I consider the changes low risk.
I have been using many of these MCUs, including L433, commercially for 4 years based on #7123