Forum: Mikrocontroller und Digitale Elektronik AVR64DD32, UART-Ausgabe bleibt hängen, Assembler


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe gerade das Problem, dass die UART-Ausgabe eines kleinen 
Programms an einer Stelle hängt, wo ich mir einfach keine Ursache dafür 
vorstellen kann. Es handelt sich um folgende Funktion, die innerhalb 
einer ISR aufgerufen wird:
1
; Send 8-bit unsigned number as two hex digits.
2
; Parameter: wri0.
3
sendDbgHex:
4
  push  wri0
5
  swap  wri0
6
  andi  wri0, 0x0F
7
  rcall  sendDbgHexDigit
8
  pop    wri0
9
  push  wri0
10
  andi  wri0, 0x0F
11
  rcall  sendDbgHexDigit
12
  pop    wri0
13
  ret
14
sendDbgHexDigit:
15
  cpi    wri0, 10
16
  brlo  sendDbgHexDigit0
17
  subi  wri0, -('A'-'9'-1)
18
sendDbgHexDigit0:
19
  subi  wri0, -'0'
20
  rcall  sendDbgByte
21
  ret

Den vollständigen Code habe ich angehängt. Das Programm soll die 
ISP-Schnittstelle eines ATtiny12 simulieren (zu Testzwecken meines 
avrispv2-Programms). Nachdem diese Routine an anderen Stellen innerhalb 
der ISR problemlos ausgeführt wird, bleibt sie nach dem Aufruf in Zeile 
298 von 'main.asm' nach der Ausgabe der ersten Null hängen: PuTTY zeigt 
"Write Program Memory, byte address 0", eigentlich müssten eine zweite 
Null und weitere UART-Ausgaben folgen.

Ich sitze nun schon eine ganze Weile und gehe den Code durch, aber 
konnte bisher nichts Verdächtiges finden. Sowas wie Stackoverflow sollte 
ausgeschlossen sein, da die 8KB RAM für die paar wenigen rcall-Ebenen ja 
dicke reichen sollten. Und Interrupts können auch nicht stören, da der 
Aufruf ja bereits in einer ISR erfolgt und somit das I-Flag gelöscht 
ist.

--Johannes

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> rcall  sendDbgByte
>
>   ret

Das kann man doch schon mal durch ein "rjmp" ersetzen 😄

von S. L. (sldt)


Lesenswert?

> in einer ISR erfolgt und somit das I-Flag gelöscht ist

Das kann man so bei den AVRxt nicht sagen ...

von Johannes F. (jofe)


Lesenswert?

Niklas G. schrieb:
> Johannes F. schrieb:
>> rcall  sendDbgByte
>>
>>   ret
>
> Das kann man doch schon mal durch ein "rjmp" ersetzen 😄

Wieso? 'sendDbgByte' ist eine andere Routine, die ein Byte an USART0 
ausgibt und auch von anderen Routinen aufgerufen wird.
1
; Parameter: wri0, the byte to be sent.
2
sendDbgByte:
3
  push  wri0
4
; Make sure the transmit data registers are empty:
5
sendDbgByte0:
6
  xin    wri0, USART0_STATUS
7
  sbrs  wri0, USART_DREIF_bp
8
  rjmp  sendDbgByte0
9
  pop    wri0
10
  xout  USART0_TXDATAL, wri0
11
  ret

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
>> in einer ISR erfolgt und somit das I-Flag gelöscht ist
>
> Das kann man so bei den AVRxt nicht sagen ...

Ah, hat sich da wohl was geändert? Dann muss ich mich damit erstmal 
beschäftigen, danke für den Tipp.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> Wieso

tail-call optimization

von Veit D. (devil-elec)


Lesenswert?

Johannes F. schrieb:
> S. L. schrieb:
>>> in einer ISR erfolgt und somit das I-Flag gelöscht ist
>>
>> Das kann man so bei den AVRxt nicht sagen ...
>
> Ah, hat sich da wohl was geändert? Dann muss ich mich damit erstmal
> beschäftigen, danke für den Tipp.

Bei dieser neuen Serie(n) kann man pauschal sagen, dass die 
Interruptflags nicht mehr automatisch gelöscht werden. Man muss sie 
manuell löschen. Paar wenige Ausnahmen davon stehen im Manual. Man macht 
jedoch nichts falsch, wenn man pauschal die Flags selbst löscht.

Da ich kein Assembler kann, folgende Frage. Da ist nicht zufällig ein 
Interruptaufruf innerhalb einer ISR drin? Das darf nicht sein.

: Bearbeitet durch User
von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Habe jetzt 'cli' und 'sei' an Anfang bzw. Ende der ISRs eingefügt, 
leider besteht das Problem aber weiterhin.

von Veit D. (devil-elec)


Lesenswert?

Johannes F. schrieb:
> Habe jetzt 'cli' und 'sei' an Anfang bzw. Ende der ISRs eingefügt,
> leider besteht das Problem aber weiterhin.

Das ist Unsinn. Innerhalb einer ISR den ISR sperren und freigeben.

von Johannes F. (jofe)


Lesenswert?

Veit D. schrieb:
> Da ich kein Assembler kann, folgende Frage. Da ist nicht zufällig ein
> Interruptaufruf innerhalb einer ISR drin? Das darf nicht sein.

Was meinst du mit Interruptaufruf, einen Aufruf einer anderen ISR? Es 
werden nur 'normale' Routinen innerhalb der ISR aufgerufen, keine 
Interrupt-Routinen.

von Veit D. (devil-elec)


Lesenswert?

Johannes F. schrieb:

> Was meinst du mit Interruptaufruf, einen Aufruf einer anderen ISR? Es
> werden nur 'normale' Routinen innerhalb der ISR aufgerufen, keine
> Interrupt-Routinen.

Ok, dann sehe ich damit kein Problem.

von Johannes F. (jofe)


Lesenswert?

Veit D. schrieb:
> Das ist Unsinn. Innerhalb einer ISR den ISR sperren und freigeben.

Hmm, wieso? Ist nicht genau das hardwaremäßig bei den älteren AVRs 
passiert? Also Löschen des I-Bits beim Aufruf einer ISR und erneutes 
Setzen durch 'reti'. Damit eben eine ISR nicht durch (andere) Interrupts 
unterbrochen wird.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

beim AVR wird in die ISR gesprungen, alles komplett ohne weitere 
Unterbrechung abgearbeitet, zurück ins Hauptprogramm, und ggf. in die 
nächste ISR gesprungen wenn notwendig usw. Eine Unterbrechung einer ISR 
durch eine andere ISR gibt es beim AVR nicht. Deswegen ist das sperren 
innerhalb einer ISR ohne Effekt bzw. negativen Effekt. Andererseits kann 
innerhalb einer ISR nichts aufgerufen werden was selbst eine ISR 
benötigt.

von Johannes F. (jofe)


Lesenswert?

Veit D. schrieb:
> beim AVR wird in die ISR gesprungen, alles komplett ohne weitere
> Unterbrechung abgearbeitet, zurück ins Hauptprogramm, und ggf. in die
> nächste ISR gesprungen wenn notwendig usw.

Im Instruction Set Manual steht (Note 1, p. 113):
"In the AVRe series of devices, the Global Interrupt Enable bit is 
cleared by hardware once an interrupt occurs, and this bit is set when 
RETI is executed.
In the AVRxm and AVRxt devices, RETI will not modify the Global 
Interrupt Enable bit in SREG since it is not cleared by hardware while 
entering ISR. This bit should be modified using SEI and CLI instructions 
when needed."

Der letzte Satz klingt für mich danach, dass man eben die ISRs mit SEI 
und CLI einklammern soll, falls ISRs nicht selbst unterbrochen werden 
sollen.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

eine ISR kann sich beim AVR nicht selbst unterbrechen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Veit D. schrieb:
> Johannes F. schrieb:
>> S. L. schrieb:
>>>> in einer ISR erfolgt und somit das I-Flag gelöscht ist
>>>
>>> Das kann man so bei den AVRxt nicht sagen ...
>>
>> Ah, hat sich da wohl was geändert? Dann muss ich mich damit erstmal
>> beschäftigen, danke für den Tipp.
>
> Bei dieser neuen Serie(n) kann man pauschal sagen, dass die
> Interruptflags nicht mehr automatisch gelöscht werden.

So wie ich das lese geht's um das I-Flag im SREG, und das wird doch nach 
wie vor bei IRQ-Auslösung auf 0 gesetzt? (Und bei RETI wieder auf 1 
gesetzt?)

Oder hab ich da was verschlafen?

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Letzteres.
  Die AVRxt haben zwei Interrupt-Prioritäten ...

PS:
> I-Flag im SREG, und das wird doch nach wie vor
> bei IRQ-Auslösung auf 0 gesetzt?

Johannes F. hatte diesbezüglich bereits zitiert.

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Dann bin ich wohl, wie es aussieht, nicht der einzige, dem dieses neue 
"Feature" der Interruptauslösung nicht bewusst war – sondern befinde 
mich in bester Gesellschaft. ;·)

Dennoch scheint dies nicht die Ursache des Problems zu sein, wie ich 
bereits schrieb, denn das Klammern mit CLI/SEI brachte keine Abhilfe. 
Ich bin weiterhin auf der Suche und auf Hinweise auf mögliche 
Fehlerquellen gespannt.

von S. L. (sldt)


Lesenswert?

> Ich bin weiterhin auf der Suche

Da sind wir zu zweit - oder besser: "waren", denn ich gebe jetzt auf, 
mir fällt nichts mehr ein. Zumal das Programm ohne entsprechende 
Umgebung schlecht zu testen ist.

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Zumal das Programm ohne entsprechende
> Umgebung schlecht zu testen ist.

Ja, das stimmt leider. Vielleicht sollte das hier für mich der Anlass 
sein, mich in die Debugging-Möglichkeiten von UPDI und MPLAB-X-IDE 
hineinzufuchsen.

von Veit D. (devil-elec)


Lesenswert?

Johann L. schrieb:
> Veit D. schrieb:
>> Johannes F. schrieb:
>>> S. L. schrieb:
>>>>> in einer ISR erfolgt und somit das I-Flag gelöscht ist
>>>>
>>>> Das kann man so bei den AVRxt nicht sagen ...
>>>
>>> Ah, hat sich da wohl was geändert? Dann muss ich mich damit erstmal
>>> beschäftigen, danke für den Tipp.
>>
>> Bei dieser neuen Serie(n) kann man pauschal sagen, dass die
>> Interruptflags nicht mehr automatisch gelöscht werden.
>
> So wie ich das lese geht's um das I-Flag im SREG, und das wird doch nach
> wie vor bei IRQ-Auslösung auf 0 gesetzt? (Und bei RETI wieder auf 1
> gesetzt?)
>
> Oder hab ich da was verschlafen?

Hallo,

ähm nein, passt schon. Das I-Flag im SREG muss man selbst nicht 
behandeln. Deswegen ist das mit sei/cli innerhalb einer ISR sinnlos.
Manuell muss man nur das Interruptflag der auslösenden ISR löschen. Ganz 
pauschal bis auf sehr wenige Ausnahmen.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> In the AVRxm and AVRxt devices, RETI will not modify the Global
> Interrupt Enable bit in SREG since it is not cleared by hardware while
> entering ISR. This bit should be modified using SEI and CLI instructions
> when needed."
>
> Der letzte Satz klingt für mich danach, dass man eben die ISRs mit SEI
> und CLI einklammern soll, falls ISRs nicht selbst unterbrochen werden
> sollen.

Das würde dann doch i.W. ein neues Function Attribute erfordern, damit 
CLI die erste Instruktion in einer ISR ist und SEI die letzte?

Ansonsten, also wenn man das händisch macht, wird CLI erst nach dem 
ISR-Prolog ausgeführt, und SEI bereits for dem ISR-Epilog.

von Johannes F. (jofe)


Lesenswert?

Veit D. schrieb:
> ähm nein, passt schon. Das I-Flag im SREG muss man selbst nicht
> behandeln. Deswegen ist das mit sei/cli innerhalb einer ISR sinnlos.
> Manuell muss man nur das Interruptflag der auslösenden ISR löschen. Ganz
> pauschal bis auf sehr wenige Ausnahmen.

Sorry, aber du bist nicht mehr auf dem aktuellen Stand.

Siehe Datenblatt des AVR64DD32, S. 134; dort wird es in Satz 2 sehr 
deutlich:
"15.3.2.4 Interrupt Priority AVR64DD32/28
CPUINT - CPU Interrupt Controller
All interrupt vectors are assigned to one of three possible priority 
levels, as shown in the table below. An interrupt request from a 
high-priority source will interrupt any ongoing interrupt handler from a 
normal-priority source. When returning from the high-priority interrupt 
handler, the execution of the normal-priority interrupt handler will 
resume."

von Johannes F. (jofe)


Lesenswert?

Johann L. schrieb:
> Das würde dann doch i.W. ein neues Function Attribute erfordern, damit
> CLI die erste Instruktion in einer ISR ist und SEI die letzte?
>
> Ansonsten, also wenn man das händisch macht, wird CLI erst nach dem
> ISR-Prolog ausgeführt, und SEI bereits for dem ISR-Epilog.

In C, meinst du, oder? Wenn ich das in Assembler code, ist ja CLI dann 
die erste Instruktion nach dem Sprung zur ISR.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> Johann L. schrieb:
>> Das würde dann doch i.W. ein neues Function Attribute erfordern, damit
>> CLI die erste Instruktion in einer ISR ist und SEI die letzte?
>>
>> Ansonsten, also wenn man das händisch macht, wird CLI erst nach dem
>> ISR-Prolog ausgeführt, und SEI bereits for dem ISR-Epilog.
>
> In C, meinst du, oder? Wenn ich das in Assembler code, ist ja CLI dann
> die erste Instruktion nach dem Sprung zur ISR.

Ja, ich meine C/C++. Zum Beispiel wird
1
long x;
2
3
__attribute__((signal(1)))
4
void my_isr (void)
5
{
6
    __asm ("cli" ::: "memory");
7
    x *= x;
8
    __asm ("sei" ::: "memory");
9
}

zu:
1
0000011e <my_isr>:
2
 11e:  0f 92         push  r0
3
 120:  0f b6         in  r0, 0x3f  ; 63
4
 122:  0f 92         push  r0
5
 124:  1f 92         push  r1
6
 126:  11 24         eor  r1, r1
7
 128:  2f 93         push  r18
8
 12a:  3f 93         push  r19
9
 12c:  4f 93         push  r20
10
 12e:  5f 93         push  r21
11
 130:  6f 93         push  r22
12
 132:  7f 93         push  r23
13
 134:  8f 93         push  r24
14
 136:  9f 93         push  r25
15
 138:  af 93         push  r26
16
 13a:  bf 93         push  r27
17
 13c:  f8 94         cli <---------------------------------------
18
 13e:  60 91 34 01   lds  r22, 0x0134  ; 0x800134 <x>
19
 142:  70 91 35 01   lds  r23, 0x0135  ; 0x800135 <x+0x1>
20
 146:  80 91 36 01   lds  r24, 0x0136  ; 0x800136 <x+0x2>
21
 14a:  90 91 37 01   lds  r25, 0x0137  ; 0x800137 <x+0x3>
22
 14e:  9b 01         movw  r18, r22
23
 150:  ac 01         movw  r20, r24
24
 152:  0e 94 21 02   call  0x442  ; 0x442 <__mulsi3>
25
 156:  60 93 34 01   sts  0x0134, r22  ; 0x800134 <x>
26
 15a:  70 93 35 01   sts  0x0135, r23  ; 0x800135 <x+0x1>
27
 15e:  80 93 36 01   sts  0x0136, r24  ; 0x800136 <x+0x2>
28
 162:  90 93 37 01   sts  0x0137, r25  ; 0x800137 <x+0x3>
29
 166:  78 94         sei <---------------------------------------
30
 168:  bf 91         pop  r27
31
 16a:  af 91         pop  r26
32
 16c:  9f 91         pop  r25
33
 16e:  8f 91         pop  r24
34
 170:  7f 91         pop  r23
35
 172:  6f 91         pop  r22
36
 174:  5f 91         pop  r21
37
 176:  4f 91         pop  r20
38
 178:  3f 91         pop  r19
39
 17a:  2f 91         pop  r18
40
 17c:  1f 90         pop  r1
41
 17e:  0f 90         pop  r0
42
 180:  0f be         out  0x3f, r0  ; 63
43
 182:  0f 90         pop  r0
44
 184:  18 95         reti

von Johannes F. (jofe)


Lesenswert?

Ich denke, diese Nested Interrupts sind auch gar nicht sooo das Problem 
– vorausgesetzt, man ist sich darüber im Klaren und rettet z.B. alle 
Register (was ich ursprünglich nicht gemacht hatte, da ich eben dachte, 
es wäre in meinem Fall nicht notwendig). Daher habe ich auch die CLI/SEI 
wieder rausgenommen, nachdem ich die PUSHs/POPs ergänzt habe. Es muss an 
irgendwas anderem liegen.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

