Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

Problems with TWI

Problems with TWI

2007-02-08 by andreaspaetsch

Hi,
I've written a code with CodeVision, so that two AT90CAN128 can
communicate together via TWI. One is the master and the other is
slave, which is interrupt-driven. But something is wrong with it, when I
send a message to the slave he should ACK it. When I disconnect the SDA
line there is no ACK and the code should say Error_write = 1 so that I
know that there has been no communikation. But Error_write is "0" so I
can't be shure, that the communikation is OK or not.
Sorry, that I post the code in this message, but I don't know how to
attach it.

Thanks,
Andreas



Here's the code for the master:
char I2C_Master_Transmitter (char I2C_Adresse, char *msg, char msgsize)
{
char temp = 0x00;
wdt_reset();
Error_write=0x00;
Abbruch = 0x0000;
TWCR = ((1<<TWINT) | (1<<TWSTA) | (1<<TWEN));
while (!(TWCR & (1<<TWINT)))
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
if ((TWSR & 0xF8) != 0x08) // a start condition
transmitted
{
TWDR = I2C_Adresse;
TWCR = ((1<<TWINT) | (1<<TWEN));
while (!(TWCR & (1<<TWINT)))
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
if ((TWSR & 0xF8) == 0x18)
{
TWDR = msgsize; // Anzahl der zu sendenden Bytes
soll gesendet werden
TWCR = ((1<<TWINT) | (1<<TWEN));
while (!(TWCR & (1<<TWINT)))
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
firsttime = 1;
TIMSK1=0x01; // jetzt erst wird Timer1
freigegeben => erst jetzt blinkt auch die LED CPU_OK
clear_LED_Messtop;
Abbruch = 0x0000;
}
if ((TWSR & 0xF8) == 0x28)
{
for (temp=0;temp<(msgsize-1);temp++)
{
TWDR = msg[temp]; // Anzahl der zu sendenden
Bytes soll gesendet werden
TWCR = ((1<<TWINT) | (1<<TWEN));
while (!(TWCR & (1<<TWINT)))
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
} // Ende von for (temp=0;temp<(msgsize-1);temp++)

TWDR = msg[temp++]; // schicken des letzten
Bytes und anschließende Stop-condition
TWCR = ((1<<TWINT) | (1<<TWEN));
while (!(TWCR & (1<<TWINT)))
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;

TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWSTO));
while (!(TWCR & (1<<TWINT)))
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
Merker_Komm_Fehler = 0;
}
I2C_write_end:
}
return Error_write;
}

char I2C_Master_Receiver (char I2C_Adresse, char *msg, char msgsize)
{
char i=0x00;
wdt_reset();
Error_read=0x00;
Abbruch = 0x0000;
TWCR = ((1<<TWINT) | (1<<TWSTA) | (1<<TWEN)); // Start
initialisieren und abschicken
while (!(TWCR & (1<<TWINT))) // warten auf
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
TWDR = I2C_Adresse;
TWCR = ((1<<TWINT) | (1<<TWEN));
while (!(TWCR & (1<<TWINT))) // warten auf
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
while (msgsize > 1)
{
TWCR = ((1<<TWINT) | (1<<TWEA) | (1<<TWEN));
while (!(TWCR & (1<<TWINT))) // warten auf
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
msg[i] = TWDR;
Merker_Komm_Fehler = 0;
Zaehler_Komm_Fehler = 0;
i++;
msgsize--;
}
TWCR = ((1<<TWINT) | (1<<TWEN)); // Start initialisieren und
abschicken
while (!(TWCR & (1<<TWINT))) // warten auf
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
msg[i] = TWDR;
Merker_Komm_Fehler = 0;
Zaehler_Komm_Fehler = 0;
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWSTO));
I2C_read_end:
return Error_read;
}


