Forum: Mikrocontroller und Digitale Elektronik AVR8ASM TWI Interrupt


von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)



Lesenswert?

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

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Ohne mich durch die Dateienflut durcharbeiten zu wollen, einfach die 
Frage: Wo wird TWEN gesetzt?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

> 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.

von Stefan F. (Gast)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

Missverständnis, Stefanus: ich dachte, Sie hätten hineingeschaut und 
vielleicht mehr gesehen als ich.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

PS:
Konkret: wo in dem 'TWI_Interrupt_2.zip' von 06:37 ist etwas zu 
"Debug-Routine ( USART-Transmit )" zu finden?

von S. Landolt (Gast)


Lesenswert?

> 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.

von S. Landolt (Gast)


Lesenswert?

PS:
Vor allem: dieser Interrupt liegt vor dem TWI-Interrupt, hat also 
höhere Priorität und folglich würde Letzterer nie ausgeführt.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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 !!!

von S. Landolt (Gast)


Lesenswert?

> 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?

von S. Landolt (Gast)


Lesenswert?

> 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?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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"

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> 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?

von Peter D. (peda)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

Auf vielfachen Wunsch (eines Einzelnen):
1
.include "m48PAdef.inc"
2
3
.org $0000
4
    rjmp    main
5
6
.org TWIaddr
7
    cbi     PORTD,2
8
    reti
9
10
main:
11
    sbi     DDRD,2  ; LED gegen Vcc
12
    sbi     PORTD,2
13
    ldi     r16,(1<<TWSTA)|(1<<TWEN)|(1<<TWIE)
14
    sts     TWCR,r16
15
    sei
16
main_loop:
17
    rjmp    main_loop

Und nein, ich schreibe das nicht für einen ATmega8 um.

Aber was fangen Sie jetzt damit an?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Nur am Rande: ein ATmega8 verlangt ein explizites Setzen des 
Stackpointers. Was aber erst beim Rücksprung aus der ISR wichtig würde.

von S. Landolt (Gast)


Lesenswert?

... oder vielleicht doch schon beim Einsprung? Was macht der Simulator, 
wenn die Rücksprungadresse bei 0 abgelegt wird?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Ich denke du sollst eine null rein schreiben.

von S. Landolt (Gast)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Ich sehe nicht, wo in Main_Test_3.asm TWINT zurückgesetzt wird. M.E. 
muss in der TWI-ISR, also irgendwo nach _TWIaddr: etwas in der Art 
stehen:
1
  in   ia,TWCR
2
  out  TWCR,ia

von c-hater (Gast)


Lesenswert?

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...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

> Grundsätzlich gebe ich dir Recht ...
> Da der Simu jedoch Fehlerhaft ist

Doppelfehler sind immer ätzend.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Florian (Gast)


Lesenswert?

Jetzt könnte Moby endlich beweisen was für ein ASM-Crack er ist! Aber 
stattdessen nicht mal ein Sabotagekommentar!

von Stefan F. (Gast)


Lesenswert?

> Jetzt könnte Moby endlich beweisen was für ein ASM-Crack er ist!

Wo siehst du denn hier einen Beitrag von Moby?

von Peter D. (peda)


Lesenswert?

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.

von Florian (Gast)


Lesenswert?

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!

von S. Landolt (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

Ist doch alles richtig. Solange kein I²C Slave antwortet, empfängt der 
µC kein ACK Signal.

von S. Landolt (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

> Übrigens, Stefanus, dass Sie den einen Beitrag von
> mir zu Anfang derart in den falschen Hals bekamen

Hä? Ich habe Dir doch zugestimmt.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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
17
18
_twi_error:
19
 ;sbi  LED_PORT,led.ok       ;OK-LED ausschalten
20
21
_exit_twiaddr:
22
 cbr  key_reg,1<<key.actuated;Tasterbetaetigung quitieren
23
 
24
 in  ia,TWCR                ;TWI-Kontroll Register lesen...
25
 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

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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
21
22
_twi_error:
23
 ;sbi  LED_PORT,led.ok       ;OK-LED ausschalten
24
25
_exit_twiaddr:
26
 cbr  key_reg,1<<key.actuated;Tasterbetaetigung quitieren
27
 
28
 out  SREG,s_sreg           ;CPU-Statusregister wiederherstellen;
29
30
 reti                       ;Ruecksprung aus der Interrupt Service Routine


Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Angehängte Dateien:

Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd S. schrieb:
> Warum wird dann dennoch weiterhin zu _TWIaddr: gesprugen ?

 Weiss ich nicht, werde später durch deinen Code durchgehen, aber das:
1
;***** Warum wird dies am Anfang gemacht ???  *****
2
 out  UDR,ia                ;Zu sendenes Zeichen in UDR hineinschreiben  
3
;***** Warum wird dies am Anfang gemacht ???  *****
4
5
 cpi  ia,#rm_twi_start      ;Wurde die Startbedingung gesendet?...
6
7
;***** Wenn ia  <> #rm_twi_start wird TWINT niemals gelöscht !!! ***
8
 brne _twi_error            ;Nein => Fehlerbehandlung noetig
9
;***** Wenn ia <> #rm_twi_start wird TWINT niemals gelöscht !!! ***
10
;***** Wenn TWINT nicht gelöscht wird, passiert WAS ? ****
11
;*****  GENAU - das, was dir passiert... *****
12
  
13
 cbi  LED_PORT,led.ok       ;...OK-LED einschalten
14
 in  ia,TWCR                ;TWI-Kontroll Register lesen...
15
 ori ia,1<<TWINT            ;...und dort das TWI-Interrupt-Flag durch...
16
 out TWCR,ia                ;...beschreiben mit einer 1 loeschen.
17
 
18
 rjmp _exit_twiaddr         ;Interrupt Service Routine ( ISR ) verlassen
19
20
_twi_error:

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

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...

von Peter D. (peda)


Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

Hier der aktuelle KOT ;-)


Bernd_Stein

von Peter D. (peda)


Lesenswert?

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.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd S. schrieb:
> Hier der aktuelle KOT ;-)

 Und ?

