ascii art of hardware 4 x 1N4148 o-+----|>|--+ | | | +--|>|--+ | | +-|--|<|--+ | | o---+--|<|--+ USI irq response time --------------------- USI hardware does hold SCL line down after detecting start condition or if configured, SCL line is also held when counter overflow occur. This feature is know as clock stretching or clock extending. More information about this feature can be found in SMBus specification or TWI/i2c specifications. Most popular raspberry pi have a serious bug in i2c hardware. Clock stretching feature can break correct sampling of i2c data. To get i2c run without clock stretching at 100kHz, maximal irq response time must be below half of period of i2c clock. At 100kHz this is 5uS. For CPU at 9.6MHz this is 48 ticks. Because other interrupts (from timer or pin change) can block USI hardware, these interrupts must reenable global interrupts. This is known as nested interrupts and can be enabled in ISR macro by ISR_NOBLOCK attribute (more info in avr-libc documentation). At worst case response time can be calculated: 1. main code run RET instruction (4 ticks) and this is interrupted 2. timer irq starts, this generates (4 ticks) for jump to isr vector 3. isr vector does RJMP at isr code (2 ticks) 4. isr immediately run SEI (1 tick) 5. next instruction is usually PUSH, and can not be interrupted (2 ticks) 6. new irq starts from PCI (4 ticks) 7. isr vector does RJMP at isr code (2 ticks) 8. isr immediately run sei (1 tick) 9. next instruction is usually push, and can not be interrupted (2 ticks) 10. USI overflow irq (4 ticks) for jump to isr vector 11. isr vector does RJMP at isr code (2 ticks) This all is 28 ticks. USI overflow must use switch to get proper function: out __GPIOR1__,r30 ;1 tick in r30,__SREG__ ;1 tick out __GPIOR2__,r30 ;1 tick out __EEDR__,r31 ;1 tick //switch based om r14 value mov r30,r14 ;1 tick clr r31 ;1 tick ijmp ;2 ticks This is 8 ticks, all together 36 ticks. ACK/NACK or data must be loaded and started by USI almost 12 ticks from code addressed by ijmp. Some time (two ticks) can be saved by moving USI overflow vector directly at position 0x1c in flash. This can be done by linker script (check file attiny25_i2c.x and i2c_fast.S). Worst function ftom ijmp switch now can use 14 ticks, actual code (check i2c_fast.S) uses maximum 9 ticks. Supported bus protocol: quick command 0 PEC reset 1 no action send byte no action, PEC update only send byte with PEC no action, PEC is not checked, is used like normal byte receive byte return 1st byte from response buffer receive byte with PEC return 1st byte from response buffer, PEC is replaced by 2nd byte from buffer (PEC is wrong or in some cases valid..) rapsberry pi support for i2c/SMBus I2C yes SMBus Quick Command yes SMBus Send Byte yes SMBus Receive Byte yes SMBus Write Byte yes SMBus Read Byte yes SMBus Write Word yes SMBus Read Word yes SMBus Process Call yes SMBus Block Write yes SMBus Block Read no SMBus Block Process Call no SMBus PEC yes I2C Block Write yes I2C Block Read yes