Launchprog

Wechseln zu: Navigation, Suche

von minifloat

Was ist das denn?[Bearbeiten]

Ein AVR-ISP-Programmer nach der Atmel AVR910-Appnote, der auf einem TI Launchpad 1.4 mit dem beiliegenden MSP430G2211 oder dem MSP430G2231 und dem beiliegenden Uhrenquarz läuft. Für wenig Geld hat man einen Steckbrettkompatiblen USB-in-System-Programmer für einige Atmel AVR Prozessoren in der Hand.

Einleitung[Bearbeiten]

Das "Henne und Ei"-Problem oder das Basteln eines AVR-ISP-Programmers "aus dem Nichts" wird dem einen oder anderen sicher einmal widerfahren sein.

Dieses Projekt wurde zwar "nur so zum Spaß" und nicht aus der Not heraus durchgeführt, trotzdem möchte ich es euch nicht vorenthalten, da es dem einen oder anderen einmal nützlich sein könnte. Zugegebenermaßen ist es schon ein bisschen dreist gegenüber TI. Aber warum nicht?

Vorteil der Sache ist, man bekommt von TI recht günstig eine funktionsfähige Hardware, die sich direkt an den USB-Port anstecken lässt. Zudem ist auf dem "Emulation" benannten Teil der roten Platine neben der Programmerhardware auch ein USB-Seriell-Adapter integriert.

Nachteil ist, dass der hier verwendete MSP430G2211 keinen UART in Hardware besitzt. Zahlreiche Implementierungen für eine Software-UART existieren in den Foren von TI. Die meistfavorisierten Lösungen benutzen das erste Zeichen, was über RX vom Rechner kommt, um sich auf die Baudrate der eintrudelnden Daten aufzusynchronisieren. Die meisten Software-UARTs benutzen also den internen RC-Oszillator. Das erste Zeichen sollte meist ein 'U' sein(0b01010101 oder 0x55). Der Nachteil an dieser Sache ist, dass das erste gesendete Zeichen nicht bei jeder steuernden Software gleich ist. Der Programmer sollte "sofort nach dem Anstecken" betriebsbereit sein. Zudem liegt den Launchpads kein "amtlicher Quarz" bei. Und wenn gerade ein Quarz rumliegt, dann ist es für einen MSP430-Neuling relativ undurchschaubar, wie man jetzt da dran einen Quarz benutzt.

Ich war zunächst generell auf der Suche nach einem Software-UART für die beiden dem Launchpad beiliegenden Prozessoren. Ich hab mich dann riesig gefreut, eine Lösung von Rick Kimball gefunden zu haben, die den beiliegenden 32,768kHz Uhrenquarz benutzt. Mit diesem wird über eine Art Software-PLL der RC-Oszillator des MSP430G2211 getrimmt. Nach dem Start hat man dann hinreichend stabile 16MHz Haupttakt. Wer wissen will, wie das genau geht, kann sich den Sourcecode zur Software-UART von Rick Kimball ansehen. Die eigentliche Soft-UART wird dann über Timer-ISRs abgewickelt. Um diesen Teil musste ich mich also nicht mehr groß kümmern. Der Software-UART von Rick Kimball braucht für sich allein und mit der "Echo"-Demo schon 1kB Flash im MSP430G2211(er hat 2kB). Aus der Frage, was noch in die restlichen 1kB Speicher passt, wurde dann die Idee zu diesem Projekt geboren.

Hardware[Bearbeiten]

