Forum: Mikrocontroller und Digitale Elektronik Problem mit USI von AtTiny26


von Kai (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.