Skip to content

Add battery management interrupt handling for safe I2C communication #173

@cptkoolbeenz

Description

@cptkoolbeenz

Background

Issue #172 revealed that continuous I2C polling to the BQ24297 battery management IC was causing hangs in the PowerAndUITask, leading to LED unresponsiveness. The fix replaced I2C polling with GPIO/ADC-based status reading.

However, there are scenarios where I2C communication with the BQ24297 is still needed (e.g., configuration changes, detailed diagnostics). This ticket tracks implementing proper interrupt-driven I2C communication.

Primary Goal: BATT_MAN_INT Pin Interrupt Handling

The BQ24297 has an interrupt output pin (BATT_MAN_INT / INT pin) that goes low when any of the following occur:

  • Charging status change
  • Fault condition (watchdog, safety timer, thermal, etc.)
  • Power good status change
  • Input voltage/current limit change

Implementation:

  1. Configure BATT_MAN_INT GPIO as change notification interrupt input
  2. On interrupt (falling edge), set a flag indicating BQ24297 status changed
  3. In PowerAndUITask, when flag is set:
    • Perform I2C read of status/fault registers
    • Update power state accordingly
    • Clear the flag
  4. This replaces continuous polling with event-driven updates

Deferred Interrupt Handler

Use a deferred interrupt pattern to avoid I2C operations during time-critical streaming:

  1. ISR (minimal work): On BATT_MAN_INT falling edge, set bq24297_status_changed flag and return
  2. Deferred task: PowerAndUITask checks flag during its normal loop
  3. Streaming awareness: If streaming is active (especially high-frequency), defer I2C read until:
    • Streaming stops, OR
    • A safe window between samples, OR
    • A timeout expires (for critical faults)

This ensures I2C bus contention doesn't affect ADC sampling timing during high-frequency acquisition.

Safe I2C Communication Requirements

When implementing I2C reads in response to the interrupt:

  • Streaming check: Do not initiate I2C transactions while streaming is active (or defer until streaming stops)
  • Critical sections: Add FreeRTOS critical sections if the Harmony I2C driver is not fully thread-safe
  • Timeout handling: Consider adding timeout wrapper around I2C operations (Harmony driver uses OSAL_WAIT_FOREVER)

Investigation Notes

  • I2C intermittent failures were observed but may have been caused by our polling frequency (~70 reads/sec on USB power)
  • The root cause of I2C hangs is not fully confirmed - could be bus contention, timing, or driver issues
  • Further investigation needed once interrupt-based approach is implemented
  • The interrupt-driven approach should dramatically reduce I2C traffic and help isolate any remaining issues

Hardware Notes

  • BATT_MAN_INT pin: Active low, directly connected to MCU GPIO
  • USB VBUS sag condition: During power rail transitions (e.g., SYST:POW:STAT 1), the VBUS voltage can sag from "Valid" to "Medium", triggering false USB_DEVICE_EVENT_POWER_REMOVED events. The current fix checks the hardware VBUS level directly via PLIB_USBHS_VBUSLevelGet() to filter these false positives.

Related

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