Reverse polarity on IO expander

This is to avoid false inputs if controllers is disconnected.
This commit is contained in:
Frederik Walk 2023-05-20 20:30:39 +02:00
parent 68457c60fe
commit aeb1719d16
3 changed files with 56 additions and 3 deletions

View File

@ -51,6 +51,11 @@ class Mcp23017 {
void setPullup(uint8_t pin, bool enable); void setPullup(uint8_t pin, bool enable);
void setPullup(uint8_t pin, Port port, bool enable); void setPullup(uint8_t pin, Port port, bool enable);
void setReversePolarity(uint16_t reverse_mask);
void setReversePolarity(Port port, uint8_t reverse_mask);
void setReversePolarity(uint8_t pin, bool reverse);
void setReversePolarity(uint8_t pin, Port port, bool reverse);
uint16_t read(); uint16_t read();
uint8_t read(Port port); uint8_t read(Port port);
bool read(uint8_t pin); bool read(uint8_t pin);

View File

@ -100,6 +100,53 @@ void Mcp23017::setPullup(uint8_t pin, Mcp23017::Port port, bool enable) {
} }
} }
void Mcp23017::setReversePolarity(uint16_t reverse_mask) { writeRegister16(Register::IPOLA, reverse_mask); }
void Mcp23017::setReversePolarity(Port port, uint8_t reverse_mask) {
switch (port) {
case Port::A:
return writeRegister8(Register::IPOLA, reverse_mask);
case Port::B:
return writeRegister8(Register::IPOLB, reverse_mask);
}
}
void Mcp23017::setReversePolarity(uint8_t pin, bool reverse) {
if (pin > 15) {
return;
}
if (pin > 7) {
return setReversePolarity(pin - 8, Port::B, reverse);
}
return setReversePolarity(pin, Port::A, reverse);
}
void Mcp23017::setReversePolarity(uint8_t pin, Port port, bool reverse) {
if (pin > 7) {
return;
}
Register target_register = Register::IPOLA;
switch (port) {
case Port::A:
target_register = Register::IPOLA;
break;
case Port::B:
target_register = Register::IPOLB;
break;
}
uint8_t reversed = readRegister8(target_register);
if (reverse) {
return writeRegister8(target_register, reversed | (1 << pin));
} else {
return writeRegister8(target_register, reversed & ~(1 << pin));
}
}
uint16_t Mcp23017::read() { return readRegister16(Register::GPIOA); } uint16_t Mcp23017::read() { return readRegister16(Register::GPIOA); }
uint8_t Mcp23017::read(Port port) { uint8_t Mcp23017::read(Port port) {

View File

@ -58,6 +58,7 @@ Buttons::Buttons(const Config &config) : m_config(config), m_socd_state{Id::DOWN
m_mcp23017 = std::make_unique<Mcp23017>(m_config.i2c.address, m_config.i2c.block); m_mcp23017 = std::make_unique<Mcp23017>(m_config.i2c.address, m_config.i2c.block);
m_mcp23017->setDirection(0xFFFF); // All inputs m_mcp23017->setDirection(0xFFFF); // All inputs
m_mcp23017->setPullup(0xFFFF); // All on m_mcp23017->setPullup(0xFFFF); // All on
m_mcp23017->setReversePolarity(0xFFFF); // All reversed
m_buttons.emplace(Id::UP, config.pins.dpad.up); m_buttons.emplace(Id::UP, config.pins.dpad.up);
m_buttons.emplace(Id::DOWN, config.pins.dpad.down); m_buttons.emplace(Id::DOWN, config.pins.dpad.down);
@ -76,7 +77,7 @@ Buttons::Buttons(const Config &config) : m_config(config), m_socd_state{Id::DOWN
} }
void Buttons::updateInputState(Utils::InputState &input_state) { void Buttons::updateInputState(Utils::InputState &input_state) {
uint16_t gpio_state = ~m_mcp23017->read(); uint16_t gpio_state = m_mcp23017->read();
for (auto &button : m_buttons) { for (auto &button : m_buttons) {
button.second.setState(gpio_state & button.second.getGpioMask(), m_config.debounce_delay_ms); button.second.setState(gpio_state & button.second.getGpioMask(), m_config.debounce_delay_ms);