Forum: Mikrocontroller und Digitale Elektronik Programmspeicher beschreiben


von Holger P. (Gast)


Lesenswert?

Nun mal ausserhalb meines kleinen Blog's eine Frage. Ich drehe hier 
nocht durch.
1
; *************************************************
2
; * Flash speicher löschen/beschreiben/überprüfen *
3
; *************************************************
4
Flashen:
5
    ldi yl,low(RS232Buffer) ; Y Pointer laden
6
    ldi yh,high(RS232Buffer)
7
8
  ldi Zaehler,PageSize ; Zähler laden 
9
  inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 
10
11
; Page buffer löschen
12
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
13
    rcall Start_SPM
14
15
; Wieder bereit machen für RWW
16
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
17
    rcall Start_SPM
18
19
NextPageAdresse:
20
; In r0 und r1 werte die in den buffer kommen
21
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
22
    mov  r0, Dummy1
23
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
24
    mov r1, Dummy1
25
  
26
    ldi SPMKommando, (1<<SELFPRGEN)
27
    rcall Start_SPM
28
    
29
    dec Zaehler          ; 1 von Zähler abziehen. 
30
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
31
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
32
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer
33
34
Programmieren:
35
; Jetzt Buffer ins Flash schreiben
36
  subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
37
  subi zh, high(PAGESIZEBYTE);
38
  
39
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
40
  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
1
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
2
    mov  r0, Dummy1
3
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
4
    mov r1, Dummy1

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

so das der Code so lautet:
1
; *************************************************
2
; * Flash speicher löschen/beschreiben/überprüfen *
3
; *************************************************
4
Flashen:
5
    ldi yl,low(RS232Buffer) ; Y Pointer laden
6
    ldi yh,high(RS232Buffer)
7
8
    ldi Zaehler,PageSize ; Zähler laden 
9
    inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 
10
11
; Page buffer löschen
12
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
13
    rcall Start_SPM
14
15
; Wieder bereit machen für RWW
16
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
17
    rcall Start_SPM
18
19
NextPageAdresse:
20
; In r0 und r1 werte die in den buffer kommen
21
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
22
    ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
23
  
24
    ldi SPMKommando, (1<<SELFPRGEN)
25
    rcall Start_SPM
26
    
27
    dec Zaehler          ; 1 von Zähler abziehen. 
28
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
29
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
30
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer
31
32
Programmieren:
33
; Jetzt Buffer ins Flash schreiben
34
    subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
35
    subi zh, high(PAGESIZEBYTE);
36
  
37
    ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
38
    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?

von Holger P. (Gast)


Angehängte Dateien:

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.

von Holger P. (Gast)


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.

von Spess53 (Gast)


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:
1
     .dseg
2
3
RS232Buffer:    .byte 64 ; Reserviert 64 Bytes
4
5
     .cseg
6
....
7
    ldi yl,low(RS232Buffer) ; Y Pointer laden
8
    ldi yh,high(RS232Buffer)

MfG Spess

von Holger P. (Gast)


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)

von Spess53 (Gast)


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

von Holger P. (Gast)


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

von Holger P. (Gast)


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

von Spess53 (Gast)


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

von Holger P. (Gast)


Lesenswert?

Ja da bin ich mir sicher
1
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
2
   ldi zh,0;
3
4
   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:
1
; *************************************************
2
; * Flash speicher löschen/beschreiben/überprüfen *
3
; *************************************************
4
Flashen:
5
    ldi yl,low(RS232Buffer) ; Y Pointer laden
6
    ldi yh,high(RS232Buffer)
7
8
    ldi Zaehler,PageSize ; Zähler laden 
9
    inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 
10
11
; Page löschen
12
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
13
    rcall Start_SPM
14
15
; Wieder bereit machen für RWW
16
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
17
    rcall Start_SPM
18
19
NextPageAdresse:
20
; In r0 und r1 werte die in den buffer kommen
21
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
22
    ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
23
  
24
    ldi SPMKommando, (1<<SELFPRGEN)
25
    rcall Start_SPM
26
    
27
    dec Zaehler          ; 1 von Zähler abziehen. 
28
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
29
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
30
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer
31
32
Programmieren:
33
; Jetzt Buffer ins Flash schreiben
34
  subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
35
  subi zh, high(PAGESIZEBYTE);
36
  
37
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
38
  rcall Start_SPM
