-
Notifications
You must be signed in to change notification settings - Fork 92
HydraFW Binary I2C mode guide
This guide is updated towards firmware release HydraFW v0.11 and later
- I2C clock stretching Implemented commit ebf732 (02 Jan 2023)
Actual firmware does not support following I2C special features (usually not used in majority of I2C devices)
This mode allows to control I2C1
- I2C1 pins: SCL=PB6, SDA=PB7
- For more details on I2C1 see https://github.com/hydrabus/hydrafw/wiki/HydraFW-I2C-guide
Once the I2C mode has been selected, the following commands are available :
-
0b00000000
Return to main mode. ReturnsBBIO1
-
0b00000001
Mode identification. ReturnsI2C1
-
0b00000010
I2C start bit -
0b00000011
I2C stop bit -
0b00000100
I2C read byte -
0b00000110
I2C ACK bit -
0b00000111
I2C NACK bit -
0b00001000
I2C Write-then-read -
0b00001111
Sniff all I2C traffic -
0b0001xxxx
Bulk I2C write -
0b00100000
I2C Clock stretching configuration -
0b01000x00
Configure I2C peripheral -
0b011000xx
Set I2C speed -
0b11xxxxxx
Binary Auxiliary pins
Send an I2C start bit. Returns 0x01
Send an I2C stop bit. Returns 0x01
Reads a byte from the I2C bus, returns the byte. You must ACK or NACK each byte manually!
Send an I2C ACK bit after reading a byte. Tells a slave device that you will read another byte.
Returns 0x01
Send an I2C NACK bit after reading a byte. Tells a slave device that you will stop reading, next bit should be an I2C stop bit.
Returns 0x01
This command is used to send at most 4096 bytes and will read at most 4096 bytes of data.
Format :
Byte 1 2 3 4 5 6 ...
|----------|----------|----------|----------|----------|----------|------...
[command ] [ Bytes to write ] [ Bytes to read ] [ Data to write
The bytes to read/write are in big-endian format.
- All data will be buffered before being sent to the I2C bus. Read data will also be buffered on the Hydrabus before being sent back to the user.
- I2C start bit is sent before sending the data.
- All read bytes are ACKed, except the last byte which is NACKed.
- At the end of the read process, Hydrabus sends an I2C stop.
More information can be found here : http://dangerousprototypes.com/docs/I2C_(binary)#0x08_-_Write_then_read
In this mode, all detected traffic is sent to the bus, using the following syntax:
-
[
: Start condition -
]
: Stop condition -
\
followed by a raw byte representing the byte sniffed on the bus. Followed by+
when an ACK was read or a-
if a NACK was read.
Send a byte to stop the sniffer. Hydrabus will respond with 0x01
once sniffer is stopped.
In this mode, the last 4 bits of the command define the number of bytes to write (from 1 to 16) (Command 0b00010000
will send 1 byte).
Hydrabus replies 0x01
to the bulk I2C command. After each data byte the Hydrabus returns the ACK 0x00
or NACK 0x01
bit from the slave device.
This command sets the I2C clock stretching timeout (32bits unsigned value up to 2^32, 0=Disable)
Format :
Byte 1 2 3 4 5
|----------|----------|----------|----------|----------|
[command ] [Maximum number of I2C clock stretch cycles]
The maximum number of I2C clock stretch cycles in big-endian format.
This command sets the I2C device speed. The two last bits will select the speed (in kHz) within the following list :
-
0b00
=> 50 kHz -
0b01
=> 100 kHz -
0b10
=> 400 kHz -
0b11
=> 1000 kHz
This commands returns 0x01
if successful, 0x00
in case of error.
This allows to set the following parameters :
-
x
sets the pull-up resistors (if 1 use internal on-board pull-up resistors about 50Kohm else use external on-board pull-up resistors)
See https://github.com/hydrabus/hydrafw/wiki/HydraFW-I2C-guide for explanation.
This commands returns 0x01
if successful, 0x00
in case of error.
The following python script can be used to read 4096 bytes from a 24AA I2C EEPROM :
import hexdump
import serial
import struct
# Open serial port
ser = serial.Serial('/dev/ttyACM0', 115200)
# Open binary mode
for i in xrange(20):
ser.write("\x00")
if "BBIO1" not in ser.read(5):
print "Could not get into binary mode"
quit()
# Switching to I2C mode
ser.write('\x02')
if "I2C1" not in ser.read(4):
print "Cannot set I2C mode"
quit()
# Reading information
while (addr < 4096*size):
#Write-then-read. 4 bytes to write, 4096 bytes to read
ser.write('\x08\x00\x04\x10\x00')
#Read command(\x03) and starting address (\x00\x00\x00)
ser.write('\x03\x00\x00\x00')
#Hydrabus will send \x01 in case of success...
ser.read(1)
#...followed by 4096 read bytes
buff += ser.read(4096)
print hexdump.hexdump(buff)
# Return to main binary mode
ser.write('\x00')
#reset to console mode
ser.write('\x0F\n')
- CHANGELOG
- Console commands
- Binary mode guide
-
NFC/HydraNFC v1 guide
- Read UID of an ISO/IEC_14443 Tag
- Read UID and data of a MIFARE Ultralight Tag
- Read UID of an ISO/IEC 15693 Tag
- Emul ISO14443a Tag
- Emul MIFARE Ultralight Tag
- Emul Mifare Classic Tag
- Unique NFC sniffer design
- Launch NFC sniffer from console
- Sniffer ISO14443A wireshark pcap
- Autonomous/stand-alone sniffer mode
- Sniffer ISO14443A real-time infinite trace mode
- HydraFW-HydraNFC-v1.x-TRF7970A-Tutorial