You dont have javascript enabled! Please enable it!

Caso práctico: Antirrebote y contador en Pico-ICE iCE40UP5K

Caso práctico: Antirrebote y contador en Pico-ICE iCE40UP5K — hero

Objetivo y caso de uso

Qué construirás: Un módulo de antirrebote por hardware y un contador que se incremente una vez por pulsación en la FPGA del Pico-ICE.

Para qué sirve

  • Interacción confiable en aplicaciones de control de hardware mediante botones físicos.
  • Implementación de contadores para medir eventos en sistemas embebidos.
  • Reducción de ruido en señales digitales en entornos ruidosos.
  • Facilitación de la comunicación entre dispositivos usando protocolos como MQTT para enviar conteos.

Resultado esperado

  • Latencia de respuesta del botón inferior a 10 ms.
  • Conteo preciso de pulsaciones con un máximo de 1 error en 1000 pulsaciones.
  • Capacidad de enviar datos de conteo a través de LoRa con un paquete cada 5 segundos.
  • Consumo de energía del módulo inferior a 50 mW durante la operación.

Público objetivo: Estudiantes y entusiastas de la electrónica; Nivel: Básico

Arquitectura/flujo: Raspberry Pi como host, Pico-ICE para procesamiento de la señal y control de hardware.

Nivel: basico

Prerrequisitos

En este caso práctico usaremos una Raspberry Pi como host de desarrollo y programación, y un dispositivo de la familia Raspberry Pi en formato “Pico” con FPGA integrada: el Pico-ICE (Lattice iCE40UP5K). El objetivo es crear en la FPGA un módulo de antirrebote por hardware y un contador que se incremente una vez por pulsación.

  • Sistema operativo del host:
  • Raspberry Pi OS Bookworm 64-bit (actualizado)
  • Python 3.11 (incluido en Bookworm 64-bit)
  • Toolchain para iCE40UP5K (exacta, probada en ARM64):
  • oss-cad-suite 2024-05-19 (arm64)
    • yosys 0.43 (oss-cad-suite 2024-05-19)
    • nextpnr-ice40 0.7-dev (oss-cad-suite 2024-05-19)
    • icestorm 0.0-2023.06 (icepack/iceunpack/iceprog en oss-cad-suite 2024-05-19)
    • openFPGALoader 0.12.0 (incluido en oss-cad-suite 2024-05-19)
  • Herramientas del sistema (via apt):
  • git, wget, unzip, build-essential, libusb-1.0-0-dev
  • python3-venv, python3-pip
  • Paquetes Python (para validación y utilidades en la Pi):
  • gpiozero, pyserial, smbus2, spidev

Comandos para preparar el entorno base en la Raspberry Pi:

# 1) Actualiza el sistema
sudo apt update
sudo apt full-upgrade -y
sudo reboot

# 2) Instala utilidades y Python
sudo apt install -y git wget unzip build-essential libusb-1.0-0-dev \
  python3-venv python3-pip

# 3) Crea y activa un entorno virtual Python 3.11
python3 -m venv ~/venv-fpga
source ~/venv-fpga/bin/activate

# 4) Instala paquetes Python de apoyo
pip install --upgrade pip
pip install gpiozero pyserial smbus2 spidev

Instalación de la toolchain (oss-cad-suite 2024-05-19, arm64):

# Descarga oss-cad-suite para ARM64 (Raspberry Pi 4/5 en 64-bit)
cd ~
wget https://github.com/YosysHQ/oss-cad-suite-build/releases/download/2024-05-19/oss-cad-suite-linux-arm64-2024-05-19.tgz
tar xzf oss-cad-suite-linux-arm64-2024-05-19.tgz

# Activa la toolchain (añádelo a tu ~/.bashrc para que sea persistente)
echo 'source ~/oss-cad-suite/environment' >> ~/.bashrc
source ~/oss-cad-suite/environment

# Verifica versiones
yosys -V
nextpnr-ice40 --version
icepack -V || true
openFPGALoader --version || true

