An interface for the MCP23S17 SPI IO expander for Raspberry Pi.
This class abstracts away the technical details of communicating with the chip via SPI, allowing for simple access
via PinView
objects. One PinView
object exists per Pin
, and PinView
objects are initialized lazily. PinView
references are returned by
getPinView
.
It is critical to note that, to allow for writing to the MCP23S17's registers in batches, the setter methods on
PinView
s (or, in general, the methods that modify state for that pin) do not actually perform a write to the
chip; they merely set program state. In order to write to the chip, each invocation of a state-changing
PinView
method (or a batch thereof) must be followed by a call to the appropriate writeXXX
method(s)
on the MCP23S17
object.
To setup the chip to use interrupts, the interrupt input pins must be passed in during construction at the appropriate static factory method; one static factory method is provided for each possible interrupt setup. Once a chip is setup for interrupts, callbacks for both pin-specific interrupts and global interrupts may be registered. Do note, however, that each pin that is supposed to generate interrupts must be setup as such in the appropriate registers. Refer to the MCP23S17 datasheet for more information.
- Author:
- Robert Russell, updated to pi4j V2 by MNG
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interface
A functional interface representing an interrupt listener callback.static enum
Enum for each physical GPIO pin on the MCP23S17 chip.final class
An abstraction of each physical GPIO pin on a MCP23S17 IO expander chip. -
Field Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
addGlobalListener
(MCP23S17.InterruptListener listener) Add a global interrupt listener.preconfigures all 16 pins of the MCP23S17 to pulled-up interrupt-inputs The correct values are also being written to the corresponding registers and the GPIO registers are read once to clear any pending interrupts on startup.getPinView
(MCP23S17.Pin pin) com.pi4j.io.spi.Spi
getSpi()
get the pi4jSpi
objectmultipleNewOnSameBus
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, int amount) Instantiate a number ofMCP23S17
objects on the same bus with consecutive adresses.multipleNewOnSameBusWithTiedInterrupts
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalInput[] interrupts, int amount, boolean readGPIO) Instantiate multiple newMCP23S17
objects on the same SPI-bus with their hardware address pins enabled and with their port A and port B interrupt lines "tied" together.static MCP23S17
newWithInterrupts
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput portAInterrupt, com.pi4j.io.gpio.digital.DigitalInput portBInterrupt) Instantiate a newMCP23S17
object with individual port A and port B interrupt lines.static MCP23S17
newWithoutInterrupts
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect) Instantiate a newMCP23S17
object with no interrupts.static MCP23S17
newWithPortAInterrupts
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput portAInterrupt) Instantiate a newMCP23S17
object with an individual port A interrupt line, but no port B interrupt line.static MCP23S17
newWithPortBInterrupts
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput portBInterrupt) Instantiate a newMCP23S17
object with an individual port B interrupt line, but no port A interrupt line.static MCP23S17
newWithTiedInterrupts
(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput interrupt) Instantiate a newMCP23S17
object with the port A and port B interrupt lines "tied" together.byte
Initiate SPI communication with the chip and read the GPINTENA register.byte
Initiate SPI communication with the chip and read the GPINTENB register.byte
Initiate SPI communication with the chip and read the GPIOA register.byte
Initiate SPI communication with the chip and read the GPIOB register.byte
Initiate SPI communication with the chip and read the IOCON register.void
Remove a global interrupt listener.void
Initiate SPI communication with the chip and write the DEFVALA byte to the DEFVALA register.void
Initiate SPI communication with the chip and write the DEFVALB byte to the DEFVALB register.void
Initiate SPI communication with the chip and write the GPINTENA byte to the GPINTENA register.void
Initiate SPI communication with the chip and write the GPINTENB byte to the GPINTENB register.void
Initiate SPI communication with the chip and write the GPPUA byte to the GPPUA register.void
Initiate SPI communication with the chip and write the GPPUB byte to the GPPUB register.void
Initiate SPI communication with the chip and write the INTCONA byte to the INTCONA register.void
Initiate SPI communication with the chip and write the INTCONB byte to the INTCONB register.void
Initiate SPI communication with the chip and write the IODIRA byte to the IODIRA register.void
Initiate SPI communication with the chip and write the IODIRB byte to the IODIRB register.void
Initiate SPI communication with the chip and write the IPOLA byte to the IPOLA register.void
Initiate SPI communication with the chip and write the IPOLB byte to the IPOLB register.void
Initiate SPI communication with the chip and write the OLATA byte to the OLATA register.void
Initiate SPI communication with the chip and write the OLATB byte to the OLATB register.
-
Method Details
-
getPinView
- Parameters:
pin
- thePin
.- Returns:
- the corresponding
PinView
.
-
getPinViewIterator
Get an
Iterator
over all thePinView
s for thisMCP23S17
.The returned
Iterator
returns thePinView
s in the order of their pin numbers (i.e. thePinView
forPIN0
comes first and thePinView
forPIN15
comes last). The returnedIterator
does not support removal of elements.Note that if certain
PinView
s have not yet been lazily-loaded, they will be loaded as needed by the returnedIterator
.- Returns:
- an iterator over all the
PinView
s for thisMCP23S17
.
-
getAllPinsAsPulledUpInterruptInput
preconfigures all 16 pins of the MCP23S17 to pulled-up interrupt-inputs The correct values are also being written to the corresponding registers and the GPIO registers are read once to clear any pending interrupts on startup.- Returns:
- an
ArrayList
of 16 MCP23S17.PinView objects that are all configured to be inpputs, pulled up and interrupt-on-change enabled. - Throws:
IOException
- when any read or write operation fails.
-
addGlobalListener
Add a global interrupt listener.
This does no error checking with respect to whether or not interrupts are enabled.
- Parameters:
listener
- the global listener to add.- Throws:
IllegalArgumentException
- if the given global listener is already registered.NullPointerException
- if the given global listener isnull
.- Implementation Requirements:
- This is synchronized on the collection of global listeners, so it is thread safe.
-
removeGlobalListener
Remove a global interrupt listener.- Parameters:
listener
- the global listener to remove.- Throws:
IllegalArgumentException
- if the given global listener was not previously registered.NullPointerException
- if the given global listener isnull
.- Implementation Requirements:
- This is synchronized on the collection of global listeners, so it is thread safe.
-
writeIODIRA
public void writeIODIRA()Initiate SPI communication with the chip and write the IODIRA byte to the IODIRA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeIODIRB
public void writeIODIRB()Initiate SPI communication with the chip and write the IODIRB byte to the IODIRB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeIPOLA
public void writeIPOLA()Initiate SPI communication with the chip and write the IPOLA byte to the IPOLA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeIPOLB
public void writeIPOLB()Initiate SPI communication with the chip and write the IPOLB byte to the IPOLB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeGPINTENA
public void writeGPINTENA()Initiate SPI communication with the chip and write the GPINTENA byte to the GPINTENA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeGPINTENB
public void writeGPINTENB()Initiate SPI communication with the chip and write the GPINTENB byte to the GPINTENB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeDEFVALA
public void writeDEFVALA()Initiate SPI communication with the chip and write the DEFVALA byte to the DEFVALA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeDEFVALB
public void writeDEFVALB()Initiate SPI communication with the chip and write the DEFVALB byte to the DEFVALB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeINTCONA
public void writeINTCONA()Initiate SPI communication with the chip and write the INTCONA byte to the INTCONA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeINTCONB
public void writeINTCONB()Initiate SPI communication with the chip and write the INTCONB byte to the INTCONB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeGPPUA
public void writeGPPUA()Initiate SPI communication with the chip and write the GPPUA byte to the GPPUA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeGPPUB
public void writeGPPUB()Initiate SPI communication with the chip and write the GPPUB byte to the GPPUB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeOLATA
public void writeOLATA()Initiate SPI communication with the chip and write the OLATA byte to the OLATA register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
writeOLATB
public void writeOLATB()Initiate SPI communication with the chip and write the OLATB byte to the OLATB register.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
readGPIOA
Initiate SPI communication with the chip and read the GPIOA register.- Returns:
- the register's byte
- Throws:
IOException
- if the SPI write procedure fails.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
readGPIOB
Initiate SPI communication with the chip and read the GPIOB register.- Returns:
- the register's byte
- Throws:
IOException
- if the SPI write procedure fails.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
readGPINTENA
Initiate SPI communication with the chip and read the GPINTENA register.- Returns:
- the register's byte
- Throws:
IOException
- if the SPI write procedure fails.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
readGPINTENB
Initiate SPI communication with the chip and read the GPINTENB register.- Returns:
- the register's byte
- Throws:
IOException
- if the SPI write procedure fails.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
readIOCON
Initiate SPI communication with the chip and read the IOCON register.- Returns:
- the register's byte
- Throws:
IOException
- if the SPI write procedure fails.- Implementation Requirements:
- This is synchronized on the
Spi
so that two or more reads/writes cannot be initiated at the same time.
-
newWithoutInterrupts
public static MCP23S17 newWithoutInterrupts(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect) Instantiate a newMCP23S17
object with no interrupts.- Parameters:
bus
- the SPI-Channel that the chip is connected to.chipSelect
- the output pin controlling the chip select line on the chip.pi4j
- the pi4j context- Returns:
- a new
MCP23S17
object with no interrupts. - Throws:
NullPointerException
- if the given chip select output isnull
.
-
multipleNewOnSameBus
public static ArrayList<MCP23S17> multipleNewOnSameBus(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, int amount) throws IOException, IllegalArgumentException Instantiate a number ofMCP23S17
objects on the same bus with consecutive adresses.- Parameters:
bus
- the SPI-Channel that the chip is connected to.pi4j
- theContext
objectamount
- the amount of chips on the bus. must be between 1 and 8- Returns:
- an
ArrayList
ofMCP23S17
objects with no interrupts. - Throws:
IOException
- if the instantiation of theSpi
object fails.IllegalArgumentException
- if there are too few/many chips on the bus (amount
not in range 1-8)NullPointerException
- if the given chip select output isnull
.
-
multipleNewOnSameBusWithTiedInterrupts
public static ArrayList<MCP23S17> multipleNewOnSameBusWithTiedInterrupts(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalInput[] interrupts, int amount, boolean readGPIO) throws IllegalArgumentException, IOException Instantiate multiple newMCP23S17
objects on the same SPI-bus with their hardware address pins enabled and with their port A and port B interrupt lines "tied" together.- Parameters:
pi4j
- the pi4jContext
objectbus
- theSpiBus
with which to communicatee with the chipsinterrupts
- an array ofDigitalInput
s to listen for interrupts from the chipsamount
- the amount of ICs on the busreadGPIO
- true if on interrupt the GPIO registers should be read instead of the INTCAP registers- Returns:
- all the newly instantiated ICs
- Throws:
IllegalArgumentException
- if the amount isn't in the range 1-8 orinterrupts.length
is smaller than amountIOException
- if the instantiation of theSpi
object fails.NullPointerException
- if theinterrupts
array contains null.
-
newWithTiedInterrupts
public static MCP23S17 newWithTiedInterrupts(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput interrupt) Instantiate a newMCP23S17
object with the port A and port B interrupt lines "tied" together.- Parameters:
bus
- the SPI-Bus that the chip is connected to.chipSelect
- the output pin controlling the chip select line on the chip.interrupt
- the interrupt input pin.pi4j
- the pi4j context- Returns:
- a new
MCP23S17
object with the port A and port B interrupt lines "tied" together. - Throws:
NullPointerException
- if the given chip select output or tied interrupt input isnull
.
-
newWithInterrupts
public static MCP23S17 newWithInterrupts(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput portAInterrupt, com.pi4j.io.gpio.digital.DigitalInput portBInterrupt) Instantiate a newMCP23S17
object with individual port A and port B interrupt lines.- Parameters:
bus
- the SPI-Bus that the chip is connected to.chipSelect
- the output pin controlling the chip select line on the chip.portAInterrupt
- the interrupt input pin for port A.portBInterrupt
- the interrupt input pin for port B.pi4j
- the pi4j context- Returns:
- a new
MCP23S17
object with individual port A and port B interrupt lines. - Throws:
NullPointerException
- if the given chip select output or either of the interrupt inputs isnull
.
-
newWithPortAInterrupts
public static MCP23S17 newWithPortAInterrupts(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput portAInterrupt) Instantiate a newMCP23S17
object with an individual port A interrupt line, but no port B interrupt line.- Parameters:
bus
- the SPI-Bus that the chip is connected to.chipSelect
- the output pin controlling the chip select line on the chip.portAInterrupt
- the interrupt input pin for port A.pi4j
- the pi4j context- Returns:
- a new
MCP23S17
object with an individual port A interrupt line, but no port B interrupt line. - Throws:
NullPointerException
- if the given chip select output or the port A interrupt inputs isnull
.
-
newWithPortBInterrupts
public static MCP23S17 newWithPortBInterrupts(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, com.pi4j.io.gpio.digital.DigitalOutput chipSelect, com.pi4j.io.gpio.digital.DigitalInput portBInterrupt) Instantiate a newMCP23S17
object with an individual port B interrupt line, but no port A interrupt line.- Parameters:
bus
- the SPI-Bus that the chip is connected to.chipSelect
- the output pin controlling the chip select line on the chip.portBInterrupt
- the interrupt input pin for port B.pi4j
- the pi4j context- Returns:
- a new
MCP23S17
object with an individual port B interrupt line, but no port A interrupt line. - Throws:
NullPointerException
- if the given chip select output or the port B interrupt inputs isnull
.
-
getSpi
public com.pi4j.io.spi.Spi getSpi()get the pi4jSpi
object- Returns:
- the pi4j
Spi
object
-