@Arne Rossius:ISP Progger

Moin Arne!

Du hast mir am 22.08. bei einem AVR Progger Problerm geholfen. Nun habe ich da nochmal ne kleine Frage :-) (Muss es leider über diesen Weg machen, denn dein Formmailer geht irgendwie nicht.) Und zwar kriege ich das Proggen des Speichers nicht sauber hin. Das ist meine Funktion: // Load Program Memory Page 0100 H000 xxxx xxxx xxxx bbbb iiii iiii // Write H (high or low) data i to Program Memory page at word address b. // Data low byte must be loaded before data high byte is applied within // the same address. // Write Program Memory Page 0100 1100 xxxx xxaa bbbb xxxx xxxx xxxx // Write Program Memory Page at address a:b. // i = data in a = address high bits b = address low bits // H = 0 - Low byte, 1 - High Byte o = data out procedure TForm1.AVRFlashSchreibenClick(Sender: TObject); var i,j,k,l:integer; begin ComOpen(COMCombo.Text); SPIInit; // Speicher löschen ISPInOut(172); ISPInOut(128); ISPInOut(0); ISPInOut(0); Delay(10); l := 0; // Positionszeiger für HexEdit for k := 0 to 3 do // \ for j := 1 to 16 do // / 16Byte Blöcke wegschreiben begin for i := 0 to 15 do // Puffer füllen begin // erst Low Byte schreiben ISPInOut(64); ISPInOut(0); ISPInOut(i); ISPInOut(hextoint(chartohex(AVRHex.GetMemory(l+1)))); // dann HighByte schreiben ISPInOut(72); ISPInOut(0); ISPInOut(i); ISPInOut(hextoint(chartohex(AVRHex.GetMemory(l)))); inc(l); inc(l); end; // checken ob ein Byte aus der Page geschrieben wurde // wenn dem so ist, kann erst die nächste Page geschrieben werden! {ISPInOut(32); //< Hi-Byte ISPInOut(k); ISPInOut(j); res := ISPInOut(0); }

// Schreibe Memory Page ISPInOut(76); ISPInOut(k); ISPInOut(j*16); ISPInOut(0); delay(10); //Memo1.Lines.Add('Schreibe Memory Page'); end; CLOSECOM; end;

Und das ist SPIInit (funzt auch sauber): // SPI Proceduren & Funktionen procedure SPIInit; var i:integer; begin TXD(1); // RTS(0); // Initialisierung einleiten Delay(100); TXD(0); Delay(100); TXD(1); Delay(100); for i:=1 to 4 do // Synchronisieren begin ISPInOut(172); ISPInOut(83); ISPInOut(0); ISPInOut(0); end; end;

Er schreibt die Werte einfach nicht sauber weg. Kannst du mir mal erklären auf was man da achten muss? Oder kannst du mir nochmal deine Funktion für das Flashen schicken?

Grüße Dominik

Reply to
Dominik Schmidt
Loading thread data ...

Der Formmailer war nur falsch konfiguriert und hat nach erfolgreichem Versenden die Hauptseite angezeigt, deine Email ist aber trotzdem nicht angekommen. Aber but das du mich drauf hingewiesen hast, sonst hätte ich es wohl nie gemerkt.

[...]

Dort habe ich 25ms Wartezeit stehen. 10ms sind nur bei 5V genug (Werte des 90S2313).

^ Da gehört das High-Byte der Adresse hin, sonst kannst du nur 256 Words programmieren.

^^^^^^^^^ Wenn das Ergebnis dieser Funktion nicht char ist, was dann?

^ siehe oben

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Hast du dir die Ergebnisse dieser Konversionen mal ausgeben lassen und überprüft?

Verstehe ich nicht. Was haben die Variablen damit zu tun? Vor allem, weil j (Low-Byte) ja von 1 bis 16 läuft (sollte es nicht 0-255 sein?).

Page? Was meinst du damit? Normalerweise kann man die Words nur einzeln schreiben (also 2 Byte, dann warten).

Was ist das für ein Befehl?

Wo synchronisierst du da was? Du sendest einfach 4x das gleiche:

Im Datenblatt des 2313 steht das hier: | The serial programming instructions will not work if the communication | is out of synchronization. When in sync, the second byte ($53) will | echo back when issu-ing the third byte of the Programming Enable | instruction. Whether the echo is correct or not, all four bytes of the | instruction must be transmitted. If the $53 did not echo back, give SCK | a positive pulse and issue a new Programming Enable instruction. If the | $53 is not seen within 32 attempts, there is no functional device | connected.

Wo prüfst du das Echo 53? Und wo gibst du den Puls auf SCK, wenn es nicht kommt?

