Arduino Bit Bashing Canon eTTL Protocol

I needed to be able to sniff the digital data exchange between a Canon G16 camera and a 430EX II flash. Prior work had determined that the Canon digital eTTL protocol interface was VERY close to SPI. Mostly. Except for signal voltage levels. I had already determined that the Arduino SPI interface was not suitable for sniffing.

My ultimate goal was to discover how the Canon eTTL protocol supported burst mode flash control - so that I could mimic that small part of the protocol. The camera was smart enough to detect the presence of a Canon flash and then control it via digital commands.

So I was forced back to basics. Fortunately Bill Grundmann had already started down this avenue and provided a sample bit bashing program. I used this code as a starting point and then many late nights expanding the program. It basically relies upon detecting change of state of the 3 SPI signal lines. An interrupt service routine is hooked to the CLCK line which then samples the current state of the 2 data lines. Low level brute foirce programming. Very timing dependent. 

One of the first issues was inconsistent behaviour of the sniffer program. It took several experiments and large amounts of head scratching to discover that bit bashing and slow blocking operations did not mix well. The obvious culprit was the standard debugging output via Serial.print. This depended upon serial interrupts. Some basic timing calculations revealed that the camera / flash data exchange operated at a higher data rate than the debug output. A dumb debug output dump of all traffic was doomed to failure. The camera - flash exchanged more data than the debug monitor could dump.

The next clue to success was based upon a general observation of the SPI interface. It was bi-directional, but not really full duplex. There was a single clock signal controlled by the Master. The Master (camera) and Slave (flash) both transmitted at the same time. Under control of the Master driven clock. The Slave can not initiate data exchange. This meant the data exchange was highly constrained. The Master could transmit a command to the Slave at any time. The Slave could not initiate a data transmission. The Slave was also constrained to transmit data at the same time as the Master, before it had received current information from the Master. These constraints result in a very chatty protocol.

Examination of the data revealed that the flash tended to continually spew status messages at the camera. This made sense since each multi-byte data exchange was initiated by the camera. The flash has not yet read the information from the camera, but is required to provide data back to the camera. So the flash often transmitted a standard "general status" message. This meant that in a steady state, with no button pushes on the camera or flash, the digital interface was constantly spewing data back and forth.

Next step was to figure out what it all meant (or at least learn enough so I could trigger my strobes).