PCA9555 / PCAL9555A Driver
API reference
Loading...
Searching...
No Matches
/home/runner/work/hf-pcal95555-driver/hf-pcal95555-driver/inc/pcal95555.hpp

Construct a new PCAL95555 driver instance using address pin levels.

Construct a new PCAL95555 driver instance using address pin levels.

Parameters
busPointer to a user-implemented I2C interface (must inherit from pcal95555::I2cInterface<I2cType>).
a0_levelInitial state of A0 pin: true = HIGH (VDD), false = LOW (GND)
a1_levelInitial state of A1 pin: true = HIGH (VDD), false = LOW (GND)
a2_levelInitial state of A2 pin: true = HIGH (VDD), false = LOW (GND)
variantOptional chip variant override. If ChipVariant::Unknown (default), the driver auto-detects during initialization. Set to ChipVariant::PCA9555 or ChipVariant::PCAL9555A to skip detection.

The constructor uses lazy initialization:

  1. Calculates the I2C address from A2-A0 levels (base 0x20 + bits)
  2. Stores pin levels for later initialization
  3. No I2C communication happens in constructor

Initialization happens automatically on first method call, or explicitly via EnsureInitialized(). Initialization includes setting address pins, verifying I2C communication, and auto-detecting the chip variant.

// Auto-detect chip variant (default) PCAL95555 driver(bus, false, false, false);

// Force PCA9555 mode (skip Agile I/O detection) PCAL95555 driver(bus, false, false, false, ChipVariant::PCA9555);

// Force PCAL9555A mode PCAL95555 driver(bus, true, false, false, ChipVariant::PCAL9555A);

