Ich habe mir einen Test gebastelt, der alle WGM Modes des Timer 1
durchprobiert und die resultierenden Flags/Interrupts anzeigt. Dabei
funktioniert der WGM Mode 4 nicht wie erwartet.
Der Test setzt OCR1A=0x4000, OCR1B=0x8000, ICR1=0xC000. Am Anfang der
einzelnen Tests wird TCNT1=0 geladen. Alle T1 Interrupts sind enabled
und werden durch einen Buchstaben angezeigt, V=TOV1, A=OCF1A, B=OCF1B,
C=ICF1.
Ich konnte das Problem umgehen, indem jeder Test zunächst in den WGM
Mode 15 umschaltet und den Timer bis zum Overflow laufen lässt. Das
meiner Meinung nach korrekte Ergebnis sieht so aus:
1
Test6.0-Timer1Test,WGM:0000
2
ABVABVABVA
3
Test6.1-Timer1Test,WGM:0001
4
VVVVVVVVVV
5
Test6.2-Timer1Test,WGM:0010
6
VVVVVVVVVV
7
Test6.3-Timer1Test,WGM:0011
8
VVVVVVVVVV
9
Test6.4-Timer1Test,WGM:0100
10
AAAAAAAAAA
11
Test6.5-Timer1Test,WGM:0101
12
VVVVVVVVVV
13
Test6.6-Timer1Test,WGM:0110
14
VVVVVVVVVV
15
Test6.7-Timer1Test,WGM:0111
16
VVVVVVVVVV
17
Test6.8-Timer1Test,WGM:1000
18
ABCBAVABCB
19
Test6.9-Timer1Test,WGM:1001
20
AVAVAVAVAV
21
Test6.A-Timer1Test,WGM:1010
22
ABCBAVABCB
23
Test6.B-Timer1Test,WGM:1011
24
AVAVAVAVAV
25
Test6.C-Timer1Test,WGM:1100
26
ABCABCABCA
27
Test6.D-Timer1Test,WGM:1101
28
VBVBVBVBVB
29
Test6.E-Timer1Test,WGM:1110
30
ABVABVABVA
31
Test6.F-Timer1Test,WGM:1111
32
VVVVVVVVVV
Wenn ich den Zwischenschritt weglasse und die WGM Modes direkt
umschalte, ergibt sich im WGM Mode 4 ein sehr merkwürdiges Bild:
1
....
2
Test6.3-Timer1Test,WGM:0011
3
VVVVVVVVVV
4
Test6.4-Timer1Test,WGM:0100
5
VBBBBBBBBB
6
Test6.5-Timer1Test,WGM:0101
7
VVVVVVVVVV
8
....
Weder Overflow noch Compare Match B sollten je erreicht werden. Trotzdem
gibt es dafür Interrupts. Noch merkwürdiger ist, dass die OCR1B
Interrupts in schneller Folge kommen, als ob dieser Interrupt permanent
getriggert würde. Übrigens kommen OCR1A Interrupts wenn man OCR1B
Interrupts unterdrückt. Vermutlich werden diese aber durch den Test
nicht angezeigt, da OCR1B Priorität zu haben scheint.
Ist das ein Bug oder habe ich im Datasheet was übersehen?
Klaus 2m5 schrieb:> Ich habe mir einen Test gebastelt
[...]
Zeig' den Code, der zu diesen Testergebnissen geführt hat. Aller
Wahrscheinlichkeit nach steckt die Ursache für die Testergebnisse darin.
Da ich das richtige Ergebnis produzieren kann, geht es mir nur darum, ob
es einen Hinweis gibt, ob man beim Umschalten zwischen bestimmten WGM
Modes etwas beachten muss. Ansonsten sehe ich das als Hardware-Bug.
Klaus 2m5 schrieb:> Da ich das richtige Ergebnis produzieren kann, geht es mir nur darum, ob> es einen Hinweis gibt, ob man beim Umschalten zwischen bestimmten WGM> Modes etwas beachten muss.
Den Hinweis gibt es:
> The Compare Output mode bits do not affect the counting sequence,> while the Waveform Generation mode bits do.
Sprich: Man muß den Timer anhalten, wenn man den Modus auf eine
sichere Weise umschalten will, weil ansonsten die Sequenz eben keine
mehr ist.
Das schließt nicht aus, das bestimmte Modusumschaltungen ggf. auch nur
in bestimmten Situationen auch bei laufendem Timer korrekt funktionieren
können. Welche das genau sind und unter welchen Randbedingungen sie
funktionieren, ergibt sich aus der Analyse der unterschiedlichen
Sequenzen anhand ihrer Diagramme.
> Ansonsten sehe ich das als Hardware-Bug.
Ich sehe es als Bug deiner Software. Du wohl auch, zumindest ein wenig,
sonst würdest du dich nicht so sträuben, sie zu zeigen...
Hallo c-hater, erst mal Danke für Deine Hilfe!
c-hater schrieb:> Den Hinweis gibt es:>>> The Compare Output mode bits do not affect the counting sequence,>> while the Waveform Generation mode bits do.>> Sprich: Man muß den Timer anhalten, wenn man den Modus auf eine> sichere Weise umschalten will, weil ansonsten die Sequenz eben keine> mehr ist.
Lese ich daraus zwar nicht, habe ich aber natürlich auch schon probiert
und hilft nicht.
c-hater schrieb:>> Ansonsten sehe ich das als Hardware-Bug.>> Ich sehe es als Bug deiner Software. Du wohl auch, zumindest ein wenig,> sonst würdest du dich nicht so sträuben, sie zu zeigen...
Das ist etwas komplizierter.. Es ist ein ATMega16 basierter 6502
Emulator auf dem ein angepasstes EHBasic läuft. Das eigentliche Programm
ist in BASIC und soll die von mir gemachten Änderungen im EHBasic und
das Interrupt-Handling meines Emulators testen. Ich kann zwar das
Basic-Programm hier reinstellen, aber das ist eher trivial. Und ich
glaube nicht, dass sich jemand durch den Rest wühlen will.
Es funktioniert ja eigentlich auch alles, bis auf diesen einen WGM Mode.
Zum Umschalten der WGM Modes wird immer die gleiche FOR Schleife
benutzt. Damit wird die Luft für einen Bug in der Software schon sehr
dünn.
Nachdem ich mir den Test unter AVRASM und ohne Balast nachgebaut habe,
ergibt sich folgendes:
Wenn in einen WGM Mode mit auf 8, 9, oder 10 bit eingeschränktem Zähler
geschaltet wurde und das ICR Register und/oder die OCR Register über
diesem eingeschränkten Bereich lagen, müssen diese Register zwingend neu
geladen werden. Dann geht es auch.
Offensichtlich werden die Register intern auf die jeweilige Zählergröße
reduziert und so wird aus 0x4000, 0x8000 und 0xc000 nur noch 0x000.
Damit kommen alle Interrupts gleichzeitig anstatt nur Overflow. Habe ich
in BASIC nicht gesehen, da der Decoder sich immer alle Flags angesehen
hat und mit dem ersten gefundenen zufrieden war.
Dadurch lief auch der CTC Mode 4 nicht, weil OCR1A intern auf 0 hing.
Offensichtlich kann aber der Wechsel auf einige der Modes einen internen
Reload der Register erzwingen (nur Mode 15 getestet) und dann war alles
wieder in Butter.