Код MicroPython
import rp2
from machine import Pin
import time
PIN_NUM = 6
INITIAL = 0xFFFFFFFF  # стартовое значение для счетчика
@rp2.asm_pio()
def freq_counter():
    pull()                  # берём INITIAL из TX-FIFO
    mov(y, osr)            # заполняем У чтобы не дергать фифо каждый раз
    wrap_target() # переходим в основной цикл 
    mov(x, y) # заполняем Х для вычитания из него кол-ва тактов прошедших за момент низкого уровня
    wait(1, pin, 0)         # ждём первого фронта
    wait(0, pin, 0)         # ждём первого спада
    label("count_loop")
    jmp(pin, "done")        # если фронт — выходим
    jmp(x_dec, "count_loop") # иначе декремент X, и назад (считаем сколько тактов сигнал был в 0)
    label("done")
    mov(isr, x)             # сохраняем остаток в ISR
    push()                  # отправляем в RX-FIFO
    wrap()
sm = rp2.StateMachine(
    0, freq_counter,
    freq=100_000_000,       # скорость ПИО = 100 МГц
    in_base=Pin(PIN_NUM),
    jmp_pin=Pin(PIN_NUM)
)
sm.put(INITIAL)         # даём INITIAL
sm.active(1)
while True:
    while not sm.rx_fifo(): # ждём, когда PIO пульнет результат
        pass
    ticks = INITIAL - sm.get()        # читаем число тактов
    freq = 100_000_000 // ticks if ticks else 0
    print(f"Частота: {freq / 1000000:.3f} МГц, Такты: {ticks}")
    time.sleep(0.2)
При этом, скорее всего, часть тактов занимаемых инструкциям подсчета не учитывается.
Как учесть эту погрешность, т.к сейчас при стабильном клоке в 1мгц на входе частота подсчитывается под 3мгц.
Если на входе 8 МГц, то вообще не удаётся считать — вывода нет, хотя запас должен быть, и даже большой: ведь частота дискретизируемого сигнала как минимум в 5 раз меньше частоты дискретизации, чего должно хватать.