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 }
uint8_t tw_send_byte( uint8_t byte ) { uint8_t status; TWDR = byte; tw_cmd(0); twi_wait( RC_FAIL ); status = TW_STATUS; if(status!=TW_MT_DATA_ACK) { return RC_FAIL1; } return RC_SUCCESS; }
uint8_t tw_send_addr( uint8_t byte ) { uint8_t status; TWDR = byte; tw_cmd(0); twi_wait(0); status = TW_STATUS; if( status != TW_MT_SLA_ACK ) { return 0; } return 1; }
uint8_t tw_rep_start(void) { uint8_t status; tw_cmd(_BV(TWSTA)); twi_wait( RC_FAIL ); status = TW_STATUS; if( (status != TW_START) && (status != TW_REP_START) ) { return RC_FAIL1; } return RC_SUCCESS; }
int tw_recv_byte( uint8_t ack ) { uint8_t status; if(!ack) { //NACK tw_cmd(0<<TWEA); } else { //ACK tw_cmd(1<<TWEA); } twi_wait(-1); status = TW_STATUS; if( ((status!=TW_MR_DATA_ACK) && ack) || ((status!=TW_MR_DATA_NACK) && !ack)) { return -1; } return TWDR; }
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 }