mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
risc-v/gd32vw55x: fix I2C master and add gd32vw553k-start sht3x example
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>
This commit is contained in:
parent
f0e4f61add
commit
30735584a4
5 changed files with 212 additions and 30 deletions
|
|
@ -194,6 +194,50 @@ capture, both watchdogs, progmem, TRNG and CRC), registered as ``/dev/i2c0``,
|
|||
``/dev/spi0``, ``/dev/adc0``, ``/dev/pwm0``, ``/dev/capture0``,
|
||||
``/dev/watchdog0`` and ``/dev/watchdog1``. No radio.
|
||||
|
||||
sht3x
|
||||
-----
|
||||
|
||||
NSH plus I2C0, the i2ctool and the Sensirion SHT3x temperature/humidity
|
||||
driver -- a small example to validate the I2C master port against a real
|
||||
device. Because SPI is *off* here, I2C0 is routed to the J1 header on
|
||||
**PA2 (SCL)** and **PA3 (SDA)** (adjacent pins on the second row of J1, both
|
||||
AF4); with SPI on (the ``periph`` case) it falls back to PB0/PB1, whose SDA
|
||||
pin is not broken out. See the pin-header tables above.
|
||||
|
||||
Wire the sensor to J1: SCL -> PA2, SDA -> PA3, VCC -> +3V3 (J2) or the module
|
||||
3.3 V, GND -> GND. A breakout with its own pull-ups is assumed; the pins are
|
||||
configured with the internal pull-ups as a fallback.
|
||||
|
||||
The bus is registered as ``/dev/i2c0`` and the sensor as ``/dev/temp0``
|
||||
(``gd32_bringup()`` registers it at address 0x44). Confirm the address with
|
||||
the i2ctool using a zero-byte write probe (``-z``); the SHT3x NACKs the
|
||||
default one-byte read probe when it has no measurement pending, so plain
|
||||
``i2c dev`` would not show it::
|
||||
|
||||
nsh> i2c dev -z 0x03 0x77
|
||||
0 1 2 3 4 5 6 7 8 9 a b c d e f
|
||||
00: -- -- -- -- -- -- -- -- -- -- -- --
|
||||
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- --
|
||||
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
70: -- -- -- -- -- -- -- --
|
||||
|
||||
The ``44`` above is the SHT3x acknowledging. Then read it through the
|
||||
driver::
|
||||
|
||||
nsh> sht3x
|
||||
Converting...
|
||||
Temperature = 26.530098
|
||||
Humidity = 47.998001
|
||||
|
||||
.. note::
|
||||
If the sensor sits at 0x45, change the address passed to
|
||||
``sht3x_register()`` in ``gd32_bringup.c`` (the i2ctool still finds it at
|
||||
its real address regardless).
|
||||
|
||||
littlefs
|
||||
--------
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue