Go Down

Topic: I2C Repeated Start (Read 10 times) previous topic - next topic

chriskner


chriskner

After some turmoil, I have retreated to the state where only 1 byte at a time may be read from a slave.

Figure 34-20. "TWI Read Operation with Multiple Data Bytes with or without Internal Address" in the SAM3X8E datasheet seems out of reach. (Page 729, of the 28-May-12 revision)

I have found that a NACK is always generated after the 1st read by some unidentified mechanism, making multiple byte reads impossible.
For the desired protocol, see Figure 34-10. "Master Read with Multiple Data Bytes" (Page 721).

It seems that the Arduino community has been driving in circles over this problem for years.  For a sample:
http://code.google.com/p/arduino/issues/detail?id=28

I haven't been able to find a way to specify how the master (the Due) should respond for multiple sequential reads.

I have resorted to supporting only 1 byte reads for the foreseeable future.  This, of course, is a hack in my 50+ device I2C network.

Any ideas/suggestions?

Code: [Select]

    TWI_StartRead(WIRE_INTERFACE, i2c_addr, i2c_register, 1);
    Embiic_WaitByteXferComplete();
    for(i = 0; i < numOfBytes; i++) {
      //Need to set STOP condition WHILE reading the last byte...
      if ((i+1) == numOfBytes) {
        TWI_SendSTOPCondition(WIRE_INTERFACE);
        //DBG_PRINT("Sending last-byte STOP.");
      }
      Embiic_WaitByteReceived();
      //DBG_PRINTLN("Read_I2C_Values: Byte Ready");
      params[i] = TWI_ReadByte(WIRE_INTERFACE);
    }
    if (Embiic_WaitByteXferComplete()) {
      DBG_PRINTLN("Read_I2C_Values: Transaction completed successfully.");
    } else {
      DBG_PRINTLN("Read_I2C_Values: Transaction nottacompleted.");
    }

cdan

Can you please post a screenshot of the output from running your algorithm with numOfBytes=2 ?

chriskner

The traces above are the same with any numOfBytes value.  That one was generated with nOB=3.

However, I get the same result for nOB= 1.

Of course, as you know, we expect the NACK on only the last read, and ACK's on all 1..n-1 reads.

The way that it is now, all reads beyond the first byte result in a timeout. (code below)

I suspect that there's a state machine somewhere (that I can't find), that I would like to look over.

I did find this:
/arduino-1.5.1r2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/html/TWI0.html
which lists the TW registers in a nice format.  However, there isn't much to play with there.

Code: [Select]

boolean Embiic_WaitByteReceived() {
  unsigned long start, now;
  start = millis();
  while (!TWI_ByteReceived(WIRE_INTERFACE)) {
    //if (WIRE_INTERFACE->TWI_SR & TWI_SR_NACK) { // Failed ACK
    //  DBG_PRINTLN("Embiic_WaitByteReceived: Failed ACK.");
    //  Error_Code = 9010;
    //  return false;
    //}
    now = millis();
    if (now < start) {  // cheap! handle overflow, at at the expense of a longer timeout
      start = now;
      now++;
    } else {
      now = now - start;
    }
    if (now > I2C_READ_TIMEOUTmS){
      DBG_PRINTLN("Embiic_WaitByteReceived: Timeout.");
      Error_Code = 9011;
      return false;
    }
  }
  return true;
}

cdan

I have just order a Bus Pirate from a retailer in RO. I'll have it tomorrow and I'll give it a try too.
I have to look closer to this issue.

Go Up