Give your gizmo the gift of sight
I've never used I2C from a linux or PC/104 so I can't really help you there. Can you find code examples for communicating with I2C devices in general? I'm sure they exist somewhere. If so, it should be pretty easy to adapt those code examples to the commands for reading basic optical flow.
After another day of searching, I managed to find some examples to piece together into an I2C interface. However, I have now found that the I2C controller built into the embedded computer we're using is in fact a SMBus controller, that only supports that superset of all the I2C commands. I am able to do the simple 2-byte Command/Value writes, and simple single-byte reads, but the crossover appears to end there. Both methods I tried for manually specifying the transaction order resulted in "operation not permitted" errors.
For more info on the functions it's letting me use: http://www.mjmwired.net/kernel/Documentation/i2c/smbus-protocol
In essence, the SMBus protocol adds a few things to the communication procedure. The control bits (Start, Stop, Ack, NAck, Address, Rd/Wr) are identical, it just switches up the order a bit of the data being sent.
For the following info I'll be using the abbreviations from the above link. Right now the CYE8 Firmware (as well documented) has the following procedure to read out optical flow values:
S Addr Wr [A] Comm [A] Data [A] P - where Comm is 2 and Data is 65, this sets it to send the 6-byte OF array, then it is read by subsequent sequences of:
S Addr Rd [A] [Data] A [Data] A [Data] A [Data] A [Data] A [Data] NA P
This is simple, easy, and works great, but unfortunately the "i2c_smbus_read_block_data()" function (the only function that reads more than 2 bytes in a transaction that my adapter supports) specifies that reads are combined messages that include a preliminary write of a single Command byte to tell the device where to read from. They also expect that the first byte of the response is the number of total bytes to read, i.e.:
S Addr Wr [A] Comm [A] S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
So, primarily for myself, and if it works I'll commit changes, I plan to make the CYE8 firmware compatible with SMBus transactions (at least the message order, not CRC checking yet)
My idea for the change here is simply to add a few COMM constants (in the 60+ range) that, when received, will change the order of output to be compatible with the SMBus superset of the I2C protocol. The only real change will be adding handlers for the command byte, then putting another switch in the TWI_STX_ADR_ACK case that makes it send the length of the output array and break instead of continuing to the TWI_STX_DATA_ACK case.
When reading more into the protocol specification it seems to assume that any time you're doing a block read (more than 2 bytes) from an I2C device, even one not using SMBus, it does a combined write/read by sending a command byte first to tell the device (usually an EEPROM) where to start reading from.
Of course it will probably end up being more complicated, but I don't see it adding any extra overhead in terms of processing or memory. The only downside I see right now is that SMBus by definition doesn't support transmitting more than 32 bytes in a transaction, so if I'm going to dump the raw image I'll have to find some way of doing it in 32 byte chunks, probably by using a command byte for "resume".
It looks like you've done your homework! I wonder though if in your case an Arduino located between the sensor(s) and the PC104 could also serve as a "glue" board. Of course this assumes weight is not an issue. But otherwise your suggestion sounds great and I encourage you to at least share your results if this works out well. (We should test the code with simple I2C first as well to verify we don't break that.) I'd suggest placing those changes into the "OS" side of the code- the associated command headers should be <30.
We actually have a much more sophisticated comm handler (written by Craig Neely) that can be adapted to handle the issue you are talking about. It is a powerful and robust handler. We opted however to not include it in the CYE8 sensor since it can be difficult to understand how it works, and it adds another layer of complexity to the packaging of bytes being sent, but it is there.