adafruit / adafruit/Adafruit-MCP23017-Arduino-Library
Adafruit_MCP23XXX::digitalWrite should read/modify/write the output register, not the input register
- Dominant language
- C++
- Stars
- 385
- Forks
- 204
- PR merge metrics
- No merged PRs in 30d
Description
MCP23XXX_GPIO should be MCP23XXX_OLAT
This bug got us when using this library. The read/modify/write should be performing this operation on the output latch register, not the raw input register. This way tristate or open drain pins don't interfere with level modifications.
Example: A pin (say GPIO0) is open drain, with other external circuitry (AND function common for OK signals, etc). The GPIO is high, so "open" on the GPIO expander, but another part is holding the net low. This is all fine and expected.
Now if another pin is modified, say GPIO4 is set low, digitalWrite(4,0) this should have no effect on GPIO0. But in this case it does: This routine reads the input levels, which GPIO0 is low, then writes the register, thus driving GPIO0 low. Then the external circuitry stops holding GPIO0 low, and now the GPIO expander holds it low.
This is a common mistake when writing routines with I/O that can be tristated.
/**************************************************************************/
/*!
@brief Write a HIGH or a LOW value to a digital pin.
@param pin the Arduino pin number
@param value HIGH or LOW
*/
/**************************************************************************/
void Adafruit_MCP23XXX::digitalWrite(uint8_t pin, uint8_t value) {
Adafruit_BusIO_Register GPIO(i2c_dev, spi_dev, MCP23XXX_SPIREG,
getRegister(MCP23XXX_GPIO, MCP_PORT(pin)));
Adafruit_BusIO_RegisterBits pin_bit(&GPIO, 1, pin % 8);
pin_bit.write((value == LOW) ? 0 : 1);
}
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at Adafruit_MCP23XXX::digitalWrite and inspect how the Adafruit_BusIO_Register is created for the pin update. Check the MCP23XXX_GPIO and MCP23XXX_OLAT definitions, then verify that changing one pin cannot overwrite another pin's output state when external circuitry changes its input level.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- embedded-iot
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100