Grundüberlegungen zur HW[Bearbeiten]

  • Am MSP430G2211 gibt es, wenn er im Launchpad steckt, an sich nicht mehr allzu viele freie Pins. Zudem wollte ich die LEDs freihalten, um darüber zunächst eine Debugmöglichkeit und später eine Ausgabe des Status zu haben. Da der Software-UART Interruptgetrieben läuft, kann man, wenn es "heiß hergeht", nicht viel mit mspdebug/msp430-gdb ausrichten.
  • Es sollten keine Modifikationen oder große Anbauten am Launchpad erfolgen, es soll "so wie es ist" als AVR910 betreibbar sein. Der vorhandene Taster S2 und die beiden LEDs sollen nachher sinnvoll nutzbar sein.
  • Das Target kann aus dem Launchpad mit 3,3V oder 5V versorgt werden. Da der MSP430G2211 mit 3,3V läuft, muss bei 5V am Target in die MISO-Leitung ein Widerstand eingefügt werden. 5V kann man sich an TP1 neben der USB-Mini-B-Buchse abgreifen(ungesichert direkt aus dem USB). Nach Nachmessen steht fest: naja, es sind wohl eher 3,5V statt 3,3V an VCC. Die Überlegungen gelten natürlich trotzdem.
  • Rick Kimballs Soft-UART-Software besaß eine Möglichkeit, an P1.0 ACLK(32kHz) und an P1.4 SMCLK(16MHz) auszugeben. Man konnte so die korrekte Funktion des Uhrenquarzes und der Synchronisationsroutine mit den 16MHz überprüfen. Das musste nach einem ersten Funktionstest rausfliegen, da sonst zuwenig Pins zur Verfügung stünden. Wer die Funktion des Quarzes und die 16MHz nachmessen möchte, kann zuerst Ricks Software aufspielen und damit testen.
  • Rick Kimballs Soft-UART läuft mit 9600Bd. Der AVR910 läuft aber, soweit ich das absehe, meist mit 19200Bd. Hier soll erstmal die reine Funktionalität im Vordergrund stehen. Da sich AVRDUDE "runterkonfigurieren" lässt, sehe ich für meinen Teil kein Problem in dieser Sache. Der USB-Seriell-Adpater des "Emulation"-Teils vom Launchpad geht zudem nur bis 9600Bd. Also soll es erstmal so sein. Ob das Launchpad bei höheren Baudraten als 9600Bd trotzdem nur 9600Bd hergibt(und damit auch 19200Bd "runtergestutzt" ohne andere Firmware funktionieren würden), habe ich noch nicht getestet.

Pinbelegung[Bearbeiten]

Launchprog an einem ATmega16

Herausgekommen ist folgende Pinbelegung für die AVR ISP Schnittstelle:

Launchpad AVR ISP Bemerkung
P1.3 ~RESET parallel dazu Taster S2 nach GND
P1.4 MOSI
P1.5 MISO
P1.7 SCK
VCC +3,5V Targetversorgung +3,5V
TP1 +5V optionale Targetversorgung +5V
GND GND

Dass auf dem Launchpad der Taster S2 an P1.3 ist, kommt einem insofern entgegen, da man damit das Targetsystem auch mal resetten kann. Es gibt also jetzt zwei Reset-Taster: einen für den AVR, einen für den MSP430. Wenn man eine Targetspannung von +5V benutzt, muss ein Widerstand von 1kΩ in die MISO-Leitung eingefügt werden.

Uhrenquarz[Bearbeiten]

Der dem Launchpad beiliegende 32,768kHz Uhrenquarz muss bestückt werden, wenn man dies noch nicht getan hat.

LEDs[Bearbeiten]

Was die LEDs auf dem Launchpad aktuell anzeigen:

# LED Funktion
LED0  Grüne LED "PWR" Spannungsversorgung Launchpad
LED1 Rote LED bei S2 Zugriff auf Target-AVR("Programming mode")
LED2 Grüne LED bei S2 AVR910 wartet auf Kommando("Idle")

Die LEDs werden nicht durch die im AVR910-Protokoll vorgesehenen Softwarekommandos gesteuert. Die LED-Softwarekommandos werden ignoriert und quittiert, da sonst die Brennsoftware am PC meckern würde. Das wurde bei Serasidis' AVR910 schon so gehandhabt.
Man sieht also an den LEDs was wirklich getan wird und nicht was die Brennsoftware einem Glauben machen will. Die Jumper J5 bei den LEDs müssen natürlich beide gesteckt sein.

