diff --git a/kernel/iec_listener.c b/kernel/iec_listener.c index 3d73d4b..7e25d49 100644 --- a/kernel/iec_listener.c +++ b/kernel/iec_listener.c @@ -242,7 +242,16 @@ static enum iec_rx receive_byte(u8 *out, bool *eoi, bool data_phase) value |= (1u << i); } - /* 4. BYTE ACKNOWLEDGE: pull DATA low (Tf), hold for the next RFD */ + /* 4. BYTE ACKNOWLEDGE: wait for the talker to pull CLK low at end of + * byte (mirrors the reference listener), THEN pull DATA low (Tf). + * Without this wait we would assert the ack while CLK is still high + * from bit 7, racing the talker's end-of-byte edge and desyncing the + * handshake. The next receive_byte() releases DATA after CLK goes high + * again (RFD), completing the per-byte handshake. */ + rc = wait_clk(true /* asserted: talker finished the byte */, + IEC_CLK_TIMEOUT_US, data_phase); + if (rc != IEC_RX_OK) + goto out; iec_data_assert(); *out = value; rc = IEC_RX_OK;