Skip to content

No generic contract for devices on the PRU pins: IOPort hosts one hard-wired TCA9538, and every new device needs a core hook #43

Description

@pratheesh

Problem

The simulator models the PRU well and the wire hardly at all. IOPort holds gpo/gpi words, and the only external device it can host is hard-wired:

  • IOPort.attach_i2c_device() takes exactly one TCA9538, with SCL/SDA frozen at pins 0/1.
  • Every other stimulus model grew its own shape and its own hook: UARTFrameGenerator.tick() is called from inside PRUCore.step(), SigmaDeltaFilter has its own path, and Loopback.sample(channel, t_ns) is a wire rather than a device.

The result is that each new external device (an encoder, an ADC, a motor/inverter plant, a second PRU's pins) needs another special case in IOPort and another hook in PRUCore.step(). PR #41 shows the pattern directly: it adds io_port.ssi_generator as a second hard-coded pre-tick in the core, plus a separate add_wire_callback mechanism for core-to-core wires.

There is also no electrical model of a shared net. With more than one driver, nothing resolves open-drain wired-AND (I2C, I3C, 1-Wire), and nothing flags two push-pull drivers fighting, which is a real short on hardware and a firmware bug the simulator should report.

Proposal

One contract for anything wired to the PRU's pins:

  • DeviceModel.tick(cycle, bus) -> (drive_mask, drive_values): a device reports what it drives, not the resulting level, because only the bus can resolve several drivers.
  • DeviceModel.events(): protocol-level decode (what the device believes it received), for comparison against an independent decoder.
  • DeviceModel.faults(): protocol violations. A model that cannot reject wrong firmware is not a useful test oracle.
  • The existing reset() / snapshot() / restore() / get_state() convention, so step-back and UI state keep working.
  • DeviceBus: resolves the PRU and every attached device per pin, as OPEN_DRAIN (wired-AND with pull-up) or PUSH_PULL (contention recorded as a fault).
  • IOPort.attach_device(), which is opt-in and leaves pins that no device drives alone.

Existing paths (attach_i2c_device, UART generator, loopback) keep working unchanged; they can migrate later.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions