# How to preset an I2C IO expander

I have a PCB that I use to make some measurements on a proprietary silicon chip. We are including a number of test structures on the PCB to allow for some automated tests, for example relays that open/close some connections, analog multiplexers that allow the sensing of certain pins of the chip, and so on.

All the test structures are controlled via 'dumb' I2C IO expanders, you control them via I2C and can set the direction of each pin, input or output, and you can set the logic state, or read it.

On the board we have a microcontroller that serves as interface between the PC (USB) and the board itself (I2C).

At POR all the expanders pin are configured as inputs, so each time that you want to use the board you need to connect it to a PC, run a small piece of code to preset it correctly, and then use it.

This is of course acceptable if you need to run automated tests, but is not so convenient if you just want to power it and use it quickly, or if you need to send it to a customer that wants to evaluate the silicon, because distributing all the software is not an option at this time.

There are various approaches to solve the issue.

Jumpers We have a number of them, but it becomes cumbersome quickly, we are talking of more than 100 IOs. Moreover, if you want to be able to bypass a relay entirely, i.e. forced open and forced closed, you need two jumpers.

pull up/down This is a bit more attractive, but it kinda defeats the purpose: I want a software reconfigurable hardware, I don't want to rework tens of boards if I find a bug.

The ideal solution I am dreaming of a very simple chip, like an I2C EEPROM or something like that, where you write a sort of boot sequence:

0xAE  0xAA
0xAE  0xBC
0x18  0x00


And so on. The data above represents couples of address, data. This fantastic chip should have a gpio input to which I can connect a button: when I press the button, the EEPROM should act as an I2C master and send the data on the I2C bus, so as an example the bytes above mean "Send 10101010 to 0xAE, then send 10111100 to 0xAE and finally send 00000000 to 0x18".

My question is:

• Is there a better way to initialize an I2C IO expander?
• Does the chip I envisioned exist, or should I just suck it up and use a microcontroller?
• That would be called a microcontroller! Jan 29 '18 at 22:27

You already indicated that you have a microcontroller on the board with all the I/O expanders. You said it already talks to the I2C stuff already!! Why not just have that microcontroller firmware setup the needed default initialized state of the I/O expanders.

If you needed several different ones of these initialized states you could even add several jumpers into that MCU to select the particular profile that is needed.

• Hi Michael, thanks for the suggestion. Using the main MCU is not that easy, as its firmware is programmed from an entirely different team, for the whole company. Jan 30 '18 at 11:07
• @VladimirCravero - I hear you regarding the ownership/location of the firmware. But despite that it is the correct way to address the issue. Any other thing you attempt to patch in would be a batch of extra hardware that would muck up your board design. Feb 1 '18 at 0:45

I have never seen such a device. But a microcontroller can do this function perfectly well, reading your default addresses and values from a separate Flash/EEPROM chip or from internal Flash/EEPROM.

Once you've programmed your microcontroller to do this, it'll look indistinguishable from the wonder chip that you dreamt of, so a win all round.

From any IC manufacturer's point of view, there's no point in them designing such a custom IC which there's limited demand for. They know the same function can be done by programming an existing IC. They want returns on their development investments, they'll design other ICs instead.

As an aside, is using a microcontroller something to 'suck up' or is there satisfaction in knowing you've made a good design choice :-)

No, i can safely say that this is not a predesigned off the shelf IC that does what you want. You could have this designed as an ASIC, but a microcontroller would be simpler and depending on your volume, cheaper. You could also implement this on your USB to I2C microcontroller so you wouldn't add a second one.

Alternatively, if you have a high enough volume or burning hole in your wallet, the expander manufacturer could design a custom version with your desired start state.

I like @Michael Karas answer, but in case the onboard microcontroller is not something you want to mess with (e.g. learning curve + resources to program), then you could go the other way and replace the big PC with something small and simple like a Raspberry Pi or other small embedded controller.

For example, this $20 LCD+switch hat from Adafruit will let you display text and read button presses. You could auto run a Python program which reads a text file on the SD card, displays the configurations on the LCD, lets the user scroll through the selection, and a button press can send the I2C data. If you need even smaller and cheaper, you can go with a Raspberry Pi Zero ($5 or \$10) though you'll need a USB cable adapter to get a full size (USB Type A) receptacle for your test fixture. LCD+Switch "hats" are also available for the RPi Zero also.

Anyway, using a cheap, tiny Linux computer would be a simple way to preconfigure your test bench for basic testing. With the right setup it can be cheap and simple for a customer to operate. Having a full OS lets you can write in a higher level language like Python, you would not need to buy any development tools (free in Linux), you can take advantage of powerful networking capabilities, you can configure it using simple text files so reconfiguring would be a matter of editing a text file on its SD card, heck you may even want to replace your USB-to-I2C MCU with an RPi Zero or other Linux embedded computer (these boards have I2C, SPI, PWM, GPIO, ADC, etc built in).

At some point, you might realize how powerful, simple, and inexpensive Linux and these tiny embedded computers are that you will have it run your testing instead of a big PC. That's where I've ended up :)

There are lots of such chips ranging in size 1k ... 512k with various speeds and low voltage ranges.

• Hey Tony, thanks for your help but I think you misread the question. I am searching for a device that can autonomously write the configuration, not just a 'passive' eeprom chip. Jan 30 '18 at 11:05
• Ah ok, I thought you might be able to get the Slave to TX the config data needed. In the past I used a serial EEPROM to initialize hardware. Jan 30 '18 at 13:09