PCA9555 / PCAL9555A Driver
API reference
Loading...
Searching...
No Matches
pcal95555.hpp
Go to the documentation of this file.
1
6#pragma once
7#include <array>
8#include <cstddef>
9#include <cstdint>
10#include <functional>
11#include <initializer_list>
12#include <utility>
13#include <stdio.h> // NOLINT(modernize-deprecated-headers) - For FILE* used by ESP-IDF headers
14#include <string.h> // NOLINT(modernize-deprecated-headers) - For C string functions (must be before namespace)
15
17
18#include "pcal95555_kconfig.hpp"
19#include "pcal95555_version.h"
20
21namespace pcal95555 {
22
47enum class Pcal95555Reg : uint8_t {
48 // === Standard PCA9555 registers (0x00-0x07) — PCA9555 + PCAL9555A ===
49 INPUT_PORT_0 = 0x00,
50 INPUT_PORT_1 = 0x01,
51 OUTPUT_PORT_0 = 0x02,
52 OUTPUT_PORT_1 = 0x03,
53 POLARITY_INV_0 = 0x04,
54 POLARITY_INV_1 = 0x05,
55 CONFIG_PORT_0 = 0x06,
56 CONFIG_PORT_1 = 0x07,
57
58 // === PCAL9555A Agile I/O registers (0x40-0x4F) — PCAL9555A only ===
59 DRIVE_STRENGTH_0 = 0x40,
60 DRIVE_STRENGTH_1 = 0x41,
61 DRIVE_STRENGTH_2 = 0x42,
62 DRIVE_STRENGTH_3 = 0x43,
63 INPUT_LATCH_0 = 0x44,
64 INPUT_LATCH_1 = 0x45,
65 PULL_ENABLE_0 = 0x46,
66 PULL_ENABLE_1 = 0x47,
67 PULL_SELECT_0 = 0x48,
68 PULL_SELECT_1 = 0x49,
69 INT_MASK_0 = 0x4A,
70 INT_MASK_1 = 0x4B,
71 INT_STATUS_0 = 0x4C,
72 INT_STATUS_1 = 0x4D,
73 OUTPUT_CONF = 0x4F
74};
75
77enum class GPIODir : uint8_t { Input = 1, Output = 0 };
78
80enum class Polarity : uint8_t { Normal = 0, Inverted = 1 };
81
83enum class DriveStrength : uint8_t { Level0 = 0, Level1 = 1, Level2 = 2, Level3 = 3 };
84
86enum class OutputMode : uint8_t { PushPull = 0, OpenDrain = 1 };
87
89enum class InterruptEdge : uint8_t {
90 Rising = 1,
91 Falling = 2,
92 Both = 3
93};
94
96enum class InterruptState : uint8_t {
97 Enabled = 0,
98 Disabled = 1
99};
100
102// NOLINTNEXTLINE(performance-enum-size) - uint16_t allows for future error code expansion
103enum class Error : uint16_t {
104 None = 0,
105 InvalidPin = 1 << 0,
106 InvalidMask = 1 << 1,
107 I2CReadFail = 1 << 2,
108 I2CWriteFail = 1 << 3,
109 UnsupportedFeature = 1 << 4,
110 InvalidAddress = 1 << 5
111};
112
114inline constexpr Error operator|(Error lhs, Error rhs) noexcept {
115 return static_cast<Error>(static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
116}
118inline constexpr Error operator&(Error lhs, Error rhs) noexcept {
119 return static_cast<Error>(static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
120}
122inline constexpr Error operator~(Error e) noexcept {
123 return static_cast<Error>(~static_cast<uint16_t>(e));
124}
125
142 static constexpr uint8_t kMaxPins = 16;
143
145 std::array<std::pair<uint8_t, bool>, kMaxPins> data{};
146
148 uint8_t count = 0;
149
150 // -- Container-like API --------------------------------------------------
151
153 [[nodiscard]] uint8_t size() const noexcept { return count; }
154
156 [[nodiscard]] bool empty() const noexcept { return count == 0; }
157
159 [[nodiscard]] const std::pair<uint8_t, bool>& operator[](uint8_t i) const noexcept {
160 return data[i];
161 }
162
164 void push_back(uint8_t pin, bool value) noexcept {
165 if (count < kMaxPins) {
166 data[count++] = {pin, value};
167 }
168 }
169
170 // -- Lookup API ----------------------------------------------------------
171
173 [[nodiscard]] bool contains(uint8_t pin) const noexcept {
174 for (uint8_t i = 0; i < count; ++i) {
175 if (data[i].first == pin) return true;
176 }
177 return false;
178 }
179
182 [[nodiscard]] const std::pair<uint8_t, bool>* find(uint8_t pin) const noexcept {
183 for (uint8_t i = 0; i < count; ++i) {
184 if (data[i].first == pin) return &data[i];
185 }
186 return nullptr;
187 }
188
189 // -- Iterator support for range-based for --------------------------------
190 using iterator = typename std::array<std::pair<uint8_t, bool>, kMaxPins>::const_iterator;
191 [[nodiscard]] iterator begin() const noexcept { return data.begin(); }
192 [[nodiscard]] iterator end() const noexcept { return data.begin() + count; }
193};
194
203enum class ChipVariant : uint8_t {
204 Unknown = 0,
205 PCA9555 = 1,
206 PCAL9555A = 2
207};
208
241template <typename I2cType>
243public:
275 PCAL95555(I2cType* bus, bool a0_level, bool a1_level, bool a2_level,
277
308 explicit PCAL95555(I2cType* bus, uint8_t address,
310
311 // ---- Version Information (compile-time, static) ----
312
325 static constexpr const char* GetDriverVersion() noexcept {
326 return HF_PCAL95555_VERSION_STRING;
327 }
328
333 static constexpr uint8_t GetDriverVersionMajor() noexcept {
334 return HF_PCAL95555_VERSION_MAJOR;
335 }
336
341 static constexpr uint8_t GetDriverVersionMinor() noexcept {
342 return HF_PCAL95555_VERSION_MINOR;
343 }
344
349 static constexpr uint8_t GetDriverVersionPatch() noexcept {
350 return HF_PCAL95555_VERSION_PATCH;
351 }
352
360 void SetRetries(int retries) noexcept;
361
367 [[nodiscard]] uint16_t GetErrorFlags() const noexcept;
368
379 [[nodiscard]] bool HasError(Error e) const noexcept;
380
386 [[nodiscard]] bool HasAnyError() const noexcept;
387
393 void ClearError(Error e) noexcept;
394
400 void ClearErrorFlags(uint16_t mask = 0xFFFF) noexcept;
401
409 void ResetToDefault() noexcept;
410
417 void InitFromConfig() noexcept;
418
426 bool SetPinDirection(uint8_t pin, GPIODir dir) noexcept;
427
439 bool SetMultipleDirections(uint16_t mask, GPIODir dir) noexcept;
440
455 bool SetDirections(std::initializer_list<std::pair<uint8_t, GPIODir>> configs) noexcept;
456
466 bool ReadPin(uint8_t pin) noexcept;
467
481 bool ReadPin(uint8_t pin, bool& level) noexcept;
482
490 bool WritePin(uint8_t pin, bool value) noexcept;
491
512 bool SetMultipleOutputs(uint16_t mask, bool value) noexcept;
513
520 bool TogglePin(uint8_t pin) noexcept;
521
536 bool WritePins(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
537
556 PinReadResult ReadPins(std::initializer_list<uint8_t> pins) noexcept;
557
572 uint16_t ReadAllInputs() noexcept;
573
582 bool ReadDualPortRegister(uint8_t reg0, uint8_t reg1, uint16_t& value) noexcept;
583
596 bool WriteDualPortRegister(uint8_t reg0, uint8_t reg1, uint16_t value) noexcept;
597
606 bool SetPullEnable(uint8_t pin, bool enable) noexcept;
607
623 bool SetPullEnables(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
624
633 bool SetPullDirection(uint8_t pin, bool pull_up) noexcept;
634
650 bool SetPullDirections(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
651
665 bool GetPullConfiguration(uint16_t& enable_mask, uint16_t& direction_mask) noexcept;
666
675 bool SetDriveStrength(uint8_t pin, DriveStrength level) noexcept;
676
692 bool SetDriveStrengths(std::initializer_list<std::pair<uint8_t, DriveStrength>> configs) noexcept;
693
709 bool ConfigureInterrupt(uint8_t pin, InterruptState state) noexcept;
710
733 bool ConfigureInterrupts(std::initializer_list<std::pair<uint8_t, InterruptState>> configs) noexcept;
734
751 bool ConfigureInterruptMask(uint16_t mask) noexcept;
759 uint16_t GetInterruptStatus() noexcept;
760
769 bool SetOutputMode(bool port_0_open_drain, bool port_1_open_drain) noexcept;
770
778 bool SetPinPolarity(uint8_t pin, Polarity polarity) noexcept;
779
791 bool SetMultiplePolarities(uint16_t mask, Polarity polarity) noexcept;
792
807 bool SetPolarities(std::initializer_list<std::pair<uint8_t, Polarity>> configs) noexcept;
808
817 bool EnableInputLatch(uint8_t pin, bool enable) noexcept;
818
831 bool EnableMultipleInputLatches(uint16_t mask, bool enable) noexcept;
832
848 bool EnableInputLatches(std::initializer_list<std::pair<uint8_t, bool>> configs) noexcept;
849
877 bool RegisterPinInterrupt(uint8_t pin, InterruptEdge edge,
878 std::function<void(uint8_t pin, bool state)> callback);
879
886 bool UnregisterPinInterrupt(uint8_t pin) noexcept;
887
905 void SetInterruptCallback(const std::function<void(uint16_t)>& callback) noexcept;
906
932 bool RegisterInterruptHandler() noexcept;
933
943 void HandleInterrupt() noexcept;
944
950 [[nodiscard]] uint8_t GetAddress() const noexcept;
951
957 [[nodiscard]] uint8_t GetAddressBits() const noexcept;
958
973 [[nodiscard]] bool HasAgileIO() const noexcept;
974
983 [[nodiscard]] ChipVariant GetChipVariant() const noexcept;
984
1010 bool ChangeAddress(bool a0_level, bool a1_level, bool a2_level) noexcept;
1011
1042 bool ChangeAddress(uint8_t address) noexcept;
1043
1069 bool EnsureInitialized() noexcept;
1070
1088 bool ForceMarkInitialized(ChipVariant variant) noexcept;
1089
1090protected:
1098 bool readRegister(uint8_t reg, uint8_t& value) noexcept;
1106 bool writeRegister(uint8_t reg, uint8_t value) noexcept;
1107
1108private:
1113 std::function<void(uint8_t pin, bool state)> callback;
1116
1117 PinInterruptCallback() : edge(InterruptEdge::Both), registered(false) {}
1118 };
1119
1120 I2cType* i2c_;
1121 uint8_t dev_addr_;
1122 uint8_t address_bits_; // A2-A0 bits (0-7)
1123 int retries_{1};
1124 uint16_t error_flags_{0};
1125 std::function<void(uint16_t)> irq_callback_; // Global callback for all interrupts
1126 PinInterruptCallback pin_callbacks_[16]; // Per-pin callbacks
1127 uint16_t previous_pin_states_{0}; // Previous pin states for edge detection
1128 bool initialized_{false}; // Lazy initialization flag
1129 bool a0_level_; // Stored pin levels for lazy init
1132 ChipVariant chip_variant_{ChipVariant::Unknown}; // Detected or user-specified chip variant
1133 ChipVariant user_variant_{ChipVariant::Unknown}; // User-requested variant (for skipping detection)
1134 uint8_t xfer_byte_{0}; // Bus transfer byte: lives in the driver object, one per chip
1135
1142 static constexpr uint8_t calculateAddress(uint8_t bits) {
1143 constexpr uint8_t BASE_ADDRESS = 0x20;
1144 constexpr uint8_t MAX_BITS = 0x07;
1145 return BASE_ADDRESS + (bits & MAX_BITS);
1146 }
1147
1153 uint16_t readPinStates() noexcept;
1154
1166 bool initialize() noexcept;
1167
1168 void setError(Error error_code) noexcept;
1169 void clearError(Error error_code) noexcept;
1170
1171 // ---- Internal R-M-W helpers (reduce code duplication) ----
1172
1176 bool readDualPort(uint8_t reg0, uint8_t reg1, uint8_t& val0, uint8_t& val1) noexcept;
1177
1181 bool writeDualPort(uint8_t reg0, uint8_t reg1, uint8_t val0, uint8_t val1) noexcept;
1182
1189 bool modifySinglePinRegister(uint8_t reg0, uint8_t reg1, uint8_t pin, bool bit_value) noexcept;
1190
1197 bool modifyDualPortByMask(uint8_t reg0, uint8_t reg1, uint16_t mask, bool bit_value) noexcept;
1198
1204 bool requireAgileIO() noexcept;
1205
1215 bool changeAddressImpl(uint8_t new_bits) noexcept;
1216
1233 bool detectChipVariant() noexcept;
1234};
1235
1236// Include template implementation
1237#define PCAL95555_HEADER_INCLUDED
1238// Source tree: inc/../src/pcal95555.ipp. Installed tree: the .ipp sits next to this header.
1239#if defined(__has_include)
1240#if __has_include("../src/pcal95555.ipp")
1241// NOLINTNEXTLINE(bugprone-suspicious-include) - Intentional: template implementation file
1242#include "../src/pcal95555.ipp"
1243#else
1244// NOLINTNEXTLINE(bugprone-suspicious-include) - Intentional: template implementation file
1245#include "pcal95555.ipp"
1246#endif
1247#else
1248// NOLINTNEXTLINE(bugprone-suspicious-include) - Intentional: template implementation file
1249#include "../src/pcal95555.ipp"
1250#endif
1251#undef PCAL95555_HEADER_INCLUDED
1252
1253
1254// Public API: Get driver version string
1255inline const char* GetDriverVersion() noexcept {
1256 return HF_PCAL95555_VERSION_STRING;
1257}
1258
1259} // namespace pcal95555
1260
1261// ---------------------------------------------------------------------------
1262// Deprecated global-scope names
1263// ---------------------------------------------------------------------------
1264// Up to 1.0.0 these types were declared in the global namespace, where names
1265// such as Error and Polarity collide with other libraries. They now live in
1266// namespace pcal95555; the aliases below keep old code compiling and will be
1267// removed in the next major version. Define HF_PCAL95555_NO_GLOBAL_ALIASES to
1268// drop them now.
1269#ifndef HF_PCAL95555_NO_GLOBAL_ALIASES
1270using Pcal95555Reg = pcal95555::Pcal95555Reg; // deprecated: use pcal95555::Pcal95555Reg
1271using GPIODir = pcal95555::GPIODir; // deprecated: use pcal95555::GPIODir
1272using Polarity = pcal95555::Polarity; // deprecated: use pcal95555::Polarity
1273using DriveStrength = pcal95555::DriveStrength; // deprecated: use pcal95555::DriveStrength
1274using OutputMode = pcal95555::OutputMode; // deprecated: use pcal95555::OutputMode
1275using InterruptEdge = pcal95555::InterruptEdge; // deprecated: use pcal95555::InterruptEdge
1276using InterruptState = pcal95555::InterruptState; // deprecated: use pcal95555::InterruptState
1277using Error = pcal95555::Error; // deprecated: use pcal95555::Error
1278using pcal95555::operator|;
1279using pcal95555::operator&;
1280using pcal95555::operator~;
1281#endif
Driver for the PCA9555 / PCAL9555A / PCAL95555AHF I²C GPIO expander.
Definition pcal95555.hpp:242
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
InterruptState
Definition pcal95555.hpp:96
@ Enabled
Interrupt enabled (mask bit = 0)
@ Disabled
Interrupt disabled/masked (mask bit = 1)
GPIODir
Definition pcal95555.hpp:77
constexpr Error operator~(Error e) noexcept
Complement an Error flag (useful with ClearErrorFlags).
Definition pcal95555.hpp:122
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)
constexpr Error operator|(Error lhs, Error rhs) noexcept
Combine two Error flags.
Definition pcal95555.hpp:114
constexpr Error operator&(Error lhs, Error rhs) noexcept
Intersect two Error flags.
Definition pcal95555.hpp:118
Template implementation of PCAL95555 I/O expander driver.
CRTP-based I2C interface for PCAL95555 driver.
ESP-IDF Kconfig default macros for PCAL95555 driver initialization.
Structure to store pin interrupt callback information.
Definition pcal95555.hpp:1112
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
Fixed-capacity result container for multi-pin read operations.
Definition pcal95555.hpp:140
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