@@ -73,29 +73,15 @@ bool Adafruit_MCP23XXX::begin_SPI(int8_t cs_pin, int8_t sck_pin,
7373*/
7474/* *************************************************************************/
7575void Adafruit_MCP23XXX::pinMode (uint8_t pin, uint8_t mode) {
76- uint8_t iodir_reg = getRegister (MCP23XXX_IODIR, PORT (pin));
77- uint8_t gppu_reg = getRegister (MCP23XXX_GPPU, PORT (pin));
76+ Adafruit_BusIO_Register IODIR (i2c_dev, spi_dev, MCP23XXX_SPIREG,
77+ getRegister (MCP23XXX_IODIR, MCP_PORT (pin)));
78+ Adafruit_BusIO_Register GPPU (i2c_dev, spi_dev, MCP23XXX_SPIREG,
79+ getRegister (MCP23XXX_GPPU, MCP_PORT (pin)));
80+ Adafruit_BusIO_RegisterBits dir_bit (&IODIR, 1 , pin % 8 );
81+ Adafruit_BusIO_RegisterBits pullup_bit (&GPPU, 1 , pin % 8 );
7882
79- uint8_t iodir = readRegister (iodir_reg);
80-
81- if (mode == OUTPUT) {
82- // clear for output
83- iodir &= ~MASK (pin);
84- } else {
85- // set for input
86- iodir |= MASK (pin);
87- // also configure internal pull-up
88- uint8_t gppu = readRegister (gppu_reg);
89- if (mode == INPUT_PULLUP) {
90- // set to enable
91- gppu |= MASK (pin);
92- } else {
93- // clear to disable
94- gppu &= ~MASK (pin);
95- }
96- writeRegister (gppu_reg, gppu);
97- }
98- writeRegister (iodir_reg, iodir);
83+ dir_bit.write ((mode == OUTPUT) ? 0 : 1 );
84+ pullup_bit.write ((mode == INPUT_PULLUP) ? 1 : 0 );
9985}
10086
10187/* *************************************************************************/
@@ -106,9 +92,11 @@ void Adafruit_MCP23XXX::pinMode(uint8_t pin, uint8_t mode) {
10692*/
10793/* *************************************************************************/
10894uint8_t Adafruit_MCP23XXX::digitalRead (uint8_t pin) {
109- if (pin >= pinCount)
110- return 0 ;
111- return ((readGPIO (PORT (pin)) & MASK (pin)) == 0 ) ? LOW : HIGH;
95+ Adafruit_BusIO_Register GPIO (i2c_dev, spi_dev, MCP23XXX_SPIREG,
96+ getRegister (MCP23XXX_GPIO, MCP_PORT (pin)));
97+ Adafruit_BusIO_RegisterBits pin_bit (&GPIO, 1 , pin % 8 );
98+
99+ return ((pin_bit.read () == 0 ) ? LOW : HIGH);
112100}
113101
114102/* *************************************************************************/
@@ -119,13 +107,11 @@ uint8_t Adafruit_MCP23XXX::digitalRead(uint8_t pin) {
119107*/
120108/* *************************************************************************/
121109void Adafruit_MCP23XXX::digitalWrite (uint8_t pin, uint8_t value) {
122- uint8_t gpio = readGPIO (PORT (pin));
123- if (value == HIGH) {
124- gpio |= MASK (pin);
125- } else {
126- gpio &= ~MASK (pin);
127- }
128- writeGPIO (gpio, PORT (pin));
110+ Adafruit_BusIO_Register GPIO (i2c_dev, spi_dev, MCP23XXX_SPIREG,
111+ getRegister (MCP23XXX_GPIO, MCP_PORT (pin)));
112+ Adafruit_BusIO_RegisterBits pin_bit (&GPIO, 1 , pin % 8 );
113+
114+ pin_bit.write ((value == LOW) ? 0 : 1 );
129115}
130116
131117/* *************************************************************************/
@@ -136,7 +122,9 @@ void Adafruit_MCP23XXX::digitalWrite(uint8_t pin, uint8_t value) {
136122*/
137123/* *************************************************************************/
138124uint8_t Adafruit_MCP23XXX::readGPIO (uint8_t port) {
139- return readRegister (getRegister (MCP23XXX_GPIO, port));
125+ Adafruit_BusIO_Register GPIO (i2c_dev, spi_dev, MCP23XXX_SPIREG,
126+ getRegister (MCP23XXX_GPIO, port));
127+ return GPIO.read () & 0xFF ;
140128}
141129
142130/* *************************************************************************/
@@ -147,7 +135,9 @@ uint8_t Adafruit_MCP23XXX::readGPIO(uint8_t port) {
147135*/
148136/* *************************************************************************/
149137void Adafruit_MCP23XXX::writeGPIO (uint8_t value, uint8_t port) {
150- writeRegister (getRegister (MCP23XXX_GPIO, port), value);
138+ Adafruit_BusIO_Register GPIO (i2c_dev, spi_dev, MCP23XXX_SPIREG,
139+ getRegister (MCP23XXX_GPIO, port));
140+ GPIO.write (value);
151141}
152142
153143/* *************************************************************************/
@@ -160,20 +150,15 @@ void Adafruit_MCP23XXX::writeGPIO(uint8_t value, uint8_t port) {
160150/* *************************************************************************/
161151void Adafruit_MCP23XXX::setupInterrupts (bool mirroring, bool openDrain,
162152 uint8_t polarity) {
163- uint8_t iocon = readRegister (getRegister (MCP23XXX_IOCON));
164- if (mirroring)
165- iocon |= 1 << 6 ;
166- else
167- iocon &= ~(1 << 6 );
168- if (openDrain)
169- iocon |= 1 << 2 ;
170- else
171- iocon &= ~(1 << 2 );
172- if (polarity == HIGH)
173- iocon |= 1 << 1 ;
174- else
175- iocon &= ~(1 << 1 );
176- writeRegister (getRegister (MCP23XXX_IOCON), iocon);
153+ Adafruit_BusIO_Register GPINTEN (i2c_dev, spi_dev, MCP23XXX_SPIREG,
154+ getRegister (MCP23XXX_IOCON));
155+ Adafruit_BusIO_RegisterBits mirror_bit (&GPINTEN, 1 , 6 );
156+ Adafruit_BusIO_RegisterBits openDrain_bit (&GPINTEN, 1 , 2 );
157+ Adafruit_BusIO_RegisterBits polarity_bit (&GPINTEN, 1 , 1 );
158+
159+ mirror_bit.write (mirroring ? 1 : 0 );
160+ openDrain_bit.write (openDrain ? 1 : 0 );
161+ polarity_bit.write ((polarity == HIGH) ? 1 : 0 );
177162}
178163
179164/* *************************************************************************/
@@ -184,31 +169,19 @@ void Adafruit_MCP23XXX::setupInterrupts(bool mirroring, bool openDrain,
184169*/
185170/* *************************************************************************/
186171void Adafruit_MCP23XXX::setupInterruptPin (uint8_t pin, uint8_t mode) {
187- // enable it
188- uint8_t reg = getRegister (MCP23XXX_GPINTEN, PORT (pin));
189- uint8_t gpinten = readRegister (reg);
190- gpinten |= MASK (pin);
191- writeRegister (reg, gpinten);
192- // set mode
193- reg = getRegister (MCP23XXX_INTCON, PORT (pin));
194- uint8_t intcon = readRegister (reg);
195- if (mode == CHANGE) {
196- // clear to compare to previous self (CHANGE)
197- intcon &= ~MASK (pin);
198- writeRegister (reg, intcon);
199- } else {
200- // set to compare to DEFVAL (LOW/HIGH)
201- intcon |= MASK (pin);
202- writeRegister (reg, intcon);
203- // set DEFVAL to 1=LOW or 0=HIGH
204- reg = getRegister (MCP23XXX_DEFVAL, PORT (pin));
205- uint8_t defval = readRegister (reg);
206- if (mode == LOW)
207- defval |= MASK (pin);
208- else
209- defval &= ~MASK (pin);
210- writeRegister (reg, defval);
211- }
172+ Adafruit_BusIO_Register GPINTEN (i2c_dev, spi_dev, MCP23XXX_SPIREG,
173+ getRegister (MCP23XXX_GPINTEN, MCP_PORT (pin)));
174+ Adafruit_BusIO_Register INTCON (i2c_dev, spi_dev, MCP23XXX_SPIREG,
175+ getRegister (MCP23XXX_INTCON, MCP_PORT (pin)));
176+ Adafruit_BusIO_Register DEFVAL (i2c_dev, spi_dev, MCP23XXX_SPIREG,
177+ getRegister (MCP23XXX_DEFVAL, MCP_PORT (pin)));
178+ Adafruit_BusIO_RegisterBits enable_bit (&GPINTEN, 1 , pin % 8 );
179+ Adafruit_BusIO_RegisterBits config_bit (&INTCON, 1 , pin % 8 );
180+ Adafruit_BusIO_RegisterBits defval_bit (&DEFVAL, 1 , pin % 8 );
181+
182+ enable_bit.write (1 ); // enable it
183+ config_bit.write ((mode == CHANGE) ? 0 : 1 ); // set mode
184+ defval_bit.write ((mode == LOW) ? 1 : 0 ); // set defval
212185}
213186
214187/* *************************************************************************/
@@ -218,10 +191,11 @@ void Adafruit_MCP23XXX::setupInterruptPin(uint8_t pin, uint8_t mode) {
218191*/
219192/* *************************************************************************/
220193void Adafruit_MCP23XXX::disableInterruptPin (uint8_t pin) {
221- uint8_t reg = getRegister (MCP23XXX_GPINTEN, PORT (pin));
222- uint8_t gpinten = readRegister (reg);
223- gpinten &= ~MASK (pin);
224- writeRegister (reg, gpinten);
194+ Adafruit_BusIO_Register GPINTEN (i2c_dev, spi_dev, MCP23XXX_SPIREG,
195+ getRegister (MCP23XXX_GPINTEN, MCP_PORT (pin)));
196+ Adafruit_BusIO_RegisterBits enable_bit (&GPINTEN, 1 , pin % 8 );
197+
198+ enable_bit.write (0 );
225199}
226200
227201/* *************************************************************************/
@@ -231,108 +205,41 @@ void Adafruit_MCP23XXX::disableInterruptPin(uint8_t pin) {
231205*/
232206/* *************************************************************************/
233207uint8_t Adafruit_MCP23XXX::getLastInterruptPin () {
234- uint8_t intf = readRegister (getRegister (MCP23XXX_INTF));
235208 uint8_t intpin = 255 ;
209+ uint8_t intf;
210+
236211 // Port A
212+ Adafruit_BusIO_Register INTFA (i2c_dev, spi_dev, MCP23XXX_SPIREG,
213+ getRegister (MCP23XXX_INTF));
214+ INTFA.read (&intf);
237215 for (uint8_t pin = 0 ; pin < 8 ; pin++) {
238216 if (intf & (1 << pin)) {
239217 intpin = pin;
240218 break ;
241219 }
242220 }
243- // Port B
244- if ((pinCount > 8 ) && (intpin != 255 )) {
245- intf = readRegister (getRegister (MCP23XXX_INTF, 1 ));
221+
222+ // Port B and still not found?
223+ if ((pinCount > 8 ) && (intpin == 255 )) {
224+ Adafruit_BusIO_Register INTFB (i2c_dev, spi_dev, MCP23XXX_SPIREG,
225+ getRegister (MCP23XXX_INTF), 1 );
226+ INTFB.read (&intf);
246227 for (uint8_t pin = 0 ; pin < 8 ; pin++) {
247228 if (intf & (1 << pin)) {
248229 intpin = pin + 8 ;
249230 break ;
250231 }
251232 }
252233 }
253- // read INTCAP to clear
254- readRegister (getRegister (MCP23XXX_INTCAP));
255- return intpin;
256- }
257-
258- /* *************************************************************************/
259- /* !
260- @brief read register
261- @param addr register address
262- @returns register value
263- */
264- /* *************************************************************************/
265- uint8_t Adafruit_MCP23XXX::readRegister (uint8_t addr) {
266- if (i2c_dev) {
267- buffer[0 ] = addr;
268- i2c_dev->write_then_read (buffer, 1 , buffer, 1 , false );
269- } else if (spi_dev) {
270- buffer[0 ] = MCP23XXX_SPI_READ;
271- buffer[1 ] = addr;
272- spi_dev->write_then_read (buffer, 2 , buffer, 1 );
273- }
274- return buffer[0 ];
275- }
276-
277- /* *************************************************************************/
278- /* !
279- @brief write register
280- @param addr register address
281- @param value value to write
282- */
283- /* *************************************************************************/
284- void Adafruit_MCP23XXX::writeRegister (uint8_t addr, uint8_t value) {
285- if (i2c_dev) {
286- buffer[0 ] = addr;
287- buffer[1 ] = value;
288- i2c_dev->write (buffer, 2 );
289- } else if (spi_dev) {
290- buffer[0 ] = MCP23XXX_SPI_WRITE;
291- buffer[1 ] = addr;
292- buffer[2 ] = value;
293- spi_dev->write (buffer, 3 );
294- }
295- }
296234
297- /* *************************************************************************/
298- /* !
299- @brief read two consecutive registers
300- @param addr first register address
301- @returns register values, first register in lower byte
302- */
303- /* *************************************************************************/
304- uint16_t Adafruit_MCP23XXX::readRegister16 (uint8_t addr) {
305- if (i2c_dev) {
306- buffer[0 ] = addr;
307- i2c_dev->write_then_read (buffer, 1 , buffer, 2 , false );
308- } else if (spi_dev) {
309- buffer[0 ] = MCP23XXX_SPI_READ;
310- buffer[1 ] = addr;
311- spi_dev->write_then_read (buffer, 2 , buffer, 2 );
235+ // clear if found
236+ if (intpin != 255 ) {
237+ Adafruit_BusIO_Register INTCAP (i2c_dev, spi_dev, MCP23XXX_SPIREG,
238+ getRegister (MCP23XXX_INTCAP));
239+ INTCAP.read ();
312240 }
313- return buffer[0 ] | (buffer[1 ] << 1 );
314- }
315241
316- /* *************************************************************************/
317- /* !
318- @brief write two consecutive registers
319- @param addr first register address
320- @param value register values, first register in lower byte
321- */
322- /* *************************************************************************/
323- void Adafruit_MCP23XXX::writeRegister16 (uint8_t addr, uint16_t value) {
324- if (i2c_dev) {
325- buffer[0 ] = addr;
326- buffer[1 ] = value & 0xFF ;
327- buffer[2 ] = (value >> 8 ) & 0xFF ;
328- i2c_dev->write (buffer, 3 );
329- } else if (spi_dev) {
330- buffer[0 ] = MCP23XXX_SPI_WRITE;
331- buffer[1 ] = addr;
332- buffer[2 ] = value & 0xFF ;
333- buffer[3 ] = (value >> 8 ) & 0xFF ;
334- spi_dev->write (buffer, 4 );
335- }
242+ return intpin;
336243}
337244
338245/* *************************************************************************/
@@ -342,15 +249,16 @@ void Adafruit_MCP23XXX::writeRegister16(uint8_t addr, uint16_t value) {
342249 @param port 0 for A, 1 for B (MCP23X17 only)
343250*/
344251/* *************************************************************************/
345- uint8_t Adafruit_MCP23XXX::getRegister (uint8_t baseAddress, uint8_t port) {
252+ uint16_t Adafruit_MCP23XXX::getRegister (uint8_t baseAddress, uint8_t port) {
346253 // MCP23x08
347- uint8_t reg = baseAddress;
254+ uint16_t reg = baseAddress;
348255 // MCP23x17 BANK=0
349256 if (pinCount > 8 ) {
350257 reg *= 2 ;
351258 // Port B
352259 if (port)
353260 reg++;
354261 }
355- return reg;
356- }
262+ // for SPI, add opcode as high byte
263+ return (spi_dev) ? (0x4000 | reg) : reg;
264+ }
0 commit comments