SchubyCNC

Willkommen auf meiner Homepage!

UPDI-Signatur auslesen: Warum LDS bei gelöschten AVR-Dx-Chips timeoutet – und wie man es löst

Wer einen eigenen UPDI-Programmer für moderne Microchip/Atmel-AVR-Chips (megaAVR0-Serie, AVR-Dx-Serie wie AVR32DB32, AVR64DB48 usw.) baut, stößt früher oder später auf ein verwirrendes Phänomen: Einfache UPDI-Registerzugriffe (LDCS) funktionieren zuverlässig, aber der Versuch, die Chip-Signatur aus dem SIGROW-Speicherbereich zu lesen (LDS), läuft immer wieder in einen Timeout – ganz ohne erkennbaren Grund in Hardware oder Code. Dieser Artikel dokumentiert die komplette Fehlersuche und die Lösung, damit ihr euch die stundenlange Suche sparen könnt.

Das Symptom

Wichtig zu wissen: Das Symptom hat nichts mit Verkabelung, Signalqualität, Baudrate oder Timeout-Werten zu tun – auch bei sauberster Hardware und großzügigem Timeout bleibt das Problem bestehen, solange der Chip gelöscht ist.

Die eigentliche Ursache

Im Microchip-Datenblatt (Kapitel „UPDI – Unified Program and Debug Interface") steht der entscheidende Satz:

„Until the lock bits are cleared, the UPDI cannot access the system bus, and only CS-space operations can be performed."

Der Grund liegt in der Architektur von UPDI selbst:

Ein zusätzliches, sehr aufschlussreiches Detail steht im Register ASI_SYS_STATUS (Offset 0x0B), Bit 1, BOOTDONE:

„This bit is set to '1' when the CPU is done with the boot sequence. The UPDI will not have access to the ACC layer until this bit is set to '1'."

Bei einem frisch gelöschten Chip (Flash komplett 0xFF) hat die CPU keinen gültigen Code zum Booten – der Boot-Vorgang wird nie sauber abgeschlossen, BOOTDONE bleibt dauerhaft 0, und der Systembus-Zugriff für UPDI bleibt blockiert. Das erklärt exakt das beobachtete Muster: kein Fehlerflag (STATUSB zeigt sauber 0x00), einfach keine Antwort.

Die Lösung: NVMPROG-Modus aktivieren

Der Weg, auch auf einem gelöschten Chip Datenraum-Zugriffe (LDS/STS) zu bekommen, führt nicht über einen wartenden Boot-Vorgang, sondern über den dedizierten NVM-Programmiermodus. Dieser Modus gewährt UPDI exklusiven Bus-Zugriff, unabhängig vom CPU-/Boot-Zustand.

Ablauf (laut Datenblatt, Kapitel „NVM Programming")

  1. NVMPROG-Key senden über die KEY-Instruktion (Opcode 0xE0, „Receive Key", 64 Bit). Die Signatur lautet 0x4E564D50726F6720 und wird LSB-first übertragen.
  2. Optional: ASI_KEY_STATUS (Offset 0x07) per LDCS lesen, um zu prüfen, ob der Key akzeptiert wurde (Bit 4 = NVMPROG).
  3. System-Reset auslösen: 0x59 in ASI_RESET_REQ (Offset 0x08) schreiben (RSTREQ-Signatur für „Normal Reset").
  4. Reset wieder freigeben: 0x00 in dasselbe Register schreiben (Signatur „RUN" – löscht die Reset-Bedingung).
  5. PROGSTART pollen: ASI_SYS_STATUS (Offset 0x0B) wiederholt per LDCS lesen, bis Bit 3 (PROGSTART) auf 1 springt.
  6. Sobald PROGSTART = 1 ist, funktionieren LDS/STS zuverlässig – auch wenn BOOTDONE weiterhin 0 bleibt.

Wichtige Stolperfallen bei der Umsetzung

Sauberes Beenden – ohne das Target „abzuschießen"

Ein zweiter Fallstrick lauert beim Beenden der UPDI-Sitzung. Im Register CTRLB (Offset 0x03) gibt es Bit 2, UPDIDIS:

„Writing a '1' to this bit disables the UPDI PHY interface. […] All the UPDI PHY configurations and keys will be reset when the UPDI is disabled."

Wer am Ende testweise 0x04 in dieses Register schreibt (z. B. um „sauber abzumelden"), deaktiviert damit die komplette UPDI-Schnittstelle auf dem Target. Danach reagiert der Chip auf keinen weiteren Befehl mehr, bis ein vollständiger, roher Enable-Impuls (das UPDI-Äquivalent eines Kaltstarts) erneut gesendet wird.

Die bessere Alternative: Nur einen System-Reset über ASI_RESET_REQ auslösen (wie in Schritt 3–4 oben beschrieben), ohne UPDIDIS zu setzen. Das Target startet neu, aber die UPDI-Verbindung selbst bleibt aktiv nutzbar.

Zusätzliche Beobachtung: Nach einer bereits aktiven Sitzung (z. B. nachdem PROGSTART erreicht wurde) reicht ein einzelner Enable-Impuls oft nicht mehr aus, um die Verbindung bei einem Neustart des Programmier-Codes zuverlässig neu aufzubauen. Ein zweiter Enable-Impuls kurz nach dem ersten schafft hier zuverlässig Abhilfe – vermutlich, weil eine bereits „wache" UPDI-PHY einen kräftigeren Weckreiz braucht als eine, die seit dem letzten echten Power-Up geschlafen hat.

Nützliches Diagnose-Werkzeug: STATUSB

Für die eigene Fehlersuche lohnt sich ein Blick in STATUSB (Offset 0x01), Bits 2:0 – das PESIG-Fehlersignaturfeld:

PESIGBedeutung
0x0Kein Fehler
0x1Parity-Fehler
0x2Frame-Fehler
0x3Access-Layer-Timeout (UPDI bekommt keine Antwort vom Access Layer)
0x4Clock-Recovery-Fehler
0x6Bus-Fehler (Adress- oder Zugriffsrechtefehler)
0x7Kollisions-/Contention-Fehler

Wer bei LDS/STS einen Timeout bekommt, sollte als Erstes STATUSB auslesen – das grenzt sofort ein, ob es sich um genau das hier beschriebene Access-Layer-Problem handelt oder um etwas anderes (Signalqualität, Kollision auf der Leitung usw.).

Kurz zusammengefasst

  1. LDCS/STCS funktionieren immer, unabhängig vom Chip-Zustand.
  2. LDS/STS brauchen entweder ein bereits laufendes Programm (BOOTDONE = 1) oder den aktiven NVM-Programmiermodus (PROGSTART = 1).
  3. Der NVM-Programmiermodus wird über KEY-Instruktion (NVMPROG-Signatur) + System-Reset-Zyklus + PROGSTART-Polling erreicht.
  4. Zum Beenden nur einen System-Reset auslösen, niemals UPDIDIS setzen – sonst ist die Verbindung komplett tot.
  5. STATUSB (PESIG-Feld) ist das erste Werkzeug bei jeder UPDI-Fehlersuche.

Damit lässt sich auf einem frisch gelöschten AVR-Dx-Chip zuverlässig die Signatur auslesen und der Weg zum eigentlichen Flash-Programmieren ist frei.