XIO Library Reference

Introduction

The XIO library was designed to make the Iowa Scaled Engineering I2C-XIO 40-channel I/O expander board easy to use with the ArduinoTM environment. The board itself needs to be connected to the SCL and SDA lines coming out of the Arduino, as well as ground. The /IORST (inverted IO reset) line can be connected to a digital I/O pin or just connected to +3.3V or +5V. The /OEN (inverted output enable) can be also be connected to a digital I/O pin or just connected to ground. If either /OEN or /IORST is left floating, the board will hold itself in a permanent reset state and do nothing interesting. The 6p6c connectors on the board implement the standard Iowa Scaled Engineering 6P6C I2C connector pinout, making it directly compatible with a wide variety of shields we offer with an I2C port.

This library will probably work for other implementations of the NXP PCA9698 as well, as our board is very close to a straight break-out board with a few value-adds such as the high power switching regulator.

Setup

You'll need to copy the XIO directory (with the XIO.cpp and XIO.h files) into your arduino/libraries directory.  This is known as "Manual Installation" of an Arduino library. More details can be found in the Arduino - Libraries documentation.

Once the files are there, start your Arduino IDE and you should be able to pick "XIO" from "Sketch->Import Library..." to add it to your sketch. You'll also likely need to import the stock "Wire" library to get I2C functionality.

Example Sketch

