www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Programmspeicher beschreiben


Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun mal ausserhalb meines kleinen Blog's eine Frage. Ich drehe hier 
nocht durch.
; *************************************************
; * Flash speicher löschen/beschreiben/überprüfen *
; *************************************************
Flashen:
    ldi yl,low(RS232Buffer) ; Y Pointer laden
    ldi yh,high(RS232Buffer)

  ldi Zaehler,PageSize ; Zähler laden 
  inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 

; Page buffer löschen
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
    rcall Start_SPM

; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

NextPageAdresse:
; In r0 und r1 werte die in den buffer kommen
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
    mov  r0, Dummy1
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
    mov r1, Dummy1
  
    ldi SPMKommando, (1<<SELFPRGEN)
    rcall Start_SPM
    
    dec Zaehler          ; 1 von Zähler abziehen. 
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer

Programmieren:
; Jetzt Buffer ins Flash schreiben
  subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
  subi zh, high(PAGESIZEBYTE);
  
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
  rcall Start_SPM

Tippe ich das ganze steht in der ersten Page fein AA 3C AA 3C u.s.w
Z Pointer ist auf 0

wechsel ich die Zeilen aus
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
    mov  r0, Dummy1
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
    mov r1, Dummy1

gegen
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
    ld r1, y+ ; In R1 Byte aus dem RS232 Buffer

so das der Code so lautet:
; *************************************************
; * Flash speicher löschen/beschreiben/überprüfen *
; *************************************************
Flashen:
    ldi yl,low(RS232Buffer) ; Y Pointer laden
    ldi yh,high(RS232Buffer)

    ldi Zaehler,PageSize ; Zähler laden 
    inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 

; Page buffer löschen
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
    rcall Start_SPM

; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

NextPageAdresse:
; In r0 und r1 werte die in den buffer kommen
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
    ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
  
    ldi SPMKommando, (1<<SELFPRGEN)
    rcall Start_SPM
    
    dec Zaehler          ; 1 von Zähler abziehen. 
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer

Programmieren:
; Jetzt Buffer ins Flash schreiben
    subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
    subi zh, high(PAGESIZEBYTE);
  
    ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
    rcall Start_SPM

steht im Programmspeicher das was im RS232Buffer steht AUSSER die ersten 
2 Byte da steht FF FF drin.

Obwohl wie ich beim Debugen sehe die ersten zwei Byte richtig in r0 und 
r1 geladen werden.

Bin ich echt so doof oder wo liegt mein fehler?

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mal zum verdeutlichen ScreenShot

Im Bild Data (1.) sieht man was im RS232Buffer steht. Fängt mit dem wert 
3C an ( grün ) und hört bei 3C auf ( grün ) das sind 64Byte ( 32 Wörter 
)

Im Bild Programm (2.) sieht mann was im Programmspeicher steht nach dem 
beschreiben. Hört auch mit 3C auf nach 64Byte ( 32 Wörter ) aber die 
ersten beiden sind weg und es steht FF da.

Im Bild Register sieht man aber das die erste zwei werte richtig in r0 
und r1 geschrieben werden.

Ich drehe echt durch.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eventeull komme ich der Lösung näher, wenn mir einer sagen kann wo der 
Page Buffer sitzt. Ab welcher Adresse? Müsste ja wohl 64Byte groß sein. 
Habe auch nix im Datenblatt gefunden, Google gibt auch nix her.

Ich bin am verzweifeln.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Eventeull komme ich der Lösung näher, wenn mir einer sagen kann wo der
>Page Buffer sitzt. Ab welcher Adresse? Müsste ja wohl 64Byte groß sein.
>Habe auch nix im Datenblatt gefunden, Google gibt auch nix her.

Den musst du selbst im Ram anlegen:

     .dseg

RS232Buffer:    .byte 64 ; Reserviert 64 Bytes

     .cseg
....
    ldi yl,low(RS232Buffer) ; Y Pointer laden
    ldi yh,high(RS232Buffer)


MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das habe ich selbst verständlich


.dseg
RS232Zeiger: .Byte 1
RS232Buffer: .Byte 64