Falls du da durchblickst:

'Datei öffnen, Endlosschleife bis Dateiende erreicht: Open FileName For Input As 1 Do Until EOF(1) Line Input #1, Record If Left(Record, 1) = ":" And Len(Record) > 10 Then 'Hexfile-Zeilen-Header von Hex nach Dezimal konvertieren Length = CLng("&H" & Mid(Record, 2, 2)) Offset = CLng("&H" & Mid(Record, 4, 4)) RecType = CLng("&H" & Mid(Record, 8, 2)) If RecType = 0 Then 'Daten im Hexfile an den Controller senden (eine Hexfile-Zeile) For A = 0 To Length - 1 Form1.lblStatus = "Programming [" & Right("0000" & Hex((Offset + A) \

2), 4) & "]" DoEvents Data = CLng("&H" & Mid(Record, 10 + 2 * A, 2)) 'Wert des Bytes Addr = (Offset + A) \ 2 'Adresse im Controller High = (Offset + A) And 1 'High-Byte oder Low-Byte? If Data &HFF Then '0xFF braucht nicht programmiert zu werden WriteFlash Data, Addr, High 'wenn das Byte 7F ist, warten, sonst pollen bis der richtige Wert gelesen wird If InStr("7F", Hex(Data)) Then DELAY 5 Else Start = Timer Failed = False Do While ReadFlash(Addr, High) Data If Timer - Start > 0.5 Then 'Timeout nach 0.5s erfolglosem warten Failed = True Exit Do End If Loop If Failed Then Exit Do End If End If Next ElseIf RecType = 1 Then 'Dateiende-Makierung im Hexfile Exit Do End If End If Loop Close

Function ReadFlash(ByVal Addr As Integer, ByVal High As Boolean) As Byte X = Send(&H20 - 8 * High) '0x20 für Low-Byte (High=0), 0x28 für High-Byte (High=-1) X = Send(Addr \ 256) 'High- & Low-Bytes der Adresse X = Send(Addr Mod 256) ReadFlash = Send(&H0) 'Byte aus dem Flash lesen und zurückgeben End Function

Sub WriteFlash(ByVal Data As Byte, ByVal Addr As Integer, ByVal High As Boolean) X = Send(&H40 - 8 * High) X = Send(Addr \ 256) X = Send(Addr Mod 256) X = Send(Data) End Sub

Gruß, Arne

Reply to
Arne Rossius

"Arne Rossius" wrote i

Moin !

Ok, das kann ich ändern. Das Löschen funzt aber. Das kann ich ja auslesen.

So und nun eben zu der generellen Programierung des Tiny26 (den wir ja nutzen). Im Datenblatt steht das: Data Polling Flash When a page is being programmed into the Flash, reading an address location within the page being programmed will give the value $FF. At the time the device is ready for a new page, the programmed value will read correctly. This is used to determine when the next page can be written. Note that the entire page is written simultaneously and any address within the page can be used for polling. Data polling of the Flash will not work for the value $FF, so when programming this value, the user will have to wait for at least tWD_FLASH before programming the next page. As a chip-erased device contains $FF in all locations, programming of addresses that are meant to contain $FF, can be skipped. See Table 59 for tWD_FLASH value.

Daraus lese ich, das ich mittels Load Program Memory Page 0100 H000 xxxx xxxx xxxx bbbb iiii iiii erstmal 16 Words in den Controller laden muss. Das High und Low Byte wird dabei durch H unterschieden. Wenn ich dann die 16 Words oder 32 Bytes im Controller habe, dann kann ich das wegschreiben. So, die Page in den Controller bringen macht dieser Teil:

for i := 0 to 15 do // Puffer füllen begin // erst Low Byte schreiben ISPInOut(64); ISPInOut(0); ISPInOut(i); ISPInOut(hextoint(chartohex(AVRHex.GetMemory(l+1)))); delay(5); // dann HighByte schreiben ISPInOut(72); ISPInOut(0); ISPInOut(i); ISPInOut(hextoint(chartohex(AVRHex.GetMemory(l)))); delay(5); inc(l); inc(l); end;

Dazu hast du geschrieben:

Das verstehe ich nicht, denn das wäre ja gegen das Datenblatt (Load Program Memory Page 0100 H000 xxxx xxxx xxxx bbbb iiii iiii)

Die Funktion ist sauber. Das Ergebnis ist ein Integer was ich auch brauche. Das habe ich geprüft.

So, wenn ich nun also eine Page im Speicher habe, dann kann ich die mittels: Write Program Memory Page 0100 1100 xxxx xxaa bbbb xxxx xxxx xxxx in den Controller schreiben lassen (bzw. der macht das dann selber).

