rambo / TinyWire

My modifications to TinyWire Arduino libs
284 stars 121 forks source link

Request Callback is not triggered #43

Open pjwl opened 6 years ago

pjwl commented 6 years ago

Using the libary following the examples, I saw that request callback is not triggered, so the slave never sends data to the master.

usiTwiSlave.c `case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA: // Execute request callback for each byte requested, as this is the intended // behavior of this library USI_REQUEST_CALLBACK(); if ( USIDR ) { // if NACK, the master does not want more data SET_USI_TO_TWI_START_CONDITION_MODE( ); finished = 1; break; } // from here we just drop straight into USI_SLAVE_SEND_DATA if the // master sent an ACK

// copy data from buffer to USIDR and set USI to shift byte
// next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
case USI_SLAVE_SEND_DATA:
  // Get data from Buffer
  if ( txCount )
  {
    USIDR = txBuf[ txTail ];
    txTail = ( txTail + 1 ) & TWI_TX_BUFFER_MASK;
    txCount--;

    overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
    SET_USI_TO_SEND_DATA( );
  }
  else
  {
    // the buffer is empty
    SET_USI_TO_READ_ACK( ); // This might be neccessary sometimes see http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=805227#805227
    SET_USI_TO_TWI_START_CONDITION_MODE( );
  } // end if
  break;

`

When I look at the code USI_REQUEST_CALLBACK is called when the overflow state is: USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA, but this state will never come, because in overflow state: USI_SLAVE_SEND_DATA txCount is zero, because no data is add to the transmit buffer.. so the overlowState variable will not change to the correct state..

tpangburn commented 6 years ago

Funny, I am just realizing I have the same problem the slave doesn't call the request call back. I looked at the history and the call back was in a different place before I think around line 619 of usiTwiSlave.c. I put it back there and also left the other call and it worked. However my driver that does the I2C read blasts 32 byte reads all at once. ( FYI... trying to copy atlas scientific way of doing the I2C accesses.. string in/string out..) So it seems to screw up the buffer after the first access. When I try to do the access the second time in my code it fails. If I force it to re-initialize the driver to clear out the buffers in-between I2C reads it seems to work. Its sort of a bad hack since I don't understand all of the code, but it gets me past the problem.

tpangburn commented 6 years ago

I ended up flushing out the transmit buffer when the state machine goes into an idle mode on line 737 of usiTwiSlave.c. Again its probably a bad hack but for some reason the transmit buffer is getting over filled after my string of reads is done and screws up subsequent accesses.

belese commented 6 years ago

oh yeah, after few hours of test, i've seen this issue. Someone has found a working solution? edit : i've find another library : https://github.com/lucullusTheOnly/TinyWire That one is ok