; ; bus_watch.pio — I2C 总线被动边沿捕获(RP2040 PIO) ; ================================================== ; 思路同 pico-examples 的 logic_analyser: 硬件只做最难的"确定性捕获" ; (电平变化即压入 FIFO), 协议解码(I2C 状态机)留给 CPU——与 PC 端 ; i2cdec.py 共享同一套算法语义(源自 I2C-Inject 真机验证的 ; i2c_sniff_decode.py)。 ; ; 接线约定(沿用 I2C-Inject): GP8=SDA, GP9=SCL, 共地, 不加上拉, ; 纯输入不驱动(开漏总线零干扰)。 ; 引脚映射: in_base = GP8 → ISR/X/Y 的 bit0=SDA bit1=SCL。 ; ; 每个 FIFO 字 = 新电平值(0..3)。时间戳由 CPU 取(边沿间隔 ≥ 500ns, ; 核1 专职轮询, 抖动远小于 1us)。 ; 环形轮询 5 条指令 @250MHz = 20ns/圈, 可分辨 ~40ns 毛刺; ; push noblock: FIFO 满则丢当前沿(Y 已更新, 后续沿仍连续可解, ; CPU 侧以"双位同变"启发式统计疑似丢沿)。 .program bus_watch top: mov isr, null ; ISR 清零(低 2 位待填) in pins, 2 ; ISR[1:0] = SCL<<1 | SDA mov x, isr jmp x != y, changed ; 电平有变 -> 送出 jmp top ; 无变 -> 继续盯 changed: mov y, x ; 先更新基线(即使 push 被丢也不失步) push noblock ; 送出新电平(FIFO 满则丢弃) jmp top