feat: I2C sensor support (config packet + data protocol) #50

Open
opened 2026-08-29 20:53:57 +00:00 by time · 1 comment
Contributor

Support low-power I2C sensors that don't require a warm-up period (this rules out most VOC/chemical sensors).

Hardware I2C conflicts with the TX on this rev. The MSSP1 I2C peripheral is fixed to RA1 (SCL) + RA2 (SDA) — there is no APFCON pin selection for I2C. RA2 is currently the TX DATA pin, so hardware I2C cannot run alongside the TX without moving the TX. Decision: bit-bang I2C (master-only) on any 2 GPIOs, which sidesteps the fixed-pin conflict and matches the rewire.

Bit-banged I2C details:

  • No ODCON on this part (GPIOs are push-pull), so emulate open-drain: drive low with the push-pull output, release high by setting the pin to input + enabling the WPUA weak pull-up + an external pull-up resistor on the bus.
  • No clock-stretch detection (we cannot see SCL held low by the sensor) — acceptable for fast, simple sensors.
  • 100 kbit/s = 10 µs/bit ≈ 10 CPU cycles/bit at 1 MHz — trivial. A minimal master driver (start/stop, byte write/read, NACK) is ~100–150 words of program memory.

TX-sleep invariant (firmware): I2C SDA idles high. The RF TX wakes and transmits when DATA is held high longer than tOFFT. So if an I2C pin ever shares a TX pin, DATA must be held low otherwise the TX wakes and transmits the SDA line. With the planned hardware MUX (next rev), the TX is physically isolated when not in use. The firmware must track TX asleep/awake as state.

Two parts:

  1. An initial configuration packet — written to the sensor (e.g. adjust the range of a PHT sensor, or set its data output format). Stored in the device config so it is re-sent on each wakeup.
  2. A data-request protocol — a per-wakeup sequence to read the sensor's data and place it in the transmitted packet.

Open questions:

  • which I2C sensors to target first (PHT = pressure/humidity/temperature? e.g. SHT3x, BME280 — but only those with fast, low-power reads and no warm-up)
  • I2C bus speed (low-power vs. speed tradeoff) and whether to gate the bus / power the sensor only during the read window
  • final I2C pin assignment (2 GPIOs) once the rewire is settled
  • how to represent the per-sensor config (address, init bytes, read command, data format) in the config store
  • how the sensor data maps into the packet format (and how the host tool's decoder generator handles it)
Support low-power I2C sensors that don't require a warm-up period (this rules out most VOC/chemical sensors). **Hardware I2C conflicts with the TX on this rev.** The MSSP1 I2C peripheral is fixed to RA1 (SCL) + RA2 (SDA) — there is no APFCON pin selection for I2C. RA2 is currently the TX DATA pin, so hardware I2C cannot run alongside the TX without moving the TX. **Decision: bit-bang I2C** (master-only) on any 2 GPIOs, which sidesteps the fixed-pin conflict and matches the rewire. **Bit-banged I2C details:** - No ODCON on this part (GPIOs are push-pull), so emulate open-drain: drive low with the push-pull output, release high by setting the pin to input + enabling the WPUA weak pull-up + an external pull-up resistor on the bus. - No clock-stretch detection (we cannot see SCL held low by the sensor) — acceptable for fast, simple sensors. - 100 kbit/s = 10 µs/bit ≈ 10 CPU cycles/bit at 1 MHz — trivial. A minimal master driver (start/stop, byte write/read, NACK) is ~100–150 words of program memory. **TX-sleep invariant (firmware):** I2C SDA idles high. The RF TX wakes and transmits when DATA is held high longer than tOFFT. So if an I2C pin ever shares a TX pin, DATA must be held low otherwise the TX wakes and transmits the SDA line. With the planned hardware MUX (next rev), the TX is physically isolated when not in use. The firmware must track TX asleep/awake as state. Two parts: 1. An initial configuration packet — written to the sensor (e.g. adjust the range of a PHT sensor, or set its data output format). Stored in the device config so it is re-sent on each wakeup. 2. A data-request protocol — a per-wakeup sequence to read the sensor's data and place it in the transmitted packet. Open questions: - which I2C sensors to target first (PHT = pressure/humidity/temperature? e.g. SHT3x, BME280 — but only those with fast, low-power reads and no warm-up) - I2C bus speed (low-power vs. speed tradeoff) and whether to gate the bus / power the sensor only during the read window - final I2C pin assignment (2 GPIOs) once the rewire is settled - how to represent the per-sensor config (address, init bytes, read command, data format) in the config store - how the sensor data maps into the packet format (and how the host tool's decoder generator handles it)
Owner

MS8607 will likely be the first targeted sensor.

MS8607 will likely be the first targeted sensor.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
daru/PICsense#50
No description provided.