And this is the code for the interrupt-driven slave:
// 2 Wire bus interrupt service routine
interrupt [TWI] void twi_isr(void)
{
switch (TWSR & 0xF8)
{
case 0x60: // Own SLA+W received, Ack has been returned
{
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWEA) | (1<<TWIE));
while (!(TWCR & (1<<TWINT)))// warten auf Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_read_end;
}
}
Abbruch = 0x0000;
M_Read_Size = 1;
M_Komm_Fehler = 0x00;
Zaehler_Komm_Fehler = 0;
break;
}
case 0x80: // Previously adressed with own SLA+W, data
received, ACK returned
{
if (M_Read_Size == 1)
{
temp = TWDR;
M_Read_Size = 0;
i = 0x00;
}
else
{
if (i < temp)
{
I2C_read[i] = TWDR;
i++;
}
}
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWEA) | (1<<TWIE));
}
case 0xA0: // A Stop condition or repeated Start condition has
been received while still adressed as slave
{
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWEA) | (1<<TWIE));
I2C_slave_read_end:
break;
}
/////////////
//Slave Transmitter
////////////
case 0xA8: // Own SLA+R received, ACK has been returned
{
TWDR = I2C_send[0];
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA));
while (!(TWCR & (1<<TWINT)))// warten auf Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_write_end;
}
}
Abbruch = 0x0000;
M_Komm_Fehler = 0x00;
Zaehler_Komm_Fehler = 0;
}
case 0xB8: // Data Byte in TWDR transmitted, ACK has been
received
{
TWDR=I2C_send[1];
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA));
while (!(TWCR & (1<<TWINT)))// warten auf Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_write_end;
}
}
Abbruch = 0x0000;
TWDR = I2C_send[2];
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWIE)/* | (1<<TWEA)*/);
while (!(TWCR & (1<<TWINT)))// warten auf Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_write_end;
}
}
Abbruch = 0x0000;
}
case 0xC0: // Data Byte in TWDR transmitted, NACK has been
received
{
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWEA) | (1<<TWIE));
j=0x00;
Sende_Daten_2 = 0x00;
}
case 0xC8: // ERROR: Last Data Byte in TWDR transmitted (TWEA
= 0), ACK has been received
{
break;
}
case 0x00:
{
TWCR = ((1 << TWSTO) | (1 << TWINT) | (1<<TWIE));
while (!(TWCR & (1<<TWINT)))// warten auf Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
break;
}
}
Abbruch = 0x0000;
}
I2C_slave_write_end:
}
}

Re: [AVR-Chat] Problems with TWI

2007-02-08 by John Samperi

At 08:32 PM 8/02/2007, you wrote:
>  But Error_write is "0" so I
>can't be shure, that the communikation is OK or not.

One way I would tackle the problem would be with at least
1 JTAG debugger. Check what's happening inside the slave,
is it receiving the data ok?
It would be nicer with 2 JTAGs and 2 copies of Studio running
but as you may need the more expensive MK2 it may not be practical.


Regards

John Samperi

********************************************************
Ampertronics Pty. Ltd.
11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
Tel. (02) 9674-6495       Fax (02) 9674-8745
Email: john@ampertronics.com.au
Website  http://www.ampertronics.com.au
*Electronic Design * Custom Products * Contract Assembly
********************************************************

Re: Problems with TWI

2007-02-09 by andreaspaetsch

Thanks John,
but I havn't a JTAG,
is there another possibility than turning on some LED's?

Andreas

--- In AVR-Chat@yahoogroups.com, John Samperi <samperi@...> wrote:
Show quoted textHide quoted text
>
> At 08:32 PM 8/02/2007, you wrote:
> >  But Error_write is "0" so I
> >can't be shure, that the communikation is OK or not.
>
> One way I would tackle the problem would be with at least
> 1 JTAG debugger. Check what's happening inside the slave,
> is it receiving the data ok?
> It would be nicer with 2 JTAGs and 2 copies of Studio running
> but as you may need the more expensive MK2 it may not be practical.
>
>
> Regards
>
> John Samperi
>
> ********************************************************
> Ampertronics Pty. Ltd.
> 11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
> Tel. (02) 9674-6495       Fax (02) 9674-8745
> Email: john@...
> Website  http://www.ampertronics.com.au
> *Electronic Design * Custom Products * Contract Assembly
> ********************************************************
>

Re: [AVR-Chat] Re: Problems with TWI

2007-02-09 by John Samperi

At 09:59 PM 9/02/2007, you wrote:
>but I havn't a JTAG,

Then life becomes hard :)

>is there another possibility than turning on some LED's?

Hook up an RS232 interface chip to the USART and send some
messages to the PC when certain events happen inside the slave.
Not much different than having leds come on when certain events
occur I guess :( A JTAG MK2 would make your debugging easier
but they are relatively expensive.


Regards

John Samperi

********************************************************
Ampertronics Pty. Ltd.
11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
Tel. (02) 9674-6495       Fax (02) 9674-8745
Email: john@ampertronics.com.au
Website  http://www.ampertronics.com.au
*Electronic Design * Custom Products * Contract Assembly
********************************************************

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.