Hii there,
currently i am working with i2c , after going through documentations it made me so clear to understand this protocol from base level, but left me with a small doubt. & i hope this community will help me out
The problem is we are using Wire.Write function to write data to the i2c slave device , and we put the address and data all in continous Wire.Write function, so how will the i2c slave will know which one is the address of memory user wish to write and what is the actual data he wants to write to that address??
for example here i am writing to a slave device
Wire.begin();
Serial.begin(115200);
Wire.beginTransmission(MPU_addr); // Start communication with MPU6050 // MPU=0x68
Wire.write(0x6B); // Talk to the register 6B
Wire.write(0b00001000); // data to write
Wire.endTransmission(true);
but what if we have 16 bit register or multiple 8 bit register and data to write to it?
what will be the possible solution? and format of writing ?
Wire.beginTransmission(MPU_addr);
This is where you specify the I2C address
Wire.write(0x6B); // Talk to the register 6B
In this case it appears that the first byte is the address of the first register to write.
Wire.write(0b00001000); // data to write
This is the data that will be written into the first register.
Many, but not all, Wire/TWI/I2C devices have an auto-increment feature. If you send multiple bytes of data, the data will be written into sequential registers. If a register is 16 bits long it will usually be stored as two consecutive bytes. You would send the two bytes separately.
wire, wire1, wire2:
These are "busses": separated wires, different wires and interfaces for master and slaves
on same "wire":
all hang now on the same bus: one master, several servers. All servers have a different slave address. Therefore, you have to specify the slave address to which one you want to send a message
the slaves, all, are listening in parallel, on the same bus: they wait until they see "its slave address sent" (which is the first byte sent on the bus).
Just if a slave sees "its address" - it will act (and only this one! and there can be different slaves but all must have a different slave address, never sharing the same address!)
When it comes to writing a (register address) inside a (selected) chip:
selected chip means: send an I2C transaction with the correct slave address.
But the following data is a "protocol": now it matters what the data stream via I2C is.
It means often: send a data stream, where the first byte is a register address (inside the chip) and the following the data byte to write.
So, the bus transmit this: SLAVE_ADDR REG_ADDR DATA_WORD
The SLAVE_ADDR selects the device (it is open know to take more), REG_ADDR is the register address inside the chip and the DATA_WORD what to write to this register (inside the selected chip).
How Read/Write as commands, as I2C "Protocol" look like, depends on the chip itself. I2C defines just how to select a slave device via SLAVE_ADDR, not how to read/write registers from/into slave itself. This depends on the chip (see datasheet).
Here is one typical example (for many I2C chips I have seen):
a read is a bit more complex! It consists of a two step operation!
I2C has two "primitives", such as read or write. Those are I2C "transactions" to do a read or a write. There is a bit (bit 0 on slave address!) which tells the direction (for Read or Write (slave address bit 0 is 0)).
But it does NOT work here this way!
Instead - for reading a register in most of I2C chips:
do a WRITE with the REG_ADDR
do a RESTART
do a READ: now you read data (in a consecutive way) getting DATA_WORD from (consecucive) REG_ADDResses
send a NACK to finish (host receiver = READER, has to acknowledge any byte as DATA_WORD anyway, but on last send NACK to stop reading)
BTW: any I2C transaction, even this RESTART READ, starts with sending SLAVE_ADDR on bus (but done automatically, you do not see).
Check in your FW if you see functions like "I2C Read" (not appropriate to read data!) or "MemoryRead": the last one is a WRITE - RESTART - READ transaction and right for your register/memory read.
Or, "imagine" this protocol:
a SLAVE_ADDR is sent and will select if a slave will keep going to listen:
if not matching - ignore all, if matching keep going to listen (on bus)
if next I2C transaction is a READ or WRITE:
in read: expect to see a write just to set the REG_ADDR (via an I2C WRITE),
or as a WRITE: first DATA_WORD is REG_ADDR,. following the values to write (DATA_WORD(s)
if a READ: it must change from WRITE to READ as I2C transaction, via a RESTART, but now
"dummy cycles" just to get the DATA_WORD(s) to read
host (master) has to tell when last DATA_WORD is done - via NACK (it works as "consecutive")
A WRITE can be a single I2C transaction, but a READ is not:
it needs a WRITE to set the REG_ADDR where to read from. So, a read look like two transactions.
Yes, "auto-increment" means: "consecutive":
often, you can WRITE, starting at an ADDR and keep writing into next, incrementing address, register.
The same on READ: you set a start address where to read from, when you (the master) keeps reading - it reads "consecutive" ADDR locations (until you stop it by acknowledging the last received DATA by NACK).
Just to bear in mind:
A WRITE can be a signle I2C transaction (sends SLAVE_ADDR, REG_ADDR, DATA_WORD within one single write I2C, but a READ is in general a "two-step-transaction" (WRITE REG_ADDR + restart and READ with dummy sent, to get DATA_WORD).