Hi*,
habe mir einen BL angepaßt, aber der schreibt nur die erste Seite.
Bei größeren Adressen als 254 werden nur xFFFF Bytes zurückgelesen.
Ich vermute, es liegt am ASM-Teil, aber daran hatte ich nichts geändert.
BL-Größe ist 4k, also keine RWW-Sektion.
Weiß jemand, wo der Fehler liegt?
1
/*
2
register unsigned int Pagedata @2;
3
register unsigned int PageAddress @4;
4
register unsigned int CurrentAddress @6;
5
register unsigned char k @8;
6
register char spmcrval @10;
7
*/
8
9
//rx_buffer[0]-[1] = PageNumber --> PageAdress
10
//rx_buffer[2]-[257] = PageData
11
12
for(i=0;i<256;i+=2){
13
Pagedata=rx_buffer1[i+2]+(rx_buffer1[i+3]<<8);
14
while(SPMCR&1);//wait for spm complete
15
CurrentAddress=(PageAddress*256)+i;
16
spmcrval=1;
17
#asm
18
movwr30,r6;//move CurrentAddress to Z pointer
19
movr1,r3;//move Pagedata MSB reg 1
20
movr0,r2;//move Pagedata LSB reg 1
21
stsSpmcrAddr,r10;//move spmcrval to SPM control register
22
spm;//store program memory
23
#endasm
24
}
25
26
while(SPMCR&1);//wait for spm complete
27
spmcrval=3;//erase page
28
#asm
29
movwr30,r4;//move PageAddress to Z pointer
30
stsSpmcrAddr,r10;//move spmcrval to SPM control register
31
spm;//erase page
32
#endasm
33
34
while(SPMCR&1);//wait for spm complete
35
spmcrval=5;//write page
36
#asm
37
movwr30,r4;//move PageAddress to Z pointer
38
stsSpmcrAddr,r10;//move spmcrval to SPM control register
39
spm;//write page
40
#endasm
41
while(SPMCR&1);// wait for spm complete
42
spmcrval=0x11;// enableRWW see mega8 datasheet for explanation
43
// P. 212 Section "Prevent reading the RWW section
44
// during self-programming
45
#asm
46
stsSpmcrAddr,r10;//move spmcrval to SPMCR
47
spm;
48
#endasm
49
50
for(j=0;j<256;j+=2){
51
CurrentAddress=(PageAddress*256)+j;
52
#asm
53
movwr30,r6;//move CurrentAddress to Z pointer
54
lpmr2,Z+;//read LSB
55
lpmr3,Z;//read MSB
56
#endasm
57
Checkdata=rx_buffer1[j+2]+(rx_buffer1[j+3]<<8);
58
// PAGEDATA HAS BEEN FILLED BY ASM PART ABOVE!
59
// Verify schlägt ab PageNumber 1 / CurrentAddress=256 fehl,
Hi,
danke für Deine Antwort, aber das Problem war simpel:
AVR Bootloading geht vereinfacht so:
1. Seite in den Flash füttern
2. Adresse eingeben, wo diese Seite hinsoll
3. Diese seite löschen
4. Den Speichervorgang anstoßen
5. Optional RWW aktivieren, bei 4k BL aber sowieso irrelevant
Da der Z-Pointer nur ein Byte groß ist, kann ich auch nur 256 Seiten
speichern. Für den Mega64 reicht das, da sinds sogar noch weniger, weil
ja der BL noch 4k haben will. Ich hatte nur vergessen, aus meiner
Seitennummer in INT (000-255) ein BYTE zu machen, welches in den
Z-Pointer kommt. Ich hatte mit obigem Quelltext immer nur das High-Byte
von PAGENUMBER (immer 0) in den Z-Pointer geschrieben, und deswegen wars
immer 0.
Man verändere obigen Source wie folgt:
1. Ganz oben einfügen: "PageAddress <<= 8;"
2. 2x ersetzen "PageAddress*256" durch "PageAddress"
Sieheda, es geht ;)
Danke, Christoph
Hi, Christoph,
freut mich, daß Deion Bootloader läuft.
Aber Deine Beschreibung ist falsch.
AVR Bootloading geht vereinfacht so:
1. Seite in den Flash füttern
2. Adresse eingeben, wo diese Seite hinsoll
3. Diese seite löschen
4. Den Speichervorgang anstoßen
5. Optional RWW aktivieren, bei 4k BL aber sowieso irrelevant
zu 1: nicht in das Flash, sondern in die Bootloader Page.
zu 2: ja.
zu 3: mit boot_page_write (page) bootloader page in flash schreiben,
dies stößt den Schreibvorgang an.
ciao
Wolfgang Horn
Eine eigene Frage?
Dieser Thread ist über 19 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.