#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <utility>
#include <stdio.h> // NOLINT(modernize-deprecated-headers) - For FILE* used by ESP-IDF headers
#include <string.h> // NOLINT(modernize-deprecated-headers) - For C string functions (must be before namespace)
#include "pcal95555_version.h"
namespace pcal95555 {
enum class Pcal95555Reg : uint8_t {
// === Standard PCA9555 registers (0x00-0x07) — PCA9555 + PCAL9555A ===
INPUT_PORT_0 = 0x00,
INPUT_PORT_1 = 0x01,
OUTPUT_PORT_0 = 0x02,
OUTPUT_PORT_1 = 0x03,
POLARITY_INV_0 = 0x04,
POLARITY_INV_1 = 0x05,
CONFIG_PORT_0 = 0x06,
CONFIG_PORT_1 = 0x07,
// === PCAL9555A Agile I/O registers (0x40-0x4F) — PCAL9555A only ===
INPUT_LATCH_0 = 0x44,
INPUT_LATCH_1 = 0x45,
PULL_ENABLE_0 = 0x46,
PULL_ENABLE_1 = 0x47,
PULL_SELECT_0 = 0x48,
PULL_SELECT_1 = 0x49,
INT_MASK_0 = 0x4A,
INT_MASK_1 = 0x4B,
INT_STATUS_0 = 0x4C,
INT_STATUS_1 = 0x4D,
OUTPUT_CONF = 0x4F
};
enum class GPIODir : uint8_t { Input = 1, Output = 0 };
enum class Polarity : uint8_t { Normal = 0, Inverted = 1 };
enum class DriveStrength : uint8_t { Level0 = 0, Level1 = 1, Level2 = 2, Level3 = 3 };
enum class OutputMode : uint8_t { PushPull = 0, OpenDrain = 1 };
enum class InterruptEdge : uint8_t {
Rising = 1,
Falling = 2,
Both = 3
};
enum class InterruptState : uint8_t {
Enabled = 0,
Disabled = 1
};
// NOLINTNEXTLINE(performance-enum-size) - uint16_t allows for future error code expansion
enum class Error : uint16_t {
None = 0,
InvalidPin = 1 << 0,
InvalidMask = 1 << 1,
I2CReadFail = 1 << 2,
I2CWriteFail = 1 << 3,
UnsupportedFeature = 1 << 4,
InvalidAddress = 1 << 5
};
inline constexpr Error operator|(Error lhs, Error rhs) noexcept {
return static_cast<Error>(static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
}
inline constexpr Error operator&(Error lhs, Error rhs) noexcept {
return static_cast<Error>(static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
}
inline constexpr Error operator~(Error e) noexcept {
return static_cast<Error>(~static_cast<uint16_t>(e));
}
struct PinReadResult {
static constexpr uint8_t kMaxPins = 16;
std::array<std::pair<uint8_t, bool>, kMaxPins> data{};
uint8_t count = 0;
// -- Container-like API --------------------------------------------------
[[nodiscard]] uint8_t size() const noexcept { return count; }
[[nodiscard]] bool empty() const noexcept { return count == 0; }
[[nodiscard]] const std::pair<uint8_t, bool>& operator[](uint8_t i) const noexcept {
return data[i];
}
void push_back(uint8_t pin, bool value) noexcept {
if (count < kMaxPins) {
data[count++] = {pin, value};
}
}
// -- Lookup API ----------------------------------------------------------
[[nodiscard]] bool contains(uint8_t pin) const noexcept {
for (uint8_t i = 0; i < count; ++i) {
if (data[i].first == pin) return true;
}
return false;
}
[[nodiscard]] const std::pair<uint8_t, bool>* find(uint8_t pin) const noexcept {
for (uint8_t i = 0; i < count; ++i) {
if (data[i].first == pin) return &data[i];
}
return nullptr;
}
// -- Iterator support for range-based for --------------------------------
using iterator = typename std::array<std::pair<uint8_t, bool>, kMaxPins>::const_iterator;
[[nodiscard]] iterator begin() const noexcept { return data.begin(); }
[[nodiscard]] iterator end() const noexcept { return data.begin() + count; }
};
enum class ChipVariant : uint8_t {
Unknown = 0,
PCA9555 = 1,
PCAL9555A = 2
};
template <typename I2cType>
class PCAL95555 {
public:
PCAL95555(I2cType* bus, bool a0_level, bool a1_level, bool a2_level,
explicit PCAL95555(I2cType* bus, uint8_t address,
// ---- Version Information (compile-time, static) ----
static constexpr const char* GetDriverVersion() noexcept {
return HF_PCAL95555_VERSION_STRING;
}
static constexpr uint8_t GetDriverVersionMajor() noexcept {
return HF_PCAL95555_VERSION_MAJOR;
}
static constexpr uint8_t GetDriverVersionMinor() noexcept {
return HF_PCAL95555_VERSION_MINOR;
}
static constexpr uint8_t GetDriverVersionPatch() noexcept {
return HF_PCAL95555_VERSION_PATCH;
}
void SetRetries(int retries) noexcept;
[[nodiscard]] uint16_t GetErrorFlags() const noexcept;
[[nodiscard]] bool HasError(Error e) const noexcept;
[[nodiscard]] bool HasAnyError() const noexcept;
void ClearError(Error e) noexcept;
void ClearErrorFlags(uint16_t mask = 0xFFFF) noexcept;
void ResetToDefault() noexcept;
void InitFromConfig() noexcept;
bool SetPinDirection(uint8_t pin, GPIODir dir) noexcept;
bool SetMultipleDirections(uint16_t mask, GPIODir dir) noexcept;
bool SetDirections(std::initializer_list<std::pair<uint8_t, GPIODir>> configs) noexcept;
bool ReadPin(uint8_t pin) noexcept;
bool ReadPin(uint8_t pin, bool& level) noexcept;
bool WritePin(uint8_t pin, bool value) noexcept;
bool SetMultipleOutputs(uint16_t mask, bool value) noexcept;
bool TogglePin(uint8_t pin) noexcept;
bool WritePins(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
PinReadResult ReadPins(std::initializer_list<uint8_t> pins) noexcept;
uint16_t ReadAllInputs() noexcept;
bool ReadDualPortRegister(uint8_t reg0, uint8_t reg1, uint16_t& value) noexcept;
bool WriteDualPortRegister(uint8_t reg0, uint8_t reg1, uint16_t value) noexcept;
bool SetPullEnable(uint8_t pin, bool enable) noexcept;
bool SetPullEnables(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
bool SetPullDirection(uint8_t pin, bool pull_up) noexcept;
bool SetPullDirections(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
bool GetPullConfiguration(uint16_t& enable_mask, uint16_t& direction_mask) noexcept;
bool SetDriveStrength(uint8_t pin, DriveStrength level) noexcept;
bool SetDriveStrengths(std::initializer_list<std::pair<uint8_t, DriveStrength>> configs) noexcept;
bool ConfigureInterrupt(uint8_t pin, InterruptState state) noexcept;
bool ConfigureInterrupts(std::initializer_list<std::pair<uint8_t, InterruptState>> configs) noexcept;
bool ConfigureInterruptMask(uint16_t mask) noexcept;
uint16_t GetInterruptStatus() noexcept;
bool SetOutputMode(bool port_0_open_drain, bool port_1_open_drain) noexcept;
bool SetPinPolarity(uint8_t pin, Polarity polarity) noexcept;
bool SetMultiplePolarities(uint16_t mask, Polarity polarity) noexcept;
bool SetPolarities(std::initializer_list<std::pair<uint8_t, Polarity>> configs) noexcept;
bool EnableInputLatch(uint8_t pin, bool enable) noexcept;
bool EnableMultipleInputLatches(uint16_t mask, bool enable) noexcept;
bool EnableInputLatches(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
bool RegisterPinInterrupt(uint8_t pin, InterruptEdge edge,
std::function<void(uint8_t pin, bool state)> callback);
bool UnregisterPinInterrupt(uint8_t pin) noexcept;
void SetInterruptCallback(const std::function<void(uint16_t)>& callback) noexcept;
bool RegisterInterruptHandler() noexcept;
void HandleInterrupt() noexcept;
[[nodiscard]] uint8_t GetAddress() const noexcept;
[[nodiscard]] uint8_t GetAddressBits() const noexcept;
[[nodiscard]] bool HasAgileIO() const noexcept;
[[nodiscard]] ChipVariant GetChipVariant() const noexcept;
bool ChangeAddress(bool a0_level, bool a1_level, bool a2_level) noexcept;
bool ChangeAddress(uint8_t address) noexcept;
bool EnsureInitialized() noexcept;
bool ForceMarkInitialized(ChipVariant variant) noexcept;
protected:
bool readRegister(uint8_t reg, uint8_t& value) noexcept;
bool writeRegister(uint8_t reg, uint8_t value) noexcept;
private:
struct PinInterruptCallback {
std::function<void(uint8_t pin, bool state)> callback;
bool registered;
PinInterruptCallback() : edge(InterruptEdge::Both), registered(false) {}
};
I2cType* i2c_;
uint8_t dev_addr_;
uint8_t address_bits_; // A2-A0 bits (0-7)
int retries_{1};
uint16_t error_flags_{0};
std::function<void(uint16_t)> irq_callback_; // Global callback for all interrupts
PinInterruptCallback pin_callbacks_[16]; // Per-pin callbacks
uint16_t previous_pin_states_{0}; // Previous pin states for edge detection
bool initialized_{false}; // Lazy initialization flag
bool a0_level_; // Stored pin levels for lazy init
bool a1_level_;
bool a2_level_;
ChipVariant chip_variant_{ChipVariant::Unknown}; // Detected or user-specified chip variant
ChipVariant user_variant_{ChipVariant::Unknown}; // User-requested variant (for skipping detection)
uint8_t xfer_byte_{0}; // Bus transfer byte: lives in the driver object, one per chip
static constexpr uint8_t calculateAddress(uint8_t bits) {
constexpr uint8_t BASE_ADDRESS = 0x20;
constexpr uint8_t MAX_BITS = 0x07;
return BASE_ADDRESS + (bits & MAX_BITS);
}
uint16_t readPinStates() noexcept;
bool initialize() noexcept;
void setError(Error error_code) noexcept;
void clearError(Error error_code) noexcept;
// ---- Internal R-M-W helpers (reduce code duplication) ----
bool readDualPort(uint8_t reg0, uint8_t reg1, uint8_t& val0, uint8_t& val1) noexcept;
bool writeDualPort(uint8_t reg0, uint8_t reg1, uint8_t val0, uint8_t val1) noexcept;
bool modifySinglePinRegister(uint8_t reg0, uint8_t reg1, uint8_t pin, bool bit_value) noexcept;
bool modifyDualPortByMask(uint8_t reg0, uint8_t reg1, uint16_t mask, bool bit_value) noexcept;
bool requireAgileIO() noexcept;
bool changeAddressImpl(uint8_t new_bits) noexcept;
bool detectChipVariant() noexcept;
};
// Include template implementation
#define PCAL95555_HEADER_INCLUDED
// Source tree: inc/../src/pcal95555.ipp. Installed tree: the .ipp sits next to this header.
#if defined(__has_include)
#if __has_include("../src/pcal95555.ipp")
// NOLINTNEXTLINE(bugprone-suspicious-include) - Intentional: template implementation file
#include "../src/pcal95555.ipp"
#else
// NOLINTNEXTLINE(bugprone-suspicious-include) - Intentional: template implementation file
#include "pcal95555.ipp"
#endif
#else
// NOLINTNEXTLINE(bugprone-suspicious-include) - Intentional: template implementation file
#include "../src/pcal95555.ipp"
#endif
#undef PCAL95555_HEADER_INCLUDED
// Public API: Get driver version string
inline const char* GetDriverVersion() noexcept {
return HF_PCAL95555_VERSION_STRING;
}
} // namespace pcal95555
// ---------------------------------------------------------------------------
// Deprecated global-scope names
// ---------------------------------------------------------------------------
// Up to 1.0.0 these types were declared in the global namespace, where names
// such as Error and Polarity collide with other libraries. They now live in
// namespace pcal95555; the aliases below keep old code compiling and will be
// removed in the next major version. Define HF_PCAL95555_NO_GLOBAL_ALIASES to
// drop them now.
#ifndef HF_PCAL95555_NO_GLOBAL_ALIASES
using Pcal95555Reg = pcal95555::Pcal95555Reg; // deprecated: use pcal95555::Pcal95555Reg
using GPIODir = pcal95555::GPIODir; // deprecated: use pcal95555::GPIODir
using Polarity = pcal95555::Polarity; // deprecated: use pcal95555::Polarity
using DriveStrength = pcal95555::DriveStrength; // deprecated: use pcal95555::DriveStrength
using OutputMode = pcal95555::OutputMode; // deprecated: use pcal95555::OutputMode
using InterruptEdge = pcal95555::InterruptEdge; // deprecated: use pcal95555::InterruptEdge
using InterruptState = pcal95555::InterruptState; // deprecated: use pcal95555::InterruptState
using Error = pcal95555::Error; // deprecated: use pcal95555::Error
using pcal95555::operator|;
using pcal95555::operator&;
using pcal95555::operator~;
#endif
bool SetPullEnables(std::initializer_list< std::pair< uint8_t, bool > > configs) noexcept
Definition pcal95555.ipp:568
bool EnableMultipleInputLatches(uint16_t mask, bool enable) noexcept
Enable or disable input latch for multiple pins using a bitmask.
Definition pcal95555.ipp:1135
bool readDualPort(uint8_t reg0, uint8_t reg1, uint8_t &val0, uint8_t &val1) noexcept
Read both port registers (port0 and port1) in one call.
Definition pcal95555.ipp:261
bool writeRegister(uint8_t reg, uint8_t value) noexcept
Write a single byte to a device register with retry logic.
Definition pcal95555.ipp:154
bool EnsureInitialized() noexcept
Definition pcal95555.ipp:75
bool RegisterPinInterrupt(uint8_t pin, InterruptEdge edge, std::function< void(uint8_t pin, bool state)> callback)
Definition pcal95555.ipp:878
bool ReadDualPortRegister(uint8_t reg0, uint8_t reg1, uint16_t &value) noexcept
Read a dual-port register pair into a 16-bit pin mask.
Definition pcal95555.ipp:964
void InitFromConfig() noexcept
Initialize the device using values from Kconfig.
Definition pcal95555.ipp:221
bool initialize() noexcept
Perform actual initialization of the driver.
Definition pcal95555.ipp:97
bool SetPullEnable(uint8_t pin, bool enable) noexcept
Enable or disable the pull-up/pull-down resistor on a pin.
Definition pcal95555.ipp:537
ChipVariant user_variant_
Definition pcal95555.hpp:1133
bool SetMultipleOutputs(uint16_t mask, bool value) noexcept
Definition pcal95555.ipp:429
uint16_t previous_pin_states_
Definition pcal95555.hpp:1127
bool SetDriveStrength(uint8_t pin, DriveStrength level) noexcept
Configure the output drive strength for a GPIO pin.
Definition pcal95555.ipp:656
bool RegisterInterruptHandler() noexcept
Definition pcal95555.ipp:934
bool a1_level_
Definition pcal95555.hpp:1130
bool SetPinPolarity(uint8_t pin, Polarity polarity) noexcept
Configure input polarity inversion for a single pin.
Definition pcal95555.ipp:1061
uint8_t dev_addr_
Definition pcal95555.hpp:1121
bool SetPullDirections(std::initializer_list< std::pair< uint8_t, bool > > configs) noexcept
Definition pcal95555.ipp:597
bool GetPullConfiguration(uint16_t &enable_mask, uint16_t &direction_mask) noexcept
Read the current pull resistor configuration from hardware registers.
Definition pcal95555.ipp:626
void SetRetries(int retries) noexcept
Configure retry mechanism for I2C transactions.
Definition pcal95555.ipp:148
bool EnableInputLatches(std::initializer_list< std::pair< uint8_t, bool > > configs) noexcept
Definition pcal95555.ipp:1151
PinReadResult ReadPins(std::initializer_list< uint8_t > pins) noexcept
Definition pcal95555.ipp:495
uint16_t readPinStates() noexcept
Read current pin states from input port registers.
Definition pcal95555.ipp:946
bool detectChipVariant() noexcept
Detect the chip variant by probing an Agile I/O register.
Definition pcal95555.ipp:1238
static constexpr uint8_t GetDriverVersionMinor() noexcept
Get the compiled driver minor version number.
Definition pcal95555.hpp:341
bool EnableInputLatch(uint8_t pin, bool enable) noexcept
Enable or disable the input latch for a single pin.
Definition pcal95555.ipp:1120
bool HasError(Error e) const noexcept
Check if a specific error flag is set.
Definition pcal95555.ipp:1184
void ClearErrorFlags(uint16_t mask=0xFFFF) noexcept
Clear specific error flags by raw bitmask.
Definition pcal95555.ipp:1199
bool SetOutputMode(bool port_0_open_drain, bool port_1_open_drain) noexcept
Configure per-port output mode (push-pull or open-drain).
Definition pcal95555.ipp:865
uint8_t xfer_byte_
Definition pcal95555.hpp:1134
static constexpr const char * GetDriverVersion() noexcept
Definition pcal95555.hpp:325
bool a0_level_
Definition pcal95555.hpp:1129
bool readRegister(uint8_t reg, uint8_t &value) noexcept
Read a device register with retry logic.
Definition pcal95555.ipp:171
bool modifyDualPortByMask(uint8_t reg0, uint8_t reg1, uint16_t mask, bool bit_value) noexcept
Batch mask read-modify-write on a dual-port register pair.
Definition pcal95555.ipp:303
static constexpr uint8_t GetDriverVersionPatch() noexcept
Get the compiled driver patch version number.
Definition pcal95555.hpp:349
uint16_t GetErrorFlags() const noexcept
Retrieve currently latched error flags.
Definition pcal95555.ipp:1179
bool SetDirections(std::initializer_list< std::pair< uint8_t, GPIODir > > configs) noexcept
Definition pcal95555.ipp:355
void ClearError(Error e) noexcept
Clear a single error flag.
Definition pcal95555.ipp:1194
bool WriteDualPortRegister(uint8_t reg0, uint8_t reg1, uint16_t value) noexcept
Write a dual-port register pair from a 16-bit pin mask (no readback).
Definition pcal95555.ipp:981
bool ConfigureInterruptMask(uint16_t mask) noexcept
Definition pcal95555.ipp:834
bool a2_level_
Definition pcal95555.hpp:1131
uint8_t GetAddress() const noexcept
Get the current I2C address of the device.
Definition pcal95555.ipp:1290
bool HasAgileIO() const noexcept
Definition pcal95555.ipp:1215
bool SetDriveStrengths(std::initializer_list< std::pair< uint8_t, DriveStrength > > configs) noexcept
Definition pcal95555.ipp:684
void clearError(Error error_code) noexcept
Definition pcal95555.ipp:1209
bool SetPolarities(std::initializer_list< std::pair< uint8_t, Polarity > > configs) noexcept
Definition pcal95555.ipp:1092
uint8_t address_bits_
Definition pcal95555.hpp:1122
static constexpr uint8_t GetDriverVersionMajor() noexcept
Get the compiled driver major version number.
Definition pcal95555.hpp:333
bool ConfigureInterrupts(std::initializer_list< std::pair< uint8_t, InterruptState > > configs) noexcept
Definition pcal95555.ipp:788
uint8_t GetAddressBits() const noexcept
Get the current A2-A0 address bits.
Definition pcal95555.ipp:1296
bool changeAddressImpl(uint8_t new_bits) noexcept
Shared implementation for ChangeAddress overloads.
Definition pcal95555.ipp:1303
ChipVariant GetChipVariant() const noexcept
Get the detected chip variant.
Definition pcal95555.ipp:1221
bool WritePin(uint8_t pin, bool value) noexcept
Write a logical level to a GPIO output pin.
Definition pcal95555.ipp:413
bool ForceMarkInitialized(ChipVariant variant) noexcept
Mark the driver initialized without the probe read.
Definition pcal95555.ipp:83
bool SetPullDirection(uint8_t pin, bool pull_up) noexcept
Select internal pull-up or pull-down resistor direction.
Definition pcal95555.ipp:552
static constexpr uint8_t calculateAddress(uint8_t bits)
Calculate I2C address from A2-A0 bits.
Definition pcal95555.hpp:1142
void SetInterruptCallback(const std::function< void(uint16_t)> &callback) noexcept
Definition pcal95555.ipp:928
bool ChangeAddress(bool a0_level, bool a1_level, bool a2_level) noexcept
Definition pcal95555.ipp:1349
PinInterruptCallback pin_callbacks_[16]
Definition pcal95555.hpp:1126
std::function< void(uint16_t)> irq_callback_
Definition pcal95555.hpp:1125
uint16_t error_flags_
Definition pcal95555.hpp:1124
bool ReadPin(uint8_t pin) noexcept
Read the current logical level of a GPIO pin.
Definition pcal95555.ipp:384
bool SetMultipleDirections(uint16_t mask, GPIODir dir) noexcept
Set the direction for multiple GPIO pins at once using a bitmask.
Definition pcal95555.ipp:339
bool ConfigureInterrupt(uint8_t pin, InterruptState state) noexcept
Definition pcal95555.ipp:749
bool initialized_
Definition pcal95555.hpp:1128
ChipVariant chip_variant_
Definition pcal95555.hpp:1132
void setError(Error error_code) noexcept
Definition pcal95555.ipp:1204
bool SetMultiplePolarities(uint16_t mask, Polarity polarity) noexcept
Configure input polarity for multiple pins using a bitmask.
Definition pcal95555.ipp:1076
bool requireAgileIO() noexcept
Check that the chip supports Agile I/O, setting error if not.
Definition pcal95555.ipp:1227
void HandleInterrupt() noexcept
Internal handler to process an interrupt event.
Definition pcal95555.ipp:992
bool SetPinDirection(uint8_t pin, GPIODir dir) noexcept
Set the direction of a single GPIO pin.
Definition pcal95555.ipp:324
bool modifySinglePinRegister(uint8_t reg0, uint8_t reg1, uint8_t pin, bool bit_value) noexcept
Single-pin read-modify-write on a dual-port register pair.
Definition pcal95555.ipp:290
bool WritePins(std::initializer_list< std::pair< uint8_t, bool > > configs) noexcept
Definition pcal95555.ipp:466
uint16_t GetInterruptStatus() noexcept
Retrieve and clear the interrupt status.
Definition pcal95555.ipp:849
int retries_
Definition pcal95555.hpp:1123
bool TogglePin(uint8_t pin) noexcept
Toggle the output state of a GPIO pin.
Definition pcal95555.ipp:444
bool HasAnyError() const noexcept
Check if any error flag is set.
Definition pcal95555.ipp:1189
bool UnregisterPinInterrupt(uint8_t pin) noexcept
Unregister callback for a specific pin interrupt.
Definition pcal95555.ipp:906
void ResetToDefault() noexcept
Reset all registers to their power-on default state.
Definition pcal95555.ipp:185
bool writeDualPort(uint8_t reg0, uint8_t reg1, uint8_t val0, uint8_t val1) noexcept
Write both port registers (port0 and port1) in one call.
Definition pcal95555.ipp:278
I2cType * i2c_
Definition pcal95555.hpp:1120
uint16_t ReadAllInputs() noexcept
Definition pcal95555.ipp:956
Definition pcal95555.hpp:21
const char * GetDriverVersion() noexcept
Definition pcal95555.hpp:1255
InterruptState
Definition pcal95555.hpp:96
@ Enabled
Interrupt enabled (mask bit = 0)
@ Disabled
Interrupt disabled/masked (mask bit = 1)
GPIODir
Definition pcal95555.hpp:77
DriveStrength
Definition pcal95555.hpp:83
Pcal95555Reg
Register addresses for the PCA9555 / PCAL9555A I/O expander chips.
Definition pcal95555.hpp:47
@ INPUT_LATCH_0
Input latch port 0 [PCAL9555A only].
@ PULL_SELECT_0
Pull-up/pull-down selection port 0 [PCAL9555A only].
@ PULL_ENABLE_0
Pull-up/pull-down enable port 0 [PCAL9555A only].
@ CONFIG_PORT_1
Configuration (direction) port 1 [PCA9555 + PCAL9555A].
@ OUTPUT_PORT_1
Output port 1 [PCA9555 + PCAL9555A].
@ OUTPUT_PORT_0
Output port 0 [PCA9555 + PCAL9555A].
@ DRIVE_STRENGTH_2
Output drive strength port 1 low nibble [PCAL9555A only].
@ INPUT_PORT_1
Input port 1 (read-only) [PCA9555 + PCAL9555A].
@ INT_MASK_1
Interrupt mask port 1 [PCAL9555A only].
@ OUTPUT_CONF
Output port configuration [PCAL9555A only].
@ DRIVE_STRENGTH_0
Output drive strength port 0 low nibble [PCAL9555A only].
@ DRIVE_STRENGTH_1
Output drive strength port 0 high nibble [PCAL9555A only].
@ CONFIG_PORT_0
Configuration (direction) port 0 [PCA9555 + PCAL9555A].
@ PULL_SELECT_1
Pull-up/pull-down selection port 1 [PCAL9555A only].
@ INPUT_PORT_0
Input port 0 (read-only) [PCA9555 + PCAL9555A].
@ INT_STATUS_1
Interrupt status port 1 (read-only) [PCAL9555A only].
@ POLARITY_INV_1
Polarity inversion port 1 [PCA9555 + PCAL9555A].
@ DRIVE_STRENGTH_3
Output drive strength port 1 high nibble [PCAL9555A only].
@ INPUT_LATCH_1
Input latch port 1 [PCAL9555A only].
@ POLARITY_INV_0
Polarity inversion port 0 [PCA9555 + PCAL9555A].
@ INT_STATUS_0
Interrupt status port 0 (read-only) [PCAL9555A only].
@ PULL_ENABLE_1
Pull-up/pull-down enable port 1 [PCAL9555A only].
@ INT_MASK_0
Interrupt mask port 0 [PCAL9555A only].
ChipVariant
Identifies the detected or user-specified chip variant.
Definition pcal95555.hpp:203
@ PCAL9555A
NXP PCAL9555A with Agile I/O (registers 0x00-0x07 + 0x40-0x4F)
@ Unknown
Not yet detected (pre-initialization)
@ PCA9555
Standard PCA9555 (registers 0x00-0x07 only)
Polarity
Definition pcal95555.hpp:80
Error
Definition pcal95555.hpp:103
@ InvalidPin
Provided pin index out of range.
@ InvalidAddress
Provided I2C address is out of valid range (0x20-0x27)
@ UnsupportedFeature
Feature requires PCAL9555A but chip is PCA9555.
@ I2CReadFail
An I2C read operation failed.
@ I2CWriteFail
An I2C write operation failed.
@ InvalidMask
A mask-form call got a mask that selects no pin (0)
OutputMode
Definition pcal95555.hpp:86
InterruptEdge
Definition pcal95555.hpp:89
@ Falling
Trigger on falling edge (HIGH to LOW)
@ Both
Trigger on both edges.
@ Rising
Trigger on rising edge (LOW to HIGH)
Template implementation of PCAL95555 I/O expander driver.
CRTP-based I2C interface for PCAL95555 driver.
ESP-IDF Kconfig default macros for PCAL95555 driver initialization.
InterruptEdge edge
Definition pcal95555.hpp:1114
PinInterruptCallback()
Definition pcal95555.hpp:1117
std::function< void(uint8_t pin, bool state)> callback
Definition pcal95555.hpp:1113
bool registered
Definition pcal95555.hpp:1115
iterator begin() const noexcept
Definition pcal95555.hpp:191
iterator end() const noexcept
Definition pcal95555.hpp:192
const std::pair< uint8_t, bool > & operator[](uint8_t i) const noexcept
Access entry by index (no bounds check).
Definition pcal95555.hpp:159
uint8_t size() const noexcept
Number of populated entries.
Definition pcal95555.hpp:153
bool contains(uint8_t pin) const noexcept
Check whether a pin number is already stored in the result set.
Definition pcal95555.hpp:173
const std::pair< uint8_t, bool > * find(uint8_t pin) const noexcept
Definition pcal95555.hpp:182
uint8_t count
Number of valid entries in data[].
Definition pcal95555.hpp:148
typename std::array< std::pair< uint8_t, bool >, kMaxPins >::const_iterator iterator
Definition pcal95555.hpp:190
bool empty() const noexcept
True when no entries have been added.
Definition pcal95555.hpp:156
std::array< std::pair< uint8_t, bool >, kMaxPins > data
Pin number / value pairs.
Definition pcal95555.hpp:145
void push_back(uint8_t pin, bool value) noexcept
Append a pin/value pair. Silently drops entries beyond kMaxPins.
Definition pcal95555.hpp:164
static constexpr uint8_t kMaxPins
Maximum number of entries (constrained by hardware: 16 GPIO pins).
Definition pcal95555.hpp:142