mit dem neuen Interrupt Controller haste recht, ist mir entgangen, weil 
ich die Features noch nie verwendet habe. Habe nochmal nachgelesen. Nun 
die Frage, hast du das Priority Feature eingeschalten? Ansonsten würde 
er sich wie gewohnt normal verhalten. Ohne konkreten Grund würde ich das 
nicht aktivieren.

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Pardon, ich wollte keine unnötige Diskussion lostreten, wollte nur den 
Satz, ganz am Anfang,
> in einer ISR erfolgt und somit das I-Flag gelöscht ist
nicht unkommentiert stehen lassen.
  So wie es mir schwerfällt, das TCA-Fragment im Programm nicht 
anzusprechen - führt alles beim eigentlichen Problem nicht weiter.

von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Guten Morgen,

Veit D. schrieb:
> Nun
> die Frage, hast du das Priority Feature eingeschalten? Ansonsten würde
> er sich wie gewohnt normal verhalten.

Nein, am Interrupt Controller habe ich nichts verändert, es gelten alle 
Default-Werte. Somit dürften also hier eigentlich auch keine Interrupts 
unterbrochen werden, da alle die normale Priorität haben und nur 
High-Priority-Interrupts andere unterbrechen können, wenn ich das 
Datenblatt richtig verstanden habe.

S. L. schrieb:
> Pardon, ich wollte keine unnötige Diskussion lostreten, wollte nur den
> Satz, ganz am Anfang,
>> in einer ISR erfolgt und somit das I-Flag gelöscht ist
> nicht unkommentiert stehen lassen.

Kein Problem, im Gegenteil – danke für den Hinweis, denn dadurch habe 
ich wieder etwas dazulernen dürfen.

S. L. schrieb:
> das TCA-Fragment im Programm

Das soll später dazu dienen, eine verzögerte Speicherung der zu 
schreibenden Bytes zu realisieren, damit ich das Verhalten des Data 
Polling untersuchen kann. Das bisherige Grundgerüst dürfte ja erstmal 
nicht stören, wenn ich nichts übersehen habe, da der Timer ja noch 
nirgends aktiviert wird.

P.S.: Anbei noch der geänderte Code, und ich habe noch den aktuellen 
Stand meines 'avrispv2' hinzugefügt – der ist aber noch sehr 
experimentell, bisher nur schwach getestet und kann noch grobe Fehler 
enthalten.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Johannes F. schrieb:
> Guten Morgen,
>
> Veit D. schrieb:
>> Nun
>> die Frage, hast du das Priority Feature eingeschalten? Ansonsten würde
>> er sich wie gewohnt normal verhalten.
>
> Nein, am Interrupt Controller habe ich nichts verändert, es gelten alle
> Default-Werte. Somit dürften also hier eigentlich auch keine Interrupts
> unterbrochen werden, da alle die normale Priorität haben und nur
> High-Priority-Interrupts andere unterbrechen können, wenn ich das
> Datenblatt richtig verstanden habe.

Hallo,

nein. Hier benötigt man Nerven.
Default ist, dass es keine gegenseitigen ISR Unterbrechungen gibt. Wenn 
zeitgleich mehrere Interrupts anstehen, wird zuerst der ausgeführt mit 
der höheren Priorität. Sie werden also nach Prio abgearbeitet. Dann gilt
"The lowest interrupt vector address has the highest priority." Siehe 
ioavr64dd32.h ab Zeile 6105.
Das heißt auch, dass nach Beendigung irgendeiner ISR die nächste ISR mit 
der aktuell höchsten Prio als Nächstes abgearbeitet wird. Es gibt keine 
wilden Sprünge innerhalb einer ISR zur nächsten ISR und zurück. Das ist 
Default.

von S. L. (sldt)


Lesenswert?

Wo tritt in der aktuellen Version welcher Fehler auf?

Nur Frage am Rande: was ist der Grund dafür, das Blank einmal als 
solches und  direkt im Anschluss als '20' auszugeben?
1
    ldi     wri0, ' '
2
    rcall   sendDbgByte
3
    rcall   sendDbgHex

von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

S. L. schrieb:
> Wo tritt in der aktuellen Version welcher Fehler auf?

Es ist noch derselbe Fehler; beim Versuch, einige Bytes in den 
simulierten Flash zu übertragen, bekomme ich die Ausgabe
1
SSFE
2
SSFE
3
RSB 00
4
RSB 01
5
RSB 02
6
SSFE
7
SSFE
8
RSB 00
9
RSB 01
10
RSB 02
11
CE
12
SSFE
13
RPM 0004 00
14
RPM 0005 00
15
WPM 0
und nach der letzten '0' hängt das Programm.

S. L. schrieb:
> Nur Frage am Rande: was ist der Grund dafür, das Blank einmal als
> solches und  direkt im Anschluss als '20' auszugeben?

Das war natürlich ein Fehler, danke für den Hinweis – habe es 
korrigiert, ebenso wie noch mehrere Fehler im Programm 'avrispv2', die 
sich im Zuge einer Umstrukturierung eingeschlichen hatten. Letzteres 
funktioniert nun wieder, getestet an einem ATmega88A (Lesen/Schreiben 
von Flash und EEPROM); habe es wieder mit in das ZIP-Archiv gepackt.

von S. L. (sldt)


Lesenswert?

Ich habe nun einen AVR32DD28 mit Ihrem Programm an mein 
Selbstbau-Programmiergerät angeschlossen, habe im Programm die Signatur 
auf ATmega48PA geändert, und kann so 'schreiben', ohne Hänger; das 
anschließende Verify geht schief, ist ja aber erstmal nachrangig:
1
SSFE
2
RSB 00
3
RSB 01
4
RSB 02
5
CE
6
WPM 0000 AB
7
WPM 0001 CD
8
WPM 0002 EF
9
WPM 0003 45
10
WPM 0004 FF
11
WPM 0005 FF
12
WPM 0006 FF
13
WPM 0007 FF
14
WPM 0008 FF
15
...
16
...

PS:
Also mein AVRe-'Programm' war einfach:
1
.cseg
2
.db  $AB,$CD,$EF,$45

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Ich habe nun einen AVR32DD28 mit Ihrem Programm an mein
> Selbstbau-Programmiergerät angeschlossen, habe im Programm die Signatur
> auf ATmega48PA geändert, und kann so 'schreiben', ohne Hänger;

Hmm, ist ja seltsam. Vielleicht stimmt auch mit meinem 64DD32 
irgendetwas nicht, evtl. zu heiß geworden beim Verlöten ... Einen 
Moment, ich probiere es mal mit einem anderen.

15:23 Uhr: Habe das Programm jetzt auf einem anderen Exemplar laufen, 
und bin zunächst nun auch über das scheiternde Programming Enable 
gestolpert – ich hatte vergessen, das Echo des 0x53 beim dritten 
SPI-Byte einzubauen. Seltsamerweise hat sich das auf dem ersten 64DD32 
noch nicht ausgewirkt, dort lief es ja bis zum Write Program Memory. 
Sehr seltsam ...

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Also das Schreiben funktioniert ja ansatzweise, aber der Lesevorgang 
muss grundlegend überdacht werden: der Master taktet (gnadenlos) nach 
dem dritten Byte weiter, da muss schnellstmöglich das zu liefernde Byte 
im SPI bereitgestellt werden; hier aber wird erstmal, wenn ich's richtig 
vestehe,
1
...
2
  rcall  sendDbgMsg
3
...
4
  rcall  sendDbgHex
5
...
6
  rcall  sendDbgHex
7
...
8
; Load the addressed byte and move it into SPI transmit register:
9
  ld  wri1, z
10
  xout  SPI0_DATA, wri1
Text ausgegeben.

von Johannes F. (jofe)


Lesenswert?

Ja, das ist tatsächlich problematisch, ich hatte deshalb schon im 
Master, also dem avrispv2-Programm, ein Delay zwischen den SPI-Bytes von 
einigen Millisekunden eingefügt (gesteuert über die Konstante 
SPI_INTERBYTE_DELAY_MS).

von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

So, ich habe das Programm nun auf den ATmega328P übertragen und dort zum 
Laufen gebracht. Zuvor habe ich noch einige Fehler gefunden, z.B. hatte 
ich vor dem Schreiben bzw. Lesen vom/in den SRAM vergessen, den Beginn 
des Arrays 'simFlash_sram' zum Z-Pointer zu addieren. Auf dem m328P 
funktioniert es nun; jetzt gilt es noch, das auch auf dem AVR-DD zu 
erreichen, dort hapert es noch an irgendetwas (momentan klappt das 
Programming Enable nicht, das 0x53 wird nicht zurückgegeben).

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Wieso? 'sendDbgByte' ist eine andere Routine, die ein Byte an USART0
> ausgibt und auch von anderen Routinen aufgerufen wird.

Aha! Etwa auch aus main()? Vermutlich ja schon. Wenn das so ist, dann 
ist der Fehler hier:

>
1
> sendDbgByte0:
2
> --------------------------------
3
>   xin    wri0, USART0_STATUS
4
> --------------------------------
5
>   sbrs  wri0, USART_DREIF_bp
6
>   rjmp  sendDbgByte0
7
>   pop    wri0
8
>   xout  USART0_TXDATAL, wri0
9
>

Dieser Teil des Codes ist eine "critical section", er darf nicht durch 
durch den Interrupt unterbrochen werden. Den tatsächlich kritischen 
Punkt habe ich mal durch Linien markiert. Wenn ausgerechnet während 
dieses Taktes bei der Ausführung in main() der Interrupt erfolgt, hast 
du eine klassische race condition.

Das ganze muss also "atomic" gemacht werden.

Das kostet ein zusätzliches Register, ich nenne es mal "scratch0". So 
lange du nichts am Standardverhalten von AVR8-Interrupts änderst (also 
in keiner ISR ein "sei" auftaucht und du auch die Features des 
neuzeitlichen Interruptcontrollers nicht nutzt), dann kannst du dieses 
Register global reservieren und in allen ISRs vollkommen frei nutzen, 
ohne es jeweils sichern und wiederherstellen zu müssen. Du darfst aber 
natürlich nicht davon ausgehen, dass es beim Eintritt in eine ISR 
bereits einen definierten Inhalt hat. Das ist allerdings für die 
Verwendung als "atomic"-Merker auch nicht nötig.

Der korrigierte Code würde also erst mal so aussehen:

>
1
> sendDbgByte0:
2
>   in scratch0, CPU_SREG  ;bzw. "SREG" für die klassischen AVR8
3
>   cli
4
> sendDbgByte1:
5
>   xin    wri0, USART0_STATUS
6
>   sbrs  wri0, USART_DREIF_bp
7
>   rjmp  sendDbgByte1
8
>   pop    wri0
9
>   xout  USART0_TXDATAL, wri0
10
>   out CPU_SREG, scratch0  ;bzw. "SREG" für die klassischen AVR8
11
>

Schwachsinnig bleibt der Code allerdings auch in dieser Form. Aber das 
ist dann schon ein anderes Thema, was da heißt: "howto implement 
buffered IO"...

von Karl B. (gustav)


Lesenswert?

Habe mir das Zip.file angesehen. Also mindestens 50% würde ich 
rauswerfen.
Die ganzen ifs und endifs zum Beispiel.
Dieses Programm ist offensichtlich "allgemein" geschrieben.
Besser wäre es, dies ganz gezielt auf das tatsächlich verwendete Target 
zu spezifizieren. Das ist ja  - ganz nebenbei bemerkt - das Manko bei 
ASM. Die Portierbarkeit wird erschwert, wenn nicht gar unmöglich.
Sonst wird das eigentliche Programm durch die Varietäteneventualitäten 
unnötig aufgeblasen.
Ich stolpere bereits über die ersten Zeilen:

; Devices to be supported (in future):
.equ T3227 = 0
.equ A64DD32 = 1 ; not supported yet
.equ M88A = 2 ; not supported yet
und vor allem:
.nolist
.if MCU == T3227
.include "C:\Program 
Files\Microchip\MPLABX\v6.20\packs\Microchip\ATtiny_DFP\3.1.260\avrasm\i 
nc\tn3227def.inc"
.else
.error "Device not supported yet."
.endif
.include "stk500v2-isp.inc"
.include "..\macros.inc"
.list

Was soll der Quatsch.
Unnötig aufgeblasen. Dient eher dazu, hinterher den Wald vor lauter 
Bäumen nicht mehr zu sehen

so sehen "meine" Programme aus: Etwas aufgeräumter möchte ich meinen
.nolist
.include "8535def.inc"
.list

.def temp = r16
.def temp1 = r17
.def zeit = r18
.def zeit1 = r19
.def zeit2 = r20
.def zeichen1 = r21

.equ daten = portb
.equ impuls = portb
.equ taste = pina

ciao
gustav

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Nachdem nun Experten mit an Bord sind, darf ich mich getrost 
verabschieden. Zumal ich vor der neuesten Version (von gestern abend) 
etwas ratlos sitze:

> ... das 0x53 wird nicht zurückgegeben ...
Nun sehe ich aber den ganzen Block §spiTcIsr6...9, in welchem $53 an SPI 
übergeben wird, auskommentiert; aber angeblich läuft es auf dem 
ATmega328 - wie gesagt, ich verstehe es leider nicht mehr.

von Karl B. (gustav)


Angehängte Dateien:

Lesenswert?

Aaarghh. wollte noch was ergänzen:
Schau mal hier:
Kannst Du auf SPI umschreiben.
Ist natürlich zum besseren pädagogischen Verständnis auch "aufgeblasen".

ciao
gustav

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Aha! Etwa auch aus main()? Vermutlich ja schon.

Nope. Es gibt keine 'main()', bzw. diese besteht nur aus einer leeren 
Schleife:
1
loop:
2
  rjmp  loop

'sendDbgByte' wird nur von Subroutinen aufgerufen, die ihrerseits in 
einer der beiden ISRs aufgerufen werden. Es kann also keine Race 
Condition geben, da Interrupts ja somit immer blockiert sind, wenn diese 
Routine ausgeführt wird (unter den genannten Voraussetzungen 
hinsichtlich SEI und Interrupt Controller, die hier erfüllt sind).

Ob S. schrieb:
> Schwachsinnig bleibt der Code allerdings auch in dieser Form. Aber das
> ist dann schon ein anderes Thema, was da heißt: "howto implement
> buffered IO"...

Mag sein, dass du es schwachsinnig findest; für mich sollte dieses 
Programm nur eine "schnelle" Möglichkeit des Testens von bestimmtem 
Verhalten meines avrispv2-Programms im Zusammenspiel mit avrdude sein. 
Dass man IO puffern kann bzw. i.d.R. sollte, weiß ich auch; das war mir 
aber für dieses Programm unangemessen aufwendig und unnötig.

Karl B. schrieb:
> Also mindestens 50% würde ich
> rauswerfen.
> Die ganzen ifs und endifs zum Beispiel.
> Dieses Programm ist offensichtlich "allgemein" geschrieben.
> Besser wäre es, dies ganz gezielt auf das tatsächlich verwendete Target
> zu spezifizieren.

Nö, das wäre meines Erachtens nach überhaupt nicht besser, weil ich dann 
mehrere Dateien (für jedes Device) parallel pflegen und jede Änderung am 
Ablauf überall vornehmen und synchron halten müsste. Das wäre viel 
aufwendiger als die Assembler-Direktiven.

Karl B. schrieb:
> Das ist ja  - ganz nebenbei bemerkt - das Manko bei
> ASM. Die Portierbarkeit wird erschwert, wenn nicht gar unmöglich.

Das ist Unsinn. Die meisten Unterschiede bestehen in den 
Peripherie-Einheiten der verschiedenen AVR-Serien, und diese muss man in 
C genauso unterschiedlich behandeln (z.B. Einrichten von UART, SPI, oder 
ob ein ISR-Flag manuell gelöscht werden muss oder nicht).

Karl B. schrieb:
> Was soll der Quatsch.
> Unnötig aufgeblasen. Dient eher dazu, hinterher den Wald vor lauter
> Bäumen nicht mehr zu sehen

Sorry, dass du es Quatsch findest. Mir dient es als Hilfe, für welche 
MCUs ich vorhatte, das Programm zu ergänzen, und ich selbst finde es 
auch nicht unübersichtlich.

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Zumal ich vor der neuesten Version (von gestern abend)
> etwas ratlos sitze:
>
>> ... das 0x53 wird nicht zurückgegeben ...
> Nun sehe ich aber den ganzen Block §spiTcIsr6...9, in welchem $53 an SPI
> übergeben wird, auskommentiert; aber angeblich läuft es auf dem
> ATmega328 - wie gesagt, ich verstehe es leider nicht mehr.

