Hallo allerseits,

ich habe hier einen ATmega 644P welcher Daten per TWI an einen ATtiny2313 schicken soll, welcher diese dann auf einem LCD-Display ausgibt.

Nun kann der ATtiny2313 ja kein echtes TWI, stattdessen läuft das Ganze über USI ab. Daher würde ich gerne zunächst wissen, ob man Hardware-TWI des 644P überhaupt mit dem USI-TWI des 2313 zum Laufen kriegen kann.

Mein Problem ist nämlich, dass ich nun schon das Ganze Wochenende dran gesessen habe, die Kommunikation zum Laufen zu kriegen, das Ganze jedoch vollkommen erfolglos. Ich habe bereits fertig implementierte I2C-Slaves für den 2313 ausprobiert, aber auch hier kriege ich keine Daten übertragen.

Master-seitig sieht der Code wie folgt aus:

Code:
#ifndef F_CPU
#define F_CPU 8000000
#endif
#include <avr/io.h>
#include <util/delay.h>

uint8_t twiControl;

void send_i2c() {
	// signalisiere START
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);									
	// warte auf Bus
	waitForTWI();
		
	// falls Bus nicht frei
	if((TWSR & 0xF8) != 0x08 && (TWSR & 0xF8) != 0x10) {
		// TODO
	} else {
		// grüne LED an
		PORTA &= ~(1<<PB2);
		
		// Slave-Adresse und WRITE senden
		TWDR = 0x40<<1;
		TWCR = (1<<TWINT)|(1<<TWEN);

		// warte auf Bus
		waitForTWI();

		// falls kein ACK oder NACK empfangen
		if((TWSR & 0xF8) != 0x18 && (TWSR & 0xF8) != 0x20) {
			// rote LED an
			PORTA &= ~(1<<PB4);
		} else {
			// gelbe LED an
			PORTA &= ~(1<<PB3);
		}
	}
	_delay_ms(20);
	// LEDs aus
	PORTA = 0b11111111;
	_delay_ms(20);
}

void waitForTWI() {
	do {
		twiControl = TWCR & 0x80;
	} while(twiControl != 0x80);
}

int main() {
	// setze TWI auf 100 kHz
	TWBR = (F_CPU/200000)-18;
	// aktiviere TWI
	TWCR = 0b00000100;
	// aktiviere PORT A
	DDRA = 0b11111111;
	PORTA = 0b11111111;
	
	while(1) {
		send_i2c();
	}
}
Auf dem Slave habe ich bis jetzt das hier:

Code:
uint8_t state = 0x00;


int main() {
	// initialisiere PWM für Ladungspumpe
	initPWM();
	// initialisiere Display
    initLCD();

	// aktiviere Interrupts
	USICR = 0b11111000;
	// aktiviere SCL-Pin
	PORTB |= (1<<PORTB7);
	// aktiviere SDA-Pin
	PORTB |= (1<<PORTB5);
	// SCL auf Eingang
	DDRB |= (1<<PORTB7);
	// SDA auf Ausgang
	DDRB &= ~(1<<PORTB5);

	// Interrupts aktivieren
	sei();
	
   	while(1) {
		// fortlaufend Inhalt von USICR, USISR und USIDR ausgeben
		lcd_home();
		hexout(USICR);
		lcd_data(' ');
		hexout(USISR);
		lcd_data(' ');
		hexout(USIDR);
   	}
}

// START-Bedingung per USI erhalten
ISR(SIG_USI_START) {
	// schreibe "START" auf LCD
	lcd_setcursor(0,2);
	lcd_string("START");
    uint8_t tmpUSISR;
    tmpUSISR = USISR;
	// setze Start-State
    state = 0x00;
	// SDA auf Eingang
    DDRB  &= ~(1<<PORTB5);
    while ((PINB & (1<<PORTB7)) & !(tmpUSISR & (1<<USIPF)) );
	// aktiviere Interrupts
    USICR  =    0b11111000;
	USISR  =    (1<<USI_START_COND_INT)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0x0<<USICNT0);    
	lcd_clear();
}

// USI-Overflow-Interrupt
ISR(SIG_USI_OVERFLOW) {
	switch(state) {
		// Start-State
		case 0x00:
			// General oder eigene Adresse erhalten
			if ((USIDR == 0) || (( USIDR>>1 ) == 0x40)) {
				// akzeptiere nur Write-Requests
        		if (!(USIDR & 0x01)) {
	          		state = 0x01;
				}
				
				// schreibe "CHECK" auf LCD
				lcd_setcursor(6,2);
				lcd_string("CHECK");

				// leere USIDR
	          	USIDR    =  0; 
				// SDA auf Ausgang                                          
        		DDRB |=  (1<<PORTB5);                           
        		USISR    =  (0<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0x0E<<USICNT0);                              
      		}
      		else {
       			USICR    =  0b101010000;
			  USISR = (0<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)|(0x00<<USICNT0);                                                                                                    \  
      		}
      		break;
	}

	_delay_ms(20);
	lcd_clear();
}
Allerdings erscheint mir der Slave-Code auch irgendwie spanisch, ich habe den aus den Appnotes AVR312 für einen USI-TWI-Slave entnommen. Doch scheint sich z.B. der Inhalt von USISR bei den entsprechenden Zuweisungen gar nicht zu ändern. Am schlimmsten ist aber, dass sich in USIDR keine Daten finden d.h. die Adresse, die ich im Master sende scheint gar nicht am Ziel anzukommen. Zudem bin ich auch skeptisch, was die Funktion des Masters angeht, da die LEDs auch fröhlich flackern, wenn der Tiny gar nicht angeschlossen ist.

Ich bin da leider wirklich mit meinem Latein am Ende und auch etwas entnervt, dass so ein Krampf als "TWI-fähig" verkauft wird.

Vielleicht kann mir ja hier jemand helfen oder mich auf die richtige Bahn lenken. Ich bin ja schon froh, dass ich am Master und Slave überhaupt ein wenig sehen kann, was passiert, aber selbst das ist doch eher dürftig

Achja, SCL und SDA sind auf dem Master mit 10k Ohm gegen VCC geschaltet, beide µC werden mit 3.3V versorgt.