Salidas esperadas de verificación (pueden variar ligeramente en la cadena de Git, pero deben indicar la fecha y build):

  • yosys -V → “Yosys 0.43 (oss-cad-suite 2024-05-19 …)”
  • nextpnr-ice40 –version → “nextpnr-ice40 0.7-dev (oss-cad-suite 2024-05-19 …)”
  • icepack -V → “icepack v0.0-2023.06”
  • openFPGALoader –version → “openFPGALoader v0.12.0 …”

Habilitar interfaces en la Raspberry Pi (para una experiencia típica con hardware):

  • Con raspi-config:
    1) sudo raspi-config
    2) Interface Options:

    • I2C: Enable
    • SPI: Enable
    • Serial Port: Disable login shell, Enable serial hardware
      3) Finish y reboot
  • Alternativa por archivo (si prefieres edición de configuración):

  • Edita /boot/firmware/config.txt y asegúrate de tener:
    • dtparam=i2c_arm=on
    • dtparam=spi=on
  • Para el UART, usa:
    • enable_uart=1
  • Guarda y reinicia.

Aunque en este proyecto no usamos I2C/SPI de la Pi directamente con la FPGA, dejar estas interfaces activadas facilita validaciones y reuso de la Pi con sensores/expansores en el futuro.

Materiales

  • 1 × Raspberry Pi (4B o 5) con Raspberry Pi OS Bookworm 64-bit, acceso a Internet.
  • 1 × Tarjeta microSD (mín. 16 GB) y fuente oficial de Raspberry Pi.
  • 1 × Dispositivo: Pico-ICE (Lattice iCE40UP5K) — modelo exacto: “Pico-ICE (Lattice iCE40UP5K)”.
  • 1 × Cable USB (USB-A a micro-USB o USB-C a micro-USB según tu Pi).
  • 1 × Protoboard mini.
  • 1 × Pulsador momentáneo (tipo tact switch).
  • 4 × LEDs difusos 5 mm (o SMD sobre adaptador) para mostrar el contador en binario.
  • 4 × Resistencias 220 Ω (limitación de corriente de cada LED).
  • 1 × Resistencia 10 kΩ (pull-down del botón, si usas lógica de pull-up a 3V3).
  • 8–10 × Cables Dupont macho-macho.
  • Opcional (para validación con la Pi): 1 × Resistencia 1 kΩ para llevar una de las líneas de salida de la FPGA a un GPIO de la Pi y medir en software.

Nota: El Pico-ICE integra un RP2040 que facilita la programación del iCE40UP5K vía USB; usaremos ese camino con la herramienta iceprog/openFPGALoader incluida en oss-cad-suite.

Preparación y conexión

Activar firmware de programación del Pico-ICE (RP2040)

En la mayoría de unidades recientes, el Pico-ICE ya viene con firmware que expone un programador compatible con icestorm/iceprog a través de USB. Si necesitas actualizar o instalarlo:

1) Conecta el Pico-ICE a la Raspberry Pi manteniendo pulsado el botón BOOTSEL (en la parte RP2040).
2) Aparecerá un volumen USB “RPI-RP2”.
3) Copia el firmware “pico-ice.uf2” al volumen. Al soltarse, el dispositivo se reenumerará.
– Descarga de ejemplo (ajusta versión si tu proveedor indica otra):
– https://github.com/tinyvision-ai-inc/pico-ice/releases/download/v0.3.0/pico-ice.uf2
4) Desconecta y vuelve a conectar sin BOOTSEL. Debe aparecer un puerto serie tipo /dev/ttyACM0.

Comprueba el puerto:

ls -l /dev/serial/by-id/
# Ejemplo de salida: usb-RP2040_Pico-ICE_Programmer_XXXXXXXX-if00

Asegúrate de que tu usuario puede acceder al dispositivo USB serie:

sudo usermod -aG dialout $USER
newgrp dialout

Conexiones de botón y LEDs al Pico-ICE

Usaremos IOs de la FPGA expuestos en los encabezados del Pico-ICE. Si tu placa está serigrafiada con nombres de pines en los conectores, seguiremos una convención típica de “PMOD” (8 señales por conector). En la tabla siguiente usamos nombres lógicos que asignaremos en el fichero de constraints (.pcf):

  • Señales de usuario:
  • BTN_IN: entrada desde el pulsador (con pull-down externo 10 kΩ y el otro extremo del pulsador a 3V3)
  • LED0..LED3: salidas a cuatro LEDs en binario (anodo a IO, cátodo a resistencia 220 Ω y a GND)

