I2C Slaveimplementierung auf einem ATTINY 2313

OP #7314064
Lesenswert?

Hallo! Ich nutze die I2C Slave-Implementierung von Martin Junghans (jtronics) schon einen ganze Weile und die hat mir super Dienste geleistet. Bisher habe ich auch nur immer ein Byte gelesen (ein paar Tasten wurden durch den ATTINY entprellt und dann der Status geliefert) und das ging prima. Nun habe ich das Problem, dass ich nun ein paar Bytes vom Master an den Slave schicken muss und auch mehrere Bytes vom Slave lesen muss.

Alle meine Daten passen sicher in den Sende oder auch Empfangsbuffer des ATTINY, aber ich finde keinen Punkt der mir sagt, wann eine Transaktion abgeschlossen ist, also die übertragenen Daten genutzt werden können. Ich hatte gedacht, dass über die Erkennung der Stopp-Bedingung realisieren zu können, aber die Stopp-Bedingung habe ich nie "gefunden"

1
  while (  ( PIN_USI & ( 1 << PIN_USI_SCL ) ) &&  !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) ));// SCL his high and SDA is low
2

3
  if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
4
    {  // A Stop Condition did not occur
5
    USICR =
6
    ( 1 << USISIE ) |                // Keep Start Condition Interrupt enabled to detect RESTART
7
    ( 1 << USIOIE ) |                // Enable Overflow Interrupt
8
    ( 1 << USIWM1 ) | ( 1 << USIWM0 ) |          // Set USI in Two-wire mode, hold SCL low on USI Counter overflow
9
    ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |  // 4-Bit Counter Source = external, both edges; Clock Source = External, positive edge  
10
    ( 0 << USITC );                  // No toggle clock-port pin
11
    }
12
  else
13
    {  // A Stop Condition did occur
14
    USICR =
15
    ( 1 << USISIE ) |                // Enable Start Condition Interrupt
16
    ( 0 << USIOIE ) |                // Disable Overflow Interrupt
17
    ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |          // Set USI in Two-wire mode, no USI Counter overflow hold
18
    ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |    // 4-Bit Counter Source = external, both edges; Clock Source = external, positive edge
19
    ( 0 << USITC );                  // No toggle clock-port pin
20
    }

Das ist die Codesequenz, in der das passieren müsste, aber in den ELSE-Zweig komme ich nie an.

Hat da jemand schon was gemacht, um das Problem zu lösen? Ich habe auch nach anderen I2C Slave Implementierungen gesucht, aber so was richtig passendes habe ich leider bisher nicht gefunden.

Danke schon mal für Tipps und Grüße Hans-Joachim

#7314074
Lesenswert?

USI Status Register – USISR: Bit 5 – USIPF: Stop Condition Flag When Two-wire mode is selected, the USIPF flag is set (one) when a stop condition is detected. The flag is cleared by writing a one to this bit. Note that this is not an interrupt flag. This signal is useful when implementing Two-wire bus master arbitration.

Gast #7314221
Lesenswert?

Zur Not darfst du gerne von meinem Projekt abgucken. Es empfängt variabel 1-10 Bytes pro Transaktion und trägt sie in ein Array ein. Die Timer-ISR konsumiert das Array, aber ich denke die ist für deine Frage irrelevant.

Beachte die kommentierte Stelle "if stop condition received, break the for loop"

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren