int main (void) { m_clockdivide(0); twi_init(I2C_ADDR); while(1) { if (receive_done) { process_command(); receive_done = false; TWI_ACK(); } } }
void twi_overflow_irq(void) #endif { #if INTERRUPTS uint8_t sreg; #endif uint8_t buf = USIDR; switch(twidriver.state){ case TWI_START: /* clear overflow bit counter */ USISR &= ~((1<<USICNT0)|(1<<USICNT1)|(1<<USICNT2)|(1<<USICNT3)); twidriver.state = TWI_ADDR; break; case TWI_ADDR: /* message for this device... */ if( ((buf & 0xfe) == twidriver.addr) #if (BUILD_VERSION > 0) ||((buf & 0xfe) == TWIADDR_BROADCAST) ||( (twidriver.addr < TWIADDR_FLIGHT_START) && ((buf & 0xfe) == (twidriver.addr+TWIADDR_FLIGHT_START))) #endif ){ /* if reading, something needs to be ready in the buffer */ if(buf & 0x1){ #if (BUILD_VERSION > 0) /* flight protocol */ if((buf & 0xfe) != twidriver.addr){ #if INTERRUPTS USICR &= ~(1<<USISIE); sreg = SREG; sei(); #endif usr_process(); #if INTERRUPTS cli(); SREG = sreg; USICR |= (1<<USISIE); #endif } else #endif /* host protocol */ if(!twidriver.size){ TWI_NACK(); break; } } /* remember cmd byte and zero the length counter */ twidriver.cmd = buf; twidriver.inlen = twidriver.outlen = 0; /* do an /ACK; */ TWI_ACK(); } /* message for some other device */ else{ TWI_NACK(); } break; /* just read the ACK bit from master... */ case TWI_TX_ACK: /* master did not /ACK */ if(twidriver.outlen && (buf & 0x1)){ TWI_NACK(); } /* master /ACKed */ else{ TWI_DDR |= (1<<SDA_PIN); /* load next byte or handle overflow */ if(twidriver.outlen < twidriver.size) USIDR = twidriver.data[twidriver.outlen++]; else USIDR = 0x55; twidriver.state = TWI_TX; } break; /* just sent the ACK bit to master... */ case TWI_RX_ACK: TWI_DDR &= ~(1<<SDA_PIN); twidriver.state = TWI_RX; break; /* master is writing to the buffer */ case TWI_RX: /* buffer if there is space */ if(twidriver.inlen < TWI_BUFSIZE){ twidriver.data[twidriver.inlen++] = buf; TWI_ACK(); } /* give up if master overruns */ else{ TWI_NACK(); } break; /* master is reading from the buffer */ case TWI_TX: TWI_GET_ACK(); break; default: break; } USISR |= (1<<USIOIF); /* clear overflow flag */ }