Hallo, Peter Danegger hat in seinem Fastboot-Bootloader eine automatische Baudraten-Erkennung verbaut, die ich gerne verstehen möchte. Der Assemblerfetzen ist allerdings, gelinde gesagt, ein undurchsichtiges Massaker... Ich wäre dem Autor unheimlich dankbar, wenn er die Funktionsweise etwas näher erläutern könnte :-) Vielen Dank und Frohes Fest. Kama PS: Quelltext gibt es z.B. hier: Beitrag "Re: UART Bootloader ATtiny13 - ATmega644"
Nun, nach längerem Nachdenken habe ich das Prinzip verstanden. Lediglich diese Korrektur ist mir noch schleierhaft:
1 | ;------------------------------ correction for USB dongle !!! ------------ |
2 | mov r0, zh |
3 | _aba5: |
4 | asr yl ; shift signed ! |
5 | lsr r0 |
6 | brne _aba5 |
Was hat es mit den USB-Dongles auf sich? In meiner Implementierung habe ich eine solche Korrektur nämlich nicht und bemerke, dass die Erkennung sporadisch nicht funktioniert, was vermutlich am USB-Dongle liegt :-) Danke und Gruß!
Die Baudratenerkennung versucht 2 low-Impulse auszumessen, deren Verhältnis etwa 1:4 beträgt. Dadurch verringere ich die Gefahr einer Fehlerkennung. Damit das auch auf AVRs ohne 16Bit-Timer funktioniert, erfolgt das Messen durch Zählschleifen. Zieht man nun ein Toleranzfenster ab, ist dieses absolut. D.h. bei kleinen Counts kann die Tolelanz zu groß sein bzw. bei großen Counts zu klein. Daher wird bei großen Counts der Wert solange halbiert, bis der Countwert unter 8 Bit ist. Damit spart man sich eine Division zur Ermittlung der relativen Toleranz. Insbesondere bei USB-Dongle ist mir eine deutlich höherer Fehler aufgefallen im Vergleich zu einer echten UART. Vermutlich liegt das daran, daß USB glatte MHz-Quarze benötigt, d.h. keine Baudratenquarze und dadurch ergibt sich ein Rechenfehler bei der Biterzeugung. Peter
Man könnte also auch sagen, diese Korrektur ist für lahme Taktraten gedacht? Denn dort entstünden ja hohe Zählwerte -- Ich versuchs mal zu verstehen:
1 | ; Prolog... |
2 | ; Y hält die Länge des vorigen SPACE |
3 | ; Z zählt die Länge des aktuellen SPACE vierfach |
4 | ; --> bei 1:4 landet Y idealerweise bei Null |
5 | sbiw yl, 1 ;2 |
6 | adiw zl, 4 ;2 count bit time |
7 | brcs timeout ;1 time to long |
8 | SKIP_RXD_1 ;1 wait until RXD = 1 |
9 | rjmp _aba4 ;2 = 8 |
10 | |
11 | |
12 | ; Z sichern, wird später noch gebraucht für die ermittelte Baudrate |
13 | mov r0, zh |
14 | |
15 | ; Warum jetzt Y und Z vermischt? |
16 | ; Und warum arithmetisch schieben, es sollte doch halbiert werden? |
17 | _aba5: |
18 | asr yl ; shift signed ! |
19 | lsr r0 |
20 | brne _aba5 |
21 | |
22 | |
23 | ; Kurzform für: |
24 | ; Wenn der Übertrag erscheint, lagen wir nahe bei Null |
25 | sbiw yl, TOLERANCE |
26 | adiw yl, 2 * TOLERANCE |
Danke!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.