Conecta así:

  • Pulsador:
  • Un terminal del pulsador a 3V3 del Pico-ICE.
  • El otro terminal del pulsador al pin FPGA asignado a BTN_IN.
  • Entre ese mismo pin y GND coloca una resistencia de 10 kΩ (pull-down).
  • LEDs:
  • Anodo de cada LED a un pin de FPGA (LED0, LED1, LED2, LED3).
  • Cátodo de cada LED a una resistencia de 220 Ω; el otro extremo de la resistencia a GND.

Para claridad, aquí tienes una tabla de referencia de conexiones físicas (ajústala a tu serigrafía; los nombres de “Header” y “Pin” son representativos y se ligan en el .pcf):

Señal HDL Header Pico-ICE Pin header Conexión física Comentario
3V3 PWR 3V3 3V3 → un lado del pulsador Alimentación lógica
GND PWR GND GND → resistencias y pulldown Referencia
BTN_IN PMOD A 1 BTN_IN ↔ pulsador y 10 kΩ a GND Entrada con pulldown
LED0 PMOD A 2 LED0 → anodo LED0 → 220 Ω → GND Bit 0
LED1 PMOD A 3 LED1 → anodo LED1 → 220 Ω → GND Bit 1
LED2 PMOD A 4 LED2 → anodo LED2 → 220 Ω → GND Bit 2
LED3 PMOD A 5 LED3 → anodo LED3 → 220 Ω → GND Bit 3

Nota: Los nombres “PMOD A”, “pin 1..5” representan los 5 IO que usaremos; el Pico-ICE ofrece más IOs, pero con estos basta. En el fichero de constraints .pcf asignaremos estos nombres HDL a los pines de paquete correctos del iCE40UP5K (package sg48).

Si planeas validar adicionalmente con la Raspberry Pi leyendo un GPIO:
– Conecta LED0 (a través de una resistencia extra de 1 kΩ en serie para protección) a un GPIO de la Pi (por ejemplo BCM 23, pin físico 16 en el cabezal de 40 pines).
– Conecta GND del Pico-ICE y GND de la Pi en común.

Código completo (Verilog para iCE40UP5K)

Implementaremos:
– Un oscilador interno (SB_HFOSC) para el clock.
– Sincronizador de dos flip-flops para la señal de botón (evita metastabilidad).
– Filtro por antirrebote: un contador que detecta estabilidad por N ciclos (p.e. 20 ms).
– Detección de flanco de subida y sumador del contador.
– Salida del contador a 4 LEDs.

Archivo: src/top.v

// top.v - Botón antirrebote y contador en iCE40UP5K (Pico-ICE)
// Nivel: básico

