Skip to content

Commit

Permalink
ReadGPIO fixed with #576, failing leftovers for PinMode, SetPullUp an…
Browse files Browse the repository at this point in the history
…d SetPolarity
  • Loading branch information
gen2thomas authored and deadprogram committed Apr 8, 2022
1 parent 954d535 commit 37eeda8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
21 changes: 14 additions & 7 deletions drivers/i2c/mcp23017_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,8 @@ func (m *MCP23017Driver) WriteGPIO(pin uint8, val uint8, portStr string) (err er
if err != nil {
return err
}
// set or clear iodir value, a 1 sets the pin as an input, 0 as an output
var iodirVal uint8
if val == 1 {
iodirVal = clearBit(iodir, uint8(pin))
} else {
iodirVal = setBit(iodir, uint8(pin))
}
// set pin as output by clearing bit
iodirVal := clearBit(iodir, uint8(pin))
// write IODIR register bit
err = m.write(selectedPort.IODIR, uint8(pin), uint8(iodirVal))
if err != nil {
Expand Down Expand Up @@ -263,6 +258,18 @@ func (m *MCP23017Driver) WriteGPIO(pin uint8, val uint8, portStr string) (err er
// port (A or B).
func (m *MCP23017Driver) ReadGPIO(pin uint8, portStr string) (val uint8, err error) {
selectedPort := m.getPort(portStr)
// read current value of IODIR register
iodir, err := m.read(selectedPort.IODIR)
if err != nil {
return 0, err
}
// set pin as input by setting bit
iodirVal := setBit(iodir, uint8(pin))
// write IODIR register bit
err = m.write(selectedPort.IODIR, uint8(pin), uint8(iodirVal))
if err != nil {
return 0, err
}
val, err = m.read(selectedPort.GPIO)
if err != nil {
return val, err
Expand Down
24 changes: 14 additions & 10 deletions drivers/i2c/mcp23017_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,36 +214,40 @@ func TestMCP23017DriverCommandsWriteGPIOErrOLAT(t *testing.T) {

func TestMCP23017DriverReadGPIO(t *testing.T) {
// sequence to read:
// * read current state of IODIR (write reg, read val) => not done here, PinMode()
// * set IODIR of pin to input (manipulate val, write reg, write val) => not done here, PinMode()
// * read current state of IODIR (write reg, read val) => see also PinMode()
// * set IODIR of pin to input (manipulate val, write reg, write val) => see also PinMode()
// * read GPIO (write reg, read val)
// * return last item of values, means the value of the requested register
// arrange
mcp, adaptor := initTestMCP23017DriverWithStubbedAdaptor(0)
for bitState := 0; bitState <= 1; bitState++ {
adaptor.written = []byte{} // reset writes of Start() and former test
// arrange some values
testPort := "A"
testPin := uint8(7)
wantReg := uint8(0x12) // GPIOA
returnRead := uint8(0x7F) // emulate bit is off
wantReg1 := uint8(0x00) // IODIRA
wantReg2 := uint8(0x12) // GPIOA
returnRead := []uint8{0x00, 0x7F} // emulate all IO's are outputs, emulate bit is off
wantReg1Val := returnRead[0] | 0x80 // IODIRA: bit 7 set, all other untouched
if bitState == 1 {
returnRead = 0xFF // emulate bit is set
returnRead[1] = 0xFF // emulate bit is set
}
// arrange reads
numCallsRead := 0
adaptor.i2cReadImpl = func(b []byte) (int, error) {
numCallsRead++
b[len(b)-1] = returnRead
b[len(b)-1] = returnRead[numCallsRead-1]
return len(b), nil
}
// act
val, err := mcp.ReadGPIO(testPin, testPort)
// assert
gobottest.Assert(t, err, nil)
gobottest.Assert(t, numCallsRead, 1)
gobottest.Assert(t, len(adaptor.written), 1)
gobottest.Assert(t, adaptor.written[0], wantReg)
gobottest.Assert(t, numCallsRead, 2)
gobottest.Assert(t, len(adaptor.written), 4)
gobottest.Assert(t, adaptor.written[0], wantReg1)
gobottest.Assert(t, adaptor.written[1], wantReg1)
gobottest.Assert(t, adaptor.written[2], wantReg1Val)
gobottest.Assert(t, adaptor.written[3], wantReg2)
gobottest.Assert(t, val, uint8(bitState))
}
}
Expand Down

0 comments on commit 37eeda8

Please sign in to comment.