Jumper J3[Bearbeiten]

Die Jumper, die den "Emulation"-Teil mit dem unteren "MSP-EXP430G2"-Teil verbinden, müssen zum Programmieren des MSP430G2211 alle gesteckt sein.
Für einen Betrieb nur als AVR910 kann man (muss man aber nicht)den "TEST"- und den "RST"-Jumper herausnehmen, falls man ein versehentliches Überschreiben des MSP430G2211 vermeiden will. Dies kann u.U. bei anderen, parallel zu den AVR-Projekten laufenden MSP430-Projekten versehentlich passieren.
Die Jumper "VCC", "TXD" und "RXD" müssen natürlich drin bleiben.

Software[Bearbeiten]

Grundüberlegungen zur SW[Bearbeiten]

  • Es gibt zahlreiche Implementierungen des AVR910, die einen gepufferten Modus unterstützen. Da der MSP430G2211 nur 128Byte RAM hat, ist wohl eher wenig Platz für einen Puffer. Die beim AVR910-Programmer v3.8 von Klaus Leidinger gewählte Puffergröße von 64Byte wollte ich nicht garantieren. Beim AVR910-Programmer v3.3 von Serasidis Vasilis gibt es keinen Puffer, es werden aber schon die "Universal Commands" unterstützt. Meine Wahl fiel deshalb auf diesen.
  • Das Launchpad soll sich wie ein generischer AVR910-Programmer verhalten. Daher wurden die zwei bereits genannten und hier im µC.net als funktionierend bekannten Implementierungen als Grundlage benutzt. Grundsätzlich wollte ich erreichen, dass sich der Launchprog wie der AVR910-Programmer v3.3 von Serasidis Vasilis verhält. Das ist bis auf zwei Stellen auch so.
  • Der Launchprog soll mit einer halbwegs modernen Version von AVRDUDE zusammenarbeiten. Ich benutzte zum Zeitpunkt der Entwicklung Version 5.8, also sollte es damit fürs Erste funktionieren.
  • Da die Sourcen für den AVR910 als AVR-Assembler vorliegen, musste das Verhalten nach C transkodiert werden. Der Code von Serasidis Vasilis enthält zahlreiche Kommentare, die C als Pseudocode zur Erklärung der Schritte in Assembler beinhalten. Oft konnten diese Pseudocode-Schnipsel direkt übernommen werden.
  • Die Namensgebung der C-Funktionen orientiert sich stark an der Namensgebung der Assembler-Routinen. Ich denke, dass im Vergleich von Assemblervorlage und meinem Code die grundsätzliche Funktion nachvollziehbar sein sollte.

Soft-UART[Bearbeiten]

Damit meine Vorgabe bezüglich der Namensgebung auch für die Soft-UART von Rick konsistent ist, habe ich ein paar kleine Wrapper-Funktionen geschrieben, die sich stark an den hier im Forum bekannten Implementierungen für einen Zugriff auf die Hardware-UART eines Atmel AVR anlehnen und die gleiche Funktionalität bieten. Damit konnte ich schon mal wie gewohnt auf AVR-Umgebung arbeiten. Bei Serasidis Vasilis' ASM-Code haben die UART-Routinen kein Präfix "uart_". Die von mir verwendete Version vom msp430-gcc hat sich -warum auch immer- über "getc()" beschwert, also musste da etwas "manuelles Name-Mangling" Korrektur schaffen.

Soft-SPI[Bearbeiten]