module top (
    input  wire BTN_IN,       // Entrada del pulsador (a 3V3 con pulldown de 10k a GND)
    output wire LED0,         // Salidas a LEDs (anodo a pin, cátodo por 220Ω a GND)
    output wire LED1,
    output wire LED2,
    output wire LED3
);
    // ------------------------------------------------------------
    // 1) Reloj interno a ~12 MHz a partir de SB_HFOSC (48 MHz / 4)
    // ------------------------------------------------------------
    wire clk_48mhz;
    SB_HFOSC #(
        .CLKHF_DIV("0b10") // 00:48 MHz, 01:24 MHz, 10:12 MHz, 11:6 MHz (documentación Lattice)
    ) hfosc_inst (
        .CLKHFEN(1'b1),
        .CLKHFPU(1'b1),
        .CLKHF(clk_48mhz)
    );
    wire clk = clk_48mhz; // ~12 MHz

    // ------------------------------------------------------------
    // 2) Sincronizador de 2 etapas para BTN_IN
    // ------------------------------------------------------------
    reg btn_sync_0 = 1'b0;
    reg btn_sync_1 = 1'b0;
    always @(posedge clk) begin
        btn_sync_0 <= BTN_IN;
        btn_sync_1 <= btn_sync_0;
    end
    wire btn_sync = btn_sync_1;

    // ------------------------------------------------------------
    // 3) Antirrebote por contador de estabilidad:
    //    - samplea btn_sync; si cambia, resetea el contador
    //    - si se mantiene estable N ciclos, adopta el nuevo estado "btn_debounced"
    // ------------------------------------------------------------
    localparam integer CLK_HZ        = 12_000_000;  // aprox.
    localparam integer DEBOUNCE_MS   = 20;          // 20 ms antirrebote
    localparam integer DEBOUNCE_TICKS = (CLK_HZ / 1000) * DEBOUNCE_MS; // ~240_000

    reg         btn_state = 1'b0;         // último estado estable aceptado
    reg [19:0]  db_count = 20'd0;         // tamaño suficiente para DEBOUNCE_TICKS
    // Nota: 2^18 = 262,144 > 240,000, por lo que con 18-20 bits basta

    always @(posedge clk) begin
        if (btn_sync != btn_state) begin
            // si hay discrepancia, incrementa el contador hasta alcanzar DEBOUNCE_TICKS
            if (db_count < DEBOUNCE_TICKS[19:0])
                db_count <= db_count + 1'b1;
            else begin
                // alcanzó estabilidad: acepta el nuevo estado y resetea el contador
                btn_state <= btn_sync;
                db_count  <= 20'd0;
            end
        end else begin
            // no hay discrepancia: contador a cero (ya estamos estables)
            db_count <= 20'd0;
        end
    end

    wire btn_debounced = btn_state;

    // ------------------------------------------------------------
    // 4) Detección de flanco de subida y contador de 4 bits
    // ------------------------------------------------------------
    reg btn_debounced_d = 1'b0;
    always @(posedge clk) begin
        btn_debounced_d <= btn_debounced;
    end
    wire btn_rising = btn_debounced & ~btn_debounced_d;

    reg [3:0] counter = 4'd0;
    always @(posedge clk) begin
        if (btn_rising) begin
            counter <= counter + 4'd1; // incrementa en cada pulsación "real"
        end
    end

    // ------------------------------------------------------------
    // 5) Salida a LEDs
    // ------------------------------------------------------------
    assign LED0 = counter[0];
    assign LED1 = counter[1];
    assign LED2 = counter[2];
    assign LED3 = counter[3];

endmodule

Archivo de constraints: src/pico-ice.pcf

Este archivo asocia los puertos HDL a pines físicos del iCE40UP5K (package sg48). Los nombres de pines exactos dependen del ruteo del fabricante del Pico-ICE hacia sus headers. A continuación se muestra un ejemplo representativo; si tu fabricante proporciona un .pcf oficial, úsalo tal cual y adapta los nombres HDL (BTN_IN, LED0..LED3) a los suyos. En ausencia de plantilla oficial, puedes partir de algo así y ajustarlo a tu serigrafía:

# pico-ice.pcf - Constraints para Pico-ICE (iCE40UP5K, package sg48)
# Ajusta A1/A2/... a los pines reales del header usado en tu Pico-ICE.

# Reloj interno SB_HFOSC no requiere constraints.

# Entrada de botón con pulldown externo (BTN_IN).
# Sustituye 'A2' por el pin real de tu header mapeado a la FPGA.
set_io BTN_IN A2

# Salidas a LEDs (LED0..LED3).
# Sustituye 'B3 B4 C3 C4' por los pines reales del header mapeado a la FPGA.
set_io LED0 B3
set_io LED1 B4
set_io LED2 C3
set_io LED3 C4

Explicación breve de cada parte clave:
– SB_HFOSC: usa el oscilador RC interno de la FPGA; con divisor “0b10” obtenemos ~12 MHz, suficiente para el filtro de 20 ms (resolución ~83 ns) y lógica de contador.
– Sincronizador: dos FF en serie reducen el riesgo de metastabilidad al muestrear señales asíncronas (el botón).
– Antirrebote: con un contador de estabilidad N ciclos; si el nivel cambia antes de N, se descarta; si permanece, el nuevo nivel se acepta como estable.
– Flanco de subida: compara el valor actual con el anterior; un 1 seguido de 0 detecta un flanco. Aquí usamos subida (0→1) ya que el botón aplica 3V3 al pulsar.
– Contador: 4 bits, visible en 4 LEDs en binario. Cada pulsación física “única” incrementa en 1.

Compilación, programación y ejecución

Estructura del proyecto (recomendada):

mkdir -p ~/pico-ice-boton-contador/src
cd ~/pico-ice-boton-contador
# Copia los archivos top.v y pico-ice.pcf a la carpeta src/

Comandos exactos con la toolchain instalada (oss-cad-suite 2024-05-19):

# 1) Activa el entorno de la toolchain en cada terminal nuevo
source ~/oss-cad-suite/environment

# 2) Síntesis con yosys
yosys -p "read_verilog src/top.v; synth_ice40 -top top -json build/top.json" -q
# -q reduce la verbosidad

# 3) Place & Route con nextpnr-ice40 (up5k, paquete sg48)
nextpnr-ice40 --up5k --package sg48 \
  --json build/top.json --pcf src/pico-ice.pcf --asc build/top.asc \
  --freq 12

# 4) Genera bitstream binario con icepack
icepack build/top.asc build/top.bin

# 5) Programa la FPGA (SRAM, no persistente) a través del RP2040 del Pico-ICE
#    Ajusta /dev/ttyACM0 al puerto detectado en tu sistema.
iceprog -S -d /dev/ttyACM0 build/top.bin

# 6) (Opcional) Programa a la Flash para que sea persistente al encendido:
#    Esto sobrescribe la configuración de la FPGA al boot.
#    Asegúrate de que quieres hacerlo antes.
# iceprog -d /dev/ttyACM0 build/top.bin

Notas:
– Si iceprog no detecta el programador, verifica con ls -l /dev/serial/by-id y usa esa ruta como -d.
– Para un flujo alternativo con openFPGALoader (si tu firmware soporta interfaz genérica):
– openFPGALoader -c pico -f build/top.bin
– Ajusta el programador (-c) si tu firmware expone otro driver.

Comprobación de recursos y temporización:
– Revisa los informes de nextpnr (en consola) para confirmar que cumple con la frecuencia objetivo (12 MHz). En este proyecto, la lógica es pequeña y no habrá problemas de timing.

Validación paso a paso

Objetivo: Confirmar que cada pulsación del botón incrementa el contador en exactamente una unidad, sin “saltos” por rebotes.

1) Verificación eléctrica básica:
– ¿LEDs conectados con la orientación correcta? Anodo al pin FPGA, cátodo a resistencia de 220 Ω y luego a GND.
– ¿Pulsador correctamente cableado? Un lado a 3V3; el otro al pin BTN_IN; resistencia de 10 kΩ entre ese pin y GND.
– ¿GND común entre todos los elementos (Pico-ICE, protoboard, Pi si la conectas para validación)?

2) Programación:
– Ejecuta la secuencia de compilación y programación (iceprog -S …). Debe finalizar sin errores.
– Tras programar, los LEDs mostrarán algún valor binario inicial (probablemente 0000).