Mir war bewusst geworden, dass das Echo von 0x53 im dritten Byte 
automatisch passiert, da dieses einfach im SPI-DATA-Register verbleibt 
und somit wieder rausgeshiftet wird. Der auskommentierte Block ist somit 
überflüssig. Das Problem, welches mal beim Programming Enable vorhanden 
war, musste wohl ein anderes sein.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> 'sendDbgByte' wird nur von Subroutinen aufgerufen, die ihrerseits in
> einer der beiden ISRs aufgerufen werden.

Dir ist schon bewußt, dass jede dieser beiden ISRs bei der gegebenen 
Implementierung das Potential besitzt, die jeweils andere quasi "endlos" 
zu blockieren?

von Johannes F. (jofe)


Lesenswert?

Karl B. schrieb:
> I2C_Test_.asm

Wenn wir schon bei "Quatsch" waren:
1
.dseg    ; Datensegment (SRAM) Start bei 
2
.org 0x0060  ; Adresse 0x0060;           ; Konstanten-Definitionen:
3
.equ daten = portb
4
.equ zeit0 = 500
5
.equ zeit1 = 65535
6
;
Warum benutzt du nicht die Konstante SRAM_START aus 'tn4313def.inc'? 
Viel besser lesbar und weniger fehleranfällig und besser portierbar.

Und warum benutzt du nicht .byte-Direktiven und lässt die Adressen damit 
vom Assembler zuweisen? So wie es oben steht, hättest du das .dseg und 
.org auch weglassen können.
1
; Interrupt Vektoren Einsprungadressen (default)
2
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3
.org 0x0001  ; ext IRQ0 Flanke
4
rjmp INT00   
5
.org 0x0002  ; ext IRQ1 Flanke
6
rjmp INT10   
7
.org 0x0003  ; Timer 1 capt
8
rjmp ICP10
9
.....
10
WDTAD:    ; ISR not in use
11
reti
12
PCIAA:    ; ISR not in use
13
reti
14
PCIDA:    ; ISR not in use
15
reti
Und das findest du übersichtlicher als meine paar .if- und .else-Zweige?
1
ldi  temp, low(ramend)  ; Stackpointer setzen
2
out  spl, temp
3
ldi  temp, high(ramend)
4
out  sph, temp
Bei den alten AVRs sollten 16-bit-Registerpaare immer mit H zuerst 
beschrieben werden (wobei es in diesem Fall egal ist, aber besser, man 
macht es immer so).

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Dir ist schon bewußt, dass jede dieser beiden ISRs bei der gegebenen
> Implementierung das Potential besitzt, die jeweils andere quasi "endlos"
> zu blockieren?

Aber wie soll das denn passieren? Während die eine ISR ausgeführt wird, 
sind Interrupts gesperrt – die andere kann also gar nicht 
dazwischenfunken.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> Es gibt keine 'main()', bzw. diese besteht nur aus einer leeren
> Schleife:

Sollte da nicht besser ein Sleep rein um Energie zu sparen?

von Karl B. (gustav)


Lesenswert?

Johannes F. schrieb:
> Der auskommentierte Block ist somit
> überflüssig.

Also doch. Dinge die nicht nötig sind, einfach so copy- and paste-mäßig 
übernommen. Ohne Sinn und Verstand.

Johannes F. schrieb:
> Mir dient es als Hilfe, für welche
> MCUs ich vorhatte, das Programm zu ergänzen, und ich selbst finde es
> auch nicht unübersichtlich.
Es ist jedem selbst überlassen. Aber eine allgemein übliche Maxime 
sollte doch lauten:
Möglichst sparsam mit Programmspeicherplatz umgehen.
Der Geiz mit Speicherplatz zeigt sich hinterher bestimmt nicht nur 
sondern gelegentlich auch in der Performance.
(Für Pädagogikzwecke kann davon abgewichen werden.)

; ATtiny4313 memory use summary [bytes]:
; Segment   Begin    End   Code Data Used Size  Use%
;[.cseg] 0x000000 0x00080e 2026  36  2062 4096 50.3%
;[.dseg] 0x000060 0x00007b    0  27    27  256 10.5%
;[.eseg] 0x000000 0x000000    0   0     0  256  0.0%
;Assembly complete, 0 errors. 0 warnings
oder großzügiger mit der Targetauswahl umgehen.

; ATmega32U2 memory use summary [bytes]:
; Segment   Begin   End    Code Data Used  Size Use%
; [.cseg] 0x000000 0x0005f2 1430  36 1466 32768 4.5%
; [.dseg] 0x000100 0x000112    0  18   18  1024 1.8%
; [.eseg] 0x000000 0x000000    0   0    0  1024 0.0%
; Assembly complete, 0 errors. 8 warnings
Letzteres Programm ist nicht identisch mit dem für den Attiny.
Hier muss zwingend eine Anpassung nicht nur der Ansprache der Peripherie 
vorgenommen werden.
Kannst Du ja selber probieren.
Insofern relativiert sich Deine Aussage oben etwas.

Johannes F. schrieb:
> Das ist Unsinn. Die meisten Unterschiede bestehen in den
> Peripherie-Einheiten der verschiedenen AVR-Serien, und diese muss man in
> C genauso unterschiedlich behandeln

ciao
gustav

von Johannes F. (jofe)


Lesenswert?

Niklas G. schrieb:
> Sollte da nicht besser ein Sleep rein um Energie zu sparen?

Mit Energiesparmodi habe ich mich noch nicht befasst, da ich bisher 
keinen Bedarf daran hatte. Hier sollte das auch keine Rolle spielen, da 
es eh nur ein Testprogramm ist und ob der Controller nun ein paar 
Stunden lang 12 mA zieht oder nicht ...

von Johannes F. (jofe)


Lesenswert?

Karl B. schrieb:
> Johannes F. schrieb:
>> Der auskommentierte Block ist somit
>> überflüssig.
>
> Also doch. Dinge die nicht nötig sind, einfach so copy- and paste-mäßig
> übernommen. Ohne Sinn und Verstand.

Was für copy and paste? Das Programm habe ich selbst geschrieben, da 
wurde nichts kopiert.

Karl B. schrieb:
> Möglichst sparsam mit Programmspeicherplatz umgehen.
> Der Geiz mit Speicherplatz zeigt sich hinterher bestimmt nicht nur
> sondern gelegentlich auch in der Performance.

.if und .else und Co. sind Assembler-Anweisungen. Die entscheiden, ob 
der Assembler das, was dazwischen steht, assembliert oder nicht. Auf den 
Speicherplatz im Mikrocontroller hat das also überhaupt keine 
Auswirkung, weil alles, was für die Ziel-MCU nicht relevant ist, 
ignoriert wird.

Karl B. schrieb:
> Letzteres Programm ist nicht identisch mit dem für den Attiny.
> Hier muss zwingend eine Anpassung nicht nur der Ansprache der Peripherie
> vorgenommen werden.
> Kannst Du ja selber probieren.
> Insofern relativiert sich Deine Aussage oben etwas.

Keine Ahnung, was genau du damit meinst. Ich schrieb: "die meisten 
Unterschiede".

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> Mit Energiesparmodi habe ich mich noch nicht befasst, da ich bisher
> keinen Bedarf daran hatte. Hier sollte das auch keine Rolle spielen, da
> es eh nur ein Testprogramm ist

Hmm, warum schreibt man das dann in Assembler? Wenn Performance und 
Energieverbrauch egal sind, kann man auch C++ nehmen. Wenn man schon 
Assembler nutzt sollte man auch jeden letzten Takt rausquetschen, sonst 
ist der Aufwand umsonst...

von Johannes F. (jofe)


Lesenswert?

Niklas G. schrieb:
> Hmm, warum schreibt man das dann in Assembler?

Weil es einem Spaß macht und man es lernen will.

Niklas G. schrieb:
> Wenn Performance und
> Energieverbrauch egal sind

Zumindest Performance ist mir nicht egal, da versuche ich schon immer zu 
optimieren, soweit ich kann.

Ich freue mich auch immer über konstruktive Kritik. Voraussetzung ist 
natürlich, dass der Kritiker auch wirklich Ahnung von Assembler hat und 
nicht bloß an Dingen herummeckert, von denen er selbst nichts versteht 
...

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Ob S. schrieb:
>> Dir ist schon bewußt, dass jede dieser beiden ISRs bei der gegebenen
>> Implementierung das Potential besitzt, die jeweils andere quasi "endlos"
>> zu blockieren?
>
> Aber wie soll das denn passieren? Während die eine ISR ausgeführt wird,
> sind Interrupts gesperrt – die andere kann also gar nicht
> dazwischenfunken.

Eben!

Die aufgerufene Routine enthält eine Warteschleife. Solange die eine ISR 
in dieser Schleife hängt, kann die andere garantiert niemals zum Zuge 
kommen. Auch (und insbesondere dann) nicht, wenn sie eigentlich zeitnah 
ein Ereignis behandeln müsste, was mit der Debugausgabe rein garnichts 
zu schaffen hat.

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Die aufgerufene Routine enthält eine Warteschleife. Solange die eine ISR
> in dieser Schleife hängt, kann die andere garantiert niemals zum Zuge
> kommen. Auch (und insbesondere dann) nicht, wenn sie eigentlich zeitnah
> ein Ereignis behandeln müsste, was mit der Debugausgabe rein garnichts
> zu schaffen hat.

OK, ich werde das Programm nochmal mit deaktivierter Debugausgabe 
assemblieren und schauen, ob das Problem dann immer noch besteht. Damit 
müsste sich ja ggf. sagen lassen, ob es damit zusammenhängt.

Johannes F. schrieb:
> Voraussetzung ist
> natürlich, dass der Kritiker auch wirklich Ahnung von Assembler hat und
> nicht bloß an Dingen herummeckert, von denen er selbst nichts versteht
> ...

Damit war natürlich nicht der darüber zitierte Niklas G. gemeint – nur 
um das klarzustellen.

*Nachtrag:* Habe gerade festgestellt, dass ich zuletzt bereits mit 
DEBUG=0 auf dem AVR64DD32 getestet hatte, und da hat das Programm nicht 
auf das Programming Enable reagiert (avrdude meldete dabei einen Fehler, 
mein 'avrispv2' hat wohl STATUS_CMD_FAILED zurückgeliefert, was 
bedeutet, dass kein 0x53 zurückkam).

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> .if und .else und Co. sind Assembler-Anweisungen. Die entscheiden, ob
> der Assembler das, was dazwischen steht, assembliert oder nicht.

Jain. Die Funktion hast du schon richtig wiedergegeben, aber eben wegen 
dieser Funktion handelt es sich nicht um "Assembler-Anweisungen", 
sondern um "Assembler-Direktiven".

Der Unterschied ist einfach: Anweisungen sind die Dinger, die Code 
erzeugen, Direktiven sind die Dinger, die das eben nicht tun.

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Jain. Die Funktion hast du schon richtig wiedergegeben, aber eben wegen
> dieser Funktion handelt es sich nicht um "Assembler-Anweisungen",
> sondern um "Assembler-Direktiven".

Ja OK, ich meinte es in dem Sinne "Anweisungen an den Assembler", aber 
stimmt, "Direktiven" ist die passende Bezeichnung. Der Punkt, worauf ich 
hinaus wollte, war ja, dass die Verwendung von .if .elif .else zur 
Anpassung an verschiedene Ziel-MCUs eben nicht den Speicherbedarf des 
Programms erhöht, wie es behauptet wurde.

von Karl B. (gustav)


Lesenswert?

Dass das von mir als Denkanstoß gedachte Programm in der Praxis gekürzt 
und noch ausgefeilt werden kann, braucht nicht besonders betont zu 
werden.
Hatte ja oben extra darauf aufmerksam gemacht, indem ich schrieb:
Karl B. schrieb:
> Ist natürlich zum besseren pädagogischen Verständnis auch "aufgeblasen".

Ein guter Cxx-Compiler übernimmt die Aufgabe schon für Dich.
Nicht umsonst will sich kaum einer mehr sich das ASM-Programmieren 
antun.

Niklas G. schrieb:
> Hmm, warum schreibt man das dann in Assembler? Wenn Performance und
> Energieverbrauch egal sind, kann man auch C++ nehmen. Wenn man schon
> Assembler nutzt sollte man auch jeden letzten Takt rausquetschen, sonst
> ist der Aufwand umsonst...

Weils Spaß macht?
Noch ein Tip: Debugger haben auch Macken. Nutze hier die Debug Funktion 
im Build and Run-Menü. Bei Studio 4. Vielleicht reden wir hier 
aneinander vorbei. Step for Step mit F10. Bis eine Meldung kommt.
Hat nur den Nachteil, die "Peripherie" muss physisch angeschlossen sein, 
die Zeitschleifen müssen angepasst werden.
ciao
gustav

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:
> Ob S. schrieb:
>> Jain. Die Funktion hast du schon richtig wiedergegeben, aber eben wegen
>> dieser Funktion handelt es sich nicht um "Assembler-Anweisungen",
>> sondern um "Assembler-Direktiven".
>
> Ja OK, ich meinte es in dem Sinne "Anweisungen an den Assembler", aber
> stimmt, "Direktiven" ist die passende Bezeichnung. Der Punkt, worauf ich
> hinaus wollte, war ja, dass die Verwendung von .if .elif .else zur
> Anpassung an verschiedene Ziel-MCUs eben nicht den Speicherbedarf des
> Programms erhöht, wie es behauptet wurde.

Wie schon gesagt: die Funktion der Sache hast du vollkommen korrekt 
beschrieben, nur die Bezeichnung passte nicht.

Zum besseren Verständnis für die C-Only-Fraktion: .if .. .elif .. .endif 
des Atmel-Assemblers entspricht weitgehend dem C-Präprozessor-Konstrukt 
mit #if .. #elif .. #endif. Übrigens: tatsächlich kann man im 
Atmel-Assembler auch den C-Präprozessor verwenden.

Allerdings ist der eingebaute des Assemblers mächtiger, denn er kann 
Zwischenergebnisse für den zweiten Pass des Assemblers bereitstellen. 
Allerdings ist diese Nutzung auch sehr fehlerträchtig. Wenn man damit 
operiert, sollte man schon sehr genau wissen, was man tut.

Du benutzt diese erweiterten Fähigkeiten in deinem Programm aber nicht, 
es ist also diesbezüglich völlig unkritisch und könnte tatsächlich 1:1 
durch den C-Style ersetzt werden.

von Johannes F. (jofe)


Lesenswert?

Karl B. schrieb:
> Dass das von mir als Denkanstoß gedachte Programm in der Praxis gekürzt
> und noch ausgefeilt werden kann, braucht nicht besonders betont zu
> werden.

Naja, es hat halt keinen direkten Bezug zu dem Problem, um das es in 
diesem Thread geht. Aber trotzdem danke.

Karl B. schrieb:
> Ein guter Cxx-Compiler übernimmt die Aufgabe schon für Dich.
> Nicht umsonst will sich kaum einer mehr sich das ASM-Programmieren
> antun.

Ich habe allerdings auch des Öfteren schon von diversen Bugs der 
AVR-Compiler gelesen. Für mich stellt sich dann die Frage, ob bei solch 
vergleichsweise "trivialen" Programmen, mit denen ich bisher gespielt 
habe (DCF77-Empfang, LCD-Ansteuerung, Infrarot-Kommunikation etc.) der 
Aufwand, der mit einem Compiler verbunden ist (Einarbeitung in 
MCU-spezifische Spracherweiterungen wie Interrupts etc., Kontrolle des 
Assembler-Outputs im Hinblick auf Nachoptimierung und evtl. 
Compiler-Bugs etc.) überhaupt in diesen Fällen sinnvoll die Vorteile der 
Hochsprache aufwiegen würde. Dass das bei komplexeren Programmen sicher 
der Fall ist, keine Frage.

Karl B. schrieb:
> Weils Spaß macht?

Da stimme ich dir zu.

> Noch ein Tip: Debugger haben auch Macken. Nutze hier die Debug Funktion
> im Build and Run-Menü. Bei Studio 4. Vielleicht reden wir hier
> aneinander vorbei. Step for Step mit F10. Bis eine Meldung kommt.
> Hat nur den Nachteil, die "Peripherie" muss physisch angeschlossen sein,
> die Zeitschleifen müssen angepasst werden.

Ja, das mit dem IDE-gestützten Debugging habe ich mir mal vorgenommen. 
Wäre ja jetzt ein guter Anlass dazu, da ich mit dem UART-Debugging 
offensichtlich nicht weiterkomme.

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Du benutzt diese erweiterten Fähigkeiten in deinem Programm aber nicht,
> es ist also diesbezüglich völlig unkritisch und könnte tatsächlich 1:1
> durch den C-Style ersetzt werden.

