uint8_t twi_read (uint8_t* data, enum twi_send_ack ack) { #if __AVR_ARCH__ <= 6 *data = TWDR; TWCR = (1 << TWINT) | (1 << TWEN) | (ack << TWEA); twi_wait(); uint8_t status = twi_status(); if (status == 0x50 || status == 0x58) return 0; else { //debug_pgm(PSTR("err twi_re")); return 1; } #elif __AVR_ARCH__ >= 100 while ( (TWI.MASTER.STATUS & (1 << 5)) == 0); //wait for CLKHOLD if ( (TWI.MASTER.STATUS & (1 << 2)) == 0) debug_pgm(PSTR("BUSERR")); TWI.MASTER.CTRLC = TWI.MASTER.CTRLC | ( (ack == NACK) << 2); *data = TWI.MASTER.DATA; return 0; #endif }
uint8_t twi_write (uint8_t data) { #if __AVR_ARCH__ <= 6 TWDR = data; TWCR = (1 << TWINT) | (1 << TWEN); twi_wait(); uint8_t status = twi_status(); if (status == 0x28 || status == 0x30) return 0; else { //debug_pgm(PSTR("err twi_wr")); return 1; } #elif __AVR_ARCH__ >= 100 TWI.MASTER.DATA = data; while ( (TWI.MASTER.STATUS & (1 << 6)) == 0); //wait for WIF TWI.MASTER.STATUS |= (1 << 6); return 0; #endif }
static int wait_twi_complete() { int status; int timeout = systick_get_ms() + TWI_TIMEOUT; do { status = twi_status(); if (status <= 0) return status; } while (systick_get_ms() < timeout); return status; }
uint8_t twi_restart (void) { #if __AVR_ARCH__ <= 6 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA); twi_wait(); uint8_t status = twi_status(); if (status == 0x08 || status == 0x10) return 0; else { //debug_pgm(PSTR("error start twi")); return 1; } #elif __AVR_ARCH__ >= 100 //on xmega start is automatically send on connect TWI.MASTER.CTRLC = TWI.MASTER.CTRLC | (1 << 0); return 0; #endif }
uint8_t twi_connect (enum twi_access_mode mode, uint8_t addr) { #if __AVR_ARCH__ <= 6 twi_restart(); //check for valid status uint8_t status;// = twi_status(); /*if(status == 0x08 || status == 0x10) return 0; else { debug_pgm(PSTR("error connect1 twi")); return 1; }*/ TWDR = (addr << 1) | mode; //byte_to_hex((addr<<1)|mode); TWCR = (1 << TWINT) | (1 << TWEN); twi_wait(); status = twi_status(); if (status == 0x18 || status == 0x20 || status == 0x40 || status == 0x48 || status == 0xF8) return 0; else { //debug_pgm(PSTR("err twi_con")); return 1; } #elif __AVR_ARCH__ >= 100 TWI.MASTER.ADDR = (addr << 1) | mode; while ( (TWI.MASTER.STATUS & (1 << 6)) == 0); //wait for WIF return 0; #endif }
uint8_t TwoWire::status(){ return twi_status(); }