von Peter D. (peda)


Lesenswert?

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.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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...

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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...

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

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.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd S. schrieb:
> Hier der aktuelle KOT ;-)

 Was ist jetzt, geht es ?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

"1251" ist relevant bzgl Herstellungsdatum.
Ansonsten ist die Beschriftung im ("complete") Datenblatt erklärt.

von spess53 (Gast)


Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

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.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

PS:
Falsch formuliert, muss heißen "... das Überdecken von Fehlern".

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

>"2564B 09/2007 Removed text about TWBR needs to be higher than 10"

Auf der ATMEL-CD von 11/2007 steht steht der Satz aber noch drin.

MfG Spess

von S. Landolt (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

> 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.

von spess53 (Gast)


Lesenswert?

Hi

>Siehe Anhang, aus dem Preliminary 2545B–AVR–01/04.

Ok. Dann nehme ich das zurück.

MfG Spess

von Uwe (Gast)


Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)



Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

> 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?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von S. Landolt (Gast)


Lesenswert?

> 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..
2
 ldi  zh,HIGH(_twi_schritt_tab);..im Z-Pointer speichern..
3
 add  zl,twi_schritt        ;..und der jeweiligen TWI-Aktion entsprechend..
4
 adc  zh,null               ;..die richtige Adresse bilden zu der..
5
 ijmp                       ;..gesprungen wird.
der TWI-Interrupt auftritt?

von S. Landolt (Gast)


Lesenswert?

Oh, Entschuldigung, da hatte ich nicht gründlich genug gelesen; an 
dieser Stelle ist der TWI-Interrupt ja gesperrt.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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..
3
> ldi  zh,HIGH(_twi_schritt_tab);..im Z-Pointer speichern..
4
> 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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)



Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)



Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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.
1
;
2
;TWI-Daten lesen
3
; 
4
_twi_data_ack: 
5
 ldi  a,#cmd_twi_ack        ;Acknowlegde-Puls..
6
 sts  TWCR,a                ;..generieren
7
8
 rjmp _twi_takten           ;Den TWI-Ablauf weitertakten
9
;
10
;TWI Daten lesen und im SRAM speichern
11
; 
12
_twi_data_read:
13
 ldi  zh,HIGH(_twi_data_r)  ;..SRAM-Basisadresse.. 
14
 ldi  zl,LOW (_twi_data_r)  ;..laden..
15
 add  zl,twi_rxd            ;..und Datenempfangszeiger..
16
 adc  zh,null               ;..hinzuaddieren
17
18
 lds  twi_data,TWDR         ;TWI-Datenbyte einlesen..
19
 st   z,twi_data            ;..und ins SRAM kopieren
20
21
 rcall _warte_udre          ;TESTZWECKE ####################################################################
22
 ld   twi_data,z            ;TESTZWECKE ####################################################################
23
 sts  UDR0,twi_data         ;TESTZWECKE ####################################################################
24
25
 tst  twi_rxd               ;Daten empfangen fertig?
26
 breq _twi_nack             ;JA => springen
27
28
 dec  twi_rxd               ;Datenempfangszeiger einen weniger
29
 
30
 dec  twi_ablauf_nr         ;Acknowlegde-Puls erzeugen
31
32
 rjmp _idle                 ;Weiter im Programmlauf
33
_twi_nack: 
34
 ldi   twi_rxd,#twi_rxd_anz ;Datenempfangszeiger erneut initialisieren
35
36
 ldi  a,#cmd_twi_action     ;TWI-Aktion ausfuehren und somit ein..
37
 sts  TWCR,a              ;..NOT Acknowlede erzeugen 
38
39
 rjmp _twi_takten           ;Den TWI-Ablauf weitertakten

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hier noch eine Seite die sich ebenfalls mit der TWI und AVR8ASM 
beschäftigt, jedoch wie üblich TWINT mittels polling auswertet.

http://www.grzesina.de/avr/i2c/i2c.html

Und noch was - ein Beschleunigungssensor ist ein Neigungssensor !

https://www.youtube.com/watch?v=Y_RazJga5jw


Bernd_Stein

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

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

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Bernd S. schrieb:
> Aber es hat ja auch noch niemand veröffentlicht, was man mit den
> 16 Kalibrationsbytes anstellen kann ;-)

Das meinst auch nur Du:

https://www.hackster.io/infusion/using-a-wii-nunchuk-with-arduino-597254

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

> 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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Nur als Ergänzung.
Hatte dies auch mal gefunden ( ATXmega32A4U ), aber als nicht 
lauffähiges Programm erachtet.

https://www.mikrocontroller.net/attachment/156333/i2c.asm


Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

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

: Bearbeitet durch User
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.