Den C-Style (insb. #define) habe ich auch schon benutzt, weil dieser im 
Gegensatz zu den Assembler-Direktiven auch Fließkommarechnung 
unterstützt (war z.B. bei meinen Infrarot-Routinen vorteilhaft für die 
Präprozessor-Berechnung der Zeitkonstanten).

Insgesamt muss ich übrigens sagen, dass ich den Atmel-Assembler avrasm2 
sehr ausbaufähig finde. Wird ja auch nicht weiterentwickelt. Z.B. würde 
ich mir lokale Sprungmarken und mehr mathematische Möglichkeiten des 
Präprozessors wünschen. Für später habe ich mir vorgenommen, mal einen 
eigenen Assembler mit solchen Features zu entwickeln, dafür muss ich 
mich allerdings erstmal tiefer in die PC-Programmierung einarbeiten.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Insgesamt muss ich übrigens sagen, dass ich den Atmel-Assembler avrasm2
> sehr ausbaufähig finde. Wird ja auch nicht weiterentwickelt. Z.B. würde
> ich mir lokale Sprungmarken

Kann er. Innerhalb von Macros.

> und mehr mathematische Möglichkeiten des
> Präprozessors wünschen

Naja, das wird halt dadurch erschlagen, das man auch den C-Präprozessor 
benutzen kann.

> Für später habe ich mir vorgenommen, mal einen
> eigenen Assembler mit solchen Features zu entwickeln

Verschenkte Lebenszeit. Höchstens zu autodidaktischen Zwecken nützlich. 
Allerdings eher in Richtung "Compilerbau" als in Richtung 
"Assemblerpropgrammierung".
Was für letzteres nötig ist, ist bereits vollständig verfügbar. Sogar 
(leider) in etlichen Inkarnationen. Man braucht wahrlich nicht noch 
einen (wieder zu allen anderen inkompatiblen).

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
>> lokale Sprungmarken
> Kann er. Innerhalb von Macros.

Echt? Wo ist das denn dokumentiert? Im AVR Assembler Manual DS40001917A 
finde ich nichts darüber.

Davon abgesehen fände ich es aber auch außerhalb von Macros sehr 
wünschenswert, um z.B. sowas schreiben zu können:
1
    tst   reg0
2
{   breq  skip
3
    mov   reg0, reg1
4
skip:}
5
    ldi   reg2, 42
Also lokale Marken z.B. durch Klammern in der Gültigkeit beschränkt, wie 
lokale Variablen in C-Funktionen, damit man nicht immer einen 
übergeordneten Bezeichner voranstellen und nummerieren muss etc. Würde 
eine Menge Tipparbeit ersparen und auch die Lesbarkeit verbessern.

Ob S. schrieb:
> Verschenkte Lebenszeit. Höchstens zu autodidaktischen Zwecken nützlich.
> Allerdings eher in Richtung "Compilerbau" als in Richtung
> "Assemblerpropgrammierung".

Naja, Compilerbau ist mir dann doch zu hoch, ich habe nicht Informatik 
studiert und weiß nicht, ob ich mir die dafür nötigen Fähigkeiten jemals 
autodidaktisch aneignen kann. Interessieren würde es mich aber schon ...

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Derart Kompaktes lässt sich, so man will, als
1
   tst    reg0
2
   breq   pc+2
3
    mov    reg0, reg1
4
   ldi    reg2, 42
5
6
    rcall doit
7
    dec  reg2
8
   brne  pc-2
schreiben. Verlangt allerdings, sobald es über mehr als 2-3 Zeilen geht, 
eine hohe Disziplin bei Programmänderungen.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Davon abgesehen fände ich es aber auch außerhalb von Macros sehr
> wünschenswert, um z.B. sowas schreiben zu können:
>
1
>     tst   reg0
2
> {   breq  skip
3
>     mov   reg0, reg1
4
> skip:}
5
>     ldi   reg2, 42
6
>

Tja, sowas macht man dann halt einfach mit Makros.
1
.macro mveq
2
 tst @0
3
 breq skip
4
 mov @0, @1
5
:skip
6
.endmacro

Aus deinem ursprünglichen Code würde dann werden:
1
 mveq reg0, reg1
2
 ldi reg2, 42

Übrigens gibt es bereits etliche solcher Macros fest eingebaut im 
Assembler. Nicht zuletzt auch "tst". Das ist keine wirkliche Anweisung, 
sondern nur ein Macro mit dem Body "or @0,@0".

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Ob S. schrieb:

> :skip

Mist, der Doppelpunkt gehört natürlich an's Ende.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Ob S. schrieb:
> Ob S. schrieb:
>
>> :skip
>
> Mist, der Doppelpunkt gehört natürlich an's Ende.

Und nochmal krasser Mist: Das Macro müßte sinnvollerweise natürlich 
"mvne" heißen. Das ist jetzt aber richtig peinlich...

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Verlangt allerdings, sobald es über mehr als 2-3 Zeilen geht,
> eine hohe Disziplin bei Programmänderungen.

Ja, und man müsste auch auf die Wortlänge der Instruktionen achten, denn 
es gibt ja solche aus einem und aus zwei Worten (JMP z.B.). Das wäre mir 
persönlich dann zu fehleranfällig.

Ob S. schrieb:
> Tja, sowas macht man dann halt einfach mit Makros.

Dann muss ich aber für jeden solcher Fälle extra ein eigenes Makro 
definieren. Das macht es dann ja leider wieder ziemlich umständlich.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Dann muss ich aber für jeden solcher Fälle extra ein eigenes Makro
> definieren. Das macht es dann ja leider wieder ziemlich umständlich.

So what? Wenn du Assembler gewählt hast, hast du ganz bewußt auch die 
"Umständlichkeit" gewählt. Willst du es einfacher haben, musst du eben 
einen viel mächtigeren Makroassembler benutzen.

Sprich: Einen C-Compiler.

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Johannes F. schrieb:
>
>> Dann muss ich aber für jeden solcher Fälle extra ein eigenes Makro
>> definieren. Das macht es dann ja leider wieder ziemlich umständlich.
>
> So what? Wenn du Assembler gewählt hast, hast du ganz bewußt auch die
> "Umständlichkeit" gewählt.

Naja, man kann ja einen vernünftigen Mittelweg finden, um sich das Leben 
nicht unnötig aufwendig zu machen. Dass andere Assemblersprachen solche 
lokalen Sprungmarken auch außerhalb von Makros haben (z.B. 
Intel-Assembler, mit einem vorangestellten Doppelpunkt, AFAIRC) deutet 
ja daraufhin, dass dieser Gedanke vielleicht nicht völlig abwegig ist. 
Und ich werde auch bei meinem Ziel bleiben, mir einen eigenen Assembler 
nach meinen Vorstellungen (und für meinen eigenen Gebrauch, muss sich ja 
sonst keiner davon stören lassen) zu implementieren, weil ich es eben 
für sinnvoll und nebenbei auch eine gute Programmierübung halte.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Ich habe allerdings auch des Öfteren schon von diversen Bugs der
> AVR-Compiler gelesen. Für mich stellt sich dann die Frage, ob bei solch
> vergleichsweise "trivialen" Programmen, mit denen ich bisher gespielt
> habe (DCF77-Empfang, LCD-Ansteuerung, Infrarot-Kommunikation etc.) der
> Aufwand, der mit einem Compiler verbunden ist (Einarbeitung in
> MCU-spezifische Spracherweiterungen wie Interrupts etc., Kontrolle des
> Assembler-Outputs im Hinblick auf Nachoptimierung und evtl.
> Compiler-Bugs etc.) überhaupt in diesen Fällen sinnvoll die Vorteile der
> Hochsprache aufwiegen würde. Dass das bei komplexeren Programmen sicher
> der Fall ist, keine Frage.

Nunja, das hängt sicher davon ab, wo man herkommt und natürlich von der 
Architektur. So einfache Architekturen wie AVR8 sind auch in Asm noch 
sehr gut beherrschbar (wenn man halt den Assembler als Sprache perfekt 
beherrscht).

Ähnlich einfach sind Architekturen wie z.B. Z80, 6502, ARM-CortexM0.

Als Abgrenzung könnte man sagen: Je komplexer die im Programm zu 
verwendende Mathematik ist, desto geneigter wird man sein, eine Sprache 
zu verwenden oberhalb von Assembler.

Lustigerweise führt das aber im Umkehrschluss oft dazu: Wie weit kann 
ich eigentlich die (sehr oft nur scheinbar) nötige komplexe Mathematik 
für den konkreten Zweck vereinfachen...

Diese Überlegungen sind keinesfalls nutzlos, selbst wenn's am Ende doch 
ein C-Programm wird, wird es von diesen Überlegungen profitieren...

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Ähnlich einfach sind Architekturen wie z.B. Z80, 6502, ARM-CortexM0.

Mich reizt tatsächlich auch die Herausforderung, mich in 
Cortex-M0+-Assembler für den RP2040 einzuarbeiten. Mal sehen, ob ich in 
absehbarer Zeit dazu komme.

Ob S. schrieb:
> Als Abgrenzung könnte man sagen: Je komplexer die im Programm zu
> verwendende Mathematik ist, desto geneigter wird man sein, eine Sprache
> zu verwenden oberhalb von Assembler.

Oder man hat umgekehrt sogar Spaß daran, komplexere Rechenfunktionen für 
einfache Architekturen in Assembler zu implementieren, um sie dort 
überhaupt mit akzeptabler Effizienz nutzbar zu machen; dazu gibt es gute 
Bücher von Manfred Schwabl-Schmidt über Fließkommaarithmetik etc. auf 
AVR, die habe ich schon lange im Schrank stehen und bisher nur mal 
durchgeblättert. Ist auch ein großes Ziel von mir, mich damit mal 
eingehend zu befassen. Aber dass das nicht für jeden was ist, ist mir 
natürlich klar.

Ob S. schrieb:
> Diese Überlegungen sind keinesfalls nutzlos, selbst wenn's am Ende doch
> ein C-Programm wird, wird es von diesen Überlegungen profitieren...

Ja bestimmt, und manchmal wird ja wohl auch bei effizienzkritischen 
Programmteilen aus Assembler erzeugter Objektcode mit vom C-Compiler 
erzeugtem zusammen gelinkt. Es muss also nicht entweder–oder sein. Und 
wer sich mit Compilerbau beschäftigt, muss auch Assembler können, und 
lernen tut man das wohl nur, indem man in Assembler programmiert. Somit 
hat Assembler schon seine Berechtigung, auch vom reinen Spaß an der 
Freude mal abgesehen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> Mich reizt tatsächlich auch die Herausforderung, mich in
> Cortex-M0+-Assembler für den RP2040 einzuarbeiten.

Na dann: ARM-ASM-Tutorial. Bezieht sich allerdings auf den STM32F1, 
welcher ein Cortex-M3 ist. Der ist aber in Assembler einfacher zu 
programmieren als der M0, weil der Instruction Set des M0 ziemlich 
limitiert ist und diverse Verrenkungen benötigt. Und nach etwas 
Einarbeitung auch besser programmierbar als der AVR, weil man mit 32bit 
einfach flüssiger arbeiten kann...

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Ja bestimmt, und manchmal wird ja wohl auch bei effizienzkritischen
> Programmteilen aus Assembler erzeugter Objektcode mit vom C-Compiler
> erzeugtem zusammen gelinkt.

Der C-Compiler selber erzeugt bereits vielfach ein Konglomerat aus 
Sachen, die er wirklich aus seiner Quellsprache übersetzt und Sachen, 
die als Assemblermakros in seinem Bauch schlummern. Gerade auch im 
Mathe-Bereich stößt man ständig auf solche Asm-Fragmente. Das beweist: 
Den Compilerbauern selber ist absolut bewusst, wie suboptimal ihr 
Compiler ist.

Nur die ausschließlich biblisch besattelte "C-only-Fraktion" glaubt 
ernsthaft, dass es nicht so wäre und ihr Compiler schon von sich aus 
immer alles optimal macht.

Richtig spannend sind allerdings die Leute, die wirklich versuchen, den 
Compiler zu verbessern. Die lassen zwar einerseits öffentlich nix auf 
C/C++ kommen, kennen aber aber andererseits wenigstens selber die 
Schwächen und versuchen, sie zu verbessern (natürlich: auf dem einzig 
möglichen Weg: neue/bessere Asm-Macros).
Interessant ist das weniger aus rein technischer Sicht, sondern vor 
allem in Bezug auf deren Argumentation...
Einerseits müssen sie Asm verteufeln (denn damit könnte es ja jeder auch 
ohne den Compiler) andererseits kommen sie aber nicht darum herum, 
selber Asm zu benutzen, um den Compiler besser zu machen. Diese 
Zwangslage führt wohl zu durchaus gepaltenen Persönlichkeiten, wie man 
in einigen Einlassungen sehen kann.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Und ich werde auch bei meinem Ziel bleiben, mir einen eigenen Assembler
> nach meinen Vorstellungen (und für meinen eigenen Gebrauch, muss sich ja
> sonst keiner davon stören lassen) zu implementieren, weil ich es eben
> für sinnvoll und nebenbei auch eine gute Programmierübung halte.

Ich kann nur vom Herzen empfehlen, sich gar nicht von irgendwelchen 
Maulhelden von diesem Weg und Ziel abbringen zu lassen, denn der 
8-Bit-AVR-Assembler ist eine sehr gute Übung, von der man später bei der 
C-Programmierung sehr viel profitieren kann, sofern man unterm Strich 
wirklich eine gewisse Anzahl an Monaten intensiven, realen Schreibens 
damit verbracht hat. AVR mit 8-Bit ist die perfekte Umgebung dafür, denn 
das gewonnene Wissen und die entstandene Erfahrung wird man für sich auf 
jeden Fall auch bestens nutzen können – später wird man z.B. unter 
anderem auch sofort beurteilen können, was der Compiler für einen 
geschrieben hat und wie man das in C eventuell auch beeinflussen kann. 
Die Maulhelden dieser Welt haben oft selbst nie richtig Assembler 
geschrieben, sie haben oft auch nie eine richtige Leiterplatte entworfen 
und herstellen lassen, sie haben oft nie ein richtiges Projekt 
durchgezogen und zum Leben erweckt, insofern haben sie – die Maulhelden 
irgendwelcher Foren – nicht das Recht, andere, die es wirklich tun, zu 
kritisieren oder zu sagen, dass man es lieber lassen sollte. Sie 
„wissen” natürlich immer sofort, wie man dies und jenes „besser” machen 
sollte, die Maulhelden. Vom STM32-Assembler kann ich in diesem 
Zusammenhang nur abraten, denn hier gibt es böse Fallen und so leicht 
wie mit dem AVR-8-Bit-Assembler wird es leider nicht gehen.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Ob S. schrieb:
> natürlich: auf dem einzig möglichen Weg: neue/bessere Asm-Macros

Die Codegenerierung ist nur ein kleiner Teil des Compilers. Vorher muss 
der C/C++ Code analysiert werden, um überhaupt festzustellen welche 
Daten wann wohin fließen und auch um die Stellen zu finden, wo solche 
Snippets hin kommen können, und das ist der eigentliche Aufwand. Viele 
Ineffizienzen der Compiler beruhen darin, dass sie manche unnötige 
Instruktionen einfügen, weil sie nicht erkennen, dass sie überflüssig 
sind - aber nicht, dass dem Compiler zu wenige Assemblertricks bekannt 
wären. Ein Compiler macht eben viel mehr als nur Snippets zusammen zu 
stückeln.

Ob S. schrieb:
> Einerseits müssen sie Asm verteufeln (denn damit könnte es ja jeder auch
> ohne den Compiler)

Warum? Die Logik musst du mal erklären.

Gregor J. schrieb:
> Vom STM32-Assembler kann ich in diesem Zusammenhang nur abraten, denn
> hier gibt es böse Fallen

Einen eigenen ARM-Assembler zu implementieren ist in der Tat 
kompliziert, aber mit einem solchen Assembler zu arbeiten ist recht 
komfortabel.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Gregor J. schrieb:

> Vom STM32-Assembler kann ich in diesem
> Zusammenhang nur abraten, denn hier gibt es böse Fallen und so leicht
> wie mit dem AVR-8-Bit-Assembler wird es leider nicht gehen.

Es gibt keinen "STM32-Assembler". STM benutzt zwar ARM-Kerne, hat die 
aber nicht erfunden. Es gibt eine riesige Vielfalt von konkurrierenden 
Anbietern, die zwar allesamt ebenfalls nicht den ARM erfunden haben, 
aber gleichermaßen benutzen.

Wenn, dann gibt es einen "ARM-Assembler". Tatsächlich gibt es deutlich 
mehr als einen. Das macht die Sache zunächst scheinbar etwas 
kompliziert. Wenn man sich aber auf CortexM0(+) beschränkt, wird es 
plötzlich wieder recht einfach. Ähnlich einfach wie beim AVR8. Natürlich 
durchaus anders (ist schließlich auch eine andere Architektur), aber 
prinzipiell ist es dieselbe Soße in grün. Ist eher sogar einfacher, weil 
es nur einen Adressraum gibt, was viel von der Komplexität der AVR8 raus 
nimmt. Nunja, es gibt andererseits natürlich auch Eigenschaften, die 
Komplexität an anderer Stelle einführen, wie etwa die sehr begrenzten 
Immediate-Fähigkeiten. Ist aber beherrschbar, so wie auch die AVR8 
beherrschbar sind.

von Norbert (der_norbert)


Lesenswert?

Johannes F. schrieb:
> Mich reizt tatsächlich auch die Herausforderung, mich in
> Cortex-M0+-Assembler für den RP2040 einzuarbeiten. Mal sehen, ob ich in
> absehbarer Zeit dazu komme.

Da empfehle ich:
1
ARM and Thumb-2 Instruction Set 
2
ARM_GNU_assembler_ref
3
ARM ThumbRefCard
4
ARM v6-M Architecture Reference Manual
5
Cortex-M0+ Technical Reference Manual

Da hast du im Grunde genommen alles, was es braucht um den RP2040 zu 
programmieren.

Für den RP23xx dann noch:
1
ARM Cortex-M33 – Processor-Datasheet
2
ARM Cortex-M33 – Technical Reference Manual
3
ARM v8-M – Architecture Reference Manual

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> ich habe gerade das Problem, dass die UART-Ausgabe eines kleinen
> Programms an einer Stelle hängt, wo ich mir einfach keine Ursache dafür
> vorstellen kann.

Bevor ich hier anfange unnötig zu schreiben, vielleicht eine Frage 
vorab: funktioniert das nach Deinen Korrekturen mit der 
UART-Schnittstelle jetzt schon wie gewünscht oder besteht dieses 
ursprüngliche Problem weiterhin?

von Johannes F. (jofe)


Lesenswert?

Gregor J. schrieb:
> funktioniert das nach Deinen Korrekturen mit der
> UART-Schnittstelle jetzt schon wie gewünscht oder besteht dieses
> ursprüngliche Problem weiterhin?

Wenn ich das Programm 'tn12-isp-simulator' für den AVR64DD32 assembliere 
und flashe, funktioniert es nicht (ist aber inzwischen ein anderer 
Fehler, denn schon beim Programming-Enable-ISP-Befehl scheitert es 
dort); die angepasste Version für den ATmega328P funktioniert auf diesem 
hingegen einwandfrei.

Ich muss jetzt erstmal los, mache dann heute Abend weiter.

Bis dahin viele Grüße & einen schönen Tag an alle

von Peter D. (peda)


Lesenswert?

Johannes F. schrieb:
> Für später habe ich mir vorgenommen, mal einen
> eigenen Assembler mit solchen Features zu entwickeln

Dann würde ich die Zeit doch besser dazu nutzen, sich in C 
einzuarbeiten. Das beschleunigt das Programmieren um Größenordnungen.
Nebenbei erhöht das auch die Lesbarkeit, Wartbarkeit und Erweiterbarkeit 
drastisch.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Johannes F. schrieb:
> Ich habe allerdings auch des Öfteren schon von diversen Bugs der
> AVR-Compiler gelesen.

Ich kann mich nicht erinnern, daß ich mit sowas nennenswert Debugzeit 
verplempern mußte. Die Hauptfehlerquelle beim Programmieren sitzt immer 
vor dem Bildschirm.
Die Compiler sind inzwischen recht ausgereift. Viele benutzen sogar noch 
den alten WINAVR 2010.

von Karl B. (gustav)


Lesenswert?

Peter D. schrieb:
> Die Compiler sind inzwischen recht ausgereift. Viele benutzen sogar noch
> den alten WINAVR 2010.

Borland ist doch so ein Stichwort.

ciao
gustav

von Johannes F. (jofe)


Lesenswert?

Peter D. schrieb:
> Dann würde ich die Zeit doch besser dazu nutzen, sich in C
> einzuarbeiten. Das beschleunigt das Programmieren um Größenordnungen.
> Nebenbei erhöht das auch die Lesbarkeit, Wartbarkeit und Erweiterbarkeit
> drastisch.

Nunja, wie oben schon geschrieben, macht mir das Programmieren in 
Assembler für solch eine vergleichsweise sehr einfache Architektur wie 
AVR eben einfach mehr Spaß. Ich finde es toll genau zu wissen, wie die 
CPU mit welchen Registern arbeitet und was wo genau im Speicher liegt.

Ich verdiene auch kein Geld mit der Programmiererei, daher steht die 
Effizienz des Prozesses nicht an erster Stelle, sondern es geht mehr um 
den Spaß an der Freude. Natürlich ist es dabei dennoch von Bedeutung, 
dass auch messbare Erfolge entstehen, aber die Art und Weise, wie ich 
diese erreiche, wähle ich eben gern selbst.

Nebenbei bemerkt habe ich auch schon in C programmiert; das war die 
erste Sprache, mir der ich mich so ca. als Siebtklässler beschäftigt 
habe, ist also schon eine Weile her, aber Grundkenntnisse sind 
vorhanden.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Wenn ich das Programm 'tn12-isp-simulator' für den AVR64DD32 assembliere
> und flashe, funktioniert es nicht (ist aber inzwischen ein anderer
> Fehler, denn schon beim Programming-Enable-ISP-Befehl scheitert es
> dort); die angepasste Version für den ATmega328P funktioniert auf diesem
> hingegen einwandfrei.
> Ich muss jetzt erstmal los, mache dann heute Abend weiter.


– Programme immer nur in kleinen Zwischenschritten testen, korrigieren 
und zum Laufen bringen; einfach alles runterschreiben und erst danach 
nach Fehlern suchen, verursacht in der Regel mehr Arbeit, denn meistens 
enthält so ein runtergeschriebener Block mehrere Flüchtigkeitsfehler, 
oft auch Denkfehler, die die Funktionsweise des Programmablaufs 
betreffen; diese Vorgehensweise der kleinen Schritte gilt inbesondere 
dann, wenn Assembler geschrieben werden möchte, aber auch in C hilft 
diese sukzessive Inbetriebnahme ungemein

– wenn Peripherieteile im Projekt verwendet werden sollen, sollte man 
diese vorher so lange üben, bis man es geschafft hat, sie zum Laufen zu 
bringen, d.h.

– erstmal nur UART (ohne alles andere) richtig zum Laufen bringen, man 
kann dazu ein neues Projekt anlegen, um es dort bis zum Erfolg zu 
exerzieren

– kann man mit UART ein Byte senden, dann im nächsten Schritt das 
Absenden von mehreren Bytes üben und real testen - das Reinschreiben in 
den Sendebuffer darf immer nur mit der Flagüberprüfung erfolgen, d.h. am 
Ende des Prozesses sollte man auch in der Lage sein, auch längere 
Bytearrays per UART fehlerfrei abzuschicken

– ist auch der UART-Empfang im Projekt relevant, dann danach mit den 
Empfangtests beginnen und erst dann weitermachen, wenn auch das mit dem 
Empfang klappt

– auch alles vorher immer auf Plausibilität prüfen: CPU-Takt auf CLKOUT 
ausgeben und die Frequenz mit einem Oszilloskop nachmessen, genauso die 
UART-Baudrate z.B. anhand eines Sendebits mit dem Oszilloskop 
nachmessen, sobald man mit UART ein Byte senden kann; hier auch mit dem 
Oszilloskop schauen, ob komplette Frames versendet werden (für solche 
Testzwecke verwende ich oft Testzahlen wie 170 oder 85, also 
01010101-Muster)

– der CCP-Mechanismus ist zeitkritisch, macht/schreibt man es falsch, 
wird der Befehl von der CPU regulär abgearbeitet, intern jedoch 
ignoriert – was man umschalten wollte, bleibt unverändert; möchte man 
eine Umschaltung unter CCP als Subroutine zur Laufzeit nutzen, muss man 
für die kritische Zeit auch die Interrupts sperren

– das UART-Senden aus der Interruptroutine heraus ist generell keine 
gute Sache, vor allem dann, wenn man mehrere Bytes absenden möchte und 
z.B. zwischendurch warten muss; es sei denn, man kann programmtechnisch 
sicherstellen, dass der Sendebuffer in dem Moment nicht voll ist, man 
dort in der ISR also etwas ohne Warterei schicken (in den Buffer 
schreiben) und anschließend ohne große Verzögerung aus der ISR wieder 
verschwinden kann

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Gregor J. schrieb:
> erstmal nur UART (ohne alles andere) richtig zum Laufen bringen, man
> kann dazu ein neues Projekt anlegen, um es dort bis zum Erfolg zu
> exerzieren

Erstmal danke für deine Tipps. Also die UART-Ausgabe hatte ja zunächst 
prinzipiell auch auf dem AVR-DD funktioniert (Strings und Zahlen wurden 
korrekt gesendet), ist nur an einer für mich unerklärlichen Stelle 
hängen geblieben.

Zuletzt hatte ich aber die UART-Ausgabe komplett deaktiviert (DEBUG=0 
gesetzt), somit ist nun nur noch SPI aktiv, am UART kann es nicht mehr 
liegen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Der allerwichtigste Tip zur Fehlersuche ist natürlich: Debugger 
(JTAG/SWD/debugWIRE) verwenden. Damit kann man sehr schnell und einfach 
eine große Zahl an Fehlern finden. Insbesondere so etwas wie "Programm 
bleibt stehen" - einfach im Debugger unterbrechen wenn dies passiert ist 
und schauen, in welchem Zustand sich das Programm befindet. Damit wäre 
möglicherweise dieser ganze Thread unnötig und das Problem in Minuten 
gelöst.

Gregor J. schrieb:
> einfach alles runterschreiben und erst danach nach Fehlern suchen,
> verursacht in der Regel mehr Arbeit

Finde ich nicht unbedingt. Man kann durchaus große Programmteile "runter 
schreiben" und dann per Debugger die Fehler finden. Man muss natürlich 
noch einen Überblick über den Code haben und etwas Routine im Umgang mit 
den Debuggingtools.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Erstmal danke für deine Tipps. Also die UART-Ausgabe hatte ja zunächst
> prinzipiell auch auf dem AVR-DD funktioniert (Strings und Zahlen wurden
> korrekt gesendet), ist nur an einer für mich unerklärlichen Stelle
> hängen geblieben.

Solche liegengebliebenen ungeklärten Leichen sind nie gut für das eigene 
Verständnis und Vorankommen, denn irgendwann mal später wird man wieder 
genau an dieser unerklärlichen Stelle landen und wieder nicht 
weiterkommen. Da UART hier jetzt aber nicht relevant ist, ist es für 
diese Betrachtung erstmal egal.


> Zuletzt hatte ich aber die UART-Ausgabe komplett deaktiviert (DEBUG=0
> gesetzt), somit ist nun nur noch SPI aktiv, am UART kann es nicht mehr
> liegen.

Mit der SPI-Schnittstelle sollte man prinzipiell genauso wie mit UART 
vorgehen – bevor irgendetwas davon in einem Projekt verwendet wird, so 
lange in einem Nebenprojekt exerzieren, bis es sitzt und zu 100% 
funktioniert. Je nach Geschwindigkeit ist auch der Gebrauch des 
SPI-Sendens in einer ISR als kritisch einzustufen, wenn zwischendurch 
gewartet werden muss.

von S. L. (sldt)


Lesenswert?

> hatte ich vor dem Schreiben bzw. Lesen vom/in den
> SRAM vergessen, den Beginn des Arrays 'simFlash_sram'
> zum Z-Pointer zu addieren

Schon, aber das darf natürlich (in §spiTcIsr10 bzw. §spiTcIsr3) erst 
nach
1
; Convert the received word address to byte address:
2
  lsl    ZL
3
  rol    ZH
erfolgen.

PS:
Beim ATmega328 hebt sich der Fehler heraus (in gewissen Grenzen), aber 
beim AVR64DD32 (mit seiner hohen SRAM-Startadresse) nicht.

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> :
> Beim ATmega328 hebt sich der Fehler heraus (in gewissen Grenzen), aber
> beim AVR64DD32 (mit seiner hohen SRAM-Startadresse) nicht

Ah OK, vielen Dank für den Hinweis, das werde ich heute Nachmittag 
gleich korrigieren. Und mal das Debuggen über UPDI ausprobieren.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Und mal das Debuggen über UPDI ausprobieren.

Hast Du es noch kein einziges mal ausprobiert? Dafür ist ja die neue 
1-Pin-Schnittstelle unter anderen auch gedacht worden – ich habe das 
auch relativ zeitnah bei der Einarbeitung in den AVR128DB ausprobiert, 
allerdings unter Atmel Studio 7.

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Gregor J. schrieb:
> Hast Du es noch kein einziges mal ausprobiert?

Tatsächlich noch nicht - ich benutze auch sonst die Mplab X IDE 
lediglich zum Setzen von Fuses, ansonsten arbeite ich mit Notepad++ und 
der Kommandozeile bzw. Batchdateien.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> ich benutze auch sonst die Mplab X IDE lediglich zum Setzen von Fuses

Ich musste diese IDE zwangsläufig auch mehrere male installieren und 
benutzen, um meine Snaps mit der richtigen Firmware zu flaschen – diese 
IDE ist mit Hintergrundthreads so überladen, dass sie schlimmer als die 
STM32CubeIDE lahmt und damit für meine Wahrnehmung für normales, flottes 
Arbeiten problematisch ist; mit einem nicht besonders schnellen PC ist 
das extrem nervig und quasi nicht zu gebrauchen, was die Leute sich da 
wieder ausgedacht haben.

von Johannes F. (jofe)


Lesenswert?

Gregor J. schrieb:
> diese IDE ist mit Hintergrundthreads so überladen,

Ja, aus diesen Gründen habe ich es bisher vermieden, damit zu arbeiten. 
Aber fürs Debugging muss es wohl sein. Leider wird das von der 
Performance her wesentlich bessere Studio ja nicht mehr weiterentwickelt 
bzw. ist nicht mehr auf dem aktuellen Stand, was neuere Devices und 
Tools betrifft.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Angehängte Dateien:

Lesenswert?

Johannes F. schrieb:
> Leider wird das von der Performance her wesentlich bessere Studio ja nicht
> mehr weiterentwickelt bzw. ist nicht mehr auf dem aktuellen Stand, was
> neuere Devices und Tools betrifft.

Die ganzen neuen AVRs sind in der Finalversion des Atmel-Studios schon 
drin und den Snap braucht man nur mit der entsprchenden Firmware mittels 
MPLAB-X-IDE flaschen – da das Atmel Studio 7 keine Updates mehr erfährt, 
ist es in diesem Fall für viele Jahre sogar vorteilhaft, wenn sich da 
nichts ändert, sonst müsste man den Snap irgendwann mal wieder mit einer 
neueren Firmware nachflaschen. Auch was der Compiler generiert, ist dann 
nach einem neuen Build immer identisch, was für mich auch vorteilhaft 
ist, weil ich immer den generierten Assembler-Code auch überprüfe und 
ggfs. über entsprechende C-Anweisungen oder -schreibweise indirekt so 
modifiziere. Wenn man die Optimierungsstufe des Projekts beibehält, 
bleibt es dann auch so – wie ich es haben wollte – erhalten. Ich habe am 
Anfang über viele Jahre hinweg alles selbst in Assembler für die AVR 
geschrieben – aus Komfort- und Zeitgründen mache ich das nicht mehr, ich 
weiß aber zu jedem Zeitpunkt, was der Compiler da für eine Akrobatik 
macht, ich weiß ebenfalls, was die Leute oft für eine komische und 
völlig unnötige Akrobatik in ihren präsentierten Assemblercodes machen.

Nachtrag: Screenshot angehängt – Dein AVR ist da natürlich auch drin und 
ein Assemblerprojekt müsste dementsprechend auch gehen

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Johannes F. schrieb:
> Niklas G. schrieb:
>> Sollte da nicht besser ein Sleep rein um Energie zu sparen?
>
> Mit Energiesparmodi habe ich mich noch nicht befasst, da ich bisher
> keinen Bedarf daran hatte. Hier sollte das auch keine Rolle spielen, da
> es eh nur ein Testprogramm ist und ob der Controller nun ein paar
> Stunden lang 12 mA zieht oder nicht ...

12 mA? Also mein AVR32DD28 begnügt sich mit 2.6 mA bei 5.0 V und 20 MHz 
(korrekt konfiguriert).

"Energie sparen" bei diesem Vorhaben? Merkwürdige Idee, unter den 
gegebenen Umständen ein paar mW sparen zu wollen - als Preis dafür aber 
eine zum Teil deutliche Verlängerung der Reaktionszeit in Kauf zu 
nehmen:
1
; Interruptverzoegerung:
2
; active :  9 T mit 2.6 mA @ 5.0 V
3
; idle   : 16 T mit 1.7 mA @ 5.0 V
4
; standby: 45 T mit 0.6 mA @ 5.0 V

Und da ich gerade beim Thema bin:
1
.org PORTA_PORT_vect
2
  jmp    spiSsIsr ; SPI Slave Select ISR
3
.org TCA0_OVF_vect
4
  jmp    tcaOvfIsr
5
.org SPI0_INT_vect
6
  jmp    spiTcIsr ; SPI Transfer Complete ISR
"Zu kurz gesprungen" kann man hier wahrhaft nicht behaupten ...

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> 12 mA? Also mein AVR32DD28 begnügt sich mit 2.6 mA bei 5.0 V und 20 MHz
> (korrekt konfiguriert).

Die 12 mA hatte ich dem Datenblatt des ATmega328P entnommen, auf diesen 
bezog sich daher die Angabe.

S. L. schrieb:
> "Zu kurz gesprungen" kann man hier wahrhaft nicht behaupten ...

Vorher hatte ich hier auch RJMPs, aber im Datenbuch stehen dort 
natürlich JMPs (bei allen Devices mit mehr als 8KB Flash), daher hatte 
ich das geändert. Eigentlich ist mir zwar bewusst, dass RJMPs bei der 
von mir gewählten Art der Notation mit den einzelnen .ORG-Direktiven 
dort ebenso funktionieren müssten, aber ich wollte sichergehen.

von S. L. (sldt)


Lesenswert?

> im Datenbuch stehen dort natürlich JMPs
1
Gewöhnlich glaubt der Mensch, wenn er nur Worte hört,
2
Es müsse sich dabei doch auch was denken lassen.

Aber zugegeben, es geht in diesem Fall nur um einen einzigen Takt; das 
restliche Programm bietet ganz anderes Potenzial.

von Peter D. (peda)


Lesenswert?

Johannes F. schrieb:
> aber im Datenbuch stehen dort
> natürlich JMPs (bei allen Devices mit mehr als 8KB Flash)

Aber RJMP funktioniert auch bei denen und in beide Richtungen. Nur wenn 
die Sprungdistanz für RJMP zu groß wird, gibt es eine Fehlermeldung und 
kein Hex-File wird erzeugt.
Assemblercode >8kB zu erstellen, ist schon ne Menge und dürfte Jahre 
dauern.

von S. L. (sldt)


Lesenswert?

> Sprungdistanz für RJMP zu groß wird, gibt es eine Fehlermeldung

Eben, und dann ist immer noch Zeit, den Einzelfall zu korrigieren (oder 
zu überlegen, ob man nicht etwas umordnet).

von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Nun gut, es wurden wieder RJMPs draus.

Ich habe wieder den jetzigen Stand angehängt, und versuche mich gerade 
am Debuggen in der MPLAB X IDE. Bisher habe ich es noch nicht geschafft, 
an irgendwelche nützlichen Informationen zu gelangen. Ich habe mal einen 
Breakpoint in Zeile 190 gesetzt, aber scheinbar wird diese überhaupt 
nicht erreicht. Seltsamerweise scheint die ISR gar nicht angesprungen zu 
werden. Keine Ahnung, woran das liegen könnte. I-Flag ist gesetzt, 
SPI-IE ebenso ...

Die spiSsIsr wird dagegen ausgeführt, das "SSFE" wird zweimal 
nacheinander gesendet, so wie es sein sollte.

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

?

Läuft doch - also ich kann (mit meinem Selbstbauprogrammiergerät) 
schreiben und lesen.
1
f
2
~ 2M5  ~ 2M0  ~ 1M25 ~ 833k ~ 200k ~  50k ~  25k ~  7k7 ~ 0k95
3
4H > 0000
4
0000  0000 0000 0000 0000 0000 0000 0000 0000
5
0008  0000 0000 0000 0000 0000 0000 0000 0000
6
0010  0000 0000 0000 0000 0000 0000 0000 0000
7
0018  0000 0000 0000 0000 0000 0000 0000 0000
8
9
F
10
~ 2M5  ~ 2M0  ~ 1M25 ~ 833k ~ 200k ~  50k ~  25k ~  7k7 ~ 0k95
11
*0004 v
12
0004
13
f
14
~ 2M5  ~ 2M0  ~ 1M25 ~ 833k ~ 200k ~  50k ~  25k ~  7k7 ~ 0k95
15
4H > 0000
16
0000  2301 6745 AB89 EFCD FFFF FFFF FFFF FFFF
17
0008  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
18
0010  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
19
0018  FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
bei 'Programm':
.db  $01,$23,$45,$67,$89,$AB,$CD,$EF

von Veit D. (devil-elec)


Lesenswert?

Gregor J. schrieb:

> – das UART-Senden aus der Interruptroutine heraus ist generell keine
> gute Sache, vor allem dann, wenn man mehrere Bytes absenden möchte und
> z.B. zwischendurch warten muss; es sei denn, man kann programmtechnisch
> sicherstellen, dass der Sendebuffer in dem Moment nicht voll ist, man
> dort in der ISR also etwas ohne Warterei schicken (in den Buffer
> schreiben) und anschließend ohne große Verzögerung aus der ISR wieder
> verschwinden kann

Wenn man einen Ringbuffer hat und eine Statemaschine, dann schreibt und 
liest in/aus dem Buffer wie man lustig ist. Dann kann bspw. der "Data 
Register Empty Interrupt" dafür sorgen, dass das nächste Byte aus dem 
Ringbuffer automatisch ins Senderegister geschoben wird. Dank Interrupt 
passiert das alles im "Hintergrund" ohne künstliche Wartezeiten. Es muss 
lauten. Man muss sicherstellen das man den Ringbuffer unter Kontrolle 
hat. Dann funktioniert auch der Rest.

von S. L. (sldt)


Lesenswert?

> Läuft doch - also ich kann ...
Und wenn ich '.equ DEBUG = 0' setze (nachdem ich nach §loop '.if DEBUG 
... .endif ; DEBUG' ergänzte), wird das Ganze sogar relativ flott:
1
F
2
~ 2M5  ~ 2M0  ~ 1M25 ~ 833k ~ 200k
3
*0004 v
4
0004
5
f
6
~ 2M5  ~ 2M0  ~ 1M25 ~ 833k ~ 200k
7
4H > 0000
8
0000  2301 6745 AB89 EFCD FFFF FFFF FFFF FFFF

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Vorher hatte ich hier auch RJMPs, aber im Datenbuch stehen dort
> natürlich JMPs (bei allen Devices mit mehr als 8KB Flash), daher hatte
> ich das geändert. Eigentlich ist mir zwar bewusst, dass RJMPs bei der
> von mir gewählten Art der Notation mit den einzelnen .ORG-Direktiven
> dort ebenso funktionieren müssten, aber ich wollte sichergehen.

Wenn man mit '.org' oder NOPs auf den richtigen Offset achtet, ist es 
quasi egal, ob man relative oder absolute Sprünge nimmt, man könnte 
vermutlich auch eine Kombination aus NOP+RJMP oder CLI+RJMP nehmen, denn 
bei den AVRs handelt es sich nicht um eine echte Vektortabelle, wie man 
sie z.B. von dem 68000 oder der STM32 kennt, sondern nur um eine 
Pseudo-Vektortabelle, wo einfach der Programmcode ausgeführt wird und 
die normalen Befehle für das Laden des Programmcounters missbraucht 
werden – diese Art der Sprünge hat damals vermutlich einfach etwas Platz 
auf Siliziumebene gespart und man behielt es dann so bis heute bei den 
auch neueren Entwicklungen bei. Wenn man überhaupt keine Interrupts 
verwendet, kann man den eigentlichen Programmcode gleich ab Adresse 0 
anfangen zu schreiben – man kann die Vektortabelle auch in eine andere 
Region verlegen und hat diese Möglichkeit, ab 0 direkt mit dem Programm 
zu beginnen, dann auch zur Verfügung.

Umgekehrt geht es aber nicht, also wo explizit RJMP verlangt wird, 
einfach JMP zu platzieren, allein aufgrund der doppelten Befehlsbreite 
ist es nicht möglich – es geht aber auch schon rein physikalisch vom 
Code her nicht, denn bei den AVRs mit diesem kleinen Flashspeicher 
fehlen (angeblich) auch die absoluten Sprungbefehle im Befehlssatz. Ob 
sie wirklich im Silizium nicht abgebildet worden sind, könnte man 
bestimmt mit einigen Tests herausfinden – ist aber nur etwas für 
irgendwelche Freaks, die sich gerne mit eher unnötigen oder weniger 
wichtigen Dingen befassen.

Die Verkleinerung der Latenz der Interruptannahme um den einen Takt ist 
im Normalfall eher nicht der Rede wert, wenn man weiß, dass da sowieso 
gleich viele PUSHs folgen werden, weil man die Register incl. 
Statusregister auf dem Stack retten muss. Bei ganz speziellen 
Anwendungen könnte diese Möglichkeit der Takteinsparung oder des 
CLI-Befehl-Einschubs doch wieder interessant sein – oft ist es aber 
sinnvoller, dann bei solchen zeitkritischen Anwendungen zu einem 
anderen, deutlich schnelleren µC zu greifen, wo die CPU mit z.B. 170 
oder 550 MHz laufen kann und einige Register in diesem schnellen Takt 
auch schon selbständig auf dem Stapel ablegen tut. Wenn auch das nicht 
reicht, kann man Dinge auch rein kombinatorisch mit z.B. einer in einem 
FPGA abgebildeten Gatter-Logik realisieren und so mit der Antwort auf 
ein Ereignis auf die Nanosekundenebene runtergehen, sofern man dazu 
befähigt ist.

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Läuft doch - also ich kann (mit meinem Selbstbauprogrammiergerät)
> schreiben und lesen.

Hmm, das ist ja seltsam. Ich werde es später noch einmal mit einem 
anderen AVR64DD32 versuchen, vielleicht liegt es doch an der Hardware 
...

Nachtrag: Habe dasselbe Hex gerade auf einen anderen 64DD32 geflasht und 
bekomme beim Programming Enable das Output "AC 53 00 00 ". Dafür wird 
aber die fallende Flanke an ¬SS nicht signalisiert. Sehr seltsam. Kann 
es vielleicht wirklich sein, dass die Hitzeeinwirkung beim 
Heißluftverlöten zu hoch war, sodass manche Teilfunktionen beschädigt 
wurden? Oder betrifft sowas immer den ganzen Chip, sodass gar nichts 
mehr funktionieren würde?

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Gerade fällt mir noch ein, dass diese billigen Dupontkabelchen, die ich 
hier auch für sämtliche Verbindungen verwende, ja wohl auch teils 
Wackelkontakte verursachen sollen. Vielleicht liegt's auch daran. Werde 
heute Nachmittag noch einen Versuch mit besseren starten.

Nachtrag: Eine Platine mit 64dd28 im DIP habe ich auch noch liegen, 
darauf werde ich das Programm auch mal laufen lassen. Damit müsste sich 
ja ausschließen bzw. bestätigen lassen, dass es an den 64dd32-Exemplaren 
liegt.

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Haben Sie keine anderen? Es ist ja eine große Familie.
  Mit entsprechender CLKCTRL-Anpassung läuft es auch auf einem 
AVR32EA28, legt man das TCA-Fragment still auch auf einem AVR16EB28; von 
den DA und DB ganz zu schweigen. Und sicher klappt es auch mit einem der 
neueren ATtinies.

Allerdings halte ich ein Problem mit den Verbindungen oder der 
Stromversorgung für wahrscheinlicher.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Nachtrag: Habe dasselbe Hex gerade auf einen anderen 64DD32 geflasht und
> bekomme beim Programming Enable das Output "AC 53 00 00 ". Dafür wird
> aber die fallende Flanke an ¬SS nicht signalisiert. Sehr seltsam. Kann
> es vielleicht wirklich sein, dass die Hitzeeinwirkung beim
> Heißluftverlöten zu hoch war, sodass manche Teilfunktionen beschädigt
> wurden? Oder betrifft sowas immer den ganzen Chip, sodass gar nichts
> mehr funktionieren würde?

Wie ich bereits schrieb, man muss den/die Fehler in kleinen Schritten 
suchen – das geht auch mit einem bereits vollständig geschriebenen 
Programm prinzipiell genauso wie mit einem, das man in Schritten erst 
entstehen lässt – man legt alles unnötige durch z.B. Auskommentieren 
oder Überspringen lahm und lässt nur einen kleinen, zu untersuchenden 
Bereich des Programms für die CPU zum Abarbeiten. Wenn dieses Teil wie 
erwartet nachweislich und reproduzierbar funktioniert, gibt man einen 
weiteren Block des eigenen Codes dazu frei und prüft das dann mit der 
neuen Funktion bzw. mit dem zusätzlichen Code. Dupontkabel, 
Steckbretter, Steckverbindungen und lange Leitungen sind übrigens für 
Interrupteingänge etc. keine gute Wahl – damit macht man sich oft selbst 
unglücklich. Und externe Pull-UPs von z.B. 10kΩ können manchmal wahre 
Wunder vollbringen, bei manchen Anwendungen muss man mit dem Wert sogar 
noch weiter runtergehen. Digitalspeicheroszilloskop unbedingt benutzen, 
um sich das alles an den besagten neuralgischen Stellen genau anschauen 
zu können – das Arbeiten ohne Oszilloskop gleicht quasi der Arbeit eines 
Blinden, wo es darauf ankommt, zu schauen und zu sehen, was vor einem 
passiert.

Die Geschichte mit der Überhitzung der ICs ist sehr unwahrscheinlich, 
man versucht sich aber damit immer wieder zu trösten und quasi zu 
verdrängen, dass es an dem liegen kann, was man da selbst 
zusammengebastelt und als Code zusammengedichtet kann. Ich habe in den 
letzten 40 Jahren keinen einzigen Transistor, Diode oder IC durch Löten 
(mit dem Lötkolben) beschädigen können und bei mancher sehr häufiger, 
penetranter Hitzebearbeitung, damit das z.B. fürs Foto gut wird, hatte 
ich teilweise auch schon die Befürchtung, dass ich da jetzt vielleicht 
übertrieben habe – leider NEIN, alle µC, ICs oder sonstige Halbleiter 
haben danach ohne Probleme funktioniert. Das einzige, was ich bem Löten 
beschädigt habe, waren sogenannte intelligente SMD-LEDs WS2812 – beim 
Erhitzen konnte man durch das Fenster sehen, dass sie im Inneren 
platzten, also schlagartig undicht und so geschrottet wurden. Das waren 
aber vermutlich Fälschungen, die ich mal vor vielen, vielen Jahren auf 
Aliexpress gekauft habe, denn die Orignalteile, die ich mir später bei 
TME besorgt hatte, platzten nicht so beim Anlöten. Das Platzen dieser 
Fälschungen war übringens reproduzierbar, d.h. es war nicht nur ein IC, 
der bei der Herstellung zufällig einen Materialfehler erfahren hatte, 
sondern sie waren quasi alle so schlecht hergestellt worden.

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Haben Sie keine anderen? Es ist ja eine große Familie.

Naja, auf dem mega328P läuft es ja, und auf anderen evtl. auch, aber es 
geht mir ja im Moment eben darum, warum es auf dem 64DD32 nicht läuft, 
und da hilft es mir ja nicht weiter, wenn ich noch andere Devices 
versuche.

Die Dupontkabel habe ich eben gegen bessere (die einzelnen von Reichelt) 
ausgetauscht, ohne Erfolg, und auch ein externer Pull-Up von 2 kΩ 
brachte keine Veränderung.

Nun bin ich gerade dabei, minimale Veränderungen für den 64DD28 
vorzunehmen, und werde dann berichten, ob es auf meinem 64DD28-I/SP 
funktioniert.

: Bearbeitet durch User
Beitrag #7823434 wurde vom Autor gelöscht.
von S. L. (sldt)


Lesenswert?

> andere Devices

Ich meinte auch keine AVRe, sondern AVRxt, also 'AVRmxyn', bei denen 
keine oder nur minimale Programmänderungen nötig sind. Und wie Sie 
selbst auch bemerkten, bringt der simple Wechsel von Hardware manchmal 
neue Erkenntnisse in einer so verfahrenen Situation wie der Ihrigen.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> warum es auf dem 64DD32 nicht läuft

Vielleicht noch das: um einen Defekt an genau diesem gerade 
verwendeteten Chip auszuschließen, müsste man genau in die gleiche 
Platine und ohne irgendwelche Veränderungen einen anderen 64DD32 mit 
Heißluft etc. einlöten. Diese Änderungen gibt es aber allein schon 
aufgrund der Tatsache, dass man für den Lötvorgang z.B. irgendweche 
Leitungen abstecken muss. Das heißt, um das wiederum ausschließen zu 
können, müsste man anschließend, sofern es tatsächlich mit einem 
zweiten, identischen Chip fehlerfrei funktioniert, dann die Chips wieder 
umlöten, um zu schauen, ob es mit dem ursprünglichen IC wieder nicht 
geht. Damit hätte man zumindest eine gewisse Wahrscheinlichkeit dafür, 
dass der erste Chip eine Macke hat oder haben könnte.

Nachtrag: ich habe auch mal einen Blick ein die Errata des 64DD32 
geworfen, die scheint aber extrem kurz zu sein bzw. nur sehr wenige 
Siliziumfehler zu enthalten, d.h. da ist kaum was drin; das sieht bei 
z.B. den AVR_DB und AVR_DA ganz anders aus

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Sooo, ich habe endlich den Fehler gefunden: Dieser lag gar nicht beim 
Programm 'tn12-isp-simulator', sondern in meinem 'avrispv2', das ich zum 
Testen des ersteren benutzte. Dort hatte ich beim Einbau einer 
1-ms-Wartezeit zwischen den einzelnen SPI-Bytes (um dem ISP-Simulator 
Zeit für die Verarbeitung der Bytes zu geben, bevor das nächste 
"geclockt" wird) das Register wri0 mit 1 geladen, und übersehen, dass 
dieses zum Zwischenspeichern des empfangenen SPI-Bytes diente ... Daher 
konnte natürlich die Erkennung des Echo-0x53 nicht mehr funktionieren.

Also Asche auf mein Haupt und Entschuldigung für die Verwirrungen ... 
Ich muss mir wohl eine andere Arbeitsweise angewöhnen, zu oft nehme ich 
zu viele Änderungen gleichzeitig an zu vielen Stellen vor, ohne einzeln 
zu testen, und weiß dann nicht mehr, wo die Fehler zu suchen sind ...

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Parbleu! Und mit dem ATmega328P als Slave funktionierte alles?

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Und mit dem ATmega328P als Slave funktionierte alles?

Hmm, ja, das ist allerdings ein guter Einwand. Es ist möglich, dass ich 
die fatale Ergänzung im 'avrispv2'-Code erst danach vornahm, nachdem es 
mit dem 328P funktionierte; leider kann ich mich an die Abfolge nicht 
mehr erinnern.

Wie gesagt, ich arbeite daran, meine Arbeitsweise besser zu 
strukturieren, und werde nun erstmal das Interbyte-Delay in 'avrispv2' 
eleganter lösen, um danach mit dem Testen des ISP-Simulators fortfahren 
zu können. Denn die Signatur wurde soeben nicht korrekt gelesen, 
'avrdude' meldete
1
Device signature = 00 01 02
2
Error: expected signature for ATtiny12 is 1E 90 05

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Johannes F. schrieb:

> Nebenbei bemerkt habe ich auch schon in C programmiert; das war die
> erste Sprache

Das ist gut. Bei aller Liebe zu Asm: Wenn man im µC-Bereich unterwegs 
ist,  führt eigentlich überhaupt kein Weg daran vorbei, C zumindest 
"lesend" zu beherrschen. Das ist mindestens genauso wichtig wie 
"Datenblatt-Englisch".

"Schreibend" hingegen ist deutlich komplizierter. Selbst sehr viele 
Leute, die ausschließlich C schreiben, können es eigentlich nicht 
richtig. Witzig ist, dass Assemblerkenntnisse durchaus dabei helfen 
können, richtigen Code in C schreiben zu können.

Fakt ist: wer (irgendeinen!) Assembler wirklich kann, wird z.B. sehr 
viel seltener in C Fehler der Klassen "off-by-one" oder 
"integer-overflow" produzieren. Einfach deshalb, weil er es von Hause 
aus gewohnt ist, über derartige Problematiken überhaupt nachzudenken...

von Johannes F. (jofe)


Lesenswert?

Nach dem Einfügen des Inter-Byte-Delays funktioniert es nun endlich auch 
auf dem AVR64DD:
1
C:\Users\Johannes>avrdude -c avrispv2 -p attiny12 -P com7 -v -U flash:w:"D:\temp\10B.hex":i
2
Avrdude version 8.0
3
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS
4
5
System wide configuration file is C:\Users\Johannes\AppData\Local\Programs\avrdude\avrdude.conf
6
7
Using port            : com7
8
Using programmer      : avrispv2
9
AVR part              : ATtiny12
10
Programming modes     : ISP, HVSP
11
Programmer type       : STK500V2
12
Description           : Serial Atmel AVR ISP using STK500v2
13
Programmer model      : AVRISP
14
HW version            : 0
15
FW Version Controller : 0.00
16
SCK period            : 0.1 us
17
18
AVR device initialized and ready to accept instructions
19
Device signature = 1E 90 05 (ATtiny12)
20
Auto-erasing chip as flash memory needs programming (-U flash:w:...)
21
specify the -D option to disable this feature
22
Erased chip
23
Reading 10 bytes for flash from input file 10B.hex
24
in 1 section [0, 9]: 5 pages and 0 pad bytes
25
Writing 10 bytes to flash
26
Writing | ################################################## | 100% 0.16 s
27
Reading | ################################################## | 100% 0.09 s
28
10 bytes of flash verified
29
30
Avrdude done.  Thank you.

Damit ist das Eröffnungsproblem dieses Threads endlich gelöst 
(ursprünglich wird es sicher eine Folge des vergessenen bzw. falsch 
platzierten RAM-Offsets gewesen sein) und ich danke herzlich allen für 
die Ratschläge und Hilfe.

Nun kann ich mich weiter der Untersuchung des Flash-Value-Polling im 
Zusammenspiel von avrdude, STK500v2 und AVRs ohne RDY/BSY-ISP-Befehl wie 
ATtiny12 zur Vervollständigung meines avrispv2-Programms widmen.

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Das ist gut. Bei aller Liebe zu Asm: Wenn man im µC-Bereich unterwegs
> ist,  führt eigentlich überhaupt kein Weg daran vorbei, C zumindest
> "lesend" zu beherrschen. Das ist mindestens genauso wichtig wie
> "Datenblatt-Englisch".

Ja, ich habe mir nun auch vorgenommen, mich mal in "Embedded-C" für AVRs 
einzuarbeiten, zunächst mit AVR-GCC oder dem Microchip XC8, da muss ich 
noch schauen, für was ich mich entscheide (Empfehlungen wären 
willkommen). Kann ja nicht schaden, auch wenn ich für AVRs mich 
weiterhin in Assembler vertiefen werde.

Ob S. schrieb:
> Fakt ist: wer (irgendeinen!) Assembler wirklich kann, wird z.B. sehr
> viel seltener in C Fehler der Klassen "off-by-one" oder
> "integer-overflow" produzieren. Einfach deshalb, weil er es von Hause
> aus gewohnt ist, über derartige Problematiken überhaupt nachzudenken...

Ja, das kann ich mir gut vorstellen.

von S. L. (sldt)


Lesenswert?

> ursprünglich wird es sicher eine Folge des vergessenen
> bzw. falsch platzierten RAM-Offsets gewesen sein

Na, da muss ich jetzt aber doch den Bömmel zitieren: "Mer wolle uns nix 
weismache" - schließlich lautet der Betreff "... UART-Ausgabe bleibt 
hängen ...", und zwar mitten in einer Hex-Ausgabe.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

S. L. schrieb:
>> ursprünglich wird es sicher eine Folge des vergessenen
>> bzw. falsch platzierten RAM-Offsets gewesen sein
>
> Na, da muss ich jetzt aber doch den Bömmel zitieren: "Mer wolle uns nix
> weismache" - schließlich lautet der Betreff "... UART-Ausgabe bleibt
> hängen ...", und zwar mitten in einer Hex-Ausgabe.

Ja, der Delinquent hat ziemlich sicher das eigentliche Problem nicht 
gefunden. Die beste Näherung war wohl:

> zu oft nehme ich
> zu viele Änderungen gleichzeitig an zu vielen Stellen vor, ohne einzeln
> zu testen, und weiß dann nicht mehr, wo die Fehler zu suchen sind ...

Ist aber ganz grundsätzlich auch viel schwieriger, wenn es mehr als ein 
Programm gibt, sondern zwei auf zwei MCUs, die miteinander hakeln 
sollen. Da hilft nur Disziplin und Debug-Erfahrung.

Aber gewinnen kann man diese Debug-Erfahrung halt nur, indem man es tut. 
Ich denke, ihm ist zumindest klar geworden, dass er es unbedingt 
systematischer tun muss.

von Johannes F. (jofe)


Lesenswert?

Ob S. schrieb:
> Ja, der Delinquent hat ziemlich sicher das eigentliche Problem nicht
> gefunden.

Scheint so, denn momentan (nach dem Wechsel zurück zum 64DD32) habe ich 
wieder das Problem, dass beim Programming Enable nur Nullen empfangen 
werden (nachdem es auf dem 64DD28 funktioniert hat):
1
Received command SIGN_ON
2
Received command GET_PARAMETER 90
3
Received command GET_PARAMETER 91
4
Received command GET_PARAMETER 92
5
Received command ENTER_PROGMODE
6
AC 00
7
53 00
8
00 00
9
00 00
10
Received command LEAVE_PROGMODE
Habe also noch einiges zu tun ...

Ob S. schrieb:
> Ich denke, ihm ist zumindest klar geworden, dass er es unbedingt
> systematischer tun muss.

Ja, definitiv.

Werde gleich mal mein RTC1002 dran hängen und nachsehen, was da auf dem 
SPI wirklich abläuft. Hätte ich schon eher mal tun sollen ...

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

"System muß sein", schreibt Arno Schmidt an einer Stelle - und seinen 
Nachsatz verschweige ich jetzt lieber.

Beim Wechsel vom DIP-AVR64DD28 auf den DD32 tritt ein Problem auf? Kann 
doch eigentlich nicht sein, ist doch dasselbe Programm. Stromversorgung, 
vor allem auch die Masseverbindung, ist aber in Ordnung?

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Stromversorgung,
> vor allem auch die Masseverbindung, ist aber in Ordnung?

Ja, die sollte hinreichend gut sein, inzwischen habe ich drei parallele 
Dupontkabel als Masseverbindung zwischen den AVRs, die über SPI 
kommunizieren. Die werden ja hoffentlich nicht alle drei gleichzeitig 
Wackelkontakt haben. Bei nächster Gelegenheit werde ich mir auch 
Dupontkabel selbst herstellen, eine Crimpzange und Kontakte dafür habe 
ich mir schon besorgt, sodass ich dann sichergehen kann, dass die 
Quetschverbindungen dann ordentlich sind.

Stromversorgung erfolgt vom PC über einen CH340-USB-UART-Adapter 
(Platine von mq-pcb.de) mit 5,0 V.

Ansonsten ist mein Aufbau schon etwas improvisiert, das muss ich 
zugeben, aber elektrisch müsste es eigentlich OK sein. Mit dem 
DIP-64DD32 hat es ja auch funktioniert. Ich bin nun schon am überlegen, 
ob mit meinen selbst designten und von JLC gefertigten 
AVR-DB/DD32-Boards irgendwas nicht stimmt.

: Bearbeitet durch User
von S. L. (sldt)


Lesenswert?

Und das haben Sie überprüft: Spannung gemessen an beiden Vdd-GND-Paaren 
des DD32, Spannung an VDIO2, Durchgang zwischen den GNDs der beiden uCs, 
immer direkt an den ICs?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johannes F. schrieb:
> Ja, ich habe mir nun auch vorgenommen, mich mal in "Embedded-C" für AVRs
> einzuarbeiten, zunächst mit AVR-GCC oder dem Microchip XC8, da muss ich
> noch schauen, für was ich mich entscheide.

Soweit mir bekannt, basiert xc8 für AVR auf den GNU-Tools (avr-gcc 
etc.), allerdings hat Microchip einige Optimierungen deaktiviert, die 
man per zu erwerbender Lizenz zukaufen kann...

Ich lasse mich da aber gerne eines besseren belehren.

Die Haupunterschied bei Verwendung der GNU-Tools sind:

1) Es wird der GNU-Assembler verwendet, der etwas andere Direktiven als 
AVRA etc. verwendet.  Siehe etwa 
https://avrdudes.github.io/avr-libc/avr-libc-user-manual/assembler.html#ass_directives

2) Verwendung eines Linker/Locators zur Erstellung eines lauffähigen 
Programms.  Zunächst werden Ojbect-Dateien erstellt (aus C/C++ oder 
Asm), die dann mit (Code aus) Libs wie AVR-LibC und libgcc zum 
ausführbaren Programm vervollständigt werden.