aber wie oben getippt verschwinden die erstn zwei nicht aus dem RAM 
sondern im Programmspeicher.

Spess53 schrieb:
> .cseg
>
> ....
>
>     ldi yl,low(RS232Buffer) ; Y Pointer laden
>
>     ldi yh,high(RS232Buffer)

auch das habe ich ja

Flashen:
    ldi yl,low(RS232Buffer) ; Y Pointer laden
    ldi yh,high(RS232Buffer)

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>aber wie oben getippt verschwinden die erstn zwei nicht aus dem RAM
>sondern im Programmspeicher.

Den Satz verstehe ich jetzt nicht. Durch Lesen verschwindet nichts aus 
dem Ram.

MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Spess53

Du könntest aber meine Rettung sein. Habe ich es verständlich machen 
können wo mein Problem liegt.

Lese doch bitte mal von oben, das kann doch nciht sein. Logisch mach ich 
ein fehler aber wo. Ich sitze echt schon stunden lang da und drehe mich 
im kreis.

Spess53 schrieb:
> Den Satz verstehe ich jetzt nicht. Durch Lesen verschwindet nichts aus
>
> dem Ram.

Nein im RAM bleibt es ja auch nur im Programmspeicher fehlen die ersten 
beide. Nehem ich feste werte sind diese im Programmspeicher. lese ich 
sie aus dem RAM aus fehlen die ersten zweite. werden aber in r0 und r1 
gelesen so wie alle auch. habe die schleife schon x mal debugt. kommt 
alles richtig in die schleife. nach dem befehl buffer schreiben in 
programmspeicher ist im programmspeicher alles drin nur die ersten 
beiden nicht.

Wie getippt wenn ich feste werte in r0 und r1 hinterlege werden alle 
übernommen

ich verstehe es nicht

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist doch wohl so das man

1. Page löschen
2. Buffer beschreiben ( r0 und r1 sind die werte eines Worts das 32 mal= 
1 Page 64 Bit)
3. Befehl für Buffer in Programmspeicher schreiben


Und genau dabei fehlt auf einmal das erste Wort. wird aber gelesen.

Meine frage zur fehlersuche ist unter anderem wo ist der Buffer vom SPM

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Also, mit Bootloadern habe ich mich noch nicht beschäftigt.

Bist du sicher, das Z richtig initialisiert ist? Das vermisse ich 
nämlich.

MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja da bin ich mir sicher
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
   ldi zh,0;

   rcall Flashen ; Schreibt RS232Buffer in Programmspeicher z Zeigt auf erste Speicheradresse ( nicht aufs Word )

Wie getippt er holt sich ja auch alle richtig und fein in r0 und r1. 
Würde ich mich nicht immer in frage tellen würde ich ja echt auf ein 
fehler im System ( debuger ) gehen. Aber der Fehler ligt mit sicherheit 
bei mir.

nur wo??

Hier nochmal die ganze Rouitine von Flashen:
; *************************************************
; * Flash speicher löschen/beschreiben/überprüfen *
; *************************************************
Flashen:
    ldi yl,low(RS232Buffer) ; Y Pointer laden
    ldi yh,high(RS232Buffer)

    ldi Zaehler,PageSize ; Zähler laden 
    inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 

; Page löschen
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
    rcall Start_SPM

; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

NextPageAdresse:
; In r0 und r1 werte die in den buffer kommen
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
    ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
  
    ldi SPMKommando, (1<<SELFPRGEN)
    rcall Start_SPM
    
    dec Zaehler          ; 1 von Zähler abziehen. 
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer

Programmieren:
; Jetzt Buffer ins Flash schreiben
  subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
  subi zh, high(PAGESIZEBYTE);
  
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
  rcall Start_SPM

Bereit:
; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

    in Dummy1, SPMCSR
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
    ret
    rjmp Bereit


Start_SPM:

; Läuft noch ein SPM? Ja? Warte bis fertig.
Wait_spm:
    in Dummy1, SPMCSR
    sbrc Dummy1, SELFPRGEN
    rjmp Wait_spm

; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
Wait_ee:
    sbic EECR, EEPE
    rjmp Wait_ee

