Gd32vw553k examples and fixes (i2c, pwm, sdcard, adc).#19524
Merged
cederom merged 4 commits intoJul 26, 2026
Conversation
JorgeGzm
force-pushed
the
gd32vw553k-start-examples-and-fixes
branch
from
July 24, 2026 23:02
6ac8149 to
0a1fe13
Compare
acassis
requested review from
cederom,
jerpelea,
linguini1,
raiden00pl and
xiaoxiang781216
July 24, 2026 23:20
acassis
previously approved these changes
Jul 24, 2026
JorgeGzm
force-pushed
the
gd32vw553k-start-examples-and-fixes
branch
from
July 25, 2026 00:13
0a1fe13 to
f40c364
Compare
xiaoxiang781216
approved these changes
Jul 25, 2026
Contributor
|
Note: next time please put changes like "arch/arm: Reserve r10 via ARCHCFLAGS and hoist the PIC module flags." into a separate PR as it impacts many ARM devices and is out of scope of GD32 update :-) |
acassis
approved these changes
Jul 25, 2026
casaroli
reviewed
Jul 25, 2026
Contributor
|
Would it be a lot of work to move out ARM R10 changes into a separate PR @JorgeGzm ? |
Contributor
The GD32VW55x I2C master (the STM32-style "v2" IP) never completed a real
transfer. Two bugs:
1. Wrong kernel clock. The protocol state machine is clocked by the I2C
kernel clock selected in RCU_CFG1.I2C0SEL, not by the APB1 bus clock that
only feeds the register interface. The driver left it at the APB1 default
and computed TIMING for PCLK1 (~80 MHz); the resulting prescaled period is
so short that the SDADEL/SCLDEL setup and hold times fall below the
analog-filter minimum of the IP, so the master latches START but never
drives SCL (STAT stuck with BUSY set). Route I2C0 to IRC16M (16 MHz) and
use it as clk_freq, and never let the prescaler drop below the value that
keeps the prescaled clock at/under 4 MHz (250 ns) so SDADEL/SCLDEL stay in
spec. This matches the vendor BSP (IRC16M, PSC=3).
2. Transfer timeout was zero. CONFIG_GD32VW55X_I2C_TIMEOTICKS has a Kconfig
default of 0 ("override when non-zero"), but the driver derived the timeout
with a plain #ifndef, which never triggers because the symbol is always
defined. The polled wait loop therefore ran a single iteration and gave
up. Address probes (NACK on the first pass) still worked and masked it;
only multi-byte transfers exercised the loop. Honour the "0 means derive
from seconds/milliseconds" contract.
Also make the interrupt wait immune to the ISR completing between startmsg()
and the wait (do not clobber a posted DONE), and drop a redundant cast.
To exercise this on hardware, add an "sht3x" configuration to the
gd32vw553k-start: the nsh base plus I2C0, the i2ctool and the Sensirion SHT3x
temperature/humidity driver, registered as /dev/i2c0 and /dev/temp0. I2C0 is
routed to PA2 (SCL) / PA3 (SDA) on AF4, the pins broken out on the J1 header
(datasheet Table 2-5); when SPI is enabled it claims PA2, so I2C0 falls back
to PB0/PB1, whose SDA pin is not broken out (the periph case).
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Add a "pwm" configuration that exercises the PWM driver on TIMER1. It is the nsh base plus the PWM driver, registered as /dev/pwm0 and driven by the pwm example (100 Hz, 50 % duty by default). TIMER1 channel 0 is routed to PA0 on the J1 header (AF1) so the waveform can be probed there; the other channels stay unrouted. Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Add an "sdcard" configuration that mounts an SD card over SPI0 with a FAT filesystem. The board provides the SPI chip-select glue (gd32_spi0select, gd32_spi0status and gd32_spi0register in a new gd32_spi.c) and gd32_bringup() binds the slot with mmcsd_spislotinitialize() and mounts /dev/mmcsd0 on /mnt/sd. The card is wired to the J1 header: SCK PA2, MISO PA1, MOSI PA0, and a software chip select on PA4. CONFIG_MMCSD_MMCSUPPORT is left off (its MMC CMD1 probe upsets SD cards). Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
adc_shutdown() gates the ADC clock (RCU_APB2EN.ADCEN) when the device is closed, but the one-shot adc_reset() that first enabled it only runs at registration and adc_setup() never re-enabled it. A second open() then drove a clock-gated peripheral whose conversions never completed, so a second run of a reader such as the adc example hung after opening the device. adc_setup() now re-enables the ADC clock; clock gating preserves the register configuration, so nothing else has to be re-programmed. Add an "adc" configuration that exercises the driver. It is the nsh base plus the ADC driver, registered as /dev/adc0 and read by the adc example. ADC channel 8 (ADC_IN8) is routed to PB0 on the J1 header so an analog voltage applied there is sampled. The board bringup samples that channel when the pin is routed, and PB0 is only claimed for the ADC when SPI is off (with SPI on it belongs to the I2C0 fallback), so the periph configuration is unaffected. The GD32VW55x ADC converts on demand rather than continuously, so the example uses the software trigger (CONFIG_EXAMPLES_ADC_SWTRIG) and is bounded to 20 sample groups so it returns to the prompt. Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
JorgeGzm
force-pushed
the
gd32vw553k-start-examples-and-fixes
branch
from
July 25, 2026 20:46
f40c364 to
bc0b7d8
Compare
acassis
approved these changes
Jul 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two GD32VW55x driver bugs and adds four
gd32vw553k-startexamples ontop of the
nshbase.Driver fixes
gd32vw55x_i2c.c: the I2C master never completed a transfer. It is clockedby the kernel clock in
RCU_CFG1.I2C0SEL, not APB1; the driver left it atthe APB1 default, so the computed
TIMINGput SDADEL/SCLDEL below the IPanalog-filter minimum and SCL was never driven. Now routes I2C0 to IRC16M
and floors the prescaler (matching the vendor BSP). Also honours the
CONFIG_GD32VW55X_I2C_TIMEOTICKS=0"derive from time" contract (the#ifndefnever fired, so the timeout was 0) and hardens the ISR wait.gd32vw55x_adc.c:adc_shutdown()gates the ADC clock on close, butadc_setup()never re-enabled it (only the one-shotadc_reset()did), soa second
open()hung.adc_setup()now re-enables the clock.New configurations
sht3x/dev/i2c0,/dev/temp0)pwm/dev/pwm0)sdcard/mnt/sdadc/dev/adc0) + adc examplePin routing is in
board.h, device registration ingd32_bringup.c, eachexample is a standalone defconfig, and the board
index.rstdocuments allfour.
Commits (4) -- each driver fix is folded into the example that exercises it:
clock/timeout bugs and adds the
sht3xconfig.pwmconfig (TIMER1 onPA0).
sdcardconfig with the SPI chip-select glue and FAT auto-mount.
clock re-enable on open and adds the
adcconfig.Impact
backward compatible.
of the arch. Only
periphenables these peripherals;nsh,wapi,sta_softap,ble,ostest,littlefsare unaffected (every change ispreprocessed out for them).
index.rstgainssht3x,pwm,sdcard,adcsections.Testing
Verified on real hardware:
gd32vw553k-start(GD32VW553KMQ, Nuclei N307),riscv-none-elf-gcc14.2.0, flashed over GD-Link/OpenOCD. All four configsbuild clean;
nxstyle/checkpatch clean on every touched file.Before the I2C fix (
gd32vw553k-start:sht3x): every transfer times out,the master is stuck with BUSY set and never drives SCL:
After the change:
sht3x-- SHT3x on I2C0 (SCL PA2, SDA PA3):(The default one-byte-read probe is NACKed by the SHT3x when no measurement is
pending, so
-zis used to detect it.)pwm-- scope/LED on PA0:sdcard-- microSD-over-SPI breakout on SPI0:The card is auto-mounted on
/mnt/sdand writes persist across a reboot. Thebreakout must be powered from 5 V (its 3.3 V regulator needs the headroom for
the card's power-up current bursts, otherwise it hangs in the ACMD41 loop).
adc-- ADC_IN8 on PB0, with 1.65 V (half of the 3.3 V full scale) applied:1.65 V lands at mid-scale (~2048); ~2110 is within the tolerance of an
uncalibrated ADC.