Weird issue, but I can't receive data using the TWI module in the ATmega128. (Writing data is documented very well in the datasheet, reading data is not). The code I'm trying to use is below. It hangs while waiting for the final STOP to be sent. So it has sent SLA+R and read a byte off the device. The byte read appears to be correct, too. I know the addresses, speed etc. are OK because I can write to the device concerned with no difficulty (it is an MCP23008 8-bit I/O expander). Before I start grabbing packets with the scope, can someone see the obvious idiot mistake in my code? The mega128 datasheet is confusing; for the situation where data byte has been Rxed and ACK sent, it does not show a bit combination for the "next step" being a STOP. Thanks for any advice. // Set address counter TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send START while (!(TWCR & (1 << TWINT))); // wait for end of START tx if ((TWSR & 0xF8) != TWI_START) return 0; TWDR = (MCP_CONTROL | ((addr & 0x07) << 1)); // load Tx buffer with address/cmd TWCR = (1 << TWINT) | (1 << TWEN); // send SLA_W while (!(TWCR & (1 << TWINT))); // wait for end of SLA_W tx if ((TWSR & 0xF8) != TWI_MT_SLA_ACK) return 0; TWDR = regnum; // load register address into Tx buf TWCR = (1 << TWINT) | (1 << TWEN); // send register address while (!(TWCR & (1 << TWINT))); // wait for end of register tx if ((TWSR & 0xF8) != TWI_MT_DATA_ACK) return 0; TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // send RESTART while (!(TWCR & (1 << TWINT))); // wait for end of RESTART tx if ((TWSR & 0xF8) != TWI_RESTART) return 0; TWDR = (MCP_CONTROL | ((addr & 0x07) << 1)) | 1; // load Tx buffer with SLA+R TWCR = (1 << TWINT) | (1 << TWEN); // send SLA_R while (!(TWCR & (1 << TWINT))); // wait for end of RESTART tx if ((TWSR & 0xF8) != TWI_SLA_ACK) return 0; TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); // Rx data byte, send ACK while (!(TWCR & (1 << TWINT))); // wait for end of data Rx if ((TWSR & 0xF8) != TWI_DATA_RX) return 0; result = TWDR; TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // send STOP while (!(TWCR & (1 << TWINT))); // wait for end of STOP
Help with TWI module on ATmega128
Started by ●January 15, 2006
Reply by ●January 15, 20062006-01-15