🛠 GPIO, touche utilisateur ADC et PWM sur le connecteur 2×20 du Lichee RV
Objectives
The Dock exposes most of the Lichee RV module pins on a 2×20 connector with 2.54 mm pitch (3.3 V logic). A key detail to know: the user button on the Dock is NOT a GPIO pin but an input of the Allwinner D1's low-power analog-to-digital converter (LRADC) ("user key (ADC)" in the CNX launch specs) — it is therefore read as an input device, not via gpiod. This tutorial covers discovering the D1's PIO controller with libgpiod, outputting a signal on a free pin, reading the ADC button, and understanding the hardware PWM output.
Hardware
- Lichee RV Dock running a mainline image with
gpiod/python3-gpiodandevtest(apt install gpiod python3-gpiod evtest) - LED + 1 kΩ resistor (3.3 V pins — never 5 V on the D1 inputs)
- Passive buzzer on a PWM pin for the PWM section
- Official Dock schematic (dl.sipeed.com, Lichee_RV-Dock/2_Schematic folder) for the mapping between physical pins ↔ D1 pins
Full Code
# 0) Inventaire : broches D1 en banques PA..PG, 32 lignes par banque
gpiodetect # gpiochip « pio » (contrôleur pinctrl sun20i)
gpioinfo pio | less # lignes, noms du device tree, état (kernel-used ?)
# 1) Touche utilisateur = LRADC -> événements input, pas GPIO :
sudo evtest # choisir l'appareil « lichee-rv ... key » ; KEY_* à chaque appui
# (en Python : pip install evdev puis lire /dev/input/event*)
# 2) Sortie GPIO brute : ligne = index_banque*32 + offset
# PB3 -> banque B (1)*32 + 3 = ligne 35 (ADAPTER à votre broche libre)
gpioget pio 35
sudo gpiod toggle pio 35 --period 200ms # clignote jusqu'à Ctrl-C (gpiod >= 1.6)
#!/usr/bin/env python3
"""demo_pio.py — sortie clignotante sur le Lichee RV (libgpiod v1 Python)."""
import gpiod, time
chip = gpiod.Chip("pio") # nom vu par gpiodetect
ligne = 35 # PB3 = 1*32 + 3 — ADAPTER après gpioinfo
req = chip.request_lines(
config={ligne: gpiod.LineSettings(direction=gpiod.line.Direction.OUTPUT)},
consumer="licheerv-demo")
try:
for _ in range(10):
req.set_value(ligne, 1); time.sleep(0.1)
req.set_value(ligne, 0); time.sleep(0.1)
finally:
req.release_lines
# PWM : le GPIO brut ne remplace pas le PWM matériel. Le D1 a un contrôleur PWM
# (/sys/class/pwm) ; si aucun pwmchip n'apparaît, activer le nœud pwm par un
# overlay device tree, puis : echo 0 > export ; period/duty_cycle en nanosecondes.
Expected Verification
gpiodetect lists a gpiochip named pio; gpioinfo pio shows the lines, their names, and those claimed by the kernel. The LED blinks at 5 Hz on the chosen pin (multimeter: 0 / ~3.3 V). evtest displays an EV_KEY event each time the user button is pressed — proof that it is the LRADC and not a GPIO reading it. If request_lines returns "Device or resource busy", the line is already in use (UART console, LED, DMIC): change the pin.
Common Errors
- Looking for the user button as a GPIO: it is on the LRADC (voltage divider); you will never see anything via raw GPIO — use evtest/input instead.
- Numbering like a Raspberry Pi (BCM 1-27): here it is bank × 32 (PA=0..31, PB=32..63, PC=64..95…); check with gpioinfo before wiring.
- Injecting 5 V: the D1 logic is 3.3 V; a 5 V input can destroy the pin.
- Forgetting pins claimed by the kernel: UART0 console (PB8/PB9), LED PC0/PC1, DMIC (PB11/PE17) are already used by the device tree.
- Following a Raspberry Pi/gpiozero tutorial: gpiozero does not know the D1; use libgpiod.
Other tutorials for this board
- Premier boot du Lichee RV Dock avec Ubuntu 24.04 RISC-V
- LEDs du Lichee RV Dock : LED verte et RGB WS2812 pilotée par le LEDC du D1
- Audio sur le Dock : enregistrer au micro numérique et jouer sur le haut-parleur 3 W
- Wi-Fi et Bluetooth du module RTL8723DS sur le Lichee RV Dock
- Tina Linux : l'OpenWrt vendor d'Allwinner pour le Lichee RV, installation et sysconfig
- Construire une image mainline complète avec Buildroot (defconfig officiel du Dock)
Code examples for this board
clignotante.pyPythonbouton-gpio.pyPythoncapteur-i2c.shBashsurveillance-temperature.shBashcapteur-dht11.pyPythonservo-pwm-sysfs.shBash