von Johannes F. (jofe)


Lesenswert?

S. L. schrieb:
> Und das haben Sie überprüft: Spannung gemessen an beiden Vdd-GND-Paaren
> des DD32, Spannung an VDIO2, Durchgang zwischen den GNDs der beiden uCs,
> immer direkt an den ICs?

Hole ich gleich noch nach ...

Vorab nur schonmal der Zwischenstand: Ich habe nun nochmal exakt 
dasselbe .Hex, das auf dem DD32(1) nicht funktionierte, auf den DD28 
geflasht, und – dort funktioniert es einwandfrei.

Anschließend habe ich den DD32(2) (zweites Exemplar meiner 
selbstgelöteten Breakout-Platine) angeschlossen und nochmal das letzte 
.Hex geflasht – auch hier läuft es nun, wie es sein soll.

Danach habe ich das ZIP aus dem Eröffnungsbeitrag wieder heruntergeladen 
und darin die bekannt gewordenen Fehler (vergessenes Offset 
'simFlash_sram') behoben sowie die Zeichenketten auf wenige Buchstaben 
gekürzt, dieses assembliert und geflasht, und auch dieses funktioniert 
nun auf DD32(2):
1
SSFE
2
SSFE
3
RSB 00
4
RSB 01
5
RSB 02
6
CE
7
SSFE
8
RPM 0004 00
9
RPM 0005 00
10
WPM 0000 AA
11
WPM 0001 BB
12
WPM 0002 CC
13
WPM 0003 DD
14
WPM 0004 EE
15
WPM 0005 00
16
RPM 0000 AA
17
RPM 0001 BB
18
RPM 0002 CC
19
RPM 0003 DD
20
RPM 0004 EE
21
RPM 0005 00
Somit sind wir ein ganzes Stück weiter, denn der Fehler ist damit auf 
die Hardware des DD32(1) eingegrenzt. Nun bleibt nur noch diese zu 
untersuchen, ob irgendeine Lötverbindung schlecht ist, ein Kurzschluss 
besteht, oder der Chip wirklich beschädigt ist.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Angehängte Dateien:

