Hallo zusammen,
ich spiele gerade mit einem ATTiny3216 und möchte über die
UPDI-Schnittstelle einen Reset auslösen. Dazu habe ich das folgende
Python-Script geschrieben:
1
import serial
2
import time
3
4
def send_reset(serial_port):
5
# Verbindungsaufbau mit dem seriellen Port
6
with serial.Serial(serial_port, baudrate=225000, timeout=1) as ser:
7
# Warten, bis die Verbindung stabil ist
8
time.sleep(2)
9
10
# 1. SYNCH-Zeichen senden (0x55)
11
ser.write(bytes([0x55]))
12
print("SYNCH: 0x55 gesendet")
13
14
# Kurze Verzögerung nach SYNCH
15
time.sleep(0.1)
16
17
# 2. Sende den STS-Befehl (010) mit der Adresse von ASI_RESET_REQ (0x08) und dem Wert 0x59
18
# Format: Opcode STS (010), Adresse, und Wert für den Soft-Reset (0x59)
ja, das könnte sein. Werde es mal probieren.
Was ist der Unterschied zwischen den beiden Registern? (STS und STCS)?
Ist der Unterschied, dass beim STS ein Acknowledge gesendet wird und
beim STCS nicht? Oder gibt es noch einen anderen Grund, anstatt das
STS-Register das STCS-Register zu verwenden?
Das ergibt sich ja aus den Namen:
'ST - Store Data from UPDI to Data Space Using Indirect Addressing'
(allgemeines Memory)
'STCS Store Data to Control and Status Register Space' (des UPDI)
Nein, es wird die CS-Adresse ($08) mit dem STCS-Opcode ($C0 = 11000000)
verodert.
Und eben war es etwas überhastet (immer schlecht), es ging ja um STS:
'STS - Store Data to Data Space Using Direct Addressing'
S. L. schrieb:> Nein, es wird die CS-Adresse ($08) mit dem STCS-Opcode ($C0 = 11000000)> verodert.
ok, aber das müsste ich ja auch dann machen. Momentan sende ich
nacheinander die Bytes 0x40 und 0x08. Dann müsste ich 0xC8 senden und
dann den Wert (0x00 und 0x59), richtig?
Ist schon länger her, und Ihr '0x40' sagt mir gerade nichts.
So auf die Schnelle aus meinem Programm gelesen: $55 $C8 $59, dann $55
$C8 $00.
Jetzt bin ich aber endgültig weg ...
Die beiden Sequenzen sollten stimmen. Ich vermute, dass UPDI nicht
korrekt aktiviert wurde gemäß Datenblatt 'UPDI Enabling - One-Wire
Enable'. Und zu Beginn zwei BREAKs senden kann auch nicht schaden, ich
mache das generell.
S. L. schrieb:> Die beiden Sequenzen sollten stimmen. Ich vermute, dass UPDI nicht> korrekt aktiviert wurde gemäß Datenblatt 'UPDI Enabling - One-Wire> Enable'. Und zu Beginn zwei BREAKs senden kann auch nicht schaden, ich> mache das generell.
Guten Morgen,
wie müsste die Sequenz aussehen, um UPDI zu aktivieren?
Herausgefunden habe ich folgendes:
Fuses Base Adress = 0x1280
SYSCFG0 Offset = 0x05
1. Schritt:
Adresse von FUSES.SYSCFG0 in NVMCTRL.ADDR laden: NVMCTRL.ADDR = 0x1285
2. Schritt:
Daten in NVMCTRL.DATA laden: NVMCTRL.DATA = 0xD4 (Bits 2 und 3 = 01)
3. Schritte:
Schreiben der Fuses initiieren: CTRLA = 0x07
Aber wie müsste jetzt die Sequenz aussehen, die ich übertragen müsste?
Wenn Du sicher wissen willst, wie Microchip das selber macht, dann
besorge Dir ein MPLAB SNAP Programmer, MPLABX und einen dieser
15€-Logicanalyzer, mache aus der IPE einen Reset und schau mit dem
Logicnalyzer nach, was das die IPE da sendet. Dann weißt Du es sicher,
und Du siehst nicht nur die Bytesequenz, sondern auch das Timing, wenn
das wichtig ist.
fchk
> wie müsste die Sequenz aussehen, um UPDI zu aktivieren?
Das steht, wie bereits gestern geschrieben, im Datenblatt unter 'UPDI
Enabling':
"The UPDI pin has a constant pull-up enable, and by driving the UPDI pin
low for more than 200 ns, a connected programmer will initiate the
start-up sequence ...".
Siehe dazu auch das Diagramm 'UPDI Enable Sequence with UPDI PAD Enabled
By Fuse'.
PS:
> Fuses ... FUSES ... Fuses ...
Als Anfänger beim ersten Gehversuch mit den Fuses zu arbeiten ist eine
schlechte Idee - ich begann damals mit dem Auslesen des SIB (System
Information Block).
PPS:
Dieses "UPDI PAD Enabled By Fuse" steht da nur, um den Gegensatz zu
"Override of Reset" zu verdeutlichen - Letzteres gibt es ohnehin nicht
bei z.B. den AVRmDx.
Ich habe an meinem USB-Port am Rechner einen USB-Seriell-Adapter
angeschlossen, der mit einer einfachen Beschaltung an den UPDI Daten
schickt und empfängt.
Wenn ich dann über avrdude den EEPROM-Inhalt auslese, wird anschließend
ein Reset beim ATTiny ausgelöst. Diesen Reset wollte ich dann mal
interessehalber mit einem einfachen Python-Programm nachstellen.
Dazu bräuchte ich aber die richtige Sequenz.
Das der UPDI-Pin für mehr 200ns low sein muss, müsste doch der
USB-Seriell-Adapter übernehmen, oder?
Wie macht das avrdude?
> Wie macht das avrdude?
Tut mir leid, das kann ich nicht beantworten - ich arbeite nicht mit
avrdude. Aber es gibt hier sicher Mitleser, die das wissen.
S. L. schrieb:> Tut mir leid, das kann ich nicht beantworten - ich arbeite nicht mit> avrdude. Aber es gibt hier sicher Mitleser, die das wissen.
Alles gut, du hast mir schon sehr viel geholfen. Zum Anfang wusste ich
noch gar nichts, jetzt ein wenig.
Mir juckt es in den Fingern, den Logic-Analyzer dazwischen zuhängen. Ich
habe nur das Problem dafür Zeit zu finden. Aber interessant wäre es
schon.
VG woto
Meldet sich niemand ... ?
Haben Sie es schon mit $FE als erstes Byte versucht? Das Startbit zieht
UPDI auf low, sollte reichen, und das lsb von $FE ist nötig wegen der
geraden Parität. Also vom PC aus senden: $FE $55 $E5, sollte den SIB
als Antwort bringen (oder Sie versuchen mit $FE $55 $C8 $59 Ihr
'reset').
Wird vermutlich nur einmal pro Einschalten funktionieren, da UPDI
nicht korrekt deaktiviert wird, wäre ja aber erstmal egal.
Stelle ich mir zumindest so vor, ausprobiert habe ich es nicht.
PS:
korrigiert zu 'wegen der geraden Parität'
PPS:
Mir fällt gerade auf:
> with serial.Serial(serial_port, baudrate=225000, timeout=1) as ser:
Wo wird da der Rest konfiguriert: 8 Datenbits, gerade Parität, 2
Stoppbits? Und für den Anfang würde ich es bei 115200 Bd belassen.
Wolfgang T. schrieb:>> Mir juckt es in den Fingern, den Logic-Analyzer dazwischen zuhängen. Ich> habe nur das Problem dafür Zeit zu finden. Aber interessant wäre es> schon.
Du könntest Dir updiprog ansehen:
https://github.com/Polarisru/updiprog
Das ist übersichtlicher C-Code bei dem man gut sehen kann was genau
passiert.
Das Ganze gibt es auch für Python (darauf basiert updiprog):
https://github.com/mraardvark/pyupdi
S. L. schrieb:> Haben Sie es schon mit $FE als erstes Byte versucht? Das Startbit zieht> UPDI auf low, sollte reichen, und das lsb von $FE ist nötig wegen der> geraden Parität. Also vom PC aus senden: $FE $55 $E5, sollte den SIB> als Antwort bringen (oder Sie versuchen mit $FE $55 $C8 $59 Ihr> 'reset').
Guten Abend,
habe das jetzt mal mit dem Senden von $FE versucht, leider kein Erfolg.
Auch die Schnittstellenparameter 8 Datenbits, gerade Parität, 2
Stoppbits habe ich jetzt eingestellt und die Baudrate auf 57600
gestellt.
Damit arbeitet die Arduino-IDE. Aber alles kein Erfolg.
Dieter S. schrieb:> Das Ganze gibt es auch für Python (darauf basiert updiprog):>> https://github.com/mraardvark/pyupdi
Auch das habe ich mir angesehen und dort werden genau die Bytes
gesendet, die auch ich sende.
Morgen kommt der Logic-Analyzer. Da bin ich gespannt was dabei
herauskommt, wenn ich mit avrdude das EEPROM auslese.
Wenn ich neue Erkenntnisse habe, werde ich mich melden.
Schönen Abend noch, Woto
Wolfgang T. schrieb:>> Auch das habe ich mir angesehen und dort werden genau die Bytes> gesendet, die auch ich sende.
updiprog (also die C Variante von pyupdi) funktioniert auf jeden Fall
mit einem ATtiny3227. Die UART ist dabei mit 115200 Baud, Even Parity
konfiguriert, Rx direkt an UPDI, Tx über einen 1 kOhm Widerstand an
UPDI.
Hallo,
ich habe jetzt den Logicanalyzer am UPDI-Eingang installiert und die
Daten mitgeschrieben (s.A.).
Wie man sieht, ist das die Bytereihenfolge, die das Python-Programm
momentan sendet.
Jetzt möchte ich die übertragenden Bytes bei Verwendung von avrdude
mitschneiden. Dazu brauche ich aber die Schnittstellenparameter.
Kennt jemand die Schnittstellenparameter bei der Verwendung von
serialupdi?
VG, Woto
Wolfgang T. schrieb:> Jetzt möchte ich die übertragenden Bytes bei Verwendung von avrdude> mitschneiden. Dazu brauche ich aber die Schnittstellenparameter.
Die Bitrate kannst Du Dir doch anhand der Länge eines Bits ausmessen.
Und die Anzahl der Daten- und Stopbits siehst Du dann auch im
Wellenformdiagramm.
fchk
> die Bytereihenfolge, die das Python-Programm momentan sendet
Das verstehe ich nicht: was soll die Sequenz '55 40 34 00 D8' bewirken?
Zumal nach meiner Meinung ein Byte zuviel ist: STS mit 'Size A'="Byte
- can address 0-255 B" und 'Size B'="Byte". Was dann wohl auch der Grund
dafür ist, dass vom uC die beiden ACK nicht rückgemeldet werden.
PS: Datenblattauszug
Frank K. schrieb:> Die Bitrate kannst Du Dir doch anhand der Länge eines Bits ausmessen.> Und die Anzahl der Daten- und Stopbits siehst Du dann auch im> Wellenformdiagramm.
Stimmt, werde ich versuchen. Danke.
S. L. schrieb:> Das verstehe ich nicht: was soll die Sequenz '55 40 34 00 D8' bewirken?> Zumal nach meiner Meinung ein Byte zuviel ist: STS mit 'Size A'="Byte> - can address 0-255 B" und 'Size B'="Byte". Was dann wohl auch der Grund> dafür ist, dass vom uC die beiden ACK nicht rückgemeldet werden.
Ja, schaue ich mir nochmal genauer an.
Mit angehängtem Programm(auszug) erhalte ich den SIB
(System-Information-Block) "...tinyAVR P:0D:0-3" von einem ATtiny412
zurück. Sie erkennen das Muster, und die Umsetzung von Pascal nach
Python ist wohl klar.
S. L. schrieb:> Mit angehängtem Programm(auszug) erhalte ich den SIB> (System-Information-Block) "...tinyAVR P:0D:0-3" von einem ATtiny412> zurück. Sie erkennen das Muster, und die Umsetzung von Pascal nach> Python ist wohl klar.
Vielen Dank. In Pascal habe ich früher auch programmiert.
Hallo,
habe das jetzt getestet, leider ohne Erfolg.
Im Anhang die gesendete Bytereihenfolge.
(Leider habe ich zwei Dateianhänge in den Beitrag hochgeladen und kann
die zweite nicht mehr löschen, gesendet habe ich aber immer nur einmal
die Bytereihenfolge)
Auch die Wartezeit von 4s habe ich eingehalten.
Tja, dann weiß ich (erstmal) nicht weiter. Bei mir läuft es. Die 4 s
sind übrigens völlig unbedeutend, es geht nur darum zu sehen, dass das
LED-Blinken auf dem ATtiny412 so lange aufhört.
An der Hardware liegt es wohl nicht, da bei Ihnen ja avrdude läuft, aber
ich schildere trotzdem mal meine: USB-seitig ein CP2102, dahinter (zur
Potenzialtrennung, aber eigentlich unbedeutend) ein ADuM1201. Wie im
gezeigten COM_UPDI.pas beschrieben geht Rx direkt auf UPDI, Tx per 100
Ohm und Siliziumdiode 1N4448. Zusätzlich zum internen UPDI-Pullup
verwende ich noch extern 100 kOhm, kann aber auch entfallen.
Was ich bislang nicht erreichte ist die Wiederherstellung der Verbindung
durch zwei BREAKs (wie im Datenblatt beschrieben); wenn sich also etwas
"verhaspelt" hat, hilft nur Aus- und wieder Einschalten der
Stromversorgung des ATtiny412.
Da ich dies alles aber nur aus allgemeinem Interesse angeschaut habe
(ich selbst arbeite mit einem Selbstbauprogrammiergerät, damit läuft
alles perfekt (auch die Wiederherstellung)), verabschiede ich mich an
dieser Stelle.
Vielen Dank.
Ich bleibe dran und melde mich wieder, wenn ich etwas herausgefunden
habe.
Im Anhang die Bytereihenfolge mit avrdude. Dabei schreibe ich mit
avrdude einen Wert ins Byte 0 vom EEPROM. Nach dem Schreiben wird der
ATTiny resetted.
Hier der Aufruf von avrdude:
Man sieht in dem Trace dass avrdude einen zweiten Anlauf braucht weil
die erste Abfrage der UPDI Revision keine Antwort liefert.
Ich würde zuerst die Verschaltung mit der UART prüfen und schauen ob es
mit updiprog bzw. pyupdi funktioniert und dann die eigenen Experimente
wiederholen.
Guten Abend,
ich habe das jetzt mit pyupdi (bzw. jetzt pymcuprog) gemacht. Erst hat
es nicht funktioniert. Aber dann habe ich die Schaltung gemäß der
Vorgabe von pymcuprog gemacht (Rx über einen 1kOhm-Widerstand an den
UPDI-Eingang und den Tx direk an den UPDI-Eingang) und damit hat der
Reset mit den folgenden Befehl funktioniert:
1
pymcuprog reset -t uart -u COM9 -d attiny3216
Die dann gesendete Bytereihenfolge resettete den Attiny (endlich). Im
Anhang die Bytereihenfolge.
Leider löst mein Python-Programm (noch) kein Reset aus, aber die
Anpassung ist jetzt nur noch eine Fleißarbeit.
Vielen Dank für eure Unterstützung.
VG Woto
Wolfgang T. schrieb:>> ich habe das jetzt mit pyupdi (bzw. jetzt pymcuprog) gemacht. Erst hat> es nicht funktioniert. Aber dann habe ich die Schaltung gemäß der> Vorgabe von pymcuprog gemacht (Rx über einen 1kOhm-Widerstand an den> UPDI-Eingang und den Tx direk an den UPDI-Eingang) und damit hat der> Reset mit den folgenden Befehl funktioniert:
Die Beschaltung laut pymcuprog ist so (das ist auch bei updiprog so),
bei Deiner Beschreibung ist Rx und Tx vertauscht:
> Leider löst mein Python-Programm (noch) kein Reset aus
Sind Sie sicher, dass das erste Byte in Ihrer Tabelle wirklich ein
'normaler' Null-Character ist und nicht etwa ein BREAK? Also 0x00 mit
stark reduzierter Übertragungsrate, z.B. 300 Bd, womit dann die im
Datenblatt geforderten 24.6 ms Low erreicht wären?