I2c or TWI, is a 2 way stream that uses 2 signal lines: SDA
and SCK
. This is used in sensors to communicate between a master and a slave.
So, how does this work? Well, here's the boilerplate:
Input:
1 I2c command represented by 2 strings where -
is a high signal, and _
is low. SDA
is always the first string.
Output:
The debug info for that command, including weather
it's a READ
or WRITE
,
which address it's to (in Hex), and
what memory the signal's addressing(in Hex).
if the transmission is invalid, print "Invalid"
How does I2c work, then?
Image from Sparkfun!
An i2c request has 2 9-bit parts. the address and the payload. The address comes first.
A bit is only READ
when the clock signal goes from LOW
to HIGH
. Going from HIGH
to LOW
is not a valid reading event.
The address is 7 bits, which come after both SDA
and SCL
are LOW
. This is sent by the master.
After the 7th bit, the next is sent by the master, which is the READ
Bit. If this bit is HIGH
, then it's a READ
operation, if the bit is LOW
, then it's a WRITE
operation.
After the 8 bits, the slave responds with an ACK bit, if the ACK bit is HIGH
, then the entire transmission is invalid.
Then, the second transmission is sent.
The first 8 bits represent the data address that the master is READ
ing or WRITE
ing.
and the final bit is the 2nd ACK bit. If this bit is HIGH
, then the entire transmission is invalid.
Examples:
Raw IN: ["--____--__----__----__----__--__--__","___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-"]
SDA: --____--__----__--__--__----__--__--__
SCK: ___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Result: 0 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0
Parse: addr[22] op:[R] data:[181] success[yes]
out: address:0x16 op:Read data:0xB5
Raw IN: ["--____--__----__------__----__--__--__","___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-"]
SDA: --____--__----__------__----__--__--__
SCK: ___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Result: 0 0 1 0 1 1 0 1 1 1 0 1 1 0 1 0 1 0
Parse: addr[22] op:[R] data:[181] success[No]
out: invalid
Note: (the ACK bit flipped high);
Raw IN: ["--_-_--__--_-__--_-_-__-_-_-_--__--__-","___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-"]
SDA: --_-_--__--_-__--___-__-_-_-_--__--__-
SCK: ___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Result: 0 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0
Parse: addr[22] op:[R] data:[181] success[yes]
out: address:0x16 op:Read data:0xB5
Note: (the bit before the change is read.);
Raw IN: ["--_____--___-----___--___--___-----__---____--____","___--_-_--_--_-_--_-_--_-_--_-_--_-_--_-___-_--__-"]
SDA: --_____--___-----___--___--___-----__---____--____
SCK: ___--_-_--_--_-_--_-_--_-_--_-_--_-_--_-___-_--__-
Result: 0 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0
Parse: addr[22] op:[R] data:[181] success[yes]
out: address:0x16 op:Read data:0xB5
Note: (Clock signals Don't have to be perfect.);
Raw IN: ["--_____--___-----___--___--___-----__---____--____","___---_-_--_-___-_--__-"]
SDA: --_____--___-----___--___--___-----__---____--____
SCK: ___---_-_--_-___-_--__-
Result: 0 0 1 0 1 0 1
Parse: Invalid
out: invalid
Note: (They do however, have to match the length of the data dignal.);
Extra rules:
The 0x
prefix must be appended to all hex values in the output, as a formality.
The input is strictly -
for HIGH
and _
for LOW
, and will always be 2 separate strings with a separator character.
If both SDA
and SCL
change at the same time, then the previous bit is read.
This is a code golf, so whoever creates a running program in the least number of bytes wins! Good luck
If both SDA and SCL change at the same time, then the previous bit is read.
\$\endgroup\$