Lesenswert?

Johannes F. schrieb:
> Stromversorgung erfolgt vom PC über einen CH340-USB-UART-Adapter
> (Platine von mq-pcb.de) mit 5,0 V.
> Ansonsten ist mein Aufbau schon etwas improvisiert, das muss ich
> zugeben, aber elektrisch müsste es eigentlich OK sein. Mit dem
> DIP-64DD32 hat es ja auch funktioniert. Ich bin nun schon am überlegen,
> ob mit meinen selbst designten und von JLC gefertigten
> AVR-DB/DD32-Boards irgendwas nicht stimmt.

Hier noch ein Foto von meinem ersten und provisorischen Aufbau von 
damals mit dem AVR128DB28, um alles genau zu prüfen und sich in die 
neue-AVR-Familie einzuarbeiten – ich wollte hier auch wissen, ob man das 
alles über den Snap und mit Atmel Studio 7 betreiben kann, incl. 
Debugging etc. Die Adapterplatine mit dem µC habe ich direkt mithilfe 
von Stiftleisten in das Lochrasterfeld meiner Platine eingelötet, um 
keine Steckverbindungen der µC-Pins zu haben – vor allem die 
Quarzverbindung ist bei dieser neuen Familie sehr störanfällig. Wenn man 
den Quarz in die Präzisionsfassung (rechts vom Chip) einsetzt und z.B. 
hin und her bewegt, läuft der µC Amok oder er stürzt regelrecht ab. bzw. 
geht in den CFD-Notfallmodus, weil ich das auch getestet habe – durch 
diese Wackeldackel-Geschichte scheint diese Umschaltung in den 
Notbetrieb aber auch nicht immer sicher zu funktionieren. Das heißt, den 
Quarz muss man hier definitiv verlöten, weil durch die relativ niedrige 
Core-Spannung der µController und damit durch den LowPower-Betrieb der 
Oszillatorschaltung das ganze nicht so robust wie bei den alten AVRs mit 
Full-Swing-Betrieb ist – ich habe das hier mit dem Quarz steckbar 
gemacht, um es mit verschiedenen Quarzen zu testen, weil es ja in dem 
ganzen Spannungsbereich auch bis 24MHz laufen sollte und es auch tut. 
Richtige Evaluationsplatinen für AVR128DB128 etc. sind schon in Planung, 
3/4 des Kerns habe ich schon fertig entworfen – das dauert aber bestimmt 
noch ein paar Wochen, bis ich sie habe, ich kann Dir aber gerne per 
eMail Bescheid geben, wenn es Dich interessiert, um z.B. ein paar von 
den ersten etwas günstiger zu bekommen.

