Sunday, July 25, 2021

I2C

Nah, not precisely that device, but quite close.

I've been lucky working on embedded systems over the last 7 years (wow. Yeah. that many already), and being part of the engineering of one for at least the last 4. I mean, my colleagues really put together chips on a multi-layer PCB following chipmaker's guidelines and their tools advice and their knowledge so that high-speed signals would arrive clean and timely where they are expected.

We eventually received a first batch of prototype and I felt like I was part of the Playstation design team while we were bringing up the board, one chip at a time, adding custom software scripts so that the hardware teams would have signals to monitor and assess whether the hardware produced was meeting the expected quality (sometimes it did, sometimes it didn't. Hopefully, there were plenty of 0-ohm resistor and not-stuffed-pull-up/low resistors on the PCB design to adjust things. Clever they).

Many of the chips we used (like HDMI receiver/transmitters, power management IC, audio CODEC and even the FPGA) are meant to work mostly standalone, but they still need to get configuration at some point. Like telling the codec which samplerate it should run at and whether it should produced 8-bit or 16-bit values. Sometimes we want to read information from them, like the board temperature or the signal resolution the HDMI receiver got. For all this, I had I2C.

And not quite that SoC, but an OMAP anyway...

I2C is a bus, connecting 2 or more chips. I has one master chip and multiple subordinate chips. Communication always happens when the master says so. It either reads (asks for data) or writes (sends data), but there is no 'interrupt' signal flowing back part of the I2C bus, nor can you have sub-to-sub communications over the bus. Unlike ISA that connected my soundBlaster and my trident SVGA cards to my 80386 CPU, the I2C uses only 2 lines: one clock line and one data line. The goal is obviously to make it as cheap as possible for chips to support it.

Let's think of it from a network guy perspective. ISA and PCI busses (and even USB) try to offer as much bandwidth as technically possible because they'll have to transmit bulks of data. I2C is the out-of-band technology you'd use next to a (r/h)igh(t) bandwidth solution you use for your data blasts. The audio CODEC chip had I2S lines dedicated to sound transport. The HDMI chip had BT1120 interface for the same purpose. At best these media busses had additional lines notifying 'start of frame', but you couldn't use them to deliver status information, and most of the time, chips using them were hard-wired as either transmitter or receiver on those lines, so using them to send configuration would be electrically dangerous to the chips.

The brilliant part in I2C is that the two chips using it don't need to agree on any speed nor be clocked with the same crystal: bits from the DATA line are sampled only when the CLK line rises. That gives the opportunity to have special 'START' and 'STOP' encoding that would otherwise be invalid. For instance, changing the DATA line while the CLK line is in a-priori requesting the DATA not to change.

Most of the systems I've worked with had dedicated I2C driving units that would handle bits transmission after you indicated one or more bytes in a FIFO buffer and the device identifier in another register. But you may also simply use a generic-purpose I/O line as DATA and another one as CLK. That will work whatever the speed of your CPU.

Much like ISA soundblaster cards would use only one of 0x220, 0x240, 0x260 or 0x280 port for their control register, an I2C-compatible sound chip would e.g. only react to chip ID 0x22, 0x24, 0x26 or 0x28. And much like you had jumpers on your soundblaster card to pick something else than 0x220 if you happened to have a tape reading device using that port as well (or too soundblaster, lucky weirdo :-D), your I2C chip will typically feature some configuration pin that you can wire to ground or VCC to pick one of the available IDs.

2 comments:

Hackaday said...

And with it being a bus, you may end up with your host-chip unable to talk to any device-chip if any of them quits the protocol, holding the data (or clock?) line pulled while it should let it float for someone else to pull ...

PypeBros said...

Oh, and I've been playing with RS485, too, and I'd have loved to be able to read about it first.