tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/mcp23017/multidevice_test.go (about) 1 package mcp23017 2 3 import ( 4 "testing" 5 6 qt "github.com/frankban/quicktest" 7 8 "tinygo.org/x/drivers/tester" 9 ) 10 11 func TestDevicesGetPins(t *testing.T) { 12 c := qt.New(t) 13 bus := tester.NewI2CBus(c) 14 fdev0 := newDevice(bus, 0x20) 15 fdev1 := newDevice(bus, 0x21) 16 fdev0.Registers[rGPIO] = 0b10101100 17 fdev0.Registers[rGPIO|portB] = 0b01010011 18 fdev1.Registers[rGPIO] = 0b10101101 19 fdev1.Registers[rGPIO|portB] = 0b01010010 20 devs, err := NewI2CDevices(bus, 0x20, 0x21) 21 c.Assert(err, qt.IsNil) 22 pins := make(PinSlice, 2) 23 err = devs.GetPins(pins) 24 c.Assert(err, qt.IsNil) 25 c.Assert(pins, qt.DeepEquals, PinSlice{0b01010011_10101100, 0b01010010_10101101}) 26 27 // It's OK to pass less elements than there are devices. 28 pins = make(PinSlice, 1) 29 err = devs.GetPins(pins) 30 c.Assert(err, qt.IsNil) 31 c.Assert(pins, qt.DeepEquals, PinSlice{0b01010011_10101100}) 32 } 33 34 func TestDevicesSetPinsAllOff(t *testing.T) { 35 c := qt.New(t) 36 bus := tester.NewI2CBus(c) 37 fdev0 := newDevice(bus, 0x20) 38 fdev1 := newDevice(bus, 0x21) 39 fdev0.Registers[rGPIO] = 0b10101100 40 fdev0.Registers[rGPIO|portB] = 0b01010011 41 fdev1.Registers[rGPIO] = 0b10101101 42 fdev1.Registers[rGPIO|portB] = 0b01010010 43 devs, err := NewI2CDevices(bus, 0x20, 0x21) 44 c.Assert(err, qt.IsNil) 45 46 err = devs.SetPins(nil, PinSlice{0xffff}) 47 c.Assert(err, qt.IsNil) 48 pins := make(PinSlice, 2) 49 err = devs.GetPins(pins) 50 c.Assert(err, qt.IsNil) 51 c.Assert(pins, qt.DeepEquals, PinSlice{0, 0}) 52 } 53 54 func TestDevicesSetPinsAllOn(t *testing.T) { 55 c := qt.New(t) 56 bus := tester.NewI2CBus(c) 57 fdev0 := newDevice(bus, 0x20) 58 fdev1 := newDevice(bus, 0x21) 59 fdev0.Registers[rGPIO] = 0b10101100 60 fdev0.Registers[rGPIO|portB] = 0b01010011 61 fdev1.Registers[rGPIO] = 0b10101101 62 fdev1.Registers[rGPIO|portB] = 0b01010010 63 devs, err := NewI2CDevices(bus, 0x20, 0x21) 64 c.Assert(err, qt.IsNil) 65 66 err = devs.SetPins(PinSlice{0xffff}, PinSlice{0xffff}) 67 c.Assert(err, qt.IsNil) 68 pins := make(PinSlice, 2) 69 err = devs.GetPins(pins) 70 c.Assert(err, qt.IsNil) 71 c.Assert(pins, qt.DeepEquals, PinSlice{0xffff, 0xffff}) 72 } 73 74 func TestDevicesSetPinsMask(t *testing.T) { 75 c := qt.New(t) 76 bus := tester.NewI2CBus(c) 77 fdev0 := newDevice(bus, 0x20) 78 fdev1 := newDevice(bus, 0x21) 79 fdev0.Registers[rGPIO] = 0b10101100 80 fdev0.Registers[rGPIO|portB] = 0b01010011 81 fdev1.Registers[rGPIO] = 0b10101101 82 fdev1.Registers[rGPIO|portB] = 0b01010010 83 devs, err := NewI2CDevices(bus, 0x20, 0x21) 84 c.Assert(err, qt.IsNil) 85 86 // Sanity check the original value of the pins. 87 pins := make(PinSlice, 2) 88 err = devs.GetPins(pins) 89 c.Assert(err, qt.IsNil) 90 c.Assert(pins, qt.DeepEquals, PinSlice{0b01010011_10101100, 0b01010010_10101101}) 91 92 pins = make(PinSlice, 2) 93 pins.High(0) 94 pins.High(1) 95 mask := make(PinSlice, 2) 96 mask.High(0) 97 mask.High(16) 98 99 err = devs.SetPins(pins, mask) 100 c.Assert(err, qt.IsNil) 101 pins = make(PinSlice, 2) 102 err = devs.GetPins(pins) 103 c.Assert(err, qt.IsNil) 104 c.Assert(pins, qt.DeepEquals, PinSlice{0b01010011_10101101, 0b01010010_10101100}) 105 } 106 107 func TestDevicesTogglePins(t *testing.T) { 108 c := qt.New(t) 109 bus := tester.NewI2CBus(c) 110 newDevice(bus, 0x20) 111 newDevice(bus, 0x21) 112 devs, err := NewI2CDevices(bus, 0x20, 0x21) 113 c.Assert(err, qt.IsNil) 114 115 mask := make(PinSlice, 2) 116 mask.High(0) 117 mask.High(16) 118 119 err = devs.TogglePins(mask) 120 c.Assert(err, qt.IsNil) 121 pins := make(PinSlice, 2) 122 err = devs.GetPins(pins) 123 c.Assert(err, qt.IsNil) 124 c.Assert(pins, qt.DeepEquals, PinSlice{0b00000000_00000001, 0b00000000_00000001}) 125 } 126 127 func TestDevicesSetGetModes(t *testing.T) { 128 c := qt.New(t) 129 bus := tester.NewI2CBus(c) 130 fdev0 := newDevice(bus, 0x20) 131 fdev1 := newDevice(bus, 0x21) 132 devs, err := NewI2CDevices(bus, 0x20, 0x21) 133 c.Assert(err, qt.IsNil) 134 // Sanity check that IODIR registers start off all ones. 135 c.Assert(fdev0.Registers[rIODIR], qt.Equals, uint8(0xff)) 136 137 // The last entry is replicated to fill them all. 138 err = devs.SetModes([]PinMode{Input | Pullup, Output}) 139 c.Assert(err, qt.IsNil) 140 c.Assert(fdev0.Registers[rIODIR], qt.Equals, uint8(1)) 141 c.Assert(fdev0.Registers[rIODIR|portB], qt.Equals, uint8(0)) 142 c.Assert(fdev1.Registers[rIODIR], qt.Equals, uint8(0)) 143 c.Assert(fdev1.Registers[rIODIR|portB], qt.Equals, uint8(0)) 144 145 modes := make([]PinMode, 2) 146 err = devs.GetModes(modes) 147 c.Assert(err, qt.Equals, nil) 148 c.Assert(modes, qt.DeepEquals, []PinMode{Input | Pullup, Output}) 149 150 // It's OK to pass a smaller slice to GetModes. 151 modes = make([]PinMode, 1) 152 err = devs.GetModes(modes) 153 c.Assert(err, qt.Equals, nil) 154 c.Assert(modes, qt.DeepEquals, []PinMode{Input | Pullup}) 155 } 156 157 func TestDevicesPin(t *testing.T) { 158 c := qt.New(t) 159 bus := tester.NewI2CBus(c) 160 newDevice(bus, 0x20) 161 fdev1 := newDevice(bus, 0x21) 162 devs, err := NewI2CDevices(bus, 0x20, 0x21) 163 c.Assert(err, qt.IsNil) 164 pin := devs.Pin(16) 165 v, err := pin.Get() 166 c.Assert(err, qt.Equals, nil) 167 c.Assert(v, qt.Equals, false) 168 err = pin.High() 169 c.Assert(err, qt.Equals, nil) 170 c.Assert(fdev1.Registers[rGPIO], qt.Equals, uint8(1)) 171 } 172 173 func TestPinSlice(t *testing.T) { 174 c := qt.New(t) 175 pins := PinSlice(nil).Ensure(20) 176 pins.Set(16, true) 177 c.Assert(pins, qt.DeepEquals, PinSlice{0, 1}) 178 pins.Set(31, true) 179 c.Assert(pins, qt.DeepEquals, PinSlice{0, 0b10000000_00000001}) 180 c.Assert(pins.Get(0), qt.Equals, false) 181 c.Assert(pins.Get(16), qt.Equals, true) 182 pins = pins.Ensure(40) 183 c.Assert(pins, qt.DeepEquals, PinSlice{0, 0b10000000_00000001, 0xffff}) 184 pins.Low(16) 185 c.Assert(pins.Get(16), qt.Equals, false) 186 pins.High(16) 187 c.Assert(pins.Get(16), qt.Equals, true) 188 pins.Toggle(16) 189 c.Assert(pins.Get(16), qt.Equals, false) 190 }