: Bearbeitet durch User
von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Hier ein Foto von meinem derzeitigen sehr provisorischen Aufbau mit 
einem meiner ATtiny3227-Boards und zwei USB-UART-Bridges, der aber 
momentan gut funktioniert. Das USB-Kabel des Snaps ist mit 
Paketklebeband an der Tischkante befestigt, damit das Ganze nicht 
unkontrolliert umherwandert und evtl. noch Kurzschlüsse verursacht – 
einen Adapter für den Snap als 100×100-mm² große Motherboard-Platine 
(die hoffentlich schwer genug wird, um auf dem Tisch liegen zu bleiben – 
ansonsten werde ich einfach noch eine leere Platine unten drunter mit 
Abstandsbolzen schrauben) habe ich bereits fertigen lassen, müsste heute 
oder spätestens morgen bei mir ankommen.

Gregor J. schrieb:
> ich kann Dir aber gerne per
> eMail Bescheid geben, wenn es Dich interessiert, um z.B. ein paar von
> den ersten etwas günstiger zu bekommen.

Gerne, ich schreibe dir gleich mal per Mail.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Wenn ich schon diese Mini-Breadboards und zig zusammengestoppelte 
Platinen sehe, dann weiß ich schon dass da nie was zuverlässig 
funktionieren kann.

