rambo/TinyWire

Request Callback is not triggered

Opened this issue · 3 comments

pjwl commented

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..

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.

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.

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