39
40
Bereit:
41
; Wieder bereit machen für RWW
42
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
43
    rcall Start_SPM
44
45
    in Dummy1, SPMCSR
46
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
47
    ret
48
    rjmp Bereit
49
50
51
Start_SPM:
52
53
; Läuft noch ein SPM? Ja? Warte bis fertig.
54
Wait_spm:
55
    in Dummy1, SPMCSR
56
    sbrc Dummy1, SELFPRGEN
57
    rjmp Wait_spm
58
59
; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
60
Wait_ee:
61
    sbic EECR, EEPE
62
    rjmp Wait_ee
63
64
; SPM starten
65
    out SPMCSR, SPMKommando
66
    spm
67
    ret

von Spess53 (Gast)


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

von Vuvuzelatus (Gast)


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.

von Holger P. (Gast)


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
1
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
2
    mov  r0, Dummy1
3
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
4
    mov r1, Dummy1

und mit diesen nicht
1
  ld r0, y+ ; In r0 Byte aus den RS232 Buffer
2
  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.

von Holger P. (Gast)


Lesenswert?

So hier st es
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1    = r16
4
.def Zaehler   = r17
5
.def SPMKommando = r21
6
7
.equ F_CPU = 8000000                            ; Systemtakt in Hz
8
.equ PAGESIZEBYTE = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words
9
10
11
.cseg    
12
.org $0E00 ; Programm im BootLoader speichern.
13
14
; Stackpointer initialisieren
15
ldi Dummy1, high(RAMEND) 
16
out SPH,Dummy1           
17
ldi Dummy1, low(RAMEND)
18
out SPL,Dummy1
19
20
21
; Ports initialisieren
22
ldi  Dummy1, 0b00000000
23
out DDRC,Dummy1 ; Port-C Eingang
24
out DDRB,Dummy1 ; Port-B Eingang
25
ldi  Dummy1, 0b00000010
26
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD
27
28
29
30
;Alle Interrups aus
31
cli
32
33
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
34
  ldi zh,0;
35
36
; *************************************************
37
; * Flash speicher löschen/beschreiben/überprüfen *
38
; *************************************************
39
Flashen:
40
    ldi yl,low(RS232Buffer) ; Y Pointer laden
41
    ldi yh,high(RS232Buffer)
42
43
  ldi Zaehler,PageSize ; Zähler laden 
44
  inc Zaehler          ; Zähler eins mehr 0 wird nicht gezählt 
45
46
; Page löschen
47
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
48
    rcall Start_SPM
49
50
; Wieder bereit machen für RWW
51
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
52
    rcall Start_SPM
53
54
NextPageAdresse:
55
; In r0 und r1 werte die in den buffer kommen
56
  ld r0, y+ ; In r0 Byte aus den RS232 Buffer
57
  ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
58
  
59
  ldi SPMKommando, (1<<SELFPRGEN)
60
  rcall Start_SPM
61
    
62
  dec Zaehler          ; 1 von Zähler abziehen. 
63
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
64
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
65
  rjmp NextPageAdresse ; Nächste Zeichen in Buffer
66
67
Programmieren:
68
; Jetzt Buffer ins Flash schreiben
69
  subi zl, low(PAGESIZEBYTE); Zeiger wieder auf ursprung
70
  sbci zh, high(PAGESIZEBYTE);
71
  
72
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
73
  rcall Start_SPM
74
75
Bereit:
76
; Wieder bereit machen für RWW
77
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
78
    rcall Start_SPM
79
80
    in Dummy1, SPMCSR
81
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
82
Ende:
83
    rjmp Ende ; Endlosschleife geht hier dann weiter
84
    rjmp Bereit
85
86
87
Start_SPM:
88
89
; Läuft noch ein SPM? Ja? Warte bis fertig.
90
Wait_spm:
91
  in Dummy1, SPMCSR
92
  sbrc Dummy1, SELFPRGEN
93
    rjmp Wait_spm
94
95
; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
96
Wait_ee:
97
  sbic EECR, EEPE
98
    rjmp Wait_ee
99
100
; SPM starten
101
    out SPMCSR, SPMKommando
102
    spm
103
    ret    
104
105
.dseg
106
RS232Zeiger: .Byte 1
107
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.

von Holger P. (Gast)


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.

von Spess53 (Gast)


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

von Vuvuzelatus (Gast)


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)

von Holger P. (Gast)


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.

von Spess53 (Gast)


Angehängte Dateien:

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.