3) Pruebas funcionales:
– Pulsa y suelta el botón con una pulsación limpia (≈100–200 ms).
– Observa que el patrón binario LED3..LED0 incrementa en 1 (0→1→2→3→…).
– Realiza varias pulsaciones seguidas, incluyendo algunas muy rápidas:
– Debe seguir incrementando de uno en uno; incluso si haces vibrar el botón, el antirrebote por hardware debe evitar múltiples incrementos por una única interacción.
– Mantén el botón presionado (varios segundos):
– No deben ocurrir incrementos continuos; el incremento ocurre al flanco de subida (al presionar). Al soltar no incrementa; al volver a presionar, incrementa otra vez.

4) Prueba de saturación:
– Al llegar a 15 (1111), la siguiente pulsación desbordará a 0 (0000). Es el comportamiento esperado del contador de 4 bits.

5) Validación adicional con la Raspberry Pi (opcional):
– Si conectaste LED0 a un GPIO de la Pi (por ejemplo BCM 23, con una resistencia extra de 1 kΩ), puedes muestrear su estado con Python.

Ejecuta este script en la Pi (con el venv activado):

# tools/monitor_led0.py
# Lee un GPIO de la Pi (BCM 23) para observar cambios del bit LSB del contador

import time
from gpiozero import LED  # usaremos LED como salida falsa para configurar, pero necesitamos InputDevice
from gpiozero import InputDevice

