Skip to content

i2c proxy bug1: SDA could while playback SCL is high #496

@nathanaelhuffman

Description

@nathanaelhuffman

In PLAY_STORED_DATA, the playback_scl_redge branch transitions to ENSURE_PLAYBACK_HOLD when v.playback_bits = sample_r.bit_count and cpu_scl_in = '1':

-- line 335-345
if playback_scl_redge = '1' then
    v.playback_bits := mux_r.playback_bits + 1;
    if v.playback_bits = sample_r.bit_count and cpu_scl_in = '1' then
        v.state := ENSURE_PLAYBACK_HOLD;
        ...
        v.dimm_sda_oe := not cpu_sda_in;   --  <--maybe problem
    end if;

mux_r.dimm_sda_oe changes in the cycle after the rising playback SCL edge — but playback_r.scl_out will still be '1' (SCL is high). Changing SDA while SCL is high is a start/stop condition to any I2C target watching the bus. The same class of bug possibly exists in the corresponding branch at lines 349–357 (the fedge branch with cpu_scl_in = '0' is fine; the redge branch is not).

Possible fix:
only transition to ENSURE_PLAYBACK_HOLD on playback_scl_fedge branches — never on playback_scl_redge. If cpu_scl_in = '1' on the rising edge, just let the playback counter run to the next falling edge and re-evaluate. The ENSURE_PLAYBACK_HOLD hold timer gives the glitch margin; you don't need to also move the transition to the rising edge.

Note that this is by analysis and sim only, I haven't managed to capture this bug actually occurring in hw, but that doesn't mean it can't or doesn't!

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions