feat(machine/stm32): add STM32F401 and NUCLEO-F401RE support - #5597
feat(machine/stm32): add STM32F401 and NUCLEO-F401RE support#5597akif999 wants to merge 1 commit into
Conversation
|
Hello @akif999 thanks for the PR. Here are some editied comments from an assisted code review:
Suggested fix: add per-chip APB1_FREQ/APB2_FREQ constants alongside the existing APB1_TIM_FREQ/APB2_TIM_FREQ in machine_stm32f401.go, machine_stm32f40x.go, and machine_stm32f469.go, and use those in all four functions. That also lets getBaudRateDivisor stay in the shared file instead of being duplicated.
adc → adc.go:11:32: undefined: machine.ADC2 To answer your question in the description: yes, please pull in src/examples/pwm/nucleo-f401re.go (see nucleo-f722ze.go for the pattern) and ADC0/ADC1/ADC2 aliases in the board file (as board_stm32f4disco.go has). Those make the results you reported reproducible. The rest of that commit can stay out. Minor / optional:
|
1. Requirements
What was implemented
What was NOT implemented in this PR
stm32f401.godevice file differs from the existing OTG FS driver (usb.go); excluded via!stm32f401build tag, left for a separate PRcrypto/rand(HW RNG)crypto/randpanics with"no rng", consistent with TinyGo's behavior on other platforms without HW RNG;math/randworks normallyblinky2Board Information
Board
Chip
2. Design
Already had comprehensive support for the STM32F4 family (F405/F407 via
feather-stm32f405,stm32f4disco; F722/F469 for other NUCLEO/disco boards). These provided:machine_stm32f4.gofor GPIO, UART, SPI, I2C, ADC, and PWM driversmachine_stm32f4_extended.gofor F405/F407-specific peripherals (extra UARTs, TIMs, DAC, CAN, etc.)runtime/runtime_stm32f4.goThe STM32F401 shares the same Cortex-M4 core and peripheral bus architecture as the F405/F407, but has a reduced peripheral set and a lower maximum clock speed (84 MHz vs. 168 MHz). The following approach was taken:
targets/stm32f401.ld— linker script (512 KB Flash, 96 KB SRAM; no CCM region)src/machine/machine_stm32f401.go— CPU frequency (84 MHz), APB timer frequency constantssrc/machine/machine_stm32f4_pll_84mhz.go— PLL parameters for 84 MHz from 8 MHz HSE (M=8, N=336, P=4, Q=7, Flash latency=2)src/runtime/runtime_stm32f401.go— clock initialization (HSE → PLL → 84 MHz SYSCLK),TIM3as the 1 kHz system tick timer (no CCM SRAM setup)src/device/stm32/stm32f401.go/stm32f401.s— generated fromlib/cmsis-svd/data/STMicro/STM32F401.svdmachine_stm32f4.goThe shared
machine_stm32f4.gocontainedgetPort()(which referenced GPIO ports F–K, not present on F401) andenableAltFuncClock()(which referenced DAC, CAN1/2, TIM6/7/8/12/13/14, SDIO, USART3–6 — none of which exist on F401), as well asTIM6,TIM7,TIM8,TIM12,TIM13,TIM14variable definitions. These were extracted out; the F405/F407 versions remain undermachine_stm32f4_extended.go(guarded by!stm32f401), and F401-specific versions are provided inmachine_stm32f401_periph.go.src/machine/machine_stm32f401_periph.go(new) — F401-specific implementations of:getPort(): GPIO ports A–E only (F401 does not have ports F–K)enableAltFuncClock(): only the peripheral clocks present on F401src/machine/machine_stm32f401_adc.go(new) — F401-specific ADC driver. The genericmachine_stm32_adc_f4.goreferences named SVD constants such asADC_SMPR1_SMP11_Cycles84which are absent from the F401-generated device file. This file providesInitADC(),Configure(),Get(), andgetChannel()using raw register bit values instead.machine_stm32f4_extended.go—//go:build stm32f4 && !stm32f401guards F405/F407-only peripherals (DAC, CAN, extra UARTs/TIMs, DCMI, crypto blocks)machine_stm32_adc_f4.go— changed fromstm32f4tostm32f4 && !stm32f401; the generic F4 ADC driver is replaced for F401 bymachine_stm32f401_adc.gomachine_stm32_otgfs_usb.go— changed fromstm32f4 || stm32f7to(stm32f4 && !stm32f401) || stm32f7; F401 excluded from the generic OTG FS USB stackmachine_stm32f4_otgfs_vbus.go— removedstm32f401from the build tag; F401 excluded from VBUS detection since USB OTG FS is not supported in this PRusb.go— added!stm32f401to the build tag (OTG FS register layout differs in the F401 SVD)runtime/rand_hwrng.go— added!stm32f401(no hardware RNG on F401)runtime/rand_norng.goandcrypto/rand/rand_baremetal.go— includestm32f401to route to the software RNG pathsrc/machine/board_nucleof401re.go— LED, button, UART1/UART2, SPI0, I2C0, ADC aliases (A0–A5), Arduino digital pin aliases (D0–D15)targets/nucleo-f401re.json—cpu = cortex-m4,fpu = fpv4-sp-d16, linker script, OpenOCDstlinkinterface,reset_config srst_only connect_assert_srstGNUmakefile— addednucleo-f401retarget tomake smoketest(afternucleo-f103rb)3. Implementation
Please refer to Files changed on GitHub. Key files are listed below.
4. Testing
Environment
devbranchFunctional Tests on NUCLEO-F401RE
Note
I have preserved the changes made to the examples during testing in a commit outside of this PR(akif999@f042c81).
I am currently debating whether to incorporate some of these changes into this PR, so I would appreciate any advice you could offer.
examples/blinky1examples/echo/echo2examples/buttonexamples/pininterruptexamples/device-idexamples/rand(crypto/rand)panic: no rng— F401RE has no HW RNG; consistent with TinyGo designtx == rxconfirmedexamples/adcexamples/pwmRegression Testing
make smoketestexecuted on both the upstreamdevbranch and the fork branchfeather-stm32f405,stm32f4disco,nucleo-f103rb,nucleo-f722ze,pico,xiao-rp2040, and others)