PIN = 23  # BCM 23

led0_in = InputDevice(PIN, pull_up=False)  # Asumimos que la línea ya tiene la referencia a GND

last = led0_in.value
print("Monitorizando LED0 (bit 0 del contador) en BCM 23. Pulsa el botón en el FPGA.")
try:
    while True:
        v = led0_in.value
        if v != last:
            print(f"Cambio detectado: {last} -> {v} @ {time.time():.3f}")
            last = v
        time.sleep(0.01)
except KeyboardInterrupt:
    pass

Ejecuta:

source ~/venv-fpga/bin/activate
python tools/monitor_led0.py
  • Al pulsar el botón, verás cambios en el bit menos significativo (LED0), alternando 0/1 en cada incremento del contador. Esto corrobora que solo cambia una vez por pulsación.

6) Ajuste fino del antirrebote (si fuese necesario):
– Si tu botón es muy “ruidoso” y aún ves dobles incrementos, incrementa DEBOUNCE_MS de 20 a 30–40 ms en top.v, recompila y reprográmalo.
– Si, por el contrario, quieres un sistema muy sensible, puedes reducirlo a 10–15 ms.

Troubleshooting

1) No aparece /dev/ttyACM0 al conectar el Pico-ICE:
– Causa: firmware del RP2040 ausente o no actualizado.
– Solución: entra en modo BOOTSEL, monta “RPI-RP2” y copia el UF2 del programador (pico-ice.uf2) compatible con iceprog. Vuelve a conectar y verifica con ls -l /dev/serial/by-id/.

2) Permisos denegados al usar iceprog:
– Causa: usuario no está en el grupo dialout o reglas udev.
– Solución: sudo usermod -aG dialout $USER; cierra sesión o ejecuta newgrp dialout. Reintenta.

3) nextpnr-ice40 falla con error de package o device:
– Causa: selección de chip o paquete incorrectos.
– Solución: para Pico-ICE usa iCE40UP5K con paquete sg48:
– nextpnr-ice40 –up5k –package sg48 …
– Verifica que el .pcf no haga referencia a pines inexistentes del paquete sg48.

4) Conflicto de pines en el .pcf:
– Causa: dos señales asignadas al mismo pin o pines reservados (como JTAG/CONFIG).
– Solución: revisa pico-ice.pcf y asigna pines únicos. Consulta la documentación del fabricante del Pico-ICE para las correspondencias reales del header a pines del iCE40UP5K.

5) LEDs no encienden:
– Causa: polaridad invertida o resistencias mal conectadas.
– Solución: recuerda: anodo del LED al pin de la FPGA; cátodo a resistencia 220 Ω; resistencia a GND. Comprueba continuidad y GND común.

6) El contador salta más de 1 por pulsación:
– Causa: rebotes del botón superan el filtro (DEBOUNCE_MS muy bajo) o cableado flojo.
– Solución: aumenta DEBOUNCE_MS a 30–40 ms y recompila. Asegura conexiones firmes. Verifica el pull-down de 10 kΩ.

7) iceprog no programa (time-out):
– Causa: puerto incorrecto o interferencia de otro dispositivo / tty ocupa el puerto.
– Solución: identifica el puerto con ls -l /dev/serial/by-id y úsalo en -d. Cierra cualquier monitor serie. Reintenta.

8) Mucho jitter en validación por GPIO de la Pi:
– Causa: cableado largo o sin resistencia de protección.
– Solución: añade la resistencia en serie de ~1 kΩ y mantén GND común. Usa un muestreo no demasiado rápido (10 ms) en el script de Python, solo con fines de verificación.