(AKA... Real developers don't read the documentation first, just shut up and show me some code, sparky!)

A sample Arduino sketch that demonstrates some simple uses of the library is available as part of the source package - it's in the "xio_example" directory. You still need to install the library itself, as described in Setup. Once the library's in place, you should be able to open up the xio_example.ino sketch from "File->Examples->XIO->xio_example" in the menu and build/upload it. The example application will blink an LED attached between port A0 and ground, via a resistor, and will print to the serial console whether A5 and A6 are connected high (+5) or low (ground).

Source Releases

The latest source code is always available from our GitHub I2C-XIO repository. Look in the src/XIO directory.

License

The XIO library is copyright 2014 by Nathan Holmes and Michael Petersen. It is free software, licensed under the GNU General Public License v3.

Classes and Structures

class XIO
{
public:
XIO();
void begin(boolean a0, boolean a1, boolean a2, char dioResetPin, char dioOutputEnablePin);
void xioPinMode(byte pin, byte mode);
void xioPinModeCached(byte pin, byte mode);
void xioDigitalWrite(byte pin, byte mode);
void xioDigitalWriteCached(byte pin, byte mode);
boolean xioDigitalRead(byte pin);
boolean xioDigitalReadCached(byte pin);
void refreshPinModes();
void refreshIO();
};

XIO Class Public Methods / Functions

XIO::XIO()

The XIO::XIO() constructor takes no arguments, and will initialize an object to control an I2C-XIO board.


void XIO::begin(boolean a0, boolean a1, boolean a2, char dioResetPin, char dioOutputEnablePin)

The XIO::begin() function should be called within the setup() function of your sketch. Input parameters a0, a1, and a2 should be either HIGH or LOW, depending on whether address jumpers for the board are open (HIGH) or have a jumper installed across the pins (LOW). Using various combinations of these pins, up to 8 I2C-XIO boards (and therefore 320 I/O lines) can be controlled on a single I2C bus.

If the /IORST line in the 6p6c connector is attached to a digital I/O pin, specify its digital I/O number as dioResetPin. If it isn't connected, pass in a -1 for the dioResetPin parameter. For most ISE shields with an I2C connector, this will be digital 4.

If the /OEN line in the 6p6c connector is attached to a digital I/O pin, specify its digital I/O number as dioOutputEnablePin. If it isn't connected, pass in a -1 for the dioOutputEnablePin parameter. For most ISE shields with an I2C connector, this will be digital 3.


void XIO::xioPinMode(byte pin, byte mode)
void XIO::xioPinModeCached(byte pin, byte mode)

The xioPinMode function works just like Arduino's pinMode function - it sets the direction (INPUT or OUTPUT) of a given pin on the I2C-XIO board. The "pin" parameter is specified as one of the I2C-XIO pin definitions, and the "mode" parameter is just "INPUT" or "OUTPUT".

The xioPinModeCached() version of the function updates the XIO object's pin direction, but does not actually send it to the I2C-XIO board until the refreshPinModes() function is called, or an xioPinMode() call is made to the same bank (A,B,C,D,E). As an example, you could use the xioPinModeCached() function to set up the direction for the first seven pins of bank A, and on the final one use xioPinMode() and it would configure all of bank A's directions with one I2C transaction. This is much more efficient than sending the configuration with every pin mode change.

Note: The I2C-XIO and therefore the XIO library initialize all pins to inputs for safety.


void XIO::xioDigitalWrite(byte pin, boolean value)
void XIO::xioDigitalWriteCached(byte pin, boolean value)

The xioDigitalWrite function works just like Arduino's digitalWrite function - it sets a pin on the I2C-XIO specified as an OUTPUT to either HIGH or LOW. The "pin" parameter is specified as one of the I2C-XIO pin definitions, and the "value" parameter should be "HIGH" or "LOW" (or any other expression that resolves to a boolean).

The xioDigitalWriteCached() version of the function updates the pin's output value in the XIO object, but does not actually send it to the I2C-XIO board until the refreshIO() function is called, or an xioDigitalWrite() call is made to the same bank (A,B,C,D,E). This is useful for minimizing the number of I2C transactions (and therefore time) to send a large number of I/O changes over to the I2C-XIO.


boolean XIO::xioDigitalRead(byte pin)
boolean XIO::xioDigitalReadCached(byte pin)

The xioDigitalRead() function works just like Arduino's digitalRead() function - it reads a pin on the I2C-XIO as either HIGH or LOW. The "pin" parameter is specified as one of the I2C-XIO pin definitions.

The xioDigitalReadCached() version of the function will get the pin's last known state from XIO object without actually doing a read over the I2C bus. The pin state will have been read from hardware the last time a xioDigitalRead() call was made to the same bank (A,B,C,D,E) or the refreshIO() function was called. This is useful for minimizing the number of I2C transactions (and therefore time) to read or write a large number of I/O states over to the I2C-XIO.


void XIO::refreshIO(void)

The refreshIO() function will - with a single I2C transaction - read the state of all XIO inputs and write the state of all XIO outputs. By using the cached versions of the read/write functions - ie, xioDigitalReadCached() and xioDigitalWriteCached() - all of the desired output states can be set up, the refreshIO() function can be called, and then the state of all inputs can be read off without having up to 80 separate I2C transactions. Since I2C only operates at 400k bits per second, and the smallest output pin write will take 30 bit-times, this can quickly add up to real latency in a system. If performance is important, please consider using the cached functions.


void XIO::refreshPinModes(void)

The refreshPinModes() function will - with a single I2C transaction - send the INPUT/OUTPUT configuration of all 40 XIO's I/O lines. By using the cached versions of the xioPinMode function - ie, xioPinModeCached() - all of the desired input or output configuration states can be sent in one I2C transaction. This can save significant time in getting the I/O lines initialized.

XIO Pin Defintions

Since the I2C-XIO uses five ports of eight pins each - A0-A7, B0-B7, C0-C7, D0-D7, and E0-E7 - there are defines to specify which bank and pin you want to access. Those defines are fairly self-explanatory, and are as follows:

Bank A Pin Definitions

  • XIO_PIN_A0
  • XIO_PIN_A1
  • XIO_PIN_A2
  • XIO_PIN_A3
  • XIO_PIN_A4
  • XIO_PIN_A5
  • XIO_PIN_A6
  • XIO_PIN_A7

Bank B Pin Definitions

  • XIO_PIN_B0
  • XIO_PIN_B1
  • XIO_PIN_B2
  • XIO_PIN_B3
  • XIO_PIN_B4
  • XIO_PIN_B5
  • XIO_PIN_B6
  • XIO_PIN_B7

Bank C Pin Definitions

  • XIO_PIN_C0
  • XIO_PIN_C1
  • XIO_PIN_C2
  • XIO_PIN_C3
  • XIO_PIN_C4
  • XIO_PIN_C5
  • XIO_PIN_C6
  • XIO_PIN_C7

Bank D Pin Definitions

  • XIO_PIN_D0
  • XIO_PIN_D1
  • XIO_PIN_D2
  • XIO_PIN_D3
  • XIO_PIN_D4
  • XIO_PIN_D5
  • XIO_PIN_D6
  • XIO_PIN_D7

Bank E Pin Definitions

  • XIO_PIN_E0
  • XIO_PIN_E1
  • XIO_PIN_E2
  • XIO_PIN_E3
  • XIO_PIN_E4
  • XIO_PIN_E5
  • XIO_PIN_E6
  • XIO_PIN_E7