Testing I2C and SPI communication

There are a number of driver variants in JeeH for external chips attached via I2C and SPI. To test these (on several different boards), I made a small circuit with both an I2C and an SPI memory chip on it. This way, automated tests can be set up to verify that everything works.

Why memory?#

Most I2C and SPI devices are not used for memory access, but for sensors and displays. The trouble is that sensors return unpredictable values (they sense their enviroment, after all) and displays are essentially output-only devices, which is of little use in automated tests.

With memory, you can write some data out and then read it back. If everything works the results will be 100% predictable and repeatable. Once tests pass, the same code will also work with other chips.

For kicks, I used FRAM instead of SRAM (FRAM stands for Ferroelectric RAM, which retains its contents when power is removed). There’s a product which comes in both I2C and SPI variants: the FM24LC16 and the FM25L16, respectively. These chips are available as SMD packages (SOIC-8). They can only store a measly 2048 bytes of data, but that’s more than enough to test with.

The circuit#

It’s all very simple. There are two connectors: 15 pins for Nucleo-32 boards and 10 pins for Nucleo-64 & Nucleo-144 boards. These pinouts are the same as on Arduino boards, but this test board is only for 3.3V systems: it cannot be used with ATMega-based 5V boards.

Connector pinout#

The way this board is set up, only one side can be connected at a time. On the left is a 15-pin header for Nucleo-32, on the right is a 10-pin header for Nucleo-64:

(note: the OLED display was only used initially to provide I2C pullups)

As it so happens, only a single connector is needed to access both I2C and SPI buses. On Nucleo-32 boards, some pin juggling was needed because one connection is shared between both bus types. For this reason, the two chips also cannot be used at the same time (not even on a Nucleo-64!).

Prototype build#

To verify the design, I built a version with SOIC breakout boards and some custom wiring on a protoboard PCB. There is also a button tied to Nucleo-32’s RESET pin.

And sure enough, it all works as expected. Both chips can be controlled using bit-banged I2C or SPI, as well as with JeeH’s polled and DMA-based drivers.

With this out of the way, the next step is to design a “real” PCB and have them fabricated.

Here is the initial design I came up with, autorouted with the “Freerouting” plugin for KiCAD:

There are a few small mistakes on there, but it was good enough to get 5 of them made as first check. I used JLCPCB in China for this. There’s a plugin for KiCAD which generates all the right files in one step, called “KiCad JLCPCB Tools” (also on GitHub).

It works!#

Here is the board, mounted in two different orientations:

The first board is a Nucleo G431KB, the second board is a Nucleo F103RB. The test board has a 10 µF SMD capacitor mounted, even though the footprint is through-hole. My second mistake was that this board does not have extra decoupling capacitors for each chip.

But hey, whatever, the tests still work perfectly fine …