Dumping EEPROM via Two-Wire Interface using Windows IoT Core and Windows Runtime APIs

I revisited Windows IoT Core a few weekends ago and found it to be useful in a quick project that involved dumping my wireless headset’s electrically erasable programmable read-only memory (EEPROM). In other words, just another weekend at Rafael’s place.
Let me walk you through what I did.
Hardware Setup
First, I pulled down the Windows IoT Core Dashboard and set up a new device. I flashed a MicroSD card with the latest build of Windows IoT Core and popped it straight into the Raspberry Pi 2 (Amazon, ~$40). After a bit of configuration, the device was online and ready to receive instructions from Visual Studio.
I then skimmed through the datasheet and attached some test clips to the EEPROM chip (ACE24C256) for Ground, Serial Clock and Serial Data access. I routed those to the Raspberry Pi’s GPIO2, GPIO3 and Ground pins where Two-Wire Serial (TWI)/Inter-integrated Circuit (I2C) communication is expected to occur.
That was the extent of the hardware configuration I performed.
(Two-Wire Interface is mostly identical to I2C, cleverly created to sidestep trademark issues with I2C. I say mostly because it’s missing a few niceties like 10-bit addressing.)
Software Setup
Windows IoT Core runs apps targeting the Universal Windows Platform (UWP), but the templates that ship with Visual Studio are way overkill for what I needed. So, I instead installed the Background Application Template from the Visual Studio Marketplace. This template creates a simpler project with a bare-bones implementation of a Background Task.
Using that starter code, I followed the usual deferral pattern (to prevent the app from killing my asynchronous tasks) and started laying down the code I needed:
- Retrieved an instance of the I2cController class, corresponding to the default I2C controller (and set of pins) on the Raspberry Pi.
- Retrieved an instance of the I2cDevice class, representing the chip I wanted to dump. This requires an I2cConnectionSettings object that points to the chip via a 7-bit numerical address. In this chip’s case, the address is crafted by setting its first 4 significant bits to [1010] and the next 3 to [000]. That becomes [1010000] or 50 in hexadecimal. (The I2C classes manage the 8th bit on the fly.)
- Took advantage of the faster clock speeds supported by the chip by setting the device Bus Speed to FastMode (400kHz).
- Prepared a file for holding the EEPROM contents
I paused at calling the I2cDevice.Read method for a moment, because it only took one parameter – a buffer to store data clocked out of the chip. It doesn’t support addressing. But I remembered I2C/TWI isn’t limited to just storage applications – it’s higher level than that. So I needed to review the datasheet again to understand the protocol implemented on top of I2C/TWI to read data correctly from the chip.
Here’s what I picked up from the datasheet:
- A Current Address Read is performed by clocking in a read bit (0). The chip responds by clocking out the byte of data at the current address.
- A Sequential Read is performed by looping a Current Address Read, paired with an acknowledgement, to effectively move the address pointer forward by 1 byte each iteration.
- A Random Read is performed by first preparing the chip for a dummy write operation, to set its internal address pointer, then switching mid-way to a Current Address Read operation. Sneaky!
I implemented this logic using the I2CDevice.Read and I2CDevice.Write methods on the Device object I created earlier. Because the I2cDevice class handles I2C/TWI addressing and other minutia (in green) for me, I only had to worry about the data portion of the protocol (in purple). In this case, to set the internal address pointer to 0, I had to write two zeros (8 bits each). Got it.
With the dummy write out of the way, I switched to using the I2CDevice.Read method to complete the Random Read operation. The I2C classes did the heavy lifting while I dumped my buffer to disk. I then come behind the app to scoop up the file with the IoT Dashboard.
With a fresh EEPROM dump in hand, I was done.
Tagged with Raspberry Pi 2, UWP, Windows 10 IoT Core, Windows Runtime