java.lang.Object
ch.ladestation.connectncharge.pui.Component
ch.ladestation.connectncharge.pui.MCP23S17

public final class MCP23S17 extends Component

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 PinViews (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 Classes
    Modifier and Type
    Class
    Description
    static 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

    Fields inherited from class ch.ladestation.connectncharge.pui.Component

    log
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    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.
    Get the PinView corresponding to the given Pin.
    Get an Iterator over all the PinViews for this MCP23S17.
    com.pi4j.io.spi.Spi
    get the pi4j Spi object
    multipleNewOnSameBus(com.pi4j.context.Context pi4j, com.pi4j.io.spi.SpiBus bus, int amount)
    Instantiate a number of MCP23S17 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 new MCP23S17 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 new MCP23S17 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 new MCP23S17 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 new MCP23S17 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 new MCP23S17 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 new MCP23S17 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.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • getPinView

      public MCP23S17.PinView getPinView(MCP23S17.Pin pin)
      Get the PinView corresponding to the given Pin.
      Parameters:
      pin - the Pin.
      Returns:
      the corresponding PinView.
    • getPinViewIterator

      public Iterator<MCP23S17.PinView> getPinViewIterator()

      Get an Iterator over all the PinViews for this MCP23S17.

      The returned Iterator returns the PinViews in the order of their pin numbers (i.e. the PinView for PIN0 comes first and the PinView for PIN15 comes last). The returned Iterator does not support removal of elements.

      Note that if certain PinViews have not yet been lazily-loaded, they will be loaded as needed by the returned Iterator.

      Returns:
      an iterator over all the PinViews for this MCP23S17.
    • getAllPinsAsPulledUpInterruptInput

      public ArrayList<MCP23S17.PinView> getAllPinsAsPulledUpInterruptInput() throws IOException
      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

      public void addGlobalListener(MCP23S17.InterruptListener listener)

      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 is null.
      Implementation Requirements:
      This is synchronized on the collection of global listeners, so it is thread safe.
    • removeGlobalListener

      public void removeGlobalListener(MCP23S17.InterruptListener listener)
      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 is null.
      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

      public byte readGPIOA() throws IOException
      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

      public byte readGPIOB() throws IOException
      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

      public byte readGPINTENA() throws IOException
      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

      public byte readGPINTENB() throws IOException
      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

      public byte readIOCON() throws IOException
      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 new MCP23S17 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 is null.
    • 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 of MCP23S17 objects on the same bus with consecutive adresses.
      Parameters:
      bus - the SPI-Channel that the chip is connected to.
      pi4j - the Context object
      amount - the amount of chips on the bus. must be between 1 and 8
      Returns:
      an ArrayList of MCP23S17 objects with no interrupts.
      Throws:
      IOException - if the instantiation of the Spi 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 is null.
    • 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 new MCP23S17 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 pi4j Context object
      bus - the SpiBus with which to communicatee with the chips
      interrupts - an array of DigitalInputs to listen for interrupts from the chips
      amount - the amount of ICs on the bus
      readGPIO - 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 or interrupts.length is smaller than amount
      IOException - if the instantiation of the Spi object fails.
      NullPointerException - if the interrupts 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 new MCP23S17 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 is null.
    • 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 new MCP23S17 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 is null.
    • 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 new MCP23S17 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 is null.
    • 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 new MCP23S17 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 is null.
    • getSpi

      public com.pi4j.io.spi.Spi getSpi()
      get the pi4j Spi object
      Returns:
      the pi4j Spi object