Problem mit USI von AtTiny26

Gast #113076
Hi!

Ich habe ein paar Probleme mit der USI des AtTiny26 und ich hoffe mir
kann jemand helfen.
Der AtTiny26 soll nachher als SPI<->I2C Wandler agieren (mit diversen
möglichkeiten den i2c bus zu konfigurieren) und ist nachher nur ein
kleiner Teil der gesammten Hardware.

Ich nutze hauptsächlich folgende Routinen:

Initialisierung:
  ;Initialisiert USI als SPI slave, MISO wird vorher schon
        ;richtig konfiguriert...
  ldi  temp, (1<<USIWM0)+(1<<USICS1)  ;+(1<<USIOIE)
  out  USICR, temp

SPI-Transfer Funktion (aus dem Datenblatt übernommen):
SpiXFer:  out  USIDR, SpiDat
SpiXFerNoWrite:  ldi  temp, (1<<USIOIF)
    out  USISR, temp
SpiXFerLoop:  sbis  USISR, USIOIF
    rjmp  SpiXFerLoop
    in  SpiDat, USIDR
    ret


Nun zu meinem Problem:
Über den SPI-Bus wird - um einen i2c write-transfer zu initiieren auf
den Bus ein paar bytes geschrieben, die in dem Ram zwischengepuffert
werden. Wenn die zu schreibenden i2c-daten alle übertragen werden, wird
ein i2c transfer durchgeführt. Wenn der i2c transfer beendet ist, rufe
ich die oben stehende Funktion SpiXFer auf und lasse damit eine
"0x00" ausgeben:

;...i2c transfer hier zuende...
ldi SpiDat, 0x00
rcall SpiXFer

Da der SPI-"Master" mitbekommen muss, wann der transfer beendet ist
polle ich momentan den SPI-Bus vom Master aus, ob der zurückgelesene
Wert=0x00 ist (der Master sendet dabei 0xff). Wenn der Wert 0x00 ist,
ist das ein Zeichen dafür, dass der i2c-transfer beendet ist.

Leider läuft an dieser stelle in 50% der Fälle die Bitsynchronisation
von Master und Slave durcheinander, das heisst der Master empfängt
werte wie:
0x0F
0xF0
Vermutlich kommt das dadurch, dass das USIDR-Register nicht
synchronisiert ist. Nur WIE warte ich auf den Zeitpunkt, dass ein Byte
zuvor komplett übertragen wurde?

Ich habe es mit folgender Funktion probiert. Damit klappt es aber auch
nicht:


SpiWait:  sbis  USISR, USIOIF
    rjmp  SpiWait

    ldi     SpiDat, 0x00
                rcall   SpiXFer

Hat jemand eine Idee, wie ich mein Problem lösen kann? Da das der erste
AVR mit USI ist, den ich benutze bin ich da momentan ziemlich ratlos.
Mit dem Overflow interrupt zu arbeiten ist leider nicht möglich, da das
Auslösen des Interrupts das Timing auf dem i2c Bus beeinflußt, was auf
keinen Fall geschehen darf, da er zu Tests von i2c slaves eingesetzt
wird (z.B. um seine maximale Clockrate zu ermitteln).

viele Grüße,

Kai

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 22 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.