Help with TWI module on ATmega128

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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


Re: Help with TWI module on ATmega128

Quoted text here. Click to load it

Never mind. TWINT is not set after sending a STOP. I'll extinguish my
crack pipe now.


Site Timeline