31#include "../SensorBuildOpt.h"
32#if !SENSORLIB_EXCLUDE_IO_EXPANDER_XL9555
43static constexpr uint8_t XL9555_UNKNOWN_ADDRESS = (0xFF);
46static constexpr uint8_t XL9555_SLAVE_ADDRESS0 = (0x20);
49static constexpr uint8_t XL9555_SLAVE_ADDRESS1 = (0x21);
52static constexpr uint8_t XL9555_SLAVE_ADDRESS2 = (0x22);
55static constexpr uint8_t XL9555_SLAVE_ADDRESS3 = (0x23);
58static constexpr uint8_t XL9555_SLAVE_ADDRESS4 = (0x24);
61static constexpr uint8_t XL9555_SLAVE_ADDRESS5 = (0x25);
64static constexpr uint8_t XL9555_SLAVE_ADDRESS6 = (0x26);
67static constexpr uint8_t XL9555_SLAVE_ADDRESS7 = (0x27);
74#define DEPRECATED_ATTR __attribute__((deprecated("use XL9555_UNKNOWN_ADDRESS instead")))
76#define DEPRECATED_ATTR
85static const int XL9555_UNKOWN_ADDRESS
DEPRECATED_ATTR = XL9555_UNKNOWN_ADDRESS;
107 IO0
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
108 IO1
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
109 IO2
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
110 IO3
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
111 IO4
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
112 IO5
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
113 IO6
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
114 IO7
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
115 IO8
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
116 IO9
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
117 IO10
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
118 IO11
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
119 IO12
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
120 IO13
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
121 IO14
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
122 IO15
__attribute__((deprecated(
"Use integer pin numbers (0-15) directly instead."))),
148 uint8_t lowByte = values & 0xFF;
149 uint8_t highByte = (values >> 8) & 0xFF;
155 writeReg(XL9555_CTRL_OUTP0, lowByte);
158 writeReg(XL9555_CTRL_OUTP1, highByte);
160 for (uint8_t
i = 0;
i < XL9555_PINS_COUNT;
i++) {
161 if (mask & (1UL <<
i)) {
180 uint8_t lowByte =
readReg(XL9555_CTRL_INP0);
181 uint8_t highByte =
readReg(XL9555_CTRL_INP1);
182 result = (highByte << 8) | lowByte;
199 if (pin >= XL9555_PINS_COUNT) {
200 SENSORLIB_LOG_E(
"Invalid pin number, pin range is 0-%d", XL9555_PINS_COUNT - 1);
203 uint8_t reg = (pin < 8) ? XL9555_CTRL_CFG0 : XL9555_CTRL_CFG1;
204 uint8_t bit = pin % 8;
205 if (mode == OUTPUT) {
234 uint8_t lowMask = pinMask & 0xFF;
235 uint8_t highMask = (pinMask >> 8) & 0xFF;
240 uint8_t cur =
readReg(XL9555_CTRL_CFG0);
251 for (uint8_t
i = 0;
i < 8;
i++) {
252 if (lowMask & (1 <<
i)) {
260 uint8_t cur =
readReg(XL9555_CTRL_CFG1);
269 for (uint8_t
i = 0;
i < 8;
i++) {
270 if (highMask & (1 <<
i)) {
288 if (pin >= XL9555_PINS_COUNT) {
289 SENSORLIB_LOG_E(
"Invalid pin number, pin range is 0-%d", XL9555_PINS_COUNT - 1);
292 uint8_t reg = (pin < 8) ? XL9555_CTRL_OUTP0 : XL9555_CTRL_OUTP1;
293 uint8_t bit = pin % 8;
312 if (pin >= XL9555_PINS_COUNT) {
313 SENSORLIB_LOG_E(
"Invalid pin number, pin range is 0-%d", XL9555_PINS_COUNT - 1);
319 uint8_t reg = (pin < 8) ? XL9555_CTRL_INP0 : XL9555_CTRL_INP1;
320 uint8_t bit = pin % 8;
322 return (value >> bit) & 1;
339 if (param == XL9555_UNKNOWN_ADDRESS) {
341 for (uint8_t address = XL9555_SLAVE_ADDRESS0; address <= XL9555_SLAVE_ADDRESS7; ++address) {
344 if (
readReg(XL9555_CTRL_INP0) >= 0) {
345 SENSORLIB_LOG_D(
"Found the xl9555 chip address is 0x%" PRIx8, address);
352 if (
readReg(XL9555_CTRL_INP0) < 0 ) {
360 static constexpr uint8_t XL9555_CTRL_INP0 = (0x00);
361 static constexpr uint8_t XL9555_CTRL_INP1 = (0x01);
362 static constexpr uint8_t XL9555_CTRL_OUTP0 = (0x02);
363 static constexpr uint8_t XL9555_CTRL_OUTP1 = (0x03);
364 static constexpr uint8_t XL9555_CTRL_PIP0 = (0x04);
365 static constexpr uint8_t XL9555_CTRL_PIP1 = (0x05);
366 static constexpr uint8_t XL9555_CTRL_CFG0 = (0x06);
367 static constexpr uint8_t XL9555_CTRL_CFG1 = (0x07);
368 static constexpr uint8_t XL9555_PINS_COUNT = 16;
#define SENSORLIB_LOG_E(...)
#define SENSORLIB_LOG_D(...)
virtual bool ensureValid() const override
Abstract base class for GPIO expander devices.
std::unique_ptr< bool[]> _outputStates
Cached output states (true = HIGH)
std::unique_ptr< uint8_t[]> _pinModes
Cached pin modes (INPUT/OUTPUT)
Concrete driver for the XL9555 16‑bit I2C GPIO expander.
uint16_t digitalReadPort() override
Read the values of all 16 input pins as a single 16-bit word.
void digitalWriteImpl(uint8_t pin, bool value) override
Write a digital value to an output pin.
~IoExpanderXL9555()=default
Destroy the IoExpanderXL9555 object.
bool digitalReadImpl(uint8_t pin) override
Read the digital value from an input pin.
void configPinsImpl(uint16_t pinMask, uint8_t mode) override
Hardware‑specific implementation for configuring multiple pins simultaneously.
bool initImpl(uint8_t param) override
Perform chip‑specific initialization.
void digitalWritePort(uint16_t mask, uint16_t values) override
Write to multiple pins simultaneously using a mask.
IoExpanderXL9555()
Construct a new IoExpanderXL9555 object.
void pinModeImpl(uint8_t pin, uint8_t mode) override
Set the direction of a single pin.
bool clrRegBit(uint8_t reg, uint8_t bit)
int readReg(uint8_t reg) const
int writeReg(uint8_t reg, uint8_t val)
void setAddress(uint8_t address)
bool setRegBit(uint8_t reg, uint8_t bit)