; SPM starten
    out SPMCSR, SPMKommando
    spm
    ret

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Würde ich mich nicht immer in frage tellen würde ich ja echt auf ein
>fehler im System ( debuger ) gehen.

Das ist kein Debugger sondern ein Simulator. Und nicht ganz fehlerfrei.

Hast du mal getestet, ob das nur bei Page0 so ist?

Poste mal dein komplettes Programm (aber im Anhang). Vielleicht komme 
ich dazu das mal im Controller zu debuggen.

MfG Spess

Autor: Vuvuzelatus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keine Ahnung, ob Dein Bug damit zu tun hat, aber das hier...

  subi zl, low(PAGESIZEBYTE)
  subi zh, high(PAGESIZEBYTE)

...erscheint mir zweifelhaft. Ich vermute, so wäre es richtig:

  subi zl, low(PAGESIZEBYTE)
  sbic zh, high(PAGESIZEBYTE)

Check das mal.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vuvuzelatus schrieb:
> Keine Ahnung, ob Dein Bug damit zu tun hat, aber das hier...
>
>
>
>   subi zl, low(PAGESIZEBYTE)
>
>   subi zh, high(PAGESIZEBYTE)
>
>
>
> ...erscheint mir zweifelhaft. Ich vermute, so wäre es richtig:
>
>
>
>   subi zl, low(PAGESIZEBYTE)
>
>   sbic zh, high(PAGESIZEBYTE)

Jo das ist falsch. Aber es müsste

     subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
     sbci zh, high(PAGESIZEBYTE);

sbci nicht wie du tipptest sbic sein. Habe es geändert aber der Fehler 
bleibt.

Würde auch nicht erkjlären warum es mit diesen zeilen geht
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
    mov  r0, Dummy1
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
    mov r1, Dummy1
 

und mit diesen nicht
  ld r0, y+ ; In r0 Byte aus den RS232 Buffer
  ld r1, y+ ; In R1 Byte aus dem RS232 Buffer

Spess53 schrieb:
> Poste mal dein komplettes Programm (aber im Anhang). Vielleicht komme
>
> ich dazu das mal im Controller zu debuggen.

Jou mach ich moment ich mach es mal zusammen.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hier st es
.INCLUDE "m88def.inc"

.def Dummy1    = r16
.def Zaehler   = r17
.def SPMKommando = r21

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ PAGESIZEBYTE = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words


.cseg    
.org $0E00 ; Programm im BootLoader speichern.

; Stackpointer initialisieren
ldi Dummy1, high(RAMEND) 
out SPH,Dummy1           
ldi Dummy1, low(RAMEND)
out SPL,Dummy1


; Ports initialisieren
ldi  Dummy1, 0b00000000
out DDRC,Dummy1 ; Port-C Eingang
out DDRB,Dummy1 ; Port-B Eingang
ldi  Dummy1, 0b00000010
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD



;Alle Interrups aus
cli

   ldi zl,0; Zeiger auf den Anfang des Flash setzen
  ldi zh,0;

; *************************************************
; * Flash speicher löschen/beschreiben/überprüfen *
; *************************************************
Flashen:
    ldi yl,low(RS232Buffer) ; Y Pointer laden
    ldi yh,high(RS232Buffer)

  ldi Zaehler,PageSize ; Zähler laden 
  inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 

; Page löschen
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
    rcall Start_SPM

; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

NextPageAdresse:
; In r0 und r1 werte die in den buffer kommen
  ld r0, y+ ; In r0 Byte aus den RS232 Buffer
  ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
  
  ldi SPMKommando, (1<<SELFPRGEN)
  rcall Start_SPM
    
  dec Zaehler          ; 1 von Zähler abziehen. 
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
  rjmp NextPageAdresse ; Nächste Zeichen in Buffer

Programmieren:
; Jetzt Buffer ins Flash schreiben
  subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
  sbci zh, high(PAGESIZEBYTE);
  
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
  rcall Start_SPM

Bereit:
; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

    in Dummy1, SPMCSR
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
Ende:
    rjmp Ende ; Endlosschleife geht hier dann weiter
    rjmp Bereit


Start_SPM:

