-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
Add few devices to the STM32WL family #34751
Conversation
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.
One nit. Register definitions are consistent with the reference manual.
Rebased, see if buildkite is happy again. |
fe23c98
to
c041959
Compare
#address-cells = <1>; | ||
#size-cells = <0>; | ||
reg = <0x58010000 0x400>; | ||
interrupts = <44 5>; |
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 you check the position of the interrupt as the entry 44 is mentioned as "Reserved" by the RefMan
subghzspi is present at position 30 of the CPU2 for the stm32wl5x.
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.
Hey you are right! I was cross referencing stm32wle5xx.h from the cube package when I did this, the header file defines:
#if defined(CORE_CM0PLUS)
...
SUBGHZSPI_IRQn = 30,
...
#else
...
SUBGHZSPI_IRQn = 44,
...
and stm32wle5xx.h only defines it on 44. Curiously enough there is a Radio IRQ on channel 44 of the EXTI, but it's not the SPI Interrupt. And the SPI driver in the cube package uses that SPI in polling mode anyway.
But setting this to 30 would not be correct either since it would try to resolve to the wrong nvic controller, and we don't have anything for the second cpu defined in the dts yet. Plus it would not help me because I'm working on a STM32WLE5, the single core version. :-)
Do you have a contact to check if maybe the definition in the cube file is correct and that reserved line is actually usable and the reference manual has to be rectified? Otherwise it means that this SPI cannot be used in interrupt mode in a single core setup.
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.
For what is worth, I hacked together a sample to probe something on that SPI and the interrupt does fire (E5 single core interrupt position 44):
Breakpoint 1, spi_stm32_isr (dev=0x20000160 <__device_dts_ord_165>)
at zephyrproject/zephyr/drivers/spi/spi_ll_stm32.c:409
409 struct spi_stm32_data *data = dev->data;
(gdb) p *dev
$1 = {name = 0x8006649 "SUBGHZSPI", config = 0x8005d74 <spi_stm32_cfg_0>, api = 0x8005d4c <api_funcs>,
state = 0x200004cc <__devstate_dts_ord_165>, data = 0x20000020 <spi_stm32_dev_data_0>,
handles = 0x8005b88 <__devicehdl_DT_N_S_soc_S_spi_58010000>}
Found few other missing bits on the clock setup to get to that point though so I'm adding a patch for those as well. :-)
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 probably a missing line in the ref manual (of the stm32wleX - RM0461): The stm32wle5xx.h from the cube is setting the SUBGHZSPI_IRQn at position = 44, for the M4. Let me check internally.
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.
Right, sorry I pasted the wrong file name on my first reply, stm32wl55xx.h defines that on both 30 and 44 depending on whether it's building for the M0 or M4, and stm32wle5xx.h only has it on 44, and only has the M4. Thanks for checking it!
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.
After checking, the entry 44 of the NVIC is the SUBGHZ SPI instance.
@@ -232,6 +242,9 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, | |||
!defined (CONFIG_SOC_SERIES_STM32G0X) | |||
uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER); | |||
#endif | |||
#if defined(CONFIG_SOC_SERIES_STM32WLX) | |||
uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_AHB3_PRESCALER); |
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.
Here you are assigning a different prescaler (STM32_AHB3_PRESCALER).
The apb3 prescaler is a good addition, but a few more steps are necessary to introduce it:
You need to introduce the apb3 flag in the device tree bindings before, then the symbol for STM32_APB3_PRESCALER, and additionally it would be fine if that prescaler is then set in the nucleo_board definitions.
I also had a short look on the adc part, will add a few comments after I had a more thorough look.
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.
Hi! From what I understand of the WL55/WLE5 clock architecture, the AHB3 (shared) prescaler output goes straight to both HCLK3 and PCLK3, so there's no APB3 prescaler in the chip. Guess I could #define STM32_APB3_PRESCALER STM32_AHB3_PRESCALER
? Though that would sound more confusing than anything else to me.
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.
@ABOSTM Can you have a check ?
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, please ignore the comment above, I didn't check against the datasheet, and assumed it would have it's own prescaler.
In that case it may be preferable to call the variable ahb3_clock and add a fix to return this rate for STM32_CLOCK_BUS_AHB3 as well as STM32_CLOCK_BUS_APB3 in the switch case below?
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 confirm no APB3 dedicated prescaler,
variable apb3_clock, is good to me as this is the clock we want to compute.
Maybe add a comment to say HCLK3=APBCLK3 to avoid thinking there is a typo.
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.
Yeah that would work, but looking more into it I found another inconsistency: the current logic uses SystemCoreClock for STM32_CLOCK_BUS_AHB3, but that's incorrect for WL series. So I did this:
- renamed the variable to ahb3_clock (from AHB3 prescaler, so no confusion here)
- defined out the default STM32_CLOCK_BUS_AHB3 for the WL
- added STM32_CLOCK_BUS_AHB3 and STM32_CLOCK_BUS_APB3 to return ahb3_clock, with a comment
How does that look?
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, yes that is how I'd prefer it. Now only the issue about the SystemCoreClock raised by @ABOSTM should be left.
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.
A few suggested changes.
As I can comment only on changed lines, additional comments below:
init function:
- add stmwl to wait LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES (around lines 712)
- need to wait for adrdy flag (around lines 733)
drivers/adc/adc_stm32.c
Outdated
@@ -339,7 +342,8 @@ static int start_read(const struct device *dev, | |||
#endif | |||
|
|||
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \ | |||
defined(CONFIG_SOC_SERIES_STM32L0X) | |||
defined(CONFIG_SOC_SERIES_STM32L0X) || \ | |||
defined(CONFIG_SOC_SERIES_STM32WLX) |
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.
Here you should wait until ccrdy flag is set like stm32g0
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.
Done.
LL_ADC_EnableInternalRegulator(adc); | ||
k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); | ||
#endif | ||
|
||
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \ | ||
defined(CONFIG_SOC_SERIES_STM32L0X) | ||
defined(CONFIG_SOC_SERIES_STM32L0X) || \ | ||
defined(CONFIG_SOC_SERIES_STM32WLX) |
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.
Here you could consider doing it the same way wb, g4,.. instead.
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.
LL_ADC_SetCommonClock with PCLK_DIV4? If I do that it does not initialize, stays spinning on while (LL_ADC_IsCalibrationOnGoing(adc)) {}
done
done |
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 this work.
Have you been able to validate all these additions (at least one instance per driver) ?
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.
LGTM
@@ -232,6 +242,9 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, | |||
!defined (CONFIG_SOC_SERIES_STM32G0X) | |||
uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER); | |||
#endif | |||
#if defined(CONFIG_SOC_SERIES_STM32WLX) | |||
uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_AHB3_PRESCALER); |
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 confirm no APB3 dedicated prescaler,
variable apb3_clock, is good to me as this is the clock we want to compute.
Maybe add a comment to say HCLK3=APBCLK3 to avoid thinking there is a typo.
Yeah I managed to test most things with a bit of hacking of the nucleo WL55 dts (but running on the Seed LoRa-E5 module I have), this what I tested:
haven't checked the other timers, can try move the led pwm sample to those if I have the pin available (it's a small module) but they should be alright. |
Not necessarily relevant for this PR, but for getting the radio module working, you might want to check if |
Hey thanks, I'll look into it. So far I've seen it driven from a special bit in the PWR module so that may need some special treatment, no mention about the the SPI HW SS but worth trying. About the other devices, I've intentionally omitted the TRNG from this PR. Gave it a try but could not get it working, it gets stuck spinning in the interrupt handler with the "invalid clock" bit set. I'll look into troubleshoot it again at some stage and send a separate PR if I can get it to work. |
Great, what would be nice is to add support directly to in tree nucleo board so that drivers could be compiled/ validated in CI. |
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.
LGTM
Add a few device nodes present in the stm32wl family. Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
Add RTC counter support for the STM32WL family. Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
Add ADC support for the STM32WL family, this seems to work following most of the L0X code path. Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
STM32WL series have an extra APB3 bus with the SUBGHZSPI device on it. Add the relevant code to enable and disable that clock, and to obtain the actual clock rate. This is enough to run the STM32 SPI driver against it. Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com>
Hi, this is adding various devices (most of the ones that have a driver anyway) to the STM32WL series. I tested most of these with the various examples on a STM32WE5 based Seed Lora-E5 module, so they should work fine on the WL55 as well, they only needed few extra defines for the RTC and ADC drivers.