import machine
import time
import micropython
# Reservar espacio estático en RAM para diagnóstico de errores dentro de la ISR
micropython.alloc_emergency_exception_buf(100)
# ============================================================================
# CONFIGURACIÓN DE HARDWARE (GPIO)
# ============================================================================
# LED en GPIO 6 controlado por la alarma física del chip (Hard IRQ)
led_timer = machine.Pin(6, machine.Pin.OUT)
# LEDs en GPIO 7 y 8 controlados por el hilo del programa principal (Main Loop)
led_main_1 = machine.Pin(7, machine.Pin.OUT)
led_main_2 = machine.Pin(8, machine.Pin.OUT)
# ============================================================================
# RUTINA DE SERVICIO DE INTERRUPCIÓN (ISR DE HARDWARE)
# ============================================================================
# Se ejecuta a nivel de vectores del NVIC. No debe alojar memoria.
def isr_hardware_timer(timer):
led_timer.toggle() # Conmutación limpia de registros de E/S
# ============================================================================
# INICIALIZACIÓN DEL TIMER DE HARDWARE PURO
# ============================================================================
# IMPORTANTE: Al no pasar ningún ID (paréntesis vacíos), MicroPython enlaza
# directamente el objeto al periférico de control de tiempo real del silicio.
t_hardware = machine.Timer()
# Configuración del registro de comparación a 200 ms (Frecuencia: 5 Hz)
t_hardware.init(period=200, mode=machine.Timer.PERIODIC, callback=isr_hardware_timer)
print("Inicializado utilizando el bloque de temporización por hardware del chip.")
print("Ejecutando tareas concurrentes...")
# ============================================================================
# BUCLE PRINCIPAL (MAIN LOOP)
# ============================================================================
try:
while True:
# Los GPIO 7 y 8 cambian de estado en el hilo principal
led_main_1.toggle()
led_main_2.toggle()
# Este retardo bloquea la CPU en el hilo principal por 500 ms...
time.sleep_ms(500)
# ... pero la línea IRQ física del timer despertará al núcleo cada 200 ms
# de manera exacta para ejecutar la ISR, interrumpiendo este sleep.
except KeyboardInterrupt:
# Desactivación obligatoria del periférico de hardware al salir
t_hardware.deinit()
# Apagar las líneas GPIO por seguridad eléctrica
led_timer.off()
led_main_1.off()
led_main_2.off()
print("\nPeriférico de hardware liberado y LEDs apagados.")