Hallo zusammen,
ich beschäftige mich gerade mit dem I2C-Bus und finde einfach nicht die
Ursache, warum nach der START-BEDINGUNG nicht in die
TWI-Interruptservice-Routine ( TWI-ISR ) gesprungen wird. Weder in Echt
noch in der ATMEL-STUDIO Simulation.
Ein ATmega8 ( Es soll mal ein ATmega8L oder 88 werden, wegen 3,3V
Betriebsspannung ) wird mit einem 1,8432Mhz Quarz an 5V betrieben. Die
Pullup-Widerstände ( 4k7 ) hängen jedoch schon an 3,3V.
Im Programm ist die USART-Geschichte ( Debugroutine ) erstmal raus,
auch andere Dinge sind erstmal auskommentiert.
Die verschiedenen Dateien erlauben, ein für mich, komfortableres
Arbeiten mit dem ATMEL-STUDIO 7, da ich nur die Reiter anklicken muss,
um beispielsweise die Unterprogramme zu finden ( UP_Wii_Nunchuk.inc )
Wii_Nunchuk4.asm ist das " Hauptprogram " von dem aus alle weiteren
eingebunden werden.
Im Unterprogramm ( UP ) _twi_start wird die START-BEDINGUNG erzeugt und
auf dem Oszi, sowie im Open Workbench Logic Analyser ist auch zu sehen,
das diese tatsächlich erzeugt wird.
An PortD5 ist ein Taster, um einmalig eine Aktion auszuführen.
( Ein-Tasterentprellroutine von Peter Danneger alias PeDa ).
Im Simulator ist zunächst Continue ( F5 ) zu klicken. Wenn das
Pausensymbol erscheint, dieses klicken, danach PIND5 klicken und
wieder Continue bis erneut das Pausensymbol erscheint. Jetzt PIND5
wieder klicken ( löschen ) und wieder Continue und warten bis man zum
Breakpoint bei rcall _twi_start gelangt. Ab nun mit Step Into ( F11 )
arbeiten.
Mit dem Schreiben des Wertes für die START-BEDINGUNG in TWCR, sollte ja
bereits das Bit TWINT dort gesetzt werden, was im Simulator allerdings
nicht passiert. Somit ist eigentlich auch klar, das die TWI-ISR nicht
angesprungen wird.
Aber warum ?
In der Appnote AN2480 bzw. AVR315 steht :
As long as the TWINT Flag is set, the SCL line is held low. This allows
the application software to
complete its tasks before allowing the TWI transmission to continue.
*The TWINT Flag is set:*
*• After the TWI has transmitted a START/REPEATED START condition*
• After the TWI has transmitted SLA+R/W
• After the TWI has transmitted an address byte
• After the TWI has lost arbitration
• After the TWI has been addressed by own Slave address or general
call
• After the TWI has received a data byte
• After a STOP or REPEATED START has been received while still
addressed as a Slave
• When a bus error has occurred due to an illegal START or STOP
condition
Leider weiß ich nicht wie ich ganz simpel das Projekt hier hochladen
kann ( Wii_Nunchuk.atsln )
Da bin ich aber gespannt, ob jemand den Fehler findet.
Bernd_Stein
S. Landolt schrieb:> Frage: Wo wird TWEN gesetzt?>
Die Dateienflut sieht schlimmer aus, als sie ist. Im Unterprogramm, dort
wo die START-BEDINGUNG erzeugt wird. ( UP_Wii_Nunchuk.inc ) zu finden.
Im Simulator sehe ich auch das dieses Bit gesetzt wurde.
Ah, du bringst mich auf eine Idee. Sicherlich braucht die Hardware etwas
Zeit um sich zu initialisieren oder so. Werde jetzt mal diese
TWI-Peripherieeinheit vorher schon mal einschalten bzw. enablen, obwohl
ich meine dies schon mal gemacht zu haben, aber in Beispielprogrammen
gesehen habe, das dies auch erst geschieht, wenn eine TWI-Aktion erzeugt
wird.
Erstaunlich sehe gerade, das die OK-LED an ist, das ist schon mal ein
sehr gutes Zeichen.
Danke, wieder einen Schritt weiter.
Leider ist in der Simu immer noch kein Sprung zur TWI-ISR. Es ist auch
nicht zu sehen das TWINT in TWCR gesetzt ist, aber das die OK-LED an
ist, sagt eigentlich das die TWI-ISR angesprungen wird.
Bernd_Stein
Hi
>ldi a,#twi_start
Wo ist das definiert? Das '#' kenne ich als Bestandteil von
Präprozessor-Direktiven. Wie der Assembler an anderen Stellen darauf
reagiert kann ich nicht sagen.
Bei meinen I2C-Routinen komme ich komplett ohne Interrupt aus.
MfG Spess
> Wo ist das definiert?
In Header_Wii_Nunchuk.h.
Ich kannte diese Verwendung von '#' auch nicht, scheint aber normal zu
sein. Ob es der Lesbarkeit zuträglich ist, sei dahin gestellt bzw. ist
wohl Geschmackssache. Letzteres ist auch, die ersten Schritte mit einer
grundlegenden Funktion über acht Dateien zu verteilen, einen guten Teil
der Befehle auszukommentieren und das dann noch mit dem Simulator zu
testen. Also mir persönlich ist das zu hoch - ich schreibe einen
Zehnzeiler mit Kontroll-LED und probiere es auf dem Steckbrett aus, ganz
simpel; von da aus kann ich dann weitermachen.
Ich habe die Dateien mal grob überflogen und keinen Fehler entdeckt.
Ich stimme S.Landolt zu.
Auch ich finde, dass die Dateien so zu unübersichtlich. Für das spätere
Programm mag es so Ok sein, aber wir sind mit deiner Struktur nicht
vertraut. Es ist ziemlich schwierig Fehler zu erkennen, die sich über
mehrere Dateien verteilen.
Reduziere dein Programm, so dass nur so viele Zeilen drin sind, wie
unbedingt nötig, um das Problem vorzuführen. Und alles bitte in einer
einzigen Datei.
Dann können wir Dir besser helfen. Wahrscheinlich siehst du den Fehler
dann sogar schon selbst.
spess53 schrieb:> Bei meinen I2C-Routinen komme ich komplett ohne Interrupt aus.>
Ja, das sehe ich oft, obwohl ATMEL selbst ja unter : " USING THE TWI "
schreibt :
" The AVR TWI is byte-oriented and interrupt based. "
Egal, jeder so wie er will. Habe das Problem jetzt mal etwas einkreisen
können. Und zwar hängt es irgendwie mit meiner Debugroutine (
USART-Transmitter ) zusammen. Habe dessen Interrupt durch
auskommentieren gesperrt und dadurch geht die OK-LED schon mal an.
In der Simu komme ich jedoch nie in die TWI-ISR, was aber sein muss,
sonst wird die OK-LED nämlich nicht eingeschaltet.
Habe jetzt mal das Program als ein Listing angehangen und hoffe das ihr
damit besser klarkommt. Die *m8def.inc* jedoch nicht, damit das Listing
nicht unnötig aufgebläht wird.
Bernd_Stein
Das Programm ist immer noch viel zu groß. Reduziere es noch weiter.
Es sollte nur noch eine einzige TWI Transaktion drin sein, sonst keine
weitere Schnittstelle.
Stefanus F. schrieb:> Das Programm ist immer noch viel zu groß. Reduziere es noch weiter.>
OK, habe ich gemacht. Einmal alles in eine Datei ( Main_Test ) + die
m8def.inc und einmal ein neues ATMEL-Studio7-Projekt angelegt. Dies als
ZIP-File, damit wer es auch mag, meiner Meinung nach komfortabler mit
den Reitern gearbeitet werden kann.
Bernd_Stein
Mann, Mann ist das nervig.
Die OK-LED geht in der Schaltung an, aber in der Simu vom ATMEL-Studio7,
wird nicht in die TWI-ISR gesprungen. Aber es ist in der Realität so,
sonst würde die OK-LED ja nicht angehen ( Kathode an PortD4 ). In der
Simu ist das eigentlich auch richtig, das nicht zur TWI-ISR gesprungen
wird, weil das TWINT-Flag ja nicht gesetzt wird ( siehe Screenshot ).
Alles was ich jetzt gelesen habe, auch in englisch sagt aber, das nach
ausgeführter TWI-Aktion das TWINT-Flag gesetzt wird. Im OLS ( dem Open
Source Logic Analyser und auf dem Oszi ) sehe ich auch eindeutig, das
die START-BEDINGUNG erzeugt wurde, was ja auch die OK-LED schlußendlich
anzeigt.
Gut ich weiß - Simulation ist nicht die Realität.
Werde jetzt wieder einzelne Sachen einfügen, um genau feststellen zu
können wo der Wurm drinn steckt. Es schien ja die Debugroutine (
USRAT-Transmit ) zu sein. Jetzt sehe erstmal zu, wieder die
ProgrammLaufAnzeige ( PLA ) zu implementieren.
PLA blinkt, OK-LED ist auch an, OLS zeigt die korrekte START-BEDINGUNG.
So jetzt noch die Debugroutine oder sollte ich erstmal den aktuellen
Programm status hochladen ? Ja, denke das ist besser, sonst wird es für
euch wahrscheinlich ein zu großer Happen, wenn ich dann schreibe: "
Jetzt ist vorbei mit OK-LED ON ".
Bernd_Stein
Bernd S. schrieb:> So jetzt noch die Debugroutine oder sollte ich erstmal den aktuellen> Programm status hochladen ?>
Das ging irgendwie unter bearbeiten nicht, deshalb hier.
Bernd_Stein
Da ist immer noch zu viel Code drin. Nimm den Timer und die
Tastenentprellung raus.
Wie gesagt soll einfach nur eine einzige TWI Transaktion im Code stehen,
sonst nichts weiter.
Vermutlich nerve ich Dich, aber genau so kreise ich Fehler ein, die sich
gut versteckt haben. Immer weiter reduzieren, bis es plötzlich
funktioniert oder auf so wenige Zeilen reduziert ist, dass ich sie fast
auswendig aufsagen könnte.
Stefanus F. schrieb:> Da ist immer noch zu viel Code drin. Nimm den Timer und die> Tastenentprellung raus.>
Die Tasterentprellung verstehste nich, hä !
Das war ein Scherz, aber ist wirklich heftig die zu verstehen. Ist Halt
PeDa like genial, aber dafür tricky. Hannes Lux hatte auch immer so
trickreiche Programme drauf, aber der kann leider Niemanden mehr direkt
helfen.
Jetzt versteh ich dich nicht. Das alles funktioniert ja, auch wenn
anscheinend die Simu im ATMEL-Studio7 nicht richtig arbeitet.
Den Taster brauch ich wirklich nur, um das Programm schrittweise testen
zu können, aber hier steckt ja nicht das Problem. Außerdem bleibt der
Timer-Overflow später bestehen, da die PLA-Funktion bleibt.
Die Ursache steht eindeutig mit der Debug-Routine ( USART-Transmit ) im
Zusammenhang, denn nun geht die OK-LED nicht mehr an.
Wenn du die Version TWI_Interrupt_2.zip laufen lassen würdest, dann
könntest du ebenfalls sehen, das die ( bei mir PD4 ) grüne OK-LED angeht
und die ( bei mir PB4 ) rote PLA-LED munter weiterblinkt, wenn der
Taster an PD5 betätigt wird. Die PLA-LED blinkt natürlich nach
Betätigung des Taster weiter, ist ja eine ProgrammLaufAnzeige ;-).
Ich denke euer Problem ist der 1,8432Mhz Quarz, aber mit dem kann ich
fast wunderbar die 100kHz im I2C-Bus Normal Mode ( TWI-NM ) erreichen (
entweder 92kHz oder 102kHz )und für die RS232 ( USART ) gängige
Baudraten. Hier 38400 Baud.
Bernd_Stein
Es geht nicht darum, den Code zu verstehen. Es geht darum, alles was vom
Problem ablenkt, zu entfernen, damit man sich auf das Problem
konzentrieren kann.
Außerdem geht es darum, mögliche Seiteneffekte zu eliminieren, um
festzustellen, oder der TWI Code selbst die direkte Problemursache ist,
oder nicht.
> Das alles funktioniert ja, auch wenn anscheinend die> Simu im ATMEL-Studio7 nicht richtig arbeitet.
Im Simulator muss es auch funktionieren.
> Wenn du die Version TWI_Interrupt_2.zip laufen lassen würdest
Ich habe gar kein Atmel Studio installiert. Mit meinen Beiträgen möchte
ich Dir helfen, das Problem einzukreisen und es selbst zu beheben.
> Ich denke euer Problem ist der 1,8432Mhz Quarz
Was meinst du damit? Ich habe kein Problem mit deinem Quarz. Wenn du
willst, kannst du deinen TWI Bus so langsam takten, wie du willst. Die
allermeisten TWI Chips haben kein unteres Limit.
Hi
Also im 4er Studio steht zum Simulator:
>Das alles funktioniert ja, auch wenn>anscheinend die Simu im ATMEL-Studio7 nicht richtig arbeitet.
Dann sieh halt mal in den 'Known Issues ' der Simulatorhilfe nach.
Beim 4er Studio steht zum Simulator:
Unsupported modules
Simulation of TWI, USI and analog peripheral is not yet implemented.
All instructions, interrupts and other peripherals are supported. See
the Simulator Modules for more information
MfG Spess
Jetzt mal unter uns, Stefanus - sehen Sie vielleicht in dem zuletzt
vorgestellten zip-File irgendwo etwas mit "Debug-Routine (
USART-Transmit )"? Also ich finde nur zwei Versionen eines
Hauptprogrammes, in einem davon auskommentierte Befehle, die irgendwie
an USART erinnern.
Herr S. Landolt, legen Sie mir bitte nicht Worte in den Mund, die ich
nicht geäußert habe.
> Da ist immer noch zu viel Code drin.> Nimm den Timer und die Tastenentprellung raus.
Da steht nichts mit USART.
Stefanus F. schrieb:> Im Simulator muss es auch funktionieren.>
Der Meinung bin ich auch und erst recht nachdem ich nachgeguggt habe was
Spess geraten hat.
https://www.microchip.com/webdoc/simulator/simulator.section.nft_gud_lc.html>> Was meinst du damit? Ich habe kein Problem mit deinem Quarz.>
Na ich dachte, es würde wenigstens jemand mal das Programm ins A-Studio
laden und diese bis jetzt ganz einfache Schaltung ( 2xLED, 1xTaster,
2xPullup 4k7, 1x100nF, 2x22pF, 1xQuarz ) auf einem Breadboard nachbauen,
so wie ich es getan habe. Solange der Wii Nunchuk nicht dran ist, kann
man ja alles mit 5V betreiben, obwohl ich schon gelesen habe, das er das
auch überleben soll.
Hauptproblem dachte ich, wäre dann der Quarz. Hauptproblem könnte jedoch
sein, das kaum jemand sich für AVR8-Assembler interessiert und noch mit
der RS232 arbeitet ohne einen USB-Wandler zu nutzten, denn dort (
USART-Transmitter ) liegt ja mein Problem.
Im Simu sehe ich, das in die Interrupt-Vektortabelle sehr oft zu dem
USART Data Register Empty Interrupt gesprungen wird. Diese Tabelle
befindet sich in der IRQm8.inc.
Ich hoffe halt darauf, das jemand so wie früher einmal mich...
Beitrag "Re: AVR-ASM Knobelei : Bitmanipulation am LCD im 4-Bit Mode"
Bernd_Stein
S. Landolt schrieb:> sehen Sie vielleicht in dem zuletzt> vorgestellten zip-File irgendwo etwas mit "Debug-Routine (> USART-Transmit )"?>
Nein, ich wollte erstmal eine Version hier hineinstellen, wo alles noch
mit allen benötigten Routinen läuft. Dachte es wäre für euch und mich
dann einfacher, sich auf den Programmteil zu konzentrieren, der die
Probleme macht.
@S. Landolt
Verstehen Sie, warum das TWINT-Flag im TWCR nicht gesetzt wird ?
Bernd_Stein
In meinem Zehnzeiler auf einem ATmega48PA wird TWINT gesetzt, aber das
war eigentlich klar, denn so steht es ja auch im Datenblatt.
Aber ich arbeite noch mit einem steinalten AVR-Studio und komme mit
dem vorgestellten zip-File nicht zurecht, verstehe jetzt auch nicht, wo
konkret das Problem liegt, beim TWINT, beim USART oder beim Simulanten -
pardon, beim Simulator.
> das in die Interrupt-Vektortabelle sehr oft zu dem> USART Data Register Empty Interrupt gesprungen wird
Ein Schuss ins Blaue: Ist dieser Interrupt freigegeben ohne dass etwas
gesendet wird, so wird ständig diese ISR aufgerufen, d.h. das
Hauptprogramm wird extrem zäh bzw. langsam.
S. Landolt schrieb:> In meinem Zehnzeiler auf einem ATmega48PA wird TWINT gesetzt, aber das> war eigentlich klar, denn so steht es ja auch im Datenblatt.>
Ich versteh nicht, das du dann nicht einfach diesen 10zeiler hier
reinsetzt und ich ihn mal im Simu laufen lassen kann.
> ...> PS:> Konkret: wo in dem 'TWI_Interrupt_2.zip' von 06:37 ist etwas zu> "Debug-Routine ( USART-Transmit )" zu finden?> ...
Haben uns wahrscheinlich mit dem Schreiben überlappt.
Lese :
Beitrag "Re: AVR8ASM TWI Interrupt"> ...> Ein Schuss ins Blaue: Ist dieser Interrupt freigegeben ohne dass etwas> gesendet wird, so wird ständig diese ISR aufgerufen, d.h. das> Hauptprogramm wird extrem zäh bzw. langsam.> ...
Da könnte was dran sein, werde ich näher untersuchen, da ich mich in
vorherigen Versionen schon gewundert habe, das es mal langsam und mal
schneller über die RS232 geht bzw. auf die Tasterbetätigung reagiert
wird.
Bernd_Stein
Bernd S. schrieb:> Im Simu sehe ich, das in die Interrupt-Vektortabelle sehr oft zu dem> USART Data Register Empty Interrupt gesprungen wird. Diese Tabelle> befindet sich in der IRQm8.inc.
Da steht aber ein RETI drin.
Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals angesprungen
werden !!!
Never ever !!!
> Ich versteh nicht ... mal im Simu laufen lassen kann.
Es würde ja nur bestätigt, was im Datenblatt steht. Und bevor ich ein
(altes) AVR8-Datenblatt anzweifle, zweifle ich erst einmal ganz massiv
am Simulator und danach eine ganze Weile an mir selbst.
> Haben uns wahrscheinlich mit dem Schreiben überlappt...
Aha - aber wo bzw. auf welcher Grundlage sollen wir nun einen Fehler
finden?
> Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals> angesprungen werden !!!> Never ever !!!
?
Wenn z.B. der Interrupt lediglich dazu dient, den uC aus einem sleep
aufzuwecken?
Peter D. schrieb:> Da steht aber ein RETI drin.> Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals angesprungen> werden !!!> Never ever !!!>
Ich dachte in diesem Fall schon, da in der ISR auch nicht mehr passiert.
Bernd S. schrieb:> Ich versteh nicht, das du dann nicht einfach diesen 10zeiler hier> reinsetzt und ich ihn mal im Simu laufen lassen kann.>
@S. Landolt
Wieso hast du so geschickt versucht, dieser Sache aus dem Weg zu gehen ?
S. Landolt schrieb:> Aha - aber wo bzw. auf welcher Grundlage sollen wir nun einen Fehler> finden?>
Für alle nicht ATMEL-Studio7 Nutzer hatte ich hier die
*Wii_Nunchuk_Komplett.asm* eingestellt.
Beitrag "Re: AVR8ASM TWI Interrupt"
> Für alle nicht ATMEL-Studio7 Nutzer hatte ich hier die> *Wii_Nunchuk_Komplett.asm* eingestellt.
Jetzt gebe ich auf - dort ist doch (fast) alles USART-Relevante
auskommentiert, bin ich denn blind?
Bernd S. schrieb:> Ich dachte in diesem Fall schon, da in der ISR auch nicht mehr passiert.
In diesem Fall gerade nicht. Nur wenige Interrupts löschen ihr
Pending-Flag automatisch, dieser nicht.
Peter D. schrieb:> In diesem Fall gerade nicht. Nur wenige Interrupts löschen ihr> Pending-Flag automatisch, dieser nicht.>
Lese mich gerade wieder in die USART-Geschichte ein, mal sehen, ob ich
das auch selbst irgendwann in den Unterlagen finde.
S. Landolt schrieb:> Und nein, ich schreibe das nicht für einen ATmega8 um.>> Aber was fangen Sie jetzt damit an?>
Na, ich beschäftige den ATMEL-Studio7 Simu damit ;-)
Tja, auch hier kein Sprung zur TWI-ISR. Also ist für mich bestätigt, das
der Simu einen Fehler hat. Danke.
Bernd_Stein
S. Landolt schrieb:> Nur am Rande: ein ATmega8 verlangt ein explizites Setzen des> Stackpointers. Was aber erst beim Rücksprung aus der ISR wichtig würde.>
Hatte ich ehrlich gesagt gar nicht dran gedacht und dies nachgeholt, da
vor dem Sprung zur ISR ja die Rücksprungadresse auf auf den Stack bzw.
die SRAM-Adresse $0000 geschrieben wird und somit die ersten
Programmzeilen überschrieben werden. Aber das brachte keine Änderung.
Wie ich gerade gesehen habe, haben wir uns auf die Minute genau
Überlappt ( 14:59 Uhr ). Im Simu wurde trotzdem PD4 richtig behandelt,
weil dies ja vor dem Sprung zur ISR passiert bzw. es ja gar nicht zu
einem Sprung dorthin kommt.
Bernd_Stein
Bernd S. schrieb:> Peter D. schrieb:>> In diesem Fall gerade nicht. Nur wenige Interrupts löschen ihr>> Pending-Flag automatisch, dieser nicht.>>> Lese mich gerade wieder in die USART-Geschichte ein, mal sehen, ob ich> das auch selbst irgendwann in den Unterlagen finde.>
Habs gefunden, muss nur noch genau überlegen, was es bedeutet und vor
allem in meinem Programm anrichtet :
" The Data Register Empty (UDRE) Flag indicates whether the transmit
buffer is ready to receive new data. This bit is set when the transmit
buffer is empty, and cleared when the transmit buffer contains data to
be transmitted that has not yet been moved into the Shift Register.
For compatibility with future devices, always write this bit to zero
when writing the UCSRA Register. "
Was meinen die jetzt mit " write this bit to zero ... " ?
Das übliche, dieses Bit durch "setzen" zu löschen, also beschreiben mit
einer Eins oder wirklich dort eine Null hinschreiben ?
Bernd_Stein
UCSRA.UDRE lässt sich nicht explizit löschen, es gibt exakt den Zustand
des transmit-buffers an; man kann nur UDR ständig füttern, oder muss
eben diesen Interrupt abschalten. So steht es ja auch im Datenblatt,
z.B. im Gegensatz zu TXC.
Zur Zeit sieht es so aus :
Als Ursache wurde die USART-Transmit-Interrupt-Routine ausgemacht. Diese
wird ständig angesprungen, da bei der Initialisierung UCRSA.UDRE gesetzt
ist und nur durch beschreiben des UDR gelöscht werden kann.
Jetziges Problem ist, das ich icht weiß warum die OK-LED nicht
eingeschltet
(Kathode an PD4 ) wird, weil der verdammte ATMEL-Studio7 Simulator nicht
richtig arbeitet, denn er setzt TWCR.TWINT nicht.
In Hterm sehe ich das die Rueckmeldung der TWI-Busschnittstelleneinheit
bzw. TWSR bestaetigt, das die START-BEDINGUNG korrekt ausgefuehrt wurde
( $08 ). Dies konnte ich jedoch bereits am Oszi und am OLS ( Logic
Analyser ) sehen.
Allerdings taucht die Rueckmeldung 2x auf ( $08 ), was ich mir z.Zt.
auch
nicht erklaeren kann.
Mir fehlt also eine Idee, wie ich es schaffen kann, über die RS232
(Debugroutine mittels USART-Transmit-Interrupt ), mir den korrekten
Inhalt des TWSR anzeigen zu lassen.
Im Anhang das Übliche. Main_Test_3.asm + m8def.inc für die Nicht
ATMEL-Studio7 Nutzer, für all die Anderen TWI_Interrupt_3.zip
IRQm8.inc ist aus versehen mit dabei.
Bernd_Stein
Peter D. schrieb:> Da steht aber ein RETI drin.
So what? Ein einziges reti ist eine völlig legale ISR. Für sehr viele
der Interrupts eines AVR8 ist nicht mehr nötig. Nämlich für all die, bei
denen das Durchlaufen des Interrupt-Vectors das entsprechende IRQ-Flag
automatisch löscht.
Natürlich ist in den allermeisten Fällen so ein leere ISR nicht gerade
sehr sinnvoll, das ist klar.
Aber es kann Ausnahmen geben. Z.B. den Klassiker: die ISR existiert
überhaupt nur, um einen Wakeup-Mechanismus zu komplettieren. In diesem
Fall ist es völlig legitim, die ISR nur aus einem reti bestehen zu
lassen (genauer: dafür sollte man dann sogar besser nur ein ret an
selber Stelle verwenden).
> Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals angesprungen> werden !!!> Never ever !!!
Bullshit. Das ist überhaupt kein Problem. Jedenfalls für alle
Interrupts, die ihren IRQ automatisch löschen, wenn sie den Vector
durchlaufen. Das ist eindeutig die deutliche Mehrheit der auf einem AVR8
verfügbaren Interrupts.
Wie immer: man muß einfach nur wissen, was man da eigentlich tut. Primär
also: das verschissene Datenblatt lesen, denn da steht sowas natürlich
drin...
S. Landolt schrieb:> Ich sehe nicht, wo in Main_Test_3.asm TWINT zurückgesetzt wird.>
Oh ha, danke. Muss natürlich gemacht werden. Heute jedoch nicht mehr,
meine Konzentrationzeit ist nahe Null.
c-hater schrieb:> Wie immer: man muß einfach nur wissen, was man da eigentlich tut. Primär> also: das verschissene Datenblatt lesen, denn da steht sowas natürlich> drin...>
Das ist nur der erste Schritt. Und Datenblatt ist um einiges
untertrieben ;-). Dabei ist zu hoffen, das dort kein Fehler ist.
Das Hauptproblem bei den verschissenen Datenbüchern ist, das richtige
Interpretieren bzw. verstehen des Inhalts.
Genau wie bei meinem Programm, das du dir sicherlich nicht reingezogen
hast, sonst hättest du ja was dazu geschrieben, wie es z.B. Landolt
getan hat.
Bernd_Stein
Mein Vorschlag mit dem in/out trifft es nicht, gar so einfach ist es
nicht - mein Tag war etwas zu lang heute.
Klar ist aber, dass die Mehrfachrückmeldung daher kommt, dass der
Interruptrequest nie gelöscht wird.
Die TWI Schnittstelle kommt mir persönlich als eine der schwierigsten
vor. Vor ein paar Jahren hatte ich mal einen I²C Master mit der USI
Schnittstelle implementiert, die ist noch ekliger.
Was mich irritiert: Warum wurde dein Interrupt nur zweimal aufgerufen?
Da du TWINT nicht zurückgesetzt hast, hätte ich eine endlose
Wiederholung erwartet.
Bernd S. schrieb:> Als Ursache wurde die USART-Transmit-Interrupt-Routine ausgemacht. Diese> wird ständig angesprungen, da bei der Initialisierung UCRSA.UDRE gesetzt> ist
Warum zum Teufel setzt Du es dann?
Als Programmierer sollte man sich defensives Programmieren angewöhnen,
d.h. Fehler vermeidendes. Und dazu gehört eben, daß man nur die
Interrupts freigibt, für die man auch einen Handler implementiert hat.
Solche einfachen Regeln sollen Dir das Programmieren erleichtern und
schränken Dich in keinster Weise ein.
Klar ist nur RETI möglich, nur ist das nie wirklich nötig. Man kann
einen Aufwachinterrupt auch nach dem Sleep disablen, bis dahin wird er
ständig ausgeführt mit einem Main-Befehl im Wechsel. Sauberer ist daher,
ihn im Handler zu disablen. Die minimale Flash-Einsparung durch den
fehlenden Handler ist dagegen unerheblich.
c-hater schrieb:> Bullshit.
Gerade für Assemblerprogrammierer sind sinnvolle Regeln überhaupt kein
Bullshit. Man hat genug andere Fallstricke und muß sich nicht
absichtlich noch weitere basteln. Warum also unnütz 8 CPU-Zyklen
vergeuden?
Peter D. schrieb:> Warum zum Teufel setzt Du es dann?> Als Programmierer sollte man sich defensives Programmieren angewöhnen,> d.h. Fehler vermeidendes. Und dazu gehört eben, daß man nur die> Interrupts freigibt, für die man auch einen Handler implementiert hat.>
Guten Morgen Peter,
wenn ich geahnt hätte, das es mit UCRSA.UDRE solch Probleme geben würde,
hätte ich es nicht verwendet. Ich will mit Interrupts arbeiten, dafür
sind sie ja da. Ich wusste halt nicht, was ich in der ISR ( damit meinst
du wohl den Handler ) hineinschreiben sollte, da...
Ich kürz es jetzt mal ab, weil es gibt ja drei USART-Interruptquellen.
Die Datenregister Leer-Unterbrechung, ist mir mittlerweile zu
kompliziert in meinem Vorhaben umzusetzen und ist daher verworfen
worden.
Die Empfänger-Unterbrechung benötige ich nicht, da bleibt jetzt noch die
Sendeschiebe-Unterbrechung, woran ich gerade arbeite ( UTXCaddr ).
Bernd_Stein
Was lernen wir daraus?
Bei "komischen" Problemen das Programm schrittweise reduzieren, bis
notfalls nur noch die wenigen Zeilen Code übrig sind, die den Fehler
auslösen.
Dazu gehört auch das Entfernen nicht benutzter Funktionen, Libraries und
Includes. Alleine schon die Existenz einer vollkommen unbenutzen
Variable kann unter ungünstigen Umständen Fehlfunktionen auslösen.
Stefanus F. schrieb:> Was lernen wir daraus?>> Bei "komischen" Problemen das Programm schrittweise reduzieren, bis> notfalls nur noch die wenigen Zeilen Code übrig sind, die den Fehler> auslösen.>
Grundsätzlich gebe ich dir Recht, jedoch in diesem Fall, hatte ich es ja
getan, da ich die Debugroutine auskommentiert hatte ( direkt erstes
Posting ). Da der Simu jedoch Fehlerhaft ist, hatte ich erstmal einen
zweiten Fehler zu erkennen, den ich dann durch den TWI-10zeiler von
Landolt dingfest machen konnte.
Das UCRSA.UDRE nur durch schreiben in UDR gelöscht werden kann, machte
mir jedoch solche Probleme in meiner Programmkonstellation, so dass ich
es glücklicherweise verwerfen konnte und die UTXCaddr Interrupt dafür
einsetzen kann.
Bernd_Stein
Bernd S. schrieb:> Ich will mit Interrupts arbeiten, dafür> sind sie ja da.
Nö, Interrupts verwendet man nicht, weil sie da sind, sondern nur, wenn
man sie auch braucht.
Und dabei gilt, erst den Handler schreiben und dann erst enablen!
Enablen ohne Handler ergibt immer Seiteneffekte.
Bernd S. schrieb:> Die Empfänger-Unterbrechung benötige ich nicht, da bleibt jetzt noch die> Sendeschiebe-Unterbrechung, woran ich gerade arbeite ( UTXCaddr ).
In der Regel ist es genau umgekehrt. Der Empfang ist kritisch, es darf
kein Byte verloren gehen, falls das Main mal länger beschäftigt ist. Das
Senden ist unkritisch, dann wartet die Gegenstelle eben länger auf das
nächste Byte.
Peter D. schrieb:> Nö, Interrupts verwendet man nicht, weil sie da sind, sondern nur, wenn> man sie auch braucht.>
Braucht man Interrupts ?
Ich sehe zu oft, das in der AVR8-Assemblerprogrammierung das Polling
benutzt wird. Ich als ASM-Programmierer sehe es als " Pflicht " an,
jeden Interrupt zu nutzen, denn durch Polling mache ich ja gerade den
hervorstechensten Vorteil der ASM-Programmierung zunichte. Nämlich seine
unübertroffene Schnelligkeit bzw. sein schnelles Reagieren.
In Bezug auf Sender und Empfänger hast zu sicherlich Recht. Nur in
meinem Fall benötige ich lediglich den Sender. Hiermit schicke ich
Debuginformationen an ein Terminalprogramm, da ja auf die ATMEL-Studio
Simu kein Verlass ist ;-)
Was genau sind Seiteneffekte ?
Es wird vielfach erwähnt, aber das was ich gefunden habe erklärt jedoch
nicht was damit genau gemeint ist. Hast du mal ein AVR8ASM-Codeschnipsel
oder Sonstiges, wo man verstehen kann was das genau ist ?
Bernd_Stein
Bernd S. schrieb:> Was genau sind Seiteneffekte ?
Du hast sie doch gesehen.
- nachfolgende Interrupts kommen nicht mehr ran.
- Main wird massiv ausgebremst.
- Interrupts mit automatischem Löschen, löschen dem Polling das Flag
unter der Nase weg.
Bernd S. schrieb:> hervorstechensten Vorteil der ASM-Programmierung zunichte. Nämlich seine> unübertroffene Schnelligkeit bzw. sein schnelles Reagieren.
Ich habe das noch nie bemerkt, da bei meinen Applikationen die CPU nicht
auf 100% ausgelastet ist.
Dagegen den Vorteil von C, der erheblich schnelleren Programmerstellung,
höheren Übersichtlichkeit, besseren Wartbarkeit, Erweiterbarkeit und
geringeren Fehlerrate habe ich sehr deutlich bemerkt.
Assembler hatte ich nur deshalb angefangen, da die ersten AT90S1200,
ATtiny15 usw. sehr mageren Flash/RAM hatten und mit Hardwarestack auch
nicht C-tauglich waren.
Peter D. schrieb:> Assembler hatte ich nur deshalb angefangen, da die ersten AT90S1200,> ATtiny15 usw. sehr mageren Flash/RAM hatten und mit Hardwarestack auch> nicht C-tauglich waren.>
Seltsam, dabei hat ATMEL damals damit geworben auf C optimierte
Controller entwickelt zu haben.
So, zurück zu meinem Programm :
Der Stand ist nun, das ich die UDRE-Interrupt Geschichte verworfen habe
und
statt dessen die USART Trasmit Complette ( UTXCaddr )Interrupt benutze.
Die OK-LED ist immer noch nicht an, da sie höchstwahrscheinlich wieder
rueck-
gesetzt wird, denn es ist eindeutig zu sehen, das der richtige Status
zurueck
gemeldet wird. ($08 in Hterm ).
Seltsam ist das die TWI-Interrupt öfters ausgeführt wird, obwohl die
Taster-
betaetigung quitiert wird.
Bernd_Stein
Eine sinnvolle Motivation, ausgerechnet in Assembler zu programmieren:
Man lernt Details des Prozessor direkter kennen, als durch die
Abstraktion höherer Sprachen hindurch.
Nicht jeder versucht sich an Assembler wegen der Performance.
Stefanus F. schrieb:> Man lernt Details des Prozessor direkter kennen, als durch die> Abstraktion höherer Sprachen hindurch.
Man darf auch in C auf IO-Register direkt zugreifen und Interrupts
programmieren. Es ist sogar einfacher, da man sich nicht immer wieder
mit lästiger Kleinarbeit (push, pop, call, jmp, skip, ld, st, SREG
sichern, Register und Variablen verwalten) aufhalten muß.
Man kann aber auch eine fertige Lib benutzen.
Wie gestern abend noch nachgeschoben, funktioniert das in/out TWICR
nicht, daran ändert auch Ihr dazwischengeschobenes 'ori ia,1<<TWINT'
nichts, denn TWINT ist an dieser Stelle bereits gesetzt, sonst wäre die
TWI-ISR nicht angesprungen worden.
Mit dem Löschen von TWINT wird direkt die nächste Aktion ausgelöst
("Also note that clearing this flag starts the operation of the TWI"),
und da TWSTA noch immer gesetzt ist, wird also wohl ein Restart
ausgelöst, ad infinitum; lassen Sie mal in der TWI-ISR auch ein
#rm_twi_restart (= $10) als gültig zu und schauen Sie, was passiert -
ganz sicher bin ich mir nicht, bin kein I2C-Spezialist.
PS:
Besser wäre es, während der Testphase sämtliche TWSR-Status-Codes
,"Rueckmeldungen" in Ihrer Nomenklatur, auf Hterm auszugeben (dabei
dafür sorgen, dass die USART nicht 'überrollt' wird). Man sieht so
schneller, was schief läuft.
S. Landolt schrieb:> (dabei> dafür sorgen, dass die USART nicht 'überrollt' wird).
Das braucht man nicht, da I2C-Master nicht zeitkritisch ist. Es ist
sogar besser, wenn die UART per Polling sendet, dann kann man die
Ausgaben direkt im Interrupt machen.
S. Landolt schrieb:> Mit dem Löschen von TWINT wird direkt die nächste Aktion ausgelöst
So ist es. Man muß erst die nächste Aktion vorbereiten und als letztes
das TWINT setzen, um es zu löschen.
In C habe ich dazu das TWCR in eine temp-Variable geschrieben, darin
alle Aktionen gemacht und dann die Variable nach TWCR zurück
geschrieben.
Stefanus F. schrieb:> Jetzt könnte Moby endlich beweisen was für ein ASM-Crack er ist!>> Wo siehst du denn hier einen Beitrag von Moby?
Davon habe ich nichts geschrieben!
an Bernd Stein:
Ihr derzeitiges Programm auf seine TWI-Grundstruktur eingedampft (nein,
zehn Zeilen haben mir diesmal nicht gereicht), bringt bei mir die
TWI-Status-Code-Folge (an SDA und SCL hängen nur die Pull-ups):
$08 $48 $10 $48 $10 $48 $10 $48 ...
also
$08: A START condition has been transmitted
$48: SLA+R has been transmitted; NOT ACK has been received
$10: A repeated START condition has been transmitted
$48: SLA+R has been transmitted; NOT ACK has been received
... ff
Ist ja schön, dass ich etwas TWI lerne, aber eigentlich sollte ab jetzt
jemand weiterhelfen, der etwas davon versteht - m.a.W., ich verabschiede
mich ins Wochenende
mit den besten Wünschen
Schon, aber zur Zeit lässt er nur $08 als gültig zu, folglich
"Die OK-LED ist immer noch nicht an"
und
"die TWI-Interrupt öfters ausgeführt wird".
Übrigens, Stefanus, dass Sie den einen Beitrag von mir zu Anfang derart
in den falschen Hals bekamen, tut mir ausgesprochen leid; ich suchte nur
Rat bei Ihnen, da ich Schwierigkeiten hatte, den Autor und seine
Programmsammlung zu verstehen.
S. Landolt schrieb:> Ihr derzeitiges Programm auf seine TWI-Grundstruktur eingedampft (nein,> zehn Zeilen haben mir diesmal nicht gereicht), bringt bei mir die> TWI-Status-Code-Folge (an SDA und SCL hängen nur die Pull-ups):>> $08 $48 $10 $48 $10 $48 $10 $48 ...> also> $08: A START condition has been transmitted> $48: SLA+R has been transmitted; NOT ACK has been received> $10: A repeated START condition has been transmitted> $48: SLA+R has been transmitted; NOT ACK has been received> ... ff>
Dies war sehr aufschlussreich, Danke. Somit hat meine Debugroutine
natürlich ihren Sinn nicht richtig erfüllen können, da sie falsch
plaziert wurde. Nachdem ich sie wie nachfolgend zu sehen, anders wo
eingesetzt habe, konnte ich ebenfalls sehen, was "wirklich" passiert.
Wirklich deshalb, weil ich sehe, das dies nicht so eine regelmäßige
Sache ist, wie du beschreibst.
Gut, dein Programm ist nicht mein Programm, deshalb kann es natürlich
diese Regemäßigkeit bei dir geben. Wäre mal wieder schön, auf Grunde
eines einzelnen, dein Programm sehen zu können ;-)
1
_TWIaddr:
2
in s_sreg,SREG ;CPU-Statusregister sichern
3
4
in ia,TWSR ;TWI-Statusregister lesen
5
andi ia,$F8 ;Nichtrelevante Bits ausmaskieren
6
7
;in ia,TWSR ;TWI Status Register lesen...
8
;mov udr_char,ia ;...und an USART ( RS232 ) uebergeben...
9
out UDR,ia ;Zu sendenes Zeichen in UDR hineinschreiben
10
11
cpi ia,#rm_twi_start ;Wurde die Startbedingung gesendet?...
12
brne _twi_error ;Nein => Fehlerbehandlung noetig
13
14
cbi LED_PORT,led.ok ;...OK-LED einschalten
15
16
rjmp _exit_twiaddr ;Interrupt Service Routine ( ISR ) verlassen
ori ia,1<<TWINT ;...und dort das TWI-Interrupt-Flag durch...
26
out TWCR,ia ;...beschreiben mit einer 1 loeschen.
27
28
out SREG,s_sreg ;CPU-Statusregister wiederherstellen;
29
30
reti ;Ruecksprung aus der Interrupt Service Routine
>Stefanus F. schrieb:> Ist doch alles richtig. Solange kein I²C Slave antwortet, empfängt der> µC kein ACK Signal.>
Nein, denn dann dürfte nicht einfach munter drauf weitergesendet werden.
In dem Buch " I2C-Bus angewandt ", Kapitel Bytelevel der
Datenübertragung, steht :
"Kein Sender darf weitersenden, wenn er als Acknowledge-Bit eine 1
empfangen hat ( wird auch NACK = Not ACKnowledge bezeichnet )."
Ob ATMEL das jetzt genau so implementiert hat,ist natürlich fraglich.
S. Landolt schrieb:> Schon, aber zur Zeit lässt er nur $08 als gültig zu, folglich> "Die OK-LED ist immer noch nicht an"> und> "die TWI-Interrupt öfters ausgeführt wird".>
Tja, daran habe ich noch zu knacken, da ich gar nicht weiß, warum gerade
immer $FF gesendet wird. Blöderweise kann im Simu TWAR oder TWDR oder
beide ( ich weiß es nicht mehr ) nicht geändert werden, obwohl sie
R/W-Register sind. Auch wenn ich im Programm beiden ein General Call
zuweise ( $00 ), wird munter immer $FF gesendet.
Bernd_Stein
Bernd S. schrieb:> "Kein Sender darf weitersenden, wenn er als Acknowledge-Bit eine 1> empfangen hat ( wird auch NACK = Not ACKnowledge bezeichnet ).">> Ob ATMEL das jetzt genau so implementiert hat,ist natürlich fraglich.
Nein, dein Verständnis der ganzen Sache ist fraglich.
ACK oder NACK wird nachher in Software ausgewertet, damit hat
ATMEL bzw. der verwendete uC nichts mehr zu tun.
P.S.
Eine 1 bedeutet auch das keine Devices sich an dieser Adrese am Bus
befinden. Deswegen darf man mit neuer Adresse weiter versuchen.
Bernd S. schrieb:>>Stefanus F. schrieb:>> Ist doch alles richtig. Solange kein I²C Slave antwortet, empfängt der>> µC kein ACK Signal.
Insofern ist das richtig, unter anderem wird so auch festgestellt
welche Adressen belegt sind.
Marc V. schrieb:> ACK oder NACK wird nachher in Software ausgewertet, damit hat> ATMEL bzw. der verwendete uC nichts mehr zu tun.
Das wird sehr wohl vom I2C-Controller ausgewertet. Nach einem NACK sind
die einzigen erlaubten Aktion STOP oder repeat START. Alle anderen
Aktionen sind undefiniert. Senden eines weiteren Datenbytes ist nicht
erlaubt und wird vermutlich ein NOP bewirken.
Peter D. schrieb:> Marc V. schrieb:>> ACK oder NACK wird nachher in Software ausgewertet, damit hat>> ATMEL bzw. der verwendete uC nichts mehr zu tun.>> Das wird sehr wohl vom I2C-Controller ausgewertet. Nach einem NACK sind> die einzigen erlaubten Aktion STOP oder repeat START. Alle anderen> Aktionen sind undefiniert. Senden eines weiteren Datenbytes ist nicht> erlaubt und wird vermutlich ein NOP bewirken.
LOL.
Das stimmt bestimmt nicht.
Bernd S. schrieb:> "Kein Sender darf weitersenden, wenn er als Acknowledge-Bit eine 1> empfangen hat ( wird auch NACK = Not ACKnowledge bezeichnet ).">> Ob ATMEL das jetzt genau so implementiert hat,ist natürlich fraglich.
Nein, das ist kein bissel "fraglich". Die Atmel-TWI-Engine ist nämlich
dafür schlicht nicht zuständig. Das ist allein die Entscheidung des
Benutzers der TWI-Engine, also deiner Wenigkeit. Machst du es einfach
nur richtig, wirst du auch diese Restriktion locker einhalten können...
Mein Gott, I2C ist doch nicht so kompliziert. Wenn man das Protokoll
wirklich verstanden hat, erschließt sich die Logik der Implementierung
der AVR8-Hardware praktisch von selbst.
@peda
Es gibt auch kein generelles Problem bei der TWI-Hardware bezüglich des
Multimaster-Modus, wie du behaupted hast (aber ja: es gab da ein Problem
bei einigen wenigen Revisionen einiger weniger AVR8, heute aber nur noch
von historischem Interesse...).
Für den riesengroßen Rest gilt: Man muss es einfach nur korrekt
umsetzen. Und ja, das geht auch problemlos in pure C, denn es gibt da
keinerlei timing constraints, auf die man sich herausreden könnte!
Man muss einfach nur das Protokoll verstanden haben und die Hardware.
Und ja: es steht alles dazu nötige im DB. Wirklich! Man muss nur selber
denken können, um auch das dem DB zu entnehmen, was nicht explizit da
steht. Sprich: man braucht nicht mehr als ein gedankliches Modell, wie
diese Hardware funktioniert und den festen Glauben, das Atmel gewollt
hat, dass sie auch im Multimaster-Modus funktioniert, da dieser als
Feature angepriesen wird...
Und das tut sie tatsächlich, wenn man sie korrekt benutzt...
Marc V. schrieb:> Nein, dein Verständnis der ganzen Sache ist fraglich.>> ACK oder NACK wird nachher in Software ausgewertet, damit hat> ATMEL bzw. der verwendete uC nichts mehr zu tun.>> P.S.> Eine 1 bedeutet auch das keine Devices sich an dieser Adrese am Bus> befinden. Deswegen darf man mit neuer Adresse weiter versuchen.>
Hallo Marc V.,
du konntest mir früher schon mal helfen, ich sezte auf dich ;-)
Beitrag "Re: AVR8ASM TWI Interrupt"
Mein Verständis ist mehr als fraglich, denn ich verstehe überhaupt nicht
warum weiterhin $FF gesendet wird, wenn ich doch in der Initialisierung
einen General Call in das TWDR und TWAR schreibe.
Das dauernde Senden ( zumindest auf dem Bus ) konnte ich wieder mal
durch verschieben dreier Codezeilen in der TWI-ISR ( _TWIaddr: ), welche
das TWINT löschen, unterbinden.
Bleibt also noch das Rätsel zu lösen, warum $FF gesendet wird und
weiterhin die RS232 mit $48 zugeballert wird, obwohl das TWINT ja dann
nicht mehr gelöscht wird.
Warum wird dann dennoch weiterhin zu _TWIaddr: gesprugen ?
1
_TWIaddr:
2
in s_sreg,SREG ;CPU-Statusregister sichern
3
4
in ia,TWSR ;TWI-Statusregister lesen
5
andi ia,$F8 ;Nichtrelevante Bits ausmaskieren
6
7
;in ia,TWSR ;TWI Status Register lesen...
8
;mov udr_char,ia ;...und an USART ( RS232 ) uebergeben...
9
out UDR,ia ;Zu sendenes Zeichen in UDR hineinschreiben
10
11
cpi ia,#rm_twi_start ;Wurde die Startbedingung gesendet?...
12
brne _twi_error ;Nein => Fehlerbehandlung noetig
13
14
cbi LED_PORT,led.ok ;...OK-LED einschalten
15
16
in ia,TWCR ;TWI-Kontroll Register lesen...
17
ori ia,1<<TWINT ;...und dort das TWI-Interrupt-Flag durch...
18
out TWCR,ia ;...beschreiben mit einer 1 loeschen.
19
20
rjmp _exit_twiaddr ;Interrupt Service Routine ( ISR ) verlassen
c-hater schrieb:> Man muss einfach nur das Protokoll verstanden haben und die Hardware.> Und ja: es steht alles dazu nötige im DB. Wirklich! Man muss nur selber> denken können, um auch das dem DB zu entnehmen, was nicht explizit da> steht.>
Gut, dann werde ich ja von dir hier nichts mehr lesen, da ich es ja ohne
deine Hilfe werde lösen können.
Danke für diese hilfreiche Information, das dieses Forum hier absolut
unnötig ist, wenn man das Datenbuch besitzt. Falls man dies besitzt und
doch nicht zu Rande kommt, kann einem eh keiner helfen, denn das Problem
kann man deiner Ansicht nach ja eh nur alleine lösen, wenn man klug
genug ist.
Nun, das bin ich nicht. Also erspare dir und vor allem mir meine
kostbare Zeit unsere beider Beiträge zu lesen.
Bernd_Stein
Peter D. schrieb:> Das wird sehr wohl vom I2C-Controller ausgewertet. Nach einem NACK sind> die einzigen erlaubten Aktion STOP oder repeat START. Alle anderen> Aktionen sind undefiniert. Senden eines weiteren Datenbytes ist nicht> erlaubt und wird vermutlich ein NOP bewirken.
Nein.
Siehe beiliegende Screenshots.
Bernd S. schrieb:> Gut, dann werde ich ja von dir hier nichts mehr lesen, da ich es ja ohne> deine Hilfe werde lösen können.
Das könntest du tatsächlich...
> Danke für diese hilfreiche Information, das dieses Forum hier absolut> unnötig ist, wenn man das Datenbuch besitzt.
Nein, das ist es nicht. Auch Datenblätter können Fehler enthalten (dann
ist es normal, Rat zu suchen) und sie können auch Sachverhalte nicht
immer erschöpfend darstellen. Gerade wenn es um Protokolle geht. Da
erwartet der Verfasser des DB nämlich schlicht Eigenleistung des
Benutzers. Und das mit völligem Recht (dann ist es nicht normal, Rat zu
suchen)!
> Falls man dies besitzt und> doch nicht zu Rande kommt, kann einem eh keiner helfen, denn das> Problem> kann man deiner Ansicht nach ja eh nur alleine lösen, wenn man klug> genug ist.
Jepp, wenn das DB und die zugehörige HW fehlerfrei ist, ist das
tatsächlich so. Das mag dir nicht gefallen, ist aber nach den
allgewaltigen Gesetzen der formalen Logik wirklich einfach so...
Sprich: Meine Empfehlung für dich ist: lerne I2C (und zwar: bevor du es
das erste Mal tatsächlich benutzt). Hättest du das getan, gäbe es diesen
ganzen Thread mit an Sicherheit grenzender Wahrscheinlichkeit einfach
nicht...
Auch das eine Tatsache, die dir nicht schmecken wird, die aber
nichtsdestotrotz unbeweifelbar WAHR ist...
c-hater schrieb:> (aber ja: es gab da ein Problem> bei einigen wenigen Revisionen einiger weniger AVR8, heute aber nur noch> von historischem Interesse...)
Konkret war es der Atmega8, also nichts historisches. Die nötigen
Würgarounds waren ziemlich heftig. Manueller Test, ob Bus frei ist,
Überwachung des STOP, Überwachung ob SDA auf low klemmt, Timeout,
Disable und Retry.
Später gab es dann den ATmega88, aber da hab ich nicht nochmal Zeit
gehabt, es zu testen.
Wenn erstmal eine Firmware freigegeben ist, dann muß es schon einen
triftigen Grund geben, neu zu programmieren und ne neue Revision in die
Produktion zu geben. Nur der Verdacht, daß der ATmega88 den Bug nicht
mehr haben könnte, reicht da nicht.
Der Report von David Cook hat mir sehr geholfen:
https://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html
c-hater schrieb:> Es gibt auch kein generelles Problem bei der TWI-Hardware bezüglich des> Multimaster-Modus, wie du behaupted hast
David hat den ATMega168 and ATMega644 benutzt, ich den ATMega8, also ist
das Problem sehr wohl generell.
Marc V. schrieb:> Nein.> Siehe beiliegende Screenshots.
Die zeigen exakt das, was ich gesagt habe. Auf Status 0x20, 0x30 darf
nur ein STOP oder repeat START erfolgen.
"can" hat in Datenblättern übersetzt eher die Bedeutung "darf". Was
nicht im Datenblatt steht, hat implizit die Bedeutung "darf nicht". Es
besteht also keine Freiheit, nicht im Datenblatt aufgeführte Sachen zu
machen. Prinzipiell dürfte der Chip dabei sogar Schaden nehmen, ohne das
Du den Chip reklamieren könntest.
P.S.:
Nehme alles zurück, es darf gesendet werden, warum auch immer.
Aber kein Slave wird darauf reagieren, weil ja alle NACK gesendet haben.
Peter D. schrieb:> c-hater schrieb:>> Es gibt auch kein generelles Problem bei der TWI-Hardware bezüglich des>> Multimaster-Modus, wie du behaupted hast>> David hat den ATMega168 and ATMega644 benutzt, ich den ATMega8, also ist> das Problem sehr wohl generell.
Nun, ich sehe das nicht als Problem an.
Multimaster-Modus bei TWI ist eher die Ausnahme, nicht die Regel, also
sollte man auch entsprechende Security-checks einbauen.
Es sollte selbstverständlich sein, dass man bei Multimaster-Modus nicht
sofort loslegt, sondern einige Zeit vorher den Bus auf Idle prüft.
Tut man nicht so, ist man selber schuld und nicht ATMEL - warum sollte
die TWI-Hardware darauf achten ?
Ist TWI-Bus frei ?
Falls Nein, warte auf STOP oder Idle > 500us.
Falls Ja, warte auf Idle > 500us sende los und nicht erst eine Tabelle
mit 1000 Zuständen vorher analysieren.
Wohlgemerkt, nur bei Multimaster-Modus...
Peter D. schrieb:> P.S.:> Nehme alles zurück, es darf gesendet werden, warum auch immer.
Sage ich doch.
> Aber kein Slave wird darauf reagieren, weil ja alle NACK gesendet haben.
Das wiederum ist nicht gesagt - wenn 2 uC miteinander komunizieren,
kann das vielleicht anders vereinbart sein...
Marc V. schrieb:> Es sollte selbstverständlich sein, dass man bei Multimaster-Modus nicht> sofort loslegt, sondern einige Zeit vorher den Bus auf Idle prüft.> Tut man nicht so, ist man selber schuld und nicht ATMEL - warum sollte> die TWI-Hardware darauf achten ?
Nö, beim originalen Philips/NXP P80C552, P89C668 funktioniert es
einwandfrei. Die halten die vorgeschriebene Pause von 4,7µs ein. Es ist
explizit erlaubt STA und STO gleichzeitig zu setzen. Nur bei Atmel
kracht es (AVR und 8051).
Den Ärger mit Atmel hatte ich auch nur deswegen, weil der P89C668
abgekündigt wurde.
Die Atmel warten zwar auch nach ihrem STOP die 4,7µs, aber wenn sie die
Arbitration verlieren, warten sie nicht nochmal die 4,7µs. Sie senden
ihr START dann 0µs nach dem STOP des anderen Masters.
Peter D. schrieb:> Nö, beim originalen Philips/NXP P80C552, P89C668 funktioniert es> einwandfrei. Die halten die vorgeschriebenen Pause von 4,7µs ein. Es ist
Ich halte es eher für ein Bonus - ist zwar schön, aber ich würde es bei
Multimaster schon selber abwarten - bei I2C ist Geschwindigkeit
bestimmt nicht der Grund zum Anwenden.
Und wie gesagt, Multimaster bei I2C ist (für mich) eher die Ausnahme.
Marc V. schrieb:> Multimaster bei I2C ist (für mich) eher die Ausnahme.
Ist schon recht praktisch, wenn jedes Modul antworten kann, sobald es
bereit ist.
Nach diesem Ärger mit den non-Philips I2C-µCs bin ich jetzt aber auf CAN
umgestiegen. Das ist sogar einfacher zu programmieren.
Peter D. schrieb:> Nach diesem Ärger mit den non-Philips I2C-µCs bin ich jetzt aber auf CAN> umgestiegen. Das ist sogar einfacher zu programmieren.
Genau.
Ich bin auch umgestiegen, aber bei AVRs nur auf Hardware-Ebene - kein
Bit Stuffing und ähnliches.
Bei STM ist CAN eine ganz andere Geschichte, da ist alles nach
Vorschrift aufgebaut und funktioniert absolut ohne Probleme.
Marc V. schrieb:> Bernd S. schrieb:>> Hier der aktuelle KOT ;-)>> Was ist jetzt, geht es ?>
Natürlich nicht. Darauf hin habe ich mal das Löschen des TWCR.TWINT
rausgenommen und somit wird SCL low natürlich "gestretched", also
verlängert.
Dies erwarte ich aber direkt nach der START-BEDINGUNG, da unter
" Using the TWI " unter Punkt 1. steht :
1. Der erste Schritt bei einer TWI Übertragung ist das Senden einer
START-BEDINGUNG. Dies wird gemacht, indem ein spezieller Wert in das
TWCR geschrieben wird, der die TWI Hardware veanlasst, eine
START-BEDINGUNG zu senden. Welcher Wert genommen werden muss, wird
später beschrieben. *Wichtig ist, dass das TWINT Bit mit dem Schreiben
des Wertes gesetzt wird.* Das Schreiben einer 1 in dass TWINT löscht
dieses Flag. *Das TWI startet keine Operation, solange das TWINT im TWCR
gesetzt ist.* Unmittelbar nachdem die Apllikation das TWINT gelöscht hat
, wird das TWI mit dem Aussenden der START-BEDINGUNG beginnen.
Die Übersetzung ist nicht von mir, ich denke jedoch, das diese Sinngemäß
richtig ist, denn es ist eine Ausarbeitung der TU-Chemnitz.
Das heißt für mich, da ich TWCR.TWINT nach der START-BEDINGUNG nicht
mehr lösche, das die TWI Hardware keine neue Aktion ausführt.
Warum wird dann verdammt noch mal dieses für mich unerklärliche $FF
gesendet ?
Ab dem 2ten Byte ist in Hterm TWCR zu sehen. $2D bedeutet das TWINT
gelöscht ist !!!. Dafür kommt jedoch TWWC hinzu, was Write Collision
bedeutet.
Bit3 - TWWC: TWI Write Collision Flag
Diese Bit wird gesetzt, wenn versucht wird in das TWI DATA Register
(TWDR) zu schreiben, während das TWINT Flag Low ist. Das TWWC Flag wird
gelöscht, wenn in das TWDR geschrieben wird, während TWINT High ist.
Das es gesetzt wird ist klar, da ich TWDR & TWAR zu beginn lösche, weil
ich sehen wollte, ob dieses gesendete $FF aus einem der beiden Register
stammt, was bei TWDR passen könnte, weil es mit $FF intialsiert wird.
Vermutlich ist es auch so und dieses TWCR.TWWC verhindert evtl. das mein
Versuch TWDR zu ändern akzeptiert wird.
Das 3te Byte und alle folgenden ($AD) zeigen jedoch, das TWCR.TWINT
gesetzt ist.
Warum verdammt noch mal ?
In _TWIaddr: verhindere ich ja durch löschen des *key_reg.key_actuated*
,das erneut etwas in TWCR geschrieben werden kann und somit keine neue
TWI Aktion ausgeführt wird und trotzdem wird TWCR.TWINT gesetzt.
Was mache ich falsch bzw. verstehe ich aus dem Datenbuch ( DB ) falsch ?
Bernd_Stein
Nachdem der Chip sich ja offenbar nicht konform zum DB verhält, bin ich
einer Sache nachgegangen, die ich beim L-Typ ausgeschlossen, aber zum
Glück noch im Hinterkopf hatte.
Der Spuk hat hiermit ein Ende.
Spess wird sicherlich ein Licht aufgehen.
Kann man an den Beschriftungen des µC erkennen, welches DB bzw.
DB-Revision hierfür zuständig ist ?
Was kann man überhaupt aus den Beschriftungen erkennen im speziellen die
auf der Rückseite ?
Bitte nicht das es ein µC von ATMEL ist => Der ATmega8L ;-)
Ich verlange schon mehr :-)
Bernd_Stein
Hi
>Nachdem der Chip sich ja offenbar nicht konform zum DB verhält, bin ich>einer Sache nachgegangen, die ich beim L-Typ ausgeschlossen, aber zum>Glück noch im Hinterkopf hatte.
Nur gut, das du der erste auf der Welt bist, der das nach 18 Jahren
festgestellt hat.
Oder finde nur ich das merkwürdig?
MfG Spess
STK500-Besitzer schrieb:> "1251" ist relevant bzgl Herstellungsdatum.> Ansonsten ist die Beschriftung im ("complete") Datenblatt erklärt.>
Schön, dann zeig mir bitte den Link zu dem Datenbuch das passend zu dem
Typ auf meinen Fotos ist.
spess53 schrieb:> Nur gut, das du der erste auf der Welt bist, der das nach 18 Jahren> festgestellt hat.>> Oder finde nur ich das merkwürdig?>
Es wird um sachdienliche Hinweise gebeten, um diese Datenleiche finden
zu können. Aktenzeichen XY ;-)
Bernd_Stein
Lieber Bernd Stein,
ohne Umschweife gerade heraus: Sie sind mit dieser Aufgabe überfordert.
Es ist nicht nur mangelndes Datenblattstudium, wie c-hater schreibt, es
ist mangelndes Verständnis, es fehlt an strukturiertem Vorgehen, es
fehlt an Sorgfalt beim Lesen der Beiträge hier. Das muss man
akzeptieren, oder um ein aktuelles Beispiel zu geben: nicht jeder kann
zweiMeterfünfunddreißig überspringen.
Eigentlich geht es mich ja nichts an, aber nachdem ich nun mal am
Anfang dabei war, mögen Sie mir bitte dieses offene Wort nachsehen.
Vielleicht kommen Sie sogar irgendwann zu einer Lösung, aber Ihre
Frustrationsschwelle müsste schon ungewöhnlich hoch sein, um auf dem Weg
dahin nicht jede Lust an der Sache zu verlieren, und das wäre doch
schade.
S. Landolt schrieb:> Eigentlich geht es mich ja nichts an, aber nachdem ich nun mal am> Anfang dabei war, mögen Sie mir bitte dieses offene Wort nachsehen.> Vielleicht kommen Sie sogar irgendwann zu einer Lösung, aber Ihre> Frustrationsschwelle müsste schon ungewöhnlich hoch sein, um auf dem Weg> dahin nicht jede Lust an der Sache zu verlieren, und das wäre doch> schade.>
Nein, ich nehme es dir nicht übel, da du eigentlich auch schon aufgeben
wolltest und dennoch dabei geblieben bist. Wie ich schrieb, habe ich den
Fehler gefunden, warum nach der START-BEDINGUNG noch $FF gesendet wurde,
obwohl dies nicht sein dürfte. Ich dachte Spees würde dies hier wieder
einfallen, denn genau das war der Fehler. Bei TWBR = 11, habe ich es
optimistischerweise gelassen und nun ist alles gut. Werde mich wieder
melden, wenn ich nicht alleine weiterkomme.
Möchte jetzt nur noch nebenbei wissen, ob im DB zum Fotografiertem µC
dieser Umstand beschrieben steht.
Beitrag "Re: I2C/TWI TWBR > 10 warum?"
Bernd_Stein
Dazu kann ich nichts sagen, ich finde im mir vorliegenden Datenblatt
diese Sequenz nicht, lediglich im Abschnitt 'Datasheet Revision History'
den ominösen Satz "... and using the TWI as Master with low TWBRR values
are added into the datasheet."
Allerdings gebe ich zu bedenken, dass gerade bei Interruptstrukturen
längere Sendezeiten ganz unerwartete Folgen haben können, auch das
Verschwinden von Fehlern.
S. Landolt schrieb:> Dazu kann ich nichts sagen, ich finde im mir vorliegenden Datenblatt> diese Sequenz nicht, lediglich im Abschnitt 'Datasheet Revision History'> den ominösen Satz "... and using the TWI as Master with low TWBRR values> are added into the datasheet.">
Hätte es beinahe nicht gefunden, da das FireFox-Suchfenster bei so
vielen Buchstaben, so tut, als ob der Text nicht vorhanden wäre.
Hab jetzt mal unter dem wahrscheinlich ältesten DB geguckt ( 2486B-12/01
Preliminary ) finde dort leider auch nichts.
>> Allerdings gebe ich zu bedenken, dass gerade bei Interruptstrukturen> längere Sendezeiten ganz unerwartete Folgen haben können, auch das> Verschwinden von Fehlern.>
Tja, die meisten wollen es hier vielleicht nicht wahr haben, aber es ist
eindeutig der Fehler, denn außer den Wert TWBR von 2 auf 11 zu
verändern, habe ich nichts weiter getan. Die Gegenprobe ( wieder auf 2
bis 10 in 2er Schritten ), hat jedesmal den Fehler produziert.
Bernd_Stein
Hi
>Nachdem der Chip sich ja offenbar nicht konform zum DB verhält, bin ich>einer Sache nachgegangen, die ich beim L-Typ ausgeschlossen, aber zum>Glück noch im Hinterkopf hatte.
Ich kann mich dunkel daran erinnern, das in der Anfangszeit der AVRs das
TWBR nicht kleiner als 10 sein sollte.
AppNote AVR315 von 10/2005:
TWBR should be 10 or higher if the TWI operates in Master mode. If TWBR
is lower than 10, the Master may produce an incorrect output on SDA and
SCL for the reminder of the byte.
Seit wann dieser Satz aus der Appnote verschwunden ist entzieht sich
meiner Kenntnis. Ebenso welche AVRs dies betrifft. Vielleich solltest du
mal einen neuen (DateCode) testen.
MfG Spess
Sehr spät, ich weiß, aber vielleicht doch noch von Nutzen:
> AppNote AVR315 von 10/2005:> TWBR should be 10 or higher ...> Seit wann dieser Satz aus der Appnote verschwunden ist ...
... steht in der neuen, AN2480:
"2564B 09/2007 Removed text about TWBR needs to be higher than 10"
Also kann der vorliegende ATmega8L-8PU von Ende 2012 wohl kaum betroffen
sein, trotz gegenteiligem Anschein
> ... aber es ist eindeutig der Fehler
Ich geb's auf, Spess - in der aktuellen AN2480, in deren Überschrift
aber noch sehr wohl "AVR315" steht, findet sich direkt unter meinem
Zitat "2564A 04/2006 Initial document release"; wie kam es dann zu Ihrer
Version von 10/2005? Es scheint ein zumindest leichtes Chaos existiert
zu haben.
Hi
Nach meinen Dokementen:
Rev. 2564B-AVR-09/04
Rev. 2564C-AVR-01/10
In AppNote 2564B steht der Satz mit den <10 drin, ab 2564C fehlt er. In
den Datenblättern ist diese Einschränkung nie aufgetaucht.
Also sind die Angaben
"2564A 04/2006 Initial document release"
"2564B 09/2007 Removed text about TWBR needs to be higher than 10"
Unsinn.
Ich habe noch eine ganze Reihe ATMEL-CDs. Danach ist die AVR315 zwischen
06/2004 und 10/2005, also vor der angebliche 'Initial document release',
herausgekommen. 10/2005 habe ich schon die Rev.B.
>Also kann der vorliegende ATmega8L-8PU von Ende 2012 wohl kaum betroffen>sein, trotz gegenteiligem Anschein
Die Nachfolger des ATMega8, die ATMega48..168, sind um 2004 erschienen.
Ab da an wird Atmel kaum noch solche kleinen Einschränkungen am Atmega8
beseitigt haben. Ich würde davon ausgehen, das du betroffen bist.
MfG Spess
> In den Datenblättern ist diese Einschränkung nie aufgetaucht.
Siehe Anhang, aus dem Preliminary 2545B–AVR–01/04.
Übrigens bin nicht ich betroffen, sondern Bernd Stein, und bis der sich
wieder meldet, lasse ich die Sache ruhen; es war vielleicht ohnehin
nicht besonders sinnvoll von mir, sie nochmals hervorzuholen.
hi,
nochmal was zum UDRE-Flag
1. immer wenn du über UART was senden willst solltest du prüfen ob es
gesetzt ist, dann und nur dann ist UDR frei.
2. UDRIE benutzt man nur wenn man ohne Unterbrechung senden will.
beim letzten zu sendendem Zeichen darf es nicht mehr gesetzt sein
sonst
springt er immer in diesen Int.
Die Schnittstelle kann geschlossen oder manipuliert werden
wenn TXCF gesetzt wurde(vorher löschen)
UDRE sagt nur das das Datenregister frei ist, nicht das
Senderegister.
Solche Dinge sind aber durch ordentliches lesen des DB durchaus
erkennbar.
Viel Erfolg, Uwe
S. Landolt schrieb:>> In den Datenblättern ist diese Einschränkung nie aufgetaucht.>> Siehe Anhang, aus dem Preliminary 2545B–AVR–01/04.>> Übrigens bin nicht ich betroffen, sondern Bernd Stein, und bis der sich> wieder meldet, lasse ich die Sache ruhen...>
Ganz schön komplizierte Sache für mich, zu erkennen, wie die
Revisionsabfolge der Datenbücherüberarbeitungen ist. Zudem hatte ich
mich auch noch zu Anfang mit der englischen Darstellung von Monat und
Jahr vertan.
In den neueren DB ist dies jetzt eindeutig.
Wenn ich soweit richtig durchblicke, ist das Rev.2486Z-02/11 Datenbuch
das passende zu meinem Ende Dezember 2012 produziertem µC.
Uwe schrieb:> Solche Dinge sind aber durch ordentliches lesen des DB durchaus> erkennbar.>
Ich hatte es schon mal erwähnt - "ordentliches" lesen reicht nicht aus,
man muss es auch verstehen ;-)
In der vergangenen Zeit habe ich versucht ein Programm auf diese
Erkenntnis hin aufzubauen, scheitere aber daran, die richtige Adresse
auszulesen.
Beitrag "ATmega8: Das Buch Kapitel TWI ( Two Wire Serial Interface )"
Bernd_Stein
Bernd S. schrieb:> Wenn ich soweit richtig durchblicke, ist das Rev.2486Z-02/11 Datenbuch> das passende zu meinem Ende Dezember 2012 produziertem µC.>
Da ich keine Antwort erhalten habe, werte ich das mal als richtig.
Jetzt wieder zu meinem Programm :
Ich verstehe nicht, warum in Hterm der twi_schritt 14 ( $E0 ) angezeigt
wird
und der X-Zeiger die Adresse $0042 hat, obwohl dieser zu Beginn mit der
Adresse (twi_status_nr_tab*2) initialisiert wird.
Im Anhang der aktuelle Kot ;-)
Bernd_Stein
Bisher sieben Downloads des Programms. Es ist wie verhext.
Da ich mir auch andere AVR8ASM-Programme bezüglich der
TWI-Interrupt-Geschichte anschaue, habe ich mir einen Trick abgeschaut,
der schon mal dafür sorgte einen Fehler mit der Hilfe des Simulators zu
finden, da ich hiermit endlich mal in die TWI-ISR springen konnte.
Ich hatte diesen Befehl auskommentiert ( siehe Screenshot ) und dadurch
wurde natürlich der X-Zeiger nicht in den Z-Zeiger kopiert.
Aber nun passiert etwas in diesem Simulator, was ich mir wieder einmal
absolut nicht erklären kann.
Bevor der letzte Befehl in der TWI-ISR ( _TWIaddr: ) ausgeführt wird (
RETI ), springt der Simulator nach dem Wiederherstellen des
CPU-Statusregisters in die Stelle des Codes, die im Anhang zu sehen ist
( Screenshot ...error_Sprungziel ).
Versteht das Jemand ?
Bernd_Stein
> Versteht das Jemand ?
Nein, von Verstehen kann meinerseits nicht die Rede sein. Nur eines
fällt mir auf: weshalb wird ZH:ZL in der TWI-ISR nicht gesichert?
Bernd_Stein schrieb:
>> Versteht das Jemand ?>>S. Landolt schrieb:> Nein, von Verstehen kann meinerseits nicht die Rede sein. Nur eines> fällt mir auf: weshalb wird ZH:ZL in der TWI-ISR nicht gesichert?>
Ich denke das kann man auch nicht verstehen. Es scheint ein kleiner Bug
zu sein, denn dies passiert auch beim Verlassen eines Unterprogramms.
Hier wird dann zum Semikolon unterhalb von *.include
"UP.inc";Unterprogramme* gesprungen bevor der RET-Befehl ausgeführt
wird.
Ich dachte es wäre unnötig den Z-Zeiger zu sichern, da er in der Main
immer neu geschrieben wird und ich ihn in der TWI-ISR praktisch im
X-Zeiger sicher.
Aber wie PeDa hier auch schrieb, sollte man sicher programmieren und es
ist ja nicht auszuschließen, das bei Programmerweiterungen doch
plötzlich ein IRQ angefordert wird, während in der Main z.B. gerade nur
der Low-Teil vom Z-Zeiger geladen wird und dieser dann in der ISR
überschrieben wird.
Deshalb habe ich jetzt natürlich in der TWI-ISR den Stack zum
kurzfristigen sichern des Z-Zeiger benutzt.
Nun zur neuen Sache. Glaube zwar nicht, das mir hier jemand
diesbezüglich helfen kann, dies ist im Moment auch nicht wichtig, da ja
eindeutig zu sehen ist, das bisher alles richtig läuft.
Aus meinen Unterlagen geht hervor, das der Wii Nunchuk mit der Bytefolge
: $A4, $40, $00 Initialisiert werden soll. Dies habe ich auch
hinbekommen, nur spinnt jetzt der Logik-Analyser ( OLS Open Workbensch
Logic Sniffer ). Er decodiert nur zwei Bytes.
Bernd_Stein
> Ich dachte es wäre unnötig den Z-Zeiger zu sichern,> da er in der Main immer neu geschrieben wird und> ich ihn in der TWI-ISR praktisch im X-Zeiger sicher.
Sie scherzen!
Was passiert, wenn innerhalb des main-Teils
1
ldi zl, LOW(_twi_schritt_tab);Adresse der TWI-Schrittsprungtabelle..
Bernd_Stein schrieb:
>> Ich dachte es wäre unnötig den Z-Zeiger zu sichern,>> da er in der Main immer neu geschrieben wird und>> ich ihn in der TWI-ISR praktisch im X-Zeiger sicher.>>S. Landolt schrieb:> Sie scherzen!> Was passiert, wenn innerhalb des main-Teils
1
>
2
> ldi zl,LOW(_twi_schritt_tab);Adresse der TWI-Schrittsprungtabelle..
> add zl,twi_schritt ;..und der jeweiligen TWI-Aktion entsprechend..
5
> adc zh,null ;..die richtige Adresse bilden zu der..
6
> ijmp ;..gesprungen wird.
7
>
> der TWI-Interrupt auftritt?>S. Landolt schrieb:> Oh, Entschuldigung, da hatte ich nicht gründlich genug gelesen; an> dieser Stelle ist der TWI-Interrupt ja gesperrt.>
Ja, genau diese Passage meinte ich, wenn nämlich das Programm geändert
wird, kann ja irgend ein IRQ zuschlagen und das führt dann zu unnötigen
Fehlern, die man durch sicherers Programmieren ausschließen kann. Du
hast also völlig Recht mit dem sichern des Z-Zeigers.
Bernd_Stein
Hallo zusammen und frohes Neues,
mittlerweile sind ja einige Monate vergangen und in letzter Zeit habe
ich mich wieder mit diesem Wii-Nunchuk und der Interruptbasierten
TWI-Programmierung dessen beschäftigt.
Wegen dem Debug-Feature *" DebugWire "* bin ich auf den ATmega88PA
umgestiegen, welcher mit mit einem 1,8432 MHz Quarz läuft und an 3,3V
betrieben wird.
Ich spreche den Nunchuk wie im Dokument des Anhangs an, wundere mich
jedoch.
1. Sowohl ein weißer, wie ein schwarzer Nunchuk, lassen sich ansprechen,
obwohl ich meine gelesen zu haben, das diese unterschiedliche
TWI-Adressen haben.
2. Aus beiden kann ich nur $FF als Daten lesen, egal wie rum ich den
Nunchuk hinlege. Es müsste sich eigentlich zumindest die X-Position
ändern.
Warum im Digramm zu DATA-READ nicht die Adresse $A5 angezeigt wird, weiß
ich nicht, muss ein Designfehler vom OLS-Programm sein, denn in der
Auflistung ( Pfeil ) wird es ja angezeigt.
Was läuft hier falsch ?
Bernd_Stein
Nachdem ich einige Beiträge gefunden habe, die auch das Problem haben,
das nur $FF aus dem Wii Nunchuk gelesen werden kann, bin ich noch auf
eine andere Dokumentation gestossen ( Siehe Anhang ). Diese erläutert
kurz, wie ein schwarzer Nunchuk zu initialisieren ist. Bei mir reagieren
wieder mal beide gleich (schwarz sowie weiß). Zusätzlich bekomme ich
auch noch Spikes, die ich mir bisher noch nicht erklären kann.
Erhalte immer die Werte $00, $A4, $20, $00, $00, $D0. Egal wie der
Nunchuk liegt.
Es ist zum Verzweifeln.
Bernd_Stein
Hier habe ich wieder eine etwas andere Erklärung, ich mache also
eigentlich alles richtig :
1. Initialize the Nunchuk:
START, 0x40, 0x00, STOP
This sequence is the normal initialization sequence, which sets the
encryption algorithm to default. Every byte which is read from the
Nunchuk must then be decrypted with (x ^ 0x17) + 0x17. A better way is
disabling encryption with this sequence:
2. Initialize the Nunchuk without encryption:
START, 0xF0, 0x55, STOP
START, 0xFB, 0x00, STOP
This has the benefit that the actual data can be used without the
decryption formula and it will work with Nunchuk-clones as well.
3. Read the device ident from extension register:
START, 0xFA, STOP
READ 6 byte
The data is the ident, which I already mentioned, if the connected
device is a Nunchuk or Classic controller and so on.
4. Read measurements from the device:
START, 0x00, STOP
READ 6 byte
https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/
Bernd_Stein
Habe nun das Problem, das über die RS232 ein Datenbyte zu wenig
angezeigt bzw. übermittelt wird.
Finde die Ursache dafür jedoch nicht.
Im OLS wird auf dem TWI-Bus folgendes *vor SLA+R* angezeigt :
START; $A4; $F0; $55 STOP
START; $A4; $FB, $00 STOP
START; $A4; $00; STOP
*SLA+R* ist im Screenshot zu sehen. Eingekreist ist die START-Bedingung.
START; $A5; $7F; $80; $3F; $7D; $17; STOP
Die ACK und den NOT-ACK habe ich bewust weggelassen, ist ja im Screeshot
zu erkennen.
Langsam wird mir klar, warum ich bisher nichts in AVR8ASM gefunden habe,
was den TWI-Interrupt nutzt, sondern immer nur das Polling von
TWCR.TWINT.
Hier der wesentliche Programmausschnitt.
Der _twi_status_check bzw. die TWI_Schritt überprüfung sind ausser
Funktion.
Endlich einen entscheidenen Schritt weiter. Nach dem der Taster einmal
betätigt wird, bekommt man die aus dem Wii Nunchuk gelesenen Daten über
die RS232 angezeigt.
Spalte 1 = X-Achse des Joysticks. Mittelwert = $7F, Links = $00, Rechts
= $FF.
Spalte 2 = Y-Achse des Joysticks. Mittelwert = $80, Zurück = $00, Vor =
$FF.
Spalte 3 = X-Achse vom Beschleunigungssensor. Mittelwert = $7F, neigen
Links = $3B, neigen Rechts = $CD
Spalte 4 = Y-Achse vom Beschleunigungssensor. Mittelwert = $7F, neigen
Zurück = $3A, neigen Vor = $C9.
Spalte 5 = Z-Achse vom Beschleunigungssensor. ?Wert = $C0.
Spalte 6 = Die beiden unteren Bits der 3 Achsen des 10Bit
-Beschleunigungssensors( jeweils Bit 1&0 ) und die Taster C & Z.
Die RS232-Aufnahme zeigt die " Neutralstellungen ".
Durch schütteln werden auch die maximal und minimal Werte des
Beschleunigungssensors erreicht ( $FF & $00 in den Spalten 3,4 und 5. )
Blöde Sache für mich, da ich dachte es wäre ein Neigungssensor
eingebaut.
Außer dem Joystick und den beiden Tastern, kann ich den
Beschleunigungssensor nur bedingt verwenden.
Ach ja, der TWI-Status Check und dementsprechend auch die
TWI-Fehlerroutinen sind zur Zeit inaktiv.
Wie kann ich auf einfache Weise das komplette AS7-Projekt hier hochladen
?
Bernd_Stein
Habe jetzt mal den weißen Nunchuk angeschlossen und seine stabile
Position zeigt folgende Werte. Stabil deshalb, da in diesem Bereich
kleine Bewegungen nicht registriert werden, es also ein Totfenster gibt.
Das ist beim schwarzen genau so. Leider ist diese Position bei dem
weißen schon nach links geneigt, so das es für mich nicht die "
Neutralstellung " einnimmt.
Das brachte mich auf die Idee, die Kalibrationsbytes, die an der
Speicheradresse $20 liegen sollen und 16 Bytes lang sein sollen, mal
auszulesen.
Der nächste Schritt soll dann das Verbiegen dieses Wertes für die
X-Achse des Beschleunigungssensors sein, damit er bei $80 oder evtl. $7F
auch seine
" Neutralstellung " hat.
Oder sollte ich gar einen anderen Wert nehmen und könnte damit
vielleicht erreichen, das links geneigt $00 ergibt und rechts geneigt
$FF ergibt ?
Bernd_Stein
Mir fehlt es jetzt erstmal an Motivation mit dem Auslesen der 16
Kalibrationsbytes weiter zu machen, da mein Erfolg ja auch gleichzeitig
einen derben Niederschlag nach sich zog, da ich ja durch blosses Bewegen
des Nunchuk keine Werte von $00 bis $FF erreiche. Somit also einen nur
sehr begrenzten Wertebereich bei diesen Bewegungen zur Verfügung habe.
Denke nun auch, das durch ändern der Kalibrationswerte dies auch nicht
erreicht werden kann. Die wenigen die dieser Thread nur noch
oberflächlich interessiert, haben davon wohl auch keine Ahnung, was ich
mit dem Ändern dieser 16 Bytes bewirken kann. Falls doch, dann ist es
jedoch unwahrscheinlich, das diese auch noch durch das von mir
geschriebene Programm durchsteigen und mir somit überhaupt richtig
helfen können.
Natürlich freue ich mich über jeden Tipp der mich weiterbringt.
Ich werde jetzt also erstmal aufarbeiten, was so gelaufen ist.
Meine Vorstellung der TWI war, das ich durch Schreiben einer 1, in das
TWI-Controlregister ( TWCR ) an der Bitposition 7 ( TWINT ), erstmal
direkt eine 1 im Simulator vorfinden würde, welche nach ein oder ein
paar wenigen Systemtakten verschwinden würde und zu diesem Zeitpunkt
z.B. die START-Bedingung auf den Bus erscheinen würde.
Da kam schon die erste Überraschung, das das ATMEL-STUDIO 7 ( AS7 ) die
TWI gar nicht simulieren kann.
Dies zu erkennen dauerte schon eine ganze Weile, da ich mich ja total
neu in den I2C-Bus eingearbeitet habe und somit noch nicht wirklich
verstanden habe, wie im einzelnen genau die TWI im µC arbeitet.
Dank S. Landolt seinem 10-Zeiler und Spess53, war dann klar das der
Simulator hierfür nicht zu gebrauchen ist.
Dann kam auch noch das Problem, das übrigens auch im Buch von Günter
Schmitt " Mikrocomputertechnik mit Controllern der Atmel
AVR-RISC-Familie " in der 4.Auflage auf der Seite 390 zum Bitratenfaktor
( TWBR ) beschrieben wird, das dieser Wert eben bei älteren
ATmega-Controllern >10 sein muss.
Was beim von mir jetzt verwendeten ATmega88PA nicht mehr der Fall ist.
Zur Sicherheit habe ich jedoch jetzt mit TWBR = 2, eine SCL-Frequenz von
92kHz verwendet, da mit 102kHz ( TWBR = 1 ), die 100kHz des I2C-Busses
um 2% überschritten würde.
Hinzu kam eine gewisse Unsicherheit mit welcher Bytefolge nun der Wii
Nunchuk zu intitialieren ist. Dank einer leider englischsprachigen
Website war nun klar warum es zwei verschiedene Versionen gab. Mir ist
die unverschlüsselte lieber. Dieser Seite habe ich es übrigens auch zu
verdanken, das ich weiß, dass es diese 16-Kalibrationsbytes gibt und
welche Bedeutung jedes einzelne Byte hat.
5. Read actual calibration data from the device
https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/
Leider gibt dieser, wohl deutschsprachige Kollege, keine eMail-Adresse
bekannt, wo ich mal meinen Dank und sicherlich auch ein paar Fragen an
ihn richten könnte.
Das Logikanalyseprogramm ( OLS ) musse ich auch erst richtig bedienen
lernen, damit ich mich nicht selbst damit verarschte.
Ein auch sehr, sehr nerviges Problem, war die RS232-Kommunikation um den
Programmablauf transparenter zu machen.
Zudem hoffte ich hier eine detailierte Erklärung zu den einzelnen
TWI-Schritten zu erhalten, da ich glaubte jemand der in AVR8ASM fitter
ist als ich und auch noch die benötigte Intelligenz besitzt sich die
einzelnen TWI-Schritte, mit der einfachen Schaltung, selbst zu
erschließen und mir genau erklären könnte was, wann passiert.
Ich brauche sogar die Pullup Widerstände nicht, da diese im Nunschuk
vorhanden sind.
Anstelle dessen gab es wie immer Unterstellungen, das das Datenbuch
nicht sorgfältig gelesen wurde und/oder es an Intelligenz hierfür
scheitert.
Meine Nunchuks haben die Platine des hier linken abgebildeten Exemplars
:
https://ardugnome.blogspot.com/2018/03/arduino-and-original-wii-nunchuck-vs_29.html
Leider ist es auch mit DebugWire im Einzelschritt nicht möglich zu
erkennen, was genau vor und nach einem Befehl in sämtlichen
TWI-Registern geschehen ist. Ich will trotzdem beschreiben, wie ich es
vermute.
Fangen wir mit der START-Bedingung an. Nach einem Reset ist das TWCR mit
$00 initialisiert. Zur Erzeugung des Startsignals, muss in diesem
Register das TWINT-Flag mit einer 1 gelöscht werden, TWSTA mit einer 1
gesetzt, mit TWEN =1, die TWI freigegeben und mit TWIE =1, der
TWI-Interrupt.
Hiernach läuft das Programm erstmal weiter. Wieviel Systemtakte genau
kann ich nicht sagen. Auf jeden Fall guckt die TWI-Hardware unabhängig
vom Programmverlauf nach, ob der Bus frei ist ( SCL & SDA = High ).
Wenn dies der Fall ist erzeugt diese das Startsignal, schreibt nach
erfolgreicher Aktion dessen ins TWSR den Wert $08 und setzt ein paar
Takte später evtl. im Gleichen, das TWINT-Flag in TWCR. Nun wird im
Programmablauf der gerade bearbeitete Befehl zu ende geführt und wie
üblich bei einem IRQ, die Adresse des darauf folgenden Befehls auf dem
Stack abgelegt.
Hierauf lädt der PC die Adresse in der Interruptverktortabelle die zu
diesem IRQ gehört. Der dort stehende Sprungbefehl springt nun zur
TWI-ISR.
Nun ist es beim TWI-Interrupt jedoch so, das das TWINT-Flag nicht
automatisch durch den Einsprung in die ISR gelöscht wird. Ich nutzte
diese Situation in meinem Programm und verhinderte den erneuten
Einsprung in die ISR bzw. ein ständigen Einsprung in diese, dadurch das
ich den TWI-Interrupt sperrte ( TWIE=0 ).
Weil es leider nicht zu ermitteln war, nach wievielen Systemtakten TWINT
durch schreiben einer 1 gelöscht wird und ich bereits nach wenigen
Systemtakten schon wieder in der Main dieses Flag auf gesetzt bzw. 1
abfragte, war also nicht klar, ob diese 1 nun durch schreiben von
TWCR.TWINT noch gesetzt war oder durch die TWI-Hardware geschah.
Deshalb bin ich in dem jetzigen Programm den Weg gegangen, das in Main
erst zum TWI-Ablauf gesprungen wird, wenn entweder der Taster betätigt
wurde oder TWEN=1 & TWIE=0 ist. Durch die Kombination TWEN=1 & TWIE=0
ist also klar, das zur TWI-ISR gesprungen wurde und nun kann zur
nächsten entsprechenden TWI-Aktion, die durch die erzeugte
Programmadresse aus _twi_ablauf: + twi_ablauf_nr, vorgegeben wird, mit
ijmp geprungen werden.
Über die TWI-Ablaufnummer ( twi_ablauf_nr ) bestimme ich also welche
TWI-Aktion ausgeführt werden soll.
Das Auslesen der Nunchukdaten bereitete mir zwei Probleme. Das erste
war, was übrigens im Programmbeispiel k4p19.asm im oben genannten Buch
zu sehen ist, das nach erzeugen von SLA+R nicht direkt TWDR eingelesen
werden darf.
Vorher ist nämlich die TWI-Aktion " Enable Acknowlege " auszuführen !!!.
Zwar nicht genau wie im Buch, denn dies erzeugt ein Not Acknowledge (
NACK ), aber mit dem zusätzlichem Setzen von TWEA ( TWI-Enable
Acknowlegde ). Also TWCR.TWINT.TWEA.TWEN.TWIE.
Zum Zweiten, das ich entweder ein Byte zu viel auf dem TWI-Bus
eingelesen habe und die Anzahl bei der RS232-Übertragung stimmte oder
die Anzahl auf dem TWI-Bus stimmte, aber in der RS232-Übertragung fehlte
das letzte einzulesende Byte. Dies war ein Programmierfehler, den ich
glücklicherweise selbst gefunden habe.
Ein weiterer Umstand, der wohl im Datenbuch ( DB ) steht ist der, das
nach der STOP-Bedingung gar nicht in die TWI-ISR bzw. das TWINT nicht
mehr von der Hardware gesetzt wird. Wie hiernach der Inhalt von TWCR ist
habe ich noch nicht überprüft.
So - und jetzt speziell zum Wii Nunchuk.
Mir ist nicht klar wie die Z-Achse zu gebrauchen ist und ob es machbar
ist, nur durch neigen des Nunchuk, die oberen 8-Bit im Bereich $00 bis
$FF nutzen zu können oder geht dies grundsätzlich nur durch
beschleunigen ( schütteln ).
Bernd_Stein
Hab mal wieder mit dem weißen Nunchuk herumexperimentiert. Auch schon
die 16 Kalibrationsbytes ab Adresse $20 ausgelesen und das erste an
Adresse $20 erfolgreich verändert. Zuerst mit $FB, später $FF.
Was ich auslas scheint jedoch nicht zu stimmen, da alle 16 Bytes $00
waren. Selbst die beiden Letzten, die ja die Checksumme bilden, blieben
$00, obwohl ich ja das erste Byte veränderte.
Noch erstaunter war ich, da ich den Nunchuk in Neutralstellung
befestigte und die 6 Positionsbytes auf einmal plausibel waren.
Zumindest die ersten Male die ich mit OLS untersuchte. Mittels RS232
konnte ich jedoch feststellen, dass auf einmal die X,X und Z-Werte des
Beschleunigungssensors ab dem 447ten Byte kippen, aber stabil bleiben.
Interessant ist, das dies auf die Bytestelle genau ( 446 )
reproduzierbar ist.
Hat hier jemals irgend wer diese 16 Kalibrationsbytes vom Wii Nunchuk
ausgelesen und kann mir schreiben, welche Werte er dort stehen hat ?
Bernd_Stein
Bearbeiten geht leider nicht mehr, deshalb hier kurz eingeschoben :
https://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck
Es scheint sich also zu bestätigen, das die minimalen und maximalen
Werte des Beschleunigungssensors nur durch schütteln zu erreichen sind.
Aber es hat ja auch noch niemand veröffentlicht, was man mit den
16 Kalibrationsbytes anstellen kann ;-)
Bernd_Stein
> Bernd S. schrieb:>> Aber es hat ja auch noch niemand veröffentlicht, was man mit den>> 16 Kalibrationsbytes anstellen kann ;-)>Dieter F. schrieb:> Das meinst auch nur Du:>> https://www.hackster.io/infusion/using-a-wii-nunchuk-with-arduino-597254>
Das hatte ich übrigens schon auf einer anderen Website gefunden und auch
hier verlinkt, aber da steht doch nur die Bedeutung dieser 16 Bytes.
Jemanden, des sich mal näher damit befasst hatte, habe ich noch nicht
gefunden. Das was ich ausgelesen hatte, kommt mir sehr suspekt vor.
https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/
Und noch was - damit wäre mir besser geholfen :
Bernd S. schrieb:> Hat hier jemals irgend wer diese 16 Kalibrationsbytes vom Wii Nunchuk> ausgelesen und kann mir schreiben, welche Werte er dort stehen hat ?>
Bernd_Stein
Auf dieser Seite konnte ich schon mal erfahren, das die
Neutralstellungswerte anscheinend bei der Beschleunigung von 1G, was
wohl der Erdanziehungskraft entspricht, angezeigt werden. Weichen etwas
von meinen ab, aber das ist ja nicht so wichtig.
Aber was ist dann 0G ?
http://rts.lab.asu.edu/web_325/CSE325_Assignment_6_F10.pdf
Bernd_Stein
Habe beim weißen Nunchuk die Adressen $20 ( OG X-Achse Bit 9:2 ) mit den
Werten $04 bis $84 in $04 Abständen beschrieben, aber dies hat keinerlei
Einfluss auf den Wert in Neutralstellung der X-Achse ( Adresse $00 ).
Diese bleibt bei $A8 stehen.
Dies ebenfalls für die Adresse $24 ( 1G X-Achse Bit 9:2 ), jedoch nur
bis zum Wert $60. Auch hier keine Änderung.
Im Foto sind die ersten 16-Byte halt die Kalibrationsbytes und die
letzten 6-Bytes die aktuellen Werte in der Neutralstellung.
Das hierzu gehörige Programm als Zip-Datei und die Abarbeitung geschieht
mittels drücken des Tasters.
Mir ist auch nicht klar, ob die Adresse nun 3-Bytes hat oder nur 2-Bytes
benötigt oder gar nur 1-Byte.
Befinden sich jetzt z.B. die aktuellen 6-Positionsbytes ab Adresse
$000000 oder $0000 und die 16-Kalibrationsbytes ab Adresse $000020 oder
$0020 oder gar $200000 bzw. $2000 oder doch nur $00 & $20, also 1-Byte ?
Antworten die hier im Thread, selbst nach Jahren noch auftauchen,
interessieren mich trotzdem, auch wenn ich es jetzt dabei belasse und
den eingeschränkten Wertebereich des Beschleunigungssensors beim Neigen
in kauf nehme.
Bernd_Stein
Hier nun der Programmstand. Mit dem schwarzen Nunchuk kann durch
links/rechts neigen ( X-Achse des Beschleunigungssensors. Spalte 3 bei
Hterm ) am PWM-Pinn OC0B ( PD5 ) die PWM in gewissen Grenzen verändert
werden. OC0A ist ein Rechteckgenerator mit 3,6kHz.
Um das Ganze zu starten, ist es nötig den Taster an PD7 einmalig zu
betätigen.
Bernd_Stein
Da der Mode 7 ( Fast PWM ) nicht optimal für eine DC-Motoransteuerung
ist, habe ich nun auf Mode 5 ( Phase Correct PWM ) umgeschwenkt.
Falls etwas bei dem TWI-Ablauf falsch läuft, wird eine Error-LED an PB5
eingeschaltet und das Programm läuft in einer Endlosschleife.
An PB4 blinkt die PLA-LED ( ProgrammLaufAnzeige ) mit ca. 1Hz.
Es darf nicht vergessen werden, den Taster an PD7 zu betätigen, damit
das Ganze läuft. Etwas länger drücken, das Entprellen ist noch nicht
optimiert.
Um den verringerten Aussteuerbereich des X-Achsenbeschleunigungssensors
auf das maximal Mögliche zu erhöhen, wird dieser Rohwert mit 1,5
multipliziert ( 384/256 ).
In Hterm ist bei " New Line at " CR+LF einstellen und alle 52 Spalten zu
nutzen, da dann in der neuen Zeile der erste Wert, des skalierten
X-Achsenwertes zu sehen ist, der an OC0B in der Timer/Counter0
Overflow-ISR ausgegeben wird ( _OVF0addr: ). Alle anderen zu sehenden
Werte sind die aufaddierten X-Achsenwerte.
Zur Zeit fliegt mir immer der L298N um die Ohren, deshalb erstmal
Programmierpause ;-)
Beitrag "Re: CRS Robotics A255 Roboterarm"
Bernd_Stein