; Läuft noch ein SPM? Ja? Warte bis fertig.
Wait_spm:
  in Dummy1, SPMCSR
  sbrc Dummy1, SELFPRGEN
    rjmp Wait_spm

; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
Wait_ee:
  sbic EECR, EEPE
    rjmp Wait_ee

; SPM starten
    out SPMCSR, SPMKommando
    spm
    ret    

.dseg
RS232Zeiger: .Byte 1
RS232Buffer: .Byte 64

Habe es jetzt mal total abgespeckt. Fehler ist genau der gleiche. Du 
musst zusehen das im .dseg Adresse 000100 etwas drin steh 65 Byte lang 
kein FF 1 Byte benutze ich als Zeiger und dan kommen die 64Byte die auch 
in denn Programmspeicher sollten. Also im.dseg RS232Buffer Ihrgendwelche 
Daten rein.

Nachdem das Programm durchgelaufen ist wirst du sehen das der Inhalt der 
in RS232Buffer im Programmspeicher steht ausser die ersten beiden vom 
RS232Buffer. Beschreibst du r0 und r1 mit feten werten geht es.

Was mit gerade beim tippen hier aufgefallen ist. Kann es sein weil 
RS232Buffer mitten in einem Wort anfängt. Also bei Byte 2. Würde es bei 
Byte 3 anfange wäre es ja bei Wort 2 ders Start.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne mit dem Wort hat es auch nix zutun habe eben das ganze mit

RS232Zeiger: .Byte 2
RS232Buffer: .Byte 64

versucht so das ich mit z genau auf einem Wort lande. Gleicher fehler 
die ersten zwei sind nicht im Programmspeicher. Werden aber gelesen in 
r0 und in r1.


Danke Dir erst mal für die Mühe.


Sage mal wie geht das eigentlich mit dem Debug auf dem Chip. Ich habe 
den AVR USB LAB kann ich das auch machen? Der hat doch auch RX und TX 
fürs Debuggen auf seinem stecker.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Sage mal wie geht das eigentlich mit dem Debug auf dem Chip. Ich habe
><den AVR USB LAB kann ich das auch machen? Der hat doch auch RX und TX
>fürs Debuggen auf seinem stecker.

Kann ich dir nicht sagen. Ich benutze AVR Dragon oder AVR ICE MKII.

Hast du eigentlich in den Simulator Options etwas bei RSTDISBL/IVSEL 
eingestellt?

MfG Spess

Autor: Vuvuzelatus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine NextPageAdresse-Schleife wird einmal zuviel durchlaufen. Dadurch 
wird das erste Word des SPM-Page-Buffers bei dem einen letzten 
überzähligen Durchlauf mit 0xFFFF überschrieben. Schmeiss "inc Zaehler" 
raus und alles ist gut.

(Jo, so einfach... g)

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klatsch mich.

Wow es geht.


Loop:
     Call ganz laut DANKE an Spess53 und Vuvuzelatus
     rjmp Loop


Aber ein gutes hat es. So ist klar das der ATMegga88 ein RingBuffer für 
eine Page nimmt :-)

Was mir noch umklar ist wo sitzt dieser PageBuffer hätte ich mir mal 
angesehen wie der sich füllt hätte ich den Fehler wohl selber finden 
können.


Echt klasse DANKE.


Ist der Weg den ich da gehe und aus dem Datenplatt übernommen habe und 
für mich verständlich gemacht habe der richtige. Oder könnte man da noch 
was optimieren.

Eins ist klar wenn der Bootloader mal fertig wird werde ich ihn genau 
beschreiben und hier veröffentlichen wenn es von Intresse ist.

Autor: Spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Was mir noch umklar ist wo sitzt dieser PageBuffer hätte ich mir mal
>angesehen wie der sich füllt hätte ich den Fehler wohl selber finden
>können.

Der sitzt in den Tiefen des Controllers.

>Ist der Weg den ich da gehe und aus dem Datenplatt übernommen habe und
>für mich verständlich gemacht habe der richtige. Oder könnte man da noch
>was optimieren.

Der Code ist schon nicht schlecht. Ich habe den heute mal in einer 
abgespeckten Version zu Testen benutzt (Anhang).

MfG Spess

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.