Wire functionality question

Hello, I'm using arduino for prototyping to another microcontroller, and my question revolves around how Wire is functioning with the I2C protocol.

I read this tutorial to get a basic understanding of the I2C command sequence:

Here it states that if for example I would read a package, I should do the following:
Send Start bit
Send 7 bit address
send read flag
Recieve acknowledge bit
Recieve data byte
Send acknowledge bit
Recieve data byte
Send acknowledge bit
... until im done, then
send NACK instead of ACK bit, followed by a Stop bit.
The image that illustrates this:

Now, I have some arduino code (which works fine by the way), that goes like this:

Setup portion

// in the setup
   Wire.beginTransmission(address);
   Wire.write(moderegadr);
   Wire.write(instruct);
   Wire.endTransmission();  
   delay(10);  

  Wire.beginTransmission(address);
   Wire.write(regb);
   Wire.write(regbdata);
   Wire.endTransmission();  
   delay(10);

Loop portion

// in the loop
   Wire.beginTransmission(address);
   Wire.write(dataregadr1);
   Wire.endTransmission();
  
   Wire.beginTransmission(address);
   Wire.requestFrom(address,6);
   delay(10);
   if(6<= Wire.available())    // if two bytes were received 
  { 
    for(i=0;i<6;i++)
    {
      readingdata[i]=Wire.read();
     }
  }

My question is: How do i translate this to "raw" I2C command sequence? My particular interest is in the last code snippet:

Is it correctly understood that the last part works like this?
Wire.beginTransmission(address) =

  • Send Start bit
  • Send Device address
  • Send write flag
    Wire.write(dataregadr1) =
  • Send register byte
    Wire.endTransmission() =
  • Send stop bit

Wire.beginTransmission(address) =

  • Send Start bit
  • Send Device address
  • Send read flag
    Wire.requestFrom(address,6) =
    this part i dont understand, does it merely listen and acknowledge 6 packets, and put them in a buffer?

At any rate, I need the entire rundown of the last code snippet, in step-by-step I2C command sequence form. If anyone can help me with this, you would be doing me a great favor! :slight_smile:

Best regards
Jesper

You have the sources to the Wire library and you have access to the ATmega 328P datasheet so you should be able to answer that question yourself.

   Wire.beginTransmission(address);
   Wire.requestFrom(address,6);
   delay(10);
   if(6<= Wire.available())    // if two bytes were received

You don't want the beginTransmission there.
You don't need the delay.
The requestFrom tells you how many bytes you got. So that could all be rewritten as:

   if (Wire.requestFrom (address, 6) == 6)

For more details see: Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino

Hi.

Thanks for the replies :slight_smile: First, I tried reading the Wire.cpp file, noticing that it called twi_readFrom(), from requestFrom(), I then tried to understand how twi_readFrom() works, in regards to the packet sequence. I feel like im reading hieroglyphs, so that didnt help me much unfortunately.

The Gammon Forum : Electronics : Microprocessors : I2C - Two-Wire Peripheral Interface - for Arduino link, is very comprehensive though! But its an overflowing waterfall of information, when all I really need to know is how requestFrom() can be translated to a raw packet sequence, so I can use it in a bitbanging (i believe its called?) library, which is written for another microcontroller.

So while I appreciate the attempt at educating me, it's just too much information for what I consider to be a small bump in the road. Please just give me a straight answer :slight_smile:

In other words: How do i break down the mentioned code part, where I only have Start(), Stop(), TxByte() and RxByte() available?