Und dafür ist dann dieser Teil zuständig: l := 0; // Positionszeiger für HexEdit for k := 0 to 3 do // \ for j := 1 to 16 do // / 16Byte Blöcke wegschreiben begin for i := 0 to 15 do // Puffer füllen begin // Puffer füllen siehe oben ! end; // Schreibe Memory Page ISPInOut(76); ISPInOut(k); ISPInOut(j*16); ISPInOut(0); delay(10); //Memo1.Lines.Add('Schreibe Memory Page'); end;

Die For Schleife mit k füllt diesen Bereich aus: Write Program Memory Page 0100 1100 xxxx xxaa bbbb xxxx xxxx xxxx ^^ also die beiden a Die for Schleife mit j füllt den Bereich mit b aus aber so: ISPInOut(j*16);

Nein, denn wenn ich das richtig lese, dann muss man beim Tiny26 Pages schreiben (=32 Byte)

Write Program Memory Page 0100 1100 xxxx xxaa bbbb xxxx xxxx xxxx

0100 1100 = 76

Schon klar. Aber ich weiss, das ich beim Tiny nach 2x senden die 53 empfange. Somit gehe ich auf Seite Sicher und schicke das 4x. Dann muss ich nicht extra auf 53h abfragen :-) Aber das funzt ja auch bei allen anderen Operationen.

Ich vermute das mir dann deine Funktionen nicht viel nützen, weil das Programmieren anders geht als beim Tiny.

Hast du trotzdem noch eine Idee??

Greetz Dominik

Reply to
Dominik Schmidt

Da musste ich mir jetzt erst mal das Datenblatt vom Tiny26 besorgen, du hast recht, da ist alles ganz anders. Ich muss jetzt erst mal verstehen, wie die das im Datenblatt genau meinen, scheint etwas komlizierter zu sein als das Wordweise programmieren.

^^^^ Deshalb stand der nicht im Datenblatt vom 2313 drin. Übrigens gibt es im Datenblatt vom Tiny26 noch einen "Read Program Memory" Befehl (ohne Page), nicht aber für Write.

Auch das ist beim Tiny26 anders als ich dachte, hier muss man einen Puls auf Reset geben, nicht auf SCK, um zu synchronisieren.

Solltest du trotzdem tun, sonst weißt du nie, ob dein Controller überhaupt gemerkt hat, dass du ihn programmieren willst.

Bau' dir den Sercon2 Mini doch einfach mal auf, ist ja nicht kompliziert, und probiere, ob es mit meiner Software nicht doch funktioniert. Vielleicht ist der Tiny26 ja abwärtskompatibel, so dass du erst mal "normal" programmieren könntest und dir keine Gedanken über Pages machen musst.

Gruß, Arne

Reply to
Arne Rossius

"Arne Rossius" wrote

Das nützt nix. Der kann nur über die Pages programmiert werden. Sonst hätte ich es schon lange am drehen.

btw. Kann ich mal deine Mailadresse bekommen, dann kann man sich doch etwas schneller austauschen. Zumal es ja um Programmierung geht ...

Kanst mir ja einfach eben ne Mail an schmidomweb.de schiggn.

Greetz Dominik

Reply to
Dominik Schmidt

Moin !

Es ist gelöst und funzt nun. Ich hatte zwei kleine Fehler in der Routine ...

Trotzdem Danke für deine Hilfe!

Grüße Dominik

Reply to
Dominik Schmidt

rd

m

Das sieht gut aus. Im Zweifel wuerde ich aber noch High-Byte first probieren. Ich bin da mit dem mega161 schon mal auf der Schnauze geflogen weil der es andersherum haben wollte als der mega103.

che.

Wobei mich wundert, dass du "GetMemory(l+1)" machst um das Low-Byte zu lesen. Auf einer Little Endian (Intel) Maschine haette ich dort das High-Byte erwartet.

tels:

j*16);

Es geht also mit aabbbb=3D000001 los - und hier sehe ich ein Problem: Da die j-Schleife bei 1 loslaeuft wird mit Page 1 statt mit Page 0 begonnen. Bei j=3D16 gibt es einen Integer-Overflow weil 16*16 nicht mehr=

in ein Byte passt ... das MSB geht also verloren und es bleibt 0 uebrig =3D> Jetzt wird Page 0 geschrieben. IMHO werden die Pages also in der Reihenfolge 1..15,0,17..31,16,33,etc. geschrieben, was wohl nicht erwuenscht ist.

Micha

--

Wenn man schon Gefangener seines eigenen Geistes ist, kann man sich
wenigstens seine Zelle vernuenftig moeblieren.

                                        Sir Peter Ustinov
Reply to
Michael Baeuerle

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.