Mejoras y variantes

  • Reset del contador:
  • Añade una segunda entrada (BTN_RST) con otro pulsador y lógica de antirrebote compartida o independiente para resetear el contador a 0.

  • Detección de pulsación larga:

  • Amplía el antirrebote con un temporizador que distinga pulsación corta (incrementa) y larga (resetea o hace auto-incremento).

  • Más bits o display 7 segmentos:

  • Amplía el contador a 8 bits y muestra en un display de 7 segmentos multiplexado. Implementa un “divisor de frecuencia” para el multiplexado y añade constraints para los segmentos y dígitos.

  • Código Gray o BCD:

  • Convierte el binario a Gray (útil en sistemas que leen cambios de un solo bit) o a BCD, partiendo de un conversor binario→BCD.

  • Filtro alternativo de antirrebote:

  • Implementa una ventana de muestreo con registro de desplazamiento (N muestras iguales antes de cambiar estado) en lugar de un contador de estabilidad.

  • Persistencia en flash:

  • Programa la configuración en la flash externa para autoarranque (iceprog build/top.bin sin -S). Útil si deseas que el contador esté disponible tras cada alimentación.

  • Comunicación con la Pi:

  • Añade un UART simple en la FPGA para enviar el valor del contador y leerlo desde Python (pyserial), o usa un protocolo sencillo via un pin adicional.

Checklist de verificación

Usa esta lista para confirmar que has cumplido cada paso:

  • [ ] Raspberry Pi OS Bookworm 64-bit actualizado (sudo apt update && sudo apt full-upgrade).
  • [ ] Entorno Python 3.11 creado y activado (venv) con gpiozero/pyserial/smbus2/spidev instalados.
  • [ ] oss-cad-suite 2024-05-19 descargado y “source ~/oss-cad-suite/environment” ejecutado.
  • [ ] Verificado yosys -V, nextpnr-ice40 –version, icepack -V sin errores.
  • [ ] Firmware de programador del Pico-ICE activo; /dev/ttyACM0 o /dev/serial/by-id/ visible.
  • [ ] Conexiones: botón a 3V3 con pulldown 10 kΩ y a BTN_IN; LEDs con 220 Ω a GND en LED0..LED3.
  • [ ] top.v y pico-ice.pcf creados en src/ con nombres de señales coherentes (BTN_IN, LED0..LED3).
  • [ ] Flujo de build ejecutado: yosys → nextpnr → icepack → iceprog -S exitoso.
  • [ ] Validación: contador incrementa 1 por pulsación; sin rebotes observables.
  • [ ] (Opcional) Validación con la Pi leyendo LED0 por GPIO y script Python.
  • [ ] Ajustes de DEBOUNCE_MS probados si se observaron dobles incrementos.
  • [ ] Variantes exploradas (opcional): reset, pulsación larga, más bits o display.

Con estos pasos habrás implementado un antirrebote por hardware y un contador en el iCE40UP5K del Pico-ICE, usando la Raspberry Pi como estación de desarrollo con Raspberry Pi OS Bookworm 64-bit y Python 3.11. La solución es compacta, robusta frente a rebotes mecánicos y fácilmente extensible a otros periféricos y lógicas más complejas.

Encuentra este producto y/o libros sobre este tema en Amazon

Ir a Amazon

Como afiliado de Amazon, gano con las compras que cumplan los requisitos. Si compras a través de este enlace, ayudas a mantener este proyecto.

Quiz rápido

Pregunta 1: ¿Qué dispositivo se utiliza como host de desarrollo en este caso práctico?




Pregunta 2: ¿Cuál es el sistema operativo mencionado para el host?




Pregunta 3: ¿Qué versión de Python se incluye en Raspberry Pi OS Bookworm?




Pregunta 4: ¿Cuál es el nombre de la toolchain utilizada para iCE40UP5K?




Pregunta 5: ¿Qué comando se usa para actualizar el sistema en la Raspberry Pi?




Pregunta 6: ¿Qué paquetes Python se instalan para validación y utilidades?




Pregunta 7: ¿Cuál es el primer paso para preparar el entorno base en la Raspberry Pi?




Pregunta 8: ¿Qué herramienta se menciona para manejar la FPGA?




Pregunta 9: ¿Qué comando se utiliza para activar el entorno virtual de Python?




Pregunta 10: ¿Qué tipo de módulo se pretende crear en la FPGA?




Carlos Núñez Zorrilla
Carlos Núñez Zorrilla
Electronics & Computer Engineer

Ingeniero Superior en Electrónica de Telecomunicaciones e Ingeniero en Informática (titulaciones oficiales en España).

Sígueme:
Scroll al inicio