von Johannes F. (jofe)


Lesenswert?

Cyblord -. schrieb:
> Wenn ich schon diese Mini-Breadboards und zig zusammengestoppelte
> Platinen sehe, dann weiß ich schon dass da nie was zuverlässig
> funktionieren kann.

Naja, irgendwie muss man ja mal was ausprobieren und experimentieren 
können. Ich kann und will ja nicht für jede erdenkliche Kombination eine 
komplette Platine fertigen lassen. Und mit vernünftigen Dupontkabeln 
funktioniert das auch.

Wenn es dann wirklich zuverlässig werden soll und die endgültige 
Schaltung feststeht, kann man ja immer noch eine Platine dafür machen. 
Bis dahin muss es nicht weltraumfest sein.

Johannes F. schrieb:
> Gerne, ich schreibe dir gleich mal per Mail.

Habe es heute Morgen nicht mehr geschafft, ich schreib dir dann 
nachmittags.

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Angehängte Dateien:

Lesenswert?

Johannes F. schrieb:
> Habe es heute Morgen nicht mehr geschafft, ich schreib dir dann
> nachmittags.

Kein Problem, eilt ja nicht. Ach ja, falls Du auch etwas Robustes für 
den Snap haben möchtest, dann könnte ich Dir sogar eine unbestückte 
Adapterplatine von dem ersten Wurf für den Snap gratis abgeben (Foto im 
Anhang). Für die AVR_Dx passt dann die UDPI_v2 mit RESET, VTG, GND und 
UPDI, die sich in der Mitte befindet – auf den Evaluationsplatinen wird 
es diese Reihenfolge dann auch exakt so geben. Reset braucht man nicht 
unbedingt, d.h. drei Leitungen würden reichen, aber falls man es 
braucht, ist es da. Die UPDI_v1, die sich innerhalb der 
2x3-ISP-Schnittstelle befindet, kann man natürlich auch abgreifen und 
nutzen, diese 2x3-Stiftleisten verwende ich auf meinen Leiterplatten 
aber nur für die alten AVRs, wo man über ISP programmiert. Die große 
Platine (Maxi) für den Snap muss ich noch machen.

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Johannes F. schrieb:
> Und mit vernünftigen Dupontkabeln funktioniert das auch.

Ich war auch schon am überlegen, alle Anschlüsse meiner Boards auf 
Schraubklemmen (im 3,5-mm-Raster oder kleiner, wenn es gibt) zu führen, 
und dann mit Litzenabschnitten mit Aderendhülsen zu verbinden. Wäre 
natürlich schöner und robuster, aber auch deutlich teurer.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Angehängte Dateien:

Lesenswert?

Johannes F. schrieb:
> Ich war auch schon am überlegen, alle Anschlüsse meiner Boards auf
> Schraubklemmen (im 3,5-mm-Raster oder kleiner, wenn es gibt) zu führen,
> und dann mit Litzenabschnitten mit Aderendhülsen zu verbinden. Wäre
> natürlich schöner und robuster, aber auch deutlich teurer.

So ganz ohne Dupont wird es beim schnellen, günstigen Prototypen nicht 
gehen – ich mache es in der Regel so, dass alles, was verlötet werden 
kann oder muss, dazu gehören z.B. VCC und GND, auch verlötet wird. Wenn 
VCC+GND nicht verlötet wird, dann habe ich selbstgemachte 
Krokodilklemmen-Leitungen, wo es an der Krokodilklemme verlötet ist und 
der Querschnitt der Leitung zumindest 100mA ohne nennenswerten 
Spannungsabfall durchlässt. Mit diesen Krokodilklemmen kann man relativ 
sicher an Stiftleisten andocken – Wackelkontakte gibt es hier nicht, 
wenn man mit der Klemme gleich zwei Stiftleisten schnappt. Diese 
günstigen, dünnen, fertiggekauften Krokodilklemmen-Leitungen sind dafür 
nicht geeignet – wie dünn die Leitung ist, sieht man, wenn man sie 
abschneidet oder sie nach intensivem Gebrauch von alleine abbricht. 
Taster, LEDs und UART-Verbindung kann man mit frischen (nicht 
ausgeleierten) Dupontkabel anbinden, Schnittstellen wie I2C oder SPI 
verbinde ich nicht gerne über Dupontkabel bei Tests, aber für einen 
kurzen Test geht es auch. Bei dedizierten Interrupteingängen muss man 
anders vorgehen – „Antennen” aller Art sind hier extrem kontraproduktiv. 
µController verlöte ich in der Regel immer, selbst die Adapterplatine, 
auf der sie verlötet wurden, wird wiederum auch verlötet (so wie hier 
bei dem AVR128DB28 in SO28), nur bei PDIP nehme ich auch mal Sockel, 
allerdings nur Präzisionsfassungen, weil diese einfachen Federkontakte 
sehr schnell Kontaktprobleme bereiten können. Ich habe jetzt auch einen 
Fall, wo ich eine PLCC-Fassung verwenden werde – diese Fassungen sind 
aber ziemlich sicher und robust, insofern auch OK. In ganz speziellen 
Fällen verwende ich Zerokraftsockel und dann dafür entsprechend auf 
Adapterplatinen aufgelötete ICs mit Stiftleisten im 2,54mm-Raster für 
den großen oder auch kleinen Sockel – hier gibt es dann definitiv keine 
Wackelkontakte (zwei Fotos im Anhang). Diese Nullkraftsockel sind 
natürlich ziemlich teuer, dafür bekommt man aber die Sicherheit, dass es 
keine Wackeldackel gibt. Steckbretter benutze ich wegen dieser genannten 
Gründe überhaupt nicht – das ist ja quasi eine Ansammlung von 
Wackelkontakten und parasitären Kapazitäten, die man sich da auf den 
Tisch stellt; wenn etwas provisiorisch aufgebaut werden muss, dann wird 
es zumindest auf Lochrasterplatinen ordentlich verlötet (wie ich es z.B. 
mit dem AVR128 gemacht habe).

PS: Schraubklemmen gibt es auch im 2,54mm-Raster, sind aber auch relativ 
teuer und diese verkleinerte Konstruktion ist entsprechend filigran

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

@ Johannes,
https://www.mikrocontroller.net/attachment/660229/IMG_20250205_080120.jpg
bei deinem Foto sieht man unten 2 Folien die mindestens dort nichts zu 
suchen haben.
Die hellere rötliche könnte Antistatisch sein.
Die untere größere silbrige ist Antistatisch.
Antistatische Folie macht zwar keinen direkten satten Kurzschluss, aber 
es bedeutet eine gewisse Leitfähigkeit. Das zusammen mit hochohmigen 
Eingängen ...  Sowas hat unter Leiterplatten im Betrieb definitiv nichts 
zu suchen.

: Bearbeitet durch User
von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Veit D. schrieb:
> Antistatische Folie macht zwar keinen direkten satten Kurzschluss, aber
> es bedeutet eine gewisse Leitfähigkeit. Das zusammen mit hochohmigen
> Eingängen ...  Sowas hat unter Leiterplatten im Betrieb definitiv nichts
> zu suchen.

Antistatische Folien haben Ableitwiderstände im Gigaohmbereich pro mm 
Abstand. Das bestätigt auch der Test mit zwei Messspitzen, in 
geringstmöglichem Abstand voneinander auf die Folie gedrückt, ein 
Multimeter zeigt bei mir OL im 200-MΩ-Bereich. Ich bezweifle, dass sich 
das bei den Schaltungen, mit denen ich hantiere, auswirken könnte.

Anbei ein Foto meines Snap-Adapters, den ich seit heute Nachmittag in 
Benutzung habe. Die 90°-Stiftleiste ist eine Ausführung mit extra langen 
THT-Beinchen (Samtec TSW-108-09-L-S-RA), die hier wegen der 
Abstandshalter unter dem Snap notwendig ist (und die sind sicher auch 
vorteilhaft, damit keine Kurzschlüsse der Beinchen der 
Snap-Buchsenleiste zur Massefläche bzw. Leiterbahnen des Motherboards 
entstehen).

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

ESD konform ist alles unter 1GOhm. Und mit einem normalen Multimeter 
brauch man dafür nicht anfangen. Aber warum schreib ich hier überhaupt 
noch.

von Johannes F. (jofe)


Angehängte Dateien:

Lesenswert?

Veit D. schrieb:
> Aber warum schreib ich hier überhaupt
> noch.

Nichts für ungut, sorry dass meine Antwort negativ rüber kam, war nicht 
so gemeint. Ich kann mir halt nur nicht vorstellen, dass diese sehr 
geringe Leitfähigkeit dieser ESD-Oberflächen in diesem Fall etwas 
ausmacht. Vielleicht irre ich mich auch, kenne mich auch nicht genau 
damit aus. Hatte die Tütchen auch als Unterlage vorhin direkt entfernt 
und durch Papier ersetzt.

Ich habe übrigens noch drei dieser Snap-Motherboards übrig und würde sie 
zum Selbstkostenpreis abgeben, falls jemand Bedarf hat.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Anbei ein Foto meines Snap-Adapters, den ich seit heute Nachmittag in
> Benutzung habe.

Glückwunsch dazu, denn reale Erfolge sind wichtig fürs Weiterkommen – 
damit sollten aber auch die Probleme mit dem Klebeband jetzt beseitigt 
sein : )

von Johannes F. (jofe)


Lesenswert?

Gregor J. schrieb:
> Glückwunsch dazu, denn reale Erfolge sind wichtig fürs Weiterkommen –
> damit sollten aber auch die Probleme mit dem Klebeband jetzt beseitigt
> sein : )

Vielen Dank :·) Ist ja ein sehr einfaches Layout, aber das Board erfüllt 
seinen Zweck, der Snap bzw. die Verbindung USB-Kabel/-Buchse ist mit dem 
Kabelbinder um das USB-Kabel auch gut darauf fixiert.

Das Kabel habe ich dennoch auch wieder an der Tischkante angeklebt, 
damit das Board nicht auf dem Tisch umherwandert, getrieben durch 
etwaige Bewegungen des recht starren Kabels.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Das Kabel habe ich dennoch auch wieder an der Tischkante angeklebt,
> damit das Board nicht auf dem Tisch umherwandert, getrieben durch
> etwaige Bewegungen des recht starren Kabels.

Ja, das schwarze USB-Kabel für den Snap scheint auch etwas dick zu sein 
– ich verwende hierfür ein einfaches, dünnes Kabel, das auch für meine 
Smartfones verwendet werden kann, um sich mit dem PC zu verbinden. Ich 
habe im Laufe der Jahre auf dem „Hauptarbeitsplatz” auch ein System der 
Anordnung der Kabel entwickelt bzw. es hat sich halt in diese Richtung 
entwickelt, wo die Spannungsquelle (Netzteil) links steht und 
dementsprechend auch von links an meine Leiterplatten angeschlossen 
werden kann und die Signalkabel wie USB oder µC-Programmieranschlüsse in 
der Regel von rechts in die Platinen gesteckt werden können, weil auch 
der PC auf der rechten Seite steht und sie von dort kommen. Auch das 
Oszilloskop steht auf der rechten Seite. Dieses Konzept versuche ich 
jetzt bei mir (auf allen Arbeitsplätzen) beizubehalten – es muss aber 
schon jeder selbst für sich herausfinden oder herauskristallisieren, was 
ihm am besten zusagt. Bei einem meiner Kunden kann das auch genau 
umgekehrt und deshalb problematisch sein – aber so ist halt das Leben, 
man kann und wird es nicht allen Recht machen können und irgendwo muss 
man dann auch einen Punkt machen und das ganze einheitlich festlegen 
bzw. durchziehen. Problematisch und chaotisch wird es nur dann, wenn es 
jedesmal anders ist, weil man bei den eigenen Entwürfen gar nicht auf 
die Ausrichtung der Stecker und Buchsen achtet – aber auch damit muss 
dann schon jeder selbst irgendwie klarkommen oder sich arrangieren.

von Johannes F. (jofe)


Lesenswert?

Gregor J. schrieb:
> Ja, das schwarze USB-Kabel für den Snap scheint auch etwas dick zu sein
> – ich verwende hierfür ein einfaches, dünnes Kabel,

Ja das stimmt, es ist recht dick, aber ich dachte immer, dass das für 
höhere Qualität spricht - evtl. bessere Abschirmung - kann aber auch ein 
Trugschluss sein.

Leider hat der SNAP keine USB-C-Buchse, denn dafür habe ich bessere 
i.S.v. flexiblere Kabel.

Gregor J. schrieb:
> Dieses Konzept versuche ich jetzt bei mir (auf allen Arbeitsplätzen)
> beizubehalten – es muss aber schon jeder selbst für sich herausfinden
> oder herauskristallisieren, was ihm am besten zusagt.

Hmm, ich hatte bisher immer die Anschlüsse so platziert, wie es fürs 
Layout am günstigsten war - aber stimmt, wenn ich die Platinen nun 
doppelseitig fertigen lasse, habe ich da natürlich mehr Freiheiten und 
kann auch an die praktischen Aspekte denken.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Johannes F. schrieb:
> Ja das stimmt, es ist recht dick, aber ich dachte immer, dass das für
> höhere Qualität spricht - evtl. bessere Abschirmung - kann aber auch ein
> Trugschluss sein.

Bei der moderaten Übertragungsgeschwindigkeit, die der Snap nutzt, muss 
hier kein Supa-Dupa-Kabel verwendet werden, auch von der 
Strombelastbarkeit bzw. vom Spannungsabfall her gesehen ist das ziemlich 
egal, denn die USB-Spannung der Buchse wird ausschließlich für die 
Snap-Schaltung verwendet, weil das VTG-Konzept des Snaps so gedacht ist, 
dass VTG eine separate, externe Spannung sein soll, die gleichzeitig 
auch die vielen kleinen Levelshifter, die da am Ende der IOs verbaut 
sind, versorgt. Das ist auch besser so, dass man es so explizit getrennt 
hat, denn jeder Kurzschluss oder zu hoher Strombedarf, der durch die 
Targetschaltung verurascht werden könnte, würde auch Auswirkungen auf 
die Stromversorgung des Snaps haben und womöglich zu irgendwelchen 
Funktionsstörungen oder Restarts führen – das sollte auch jeder 
bedenken, der auf Teufel komm raus die Spannung dieser USB-Buchse nutzen 
möchte. Der µC des Snaps wird auch handwarm, aber bei 300 MHz als Takt 
(oder womit auch immer der µC da in dieser Größenordung läuft) ist das 
ganz normal und bedeutet nicht, dass hier extrem viel Strom fließt – 
100mA reichen bei 3,3V völlig aus, um die Wärmeentwicklung am IC-Gehäuse 
mit der Hand deutlich zu spüren. Die alten 8751, 68000, die noch nicht 
in CMOS hergestellt wurden, wurden bei 5V und 170-200mA mit nur 12 bzw. 
8 MHz alt Takt schon richtig heiß.

: Bearbeitet durch User
von Johannes F. (jofe)


Lesenswert?

Habe soeben alle Füßchen des betreffenden AVR64DD32 mit viel Flussmittel 
und Lötkolben nachgelötet, die Lötstellen sehen alle m.E.n. gut aus, 
nichts auffälliges zu sehen. Trotzdem funktioniert er nach wie vor 
nicht, dasselbe Programm auf einem anderen DD32 auf baugleicher Platine 
dagegen schon. Ich verbuche den ersten DD32 nun einfach als defekt, 
vielleicht hat er auch irgendwie ESD-mäßig mal was abbekommen, obwohl 
ich darauf eigentlich immer achte.

Wie auch immer, so langsam vergeht mir die Lust auf die Suche nach der 
exakten Ursache, ich werde den Fall jetzt ad acta legen, dieser Thread 
kann damit als erledigt betrachtet werden. Vielen aufrichtigen Dank an 
alle für die hilfreichen Antworten.

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.