Zugegebenermaßen bin ich zuerst nicht wirklich durch die ASM-Routine "wrser" für Schreiben auf die SPI durchgestiegen. Aufgrund dessen habe ich eine eigene Routine dafür genommen, die sich bei meinen bescheidenen Basteleien bewährt hat. Anstatt hier und da zu schieben und eine Zählvariable zu benutzen, nehme ich eine Bitmaske und statt zu zählen wird eben geschoben/durch 2 geteilt. Mittlerweile habe ich die Funktion der Originalroutine verstanden. Meine Implementierung sollte sich gleich verhalten. Die Funktionalität der SPI-Leseroutine "rdser" wurde durch ein Makro erreicht.

Devicecodes[Bearbeiten]

Die Liste der von Launchprog unterstützten Devices(Target-Prozessoren) ist gleich der Liste der von Serasidis Vasilis' AVR910. Mit ein bisschen "Find & Replace" war die Liste auch recht schnell nach C umgesetzt. Ich hab sie einfach in ein Headerfile geworfen. Beim Test, ob der von der Brennsoftware am PC gewählte Devicecode überhaupt in der Liste der unterstützten Devices ist, wurde im Assemblercode eine ziemlich zeitraubende Methode gewählt:

  • Es lässt sich grundsätzlich erst mal jeder Devicecode auswählen
  • Jedesmal vor dem Zugriff auf die Programmierroutinen wird geprüft, ob der Devicecode gültig ist. Wenn der Devicecode nicht gültig ist, wird eine Fehlermeldung ausgegeben und wieder die "warte auf Kommando"-Marke angesprungen. Für jedes zu schreibende Byte muss die Überprüfung durchgeführt werden. Das erschien mir ein wenig ineffizient.

Die Gültigkeit des gewählten Devicecodes wird in meinem C-Code sofort nach der Auswahl geprüft.

  • Wenn der Devicecode stimmt, wird ein Flag "dev_ok" gesetzt und quittiert(CR ausgeben). Außerdem wird ein Device-abhängiges Flag gesetzt, welches erst beim Programmieren wichtig ist, das war aber auch schon im Original so.
  • Wenn der Devicecode nicht stimmt, wird das Flag nicht gesetzt und eine Fehlermeldung ausgegeben("?").
  • Die Funktionen zum Zugriff auf das Target sind bei nicht gesetztem Flag nicht zugänglich, es wird nach Ausgabe der Fehlermeldung ("?") durch ein "continue;" wieder zum "Warte auf Kommando" zurückgekehrt.

Wer genau wissen will, was da vor sich geht, sei auf den C-Quelltext und zum Vergleich die Assemblersource von Serasidis Vasilis verwiesen.

Bei Version 1.2 wurde ein Bug in der Deviceauswahl beseitigt. Dieser rief das "Kaltstartproblem" hervor(siehe Known Bugs). Der Zugriff auf die Programmierroutinen ist nun grundsätzlich erlaubt, es sei denn, es wird ein "falscher" Devicecode eingestellt.

Blockmodus[Bearbeiten]

AVRDUDE führt vor jedem Start eines Programmier- oder Lesevorgang auf dem Target eine Art Service-Discovery des Programmers durch. Bei den ersten Tests meldete sich avrdude mit "Programmer not responding". Um dieser Sache auf den Grund zu gehen, habe ich einen zweiten USB-Seriell-Adapter an die RX-Leitung gehängt. Mit diesem Lauschangriff konnte ich sehen, ob es nun an AVRDUDE oder an meinem Code liegt. Nun - es lag an beidem. AVRDUDE schreibt ein 'b', um festzustellen, ob der angeschlossene AVR910 den gepufferten Blockmodus unterstützt. Da dieses Kommando in Serasidis Vasilis' Code nicht existiert, meldet der Programmer '?'. So war es also auch bei mir. Aus den Sourcen von Klaus Leidinger habe ich die Info entnommen, was es mit dem 'b' überhaupt auf sich hat. Launchprog meldet auf das Kommando 'b' nun ein 'N' wie "Nein, ich unterstütze keinen Blockmode". Soweit scheint dieses Problem gelöst zu sein.

