Claude bcb3ab5dd8 [gpio_expander] Add interrupt pin support for efficient event-driven operation
This commit adds interrupt-based GPIO expander support to eliminate continuous
polling and significantly reduce I2C/SPI traffic and CPU usage.

## Key Changes

### Core Infrastructure (gpio_expander/cached_gpio.h)
- Extended CachedGpioExpander base class with interrupt pin support
- Added setup_interrupt_pin() method to attach native GPIO interrupt handlers
- Implemented interrupt-driven cache management:
  - ISR sets flag and enables component loop when interrupt fires
  - process_interrupt_() reads chip-specific interrupt status registers
  - Cache remains valid between interrupts (no polling)
  - Component loop automatically disabled until next interrupt
- Added virtual read_interrupt_status_() for chip-specific implementations
- Maintains backward compatibility: interrupt_pin is optional, defaults to polling

### MCP23xxx Family Support
- MCP23x17 (16-pin): Added INTF/INTCAP register reading
- MCP23x08 (8-pin): Added INTF/INTCAP register reading
- Configured IOCON register for interrupt mirroring (INTA=INTB)
- Combined with existing open_drain_ints support
- Chips: MCP23017, MCP23008, MCP23S17, MCP23S08

### PI4IOE5V6408 Support
- Implemented interrupt status register (0x13) reading
- Reads input state register (0x0F) to capture values and clear interrupt
- Single 8-pin bank design

### Python Configuration
- Added CONF_INTERRUPT_PIN to component schemas
- Uses pins.internal_gpio_input_pin_schema for validation
- Optional configuration maintains full backward compatibility
- Example:
  ```yaml
  mcp23017:
    id: my_expander
    interrupt_pin: GPIO5  # Connect to INTA/INTB

  binary_sensor:
    - platform: gpio
      pin:
        mcp23xxx: my_expander
        number: 0
        interrupt: CHANGE  # Existing config, now uses hardware interrupt
  ```

### Testing
- Updated component test configurations
- Added interrupt_pin test cases for both MCP23017 and PI4IOE5V6408
- Tests both polling mode (no interrupt_pin) and interrupt mode

## Benefits

| Aspect         | Before (Polling) | After (Interrupts) |
|----------------|------------------|-------------------|
| I2C Reads      | 60-120/sec       | 2 per state change|
| CPU Usage      | Continuous loop  | ISR + event-driven|
| Latency        | ~16ms (loop)     | <1ms (ISR)        |
| Power          | Higher           | Lower (sleep)     |

## Implementation Details

**Interrupt Flow:**
1. Setup: Native GPIO interrupt attached to INTA/INTB pin (FALLING edge)
2. ISR: Sets pending flag, calls enable_loop_soon_any_context()
3. Loop: Reads interrupt status register to identify changed pins
4. Cache: Updates only changed pins, keeps cache valid
5. Optimization: Calls disable_loop() until next interrupt

**Safety:**
- Uses volatile bool for interrupt_pending_ flag
- IRAM_ATTR on ISR for fast execution
- Gracefully falls back to polling if interrupt_pin not configured
- No changes required to binary_sensor platform code

## Backward Compatibility

✅ Existing configurations work unchanged (polling mode)
✅ interrupt_pin is optional - add when ready
✅ No breaking changes to any APIs
✅ Binary sensors automatically benefit from interrupt efficiency

Addresses the need for efficient GPIO expander operation by eliminating
unnecessary continuous polling when hardware interrupts are available.
2025-11-17 21:45:47 +00:00
2023-06-12 17:00:34 +12:00
2022-09-06 15:48:01 +12:00
2024-03-28 10:20:51 +13:00
2025-07-17 22:40:28 +12:00
2025-11-13 17:00:47 +13:00
2025-07-17 22:40:28 +12:00
S
Description
ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.
Readme GPL-3.0, MIT
701 MiB
0 Stars 2 Watchers 0 Forks
Languages
C++ 55%
Python 44.2%
C 0.3%
Shell 0.3%
JavaScript 0.2%