At the moment I am working on a little project that targets on using attiny's for led lighting control (on/off/pwm dimming/etc) using twi/i2c. The final version will be using '85's (8 pins) but I am developing on the '861 for ease of debugging. I am pretty sure the pwm will be no problem, so I didn't yet start on that.
I am using an avr dragon in isp mode and avr-gcc for development, the attiny is programmed in-circuit on the development board (i.e. it's not on the dragon). The development board has four leds and two buttons for debugging.
To start with, I am trying to make twi/i2c, as a slave, working.
Of course I started with avr application note 312, made some changes to make it work on avr-gcc and of course it didn't work ;-) A start condition was triggered, but the direction was the wrong way around and the address was halved (i.e. I was sending address 0x04 from the master and the slave responded to address 0x02).
So yes, I fell into the trap of the slow clock (1 MHz). I changed it 8 Mhz, then the direction was good and the address was good. Reception was okay, but I never managed to reply something to the master.
Then I switched to Don Blake's usi/twi slave code, which at least allowed me to receive correctly on the slave and replying as going well. Thanks Don :-)
BUT it's still not 100% okay. The i2c bus kept locking up when more bytes were read than available in the buffer. After a quick inspection of the code I found a comment about having changed the behaviour on an out-of-data condition, from "sending NACK" to skip any action, to make the master wait for data from the slave to appear (Arduino seems to expect that). This is NOT the behaviour I want. I want to make a very robust system between master and slave, which means the master must be able to "flush" data that may be in the slave's buffer from a previous, interrupted command. It would do so by reading data until an error occurs. With the current Don Blake code, this will lock up the bus.
So I re-activated the code to go to start condition on out-of-data condition (which was commented out). This did not resolve the issue though. The slave DOES go into start condition, but appears to leave SDA low (active), so again the bus gets locked up.
Then I added a line of code to the macro that sets start condition, to explicitly set SDA to "input" and now it works. I am not completely sure this is completely right though.
- Should the "set sda to input" line be added to the start condition macro, or is it sufficient to add it to the point where out-of-data occurs?
- The read now does NOT yield an error on out-of-data, instead it returns 0xff. I am not completely sure that's a result of the code or that the master returns 0xff on error
- Shouldn't the slave return NACK (on out of data condition) instead of simply going to "start condition"? I can't find any code that does so, though, I think it's not so easy to implement anyway (exact timings...)
So, to summary, I'd like to be able to do a read of "many" bytes from the slave, and the slave should return all bytes it still has in it's buffer and then post a NACK to signal no more bytes available. How should I approach that?