Version[Bearbeiten]

Die Service-Discovery-Funktionen, die Soft- und Hardwareversion zurückgeben, geben aktuell die Versionsnummern von Serasidis Vasilis' AVR910 zurück. Dies habe ich aus Kompatibilitätsgründen so gewählt. Die Versionsnummern stimmen natürlich nicht mit der Launchprog-Version überein.

Build der Firmware[Bearbeiten]

Zum Bau der Firmware wurde msp430-gcc v4.5.3 verwendet. In Rick Kimballs Code fanden sich noch einige nach diesem Stand veraltete Headerdateien. Ich hab das ein wenig aufgeräumt und der Bau sollte ohne Fehler und ohne Warnungen durchgehen. Wer die Software nicht selbst zusammenbauen kann oder möchte, kann auch das fertige Binary direkt auf den MSP430G2211 aufspielen. Quellcode und Binary gibt es in der Download-Sektion unten.

Known Bugs[Bearbeiten]

Tracking[Bearbeiten]

Bug# Kurzbeschreibung Prio Erkannt Beseitigt
Bug1 Kaltstartproblem hoch v1.1 v1.2
Bug2 Target-Reset niedrig v1.1 -

Beschreibung der Bugs[Bearbeiten]

Bug1 "Kaltstartproblem" (Beseitigt!)
Das erste Kommando von AVRDUDE, nachdem der MSP430G2211 läuft, wird teilweise verschluckt. AVRDUDE gibt einen Fehler zurück. Wenn man das Ding am USB stecken lässt, sind alle weiteren Versuche von AVRDUDE erfolgreich (bis zum nächsten Reset des MSP430G2211 bzw. Anstecken des Launchpads).

Bug2 "Target-Reset" (Muss noch geprüft werden)
Das Verhalten am ~RESET-Pin sollte noch einmal genauer unter die Lupe genommen werden. Der Pin wird eventuell nach dem Verlassen des Programmiermodus kurz aktiv nach High gezogen, bevor der ganze Port "losgelassen" wird. Das Verhalten der Portpins bei den MSP430 beinhaltet eigene Register zur Aktivierung von Pullups. Beim Verlassen des Programmiermodus(rote LED geht aus) sollte S2 nicht gedrückt werden. Aber wer tut das schon...

Tests[Bearbeiten]

Testkonditionen[Bearbeiten]

Um die grundsätzliche Funktionalität von meinem Launchprog zu ergründen,
wurden mit einigen unterstützten Atmel AVR folgende Tests durchgeführt:

  • Programmieren des Flash mit Launchprog
  • Verify des Flash mit Launchprog
  • Verify des Flash mit einem USBasp v2011-05-28
  • Programmieren des EEPROM Launchprog
  • Verify des EEPROM mit Launchprog
  • Verify des EEPROM mit einem USBasp v2011-05-28
  • Programmieren eines Fusebits mit Launchprog
  • Verify der Fusebits mit Launchprog
  • Verify der Fusebits mit einem USBasp v2011-05-28

Funktionierende Konfigurationen[Bearbeiten]

Folgende Prozessoren sind mit Launchprog v1.2 + AVRDUDE getestet worden:

Launchprog an einem ATtiny13A
Target-AVR → ATmega16 ATmega8 ATtiny2313A ATtiny13A AT90USB162[2]
Avrdude Version 5.11 5.8 5.8 5.11 5.11
Flash Prog. Launchprog √ [1]
Verify Flash Launchprog √ [1]
Verify Flash USBasp -
EEPROM Prog. Launchprog √ [1] -
Verify EEPROM Launchprog √ [1] -
Verify EEPROM USBasp -
Fuses Prog Launchprog √ [1] -
Verify Fuses Launchprog √ [1] -
Verify Fuses USBasp -

"√" = geht/OK
"t" = Test geplant/ Test wird durchgeführt
"-" = noch nicht getestet
"X" = geht nicht/nicht OK

Anmerkungen:
[1] in der avrdude-Konfigurationsdatei avrdude.conf muss in der Sektion für den ATtiny13 ein Devicecode für den AVR910 hinzugefügt werden.
An der Firmware des Launchprog muss nichts geändert werden. Hier habe ich zum Test mal den Devicecode vom ATtiny19 genommen(die zugehörige Hex-Zahl kann man z.B. devcodes.h im Sourcecode des Launchprog entnehmen):

...
stk500_devcode      = 0x14;
# this is the devicecode for Tiny19, works though
avr910_devcode      = 0x58;
signature           = 0x1e 0x90 0x07;
...

Es empfiehlt sich, für "neue" Prozessoren einen Devicecode ohne 'P' zu benutzen. Das zusätzliche Delay beim Beschreiben des Flash schadet in keinem Fall.
Mit avrdude macht es keinen Unterschied, da avrdude nach Einsprung in den Programmiermodus sowieso nur noch die "universal commands" benutzt und Delays entsprechend der avrdude.conf einfügt.
[2] Parameter "-x devcode=0x60" war nötig.
Mehr Prozessoren:
Wer noch ein paar andere Prozessoren testen möchte: Nicht zögern, dies zu tun. Bitte auch die Ergebnisse in die Tabelle eintragen oder sonstwie hier dokumentieren. Ab und zu werden auch weitere Einträge in der Tabelle von mir erscheinen.

Aufruf von AVRDUDE[Bearbeiten]

Der Launchprog verhält sich in der jetzigen Version 1.2 nahezu wie ein generischer AVR910-Programmer. Er läuft jedoch mit 9600Bd statt wie im Original mit 19200Bd. Der Aufruf von AVRDUDE sollte also wie folgt stattfinden:

avrdude -c avr910 -b 9600 -P <PORT> -p <PART> -U <KOMMANDO>

Wer eine GUI für AVRDUDE benutzt, sollte nach einer "Speed" oder "Baudrate" genannten Konfigurationsmöglichkeit Ausschau halten. Hierbei ist lediglich die Geschwindigkeit der seriellen Schnittstelle gemeint, nicht die Frequenz des ISP-Taktes an SCK!

Weitere Entwicklung[Bearbeiten]

Ich(minifloat) werde den Kram hier nicht mehr weiter Entwickeln oder Pflegen. Wer sich dran freut das zu tun den lass ich gerne vor.

Downloads[Bearbeiten]

Neueste Version:

Alte Versionen:

Troubleshooting[Bearbeiten]

error: 'TA0IV_TACCR1' undeclared[Bearbeiten]

Falls beim kompilieren der Version 1.2 folgender Fehler auftritt:

$ make
msp430-gcc -Os -Wall -g -mmcu=msp430g2231 -c main.c
msp430-gcc -Os -Wall -g -mmcu=msp430g2231 -c softserial.c
softserial.c: In function 'SoftSerial_RX_ISR':
softserial.c:281:19: error: 'TA0IV_TACCR1' undeclared (first use in this function)
softserial.c:281:19: note: each undeclared identifier is reported only once for each function it appears in
make: *** [softserial.o] Error 1

Hilft folgender Patch für softserial.c

--- softserial.c	2012-12-26 14:54:00.974029300 +0100
+++ softserial.c.new	2012-12-26 14:54:22.943562900 +0100
@@ -273,6 +273,10 @@
     static unsigned char rxBitCnt = 8;
     static unsigned char rxData = 0;
 
+#ifndef TA0IV_TACCR1
+#define TA0IV_TACCR1 TAIV_TACCR1
+#endif /* TA0IV_TACCR1 */
+
 #ifdef TIMER0_A1_VECTOR
     if ( TA0IV == TA0IV_TACCR1 ) {     // this mcu has multiple TIMERA peripherals
 #else

Links und Referenzen[Bearbeiten]