Hi,
in libc boot.h there is a very good example :
void writePageFlash(uint32_t address_toWrite, uint8_t *buffer_toWrite)
{
uint16_t i, w;
cli();
// Erase page.
boot_page_erase((uint32_t)address_toWrite);
while(boot_rww_busy()){
boot_rww_enable();
}
// Fill Temporary Buffer
for(uint32_t i = address_toWrite; i < address_toWrite + SPM_PAGESIZE; i
+= 2){
boot_page_fill(i, (i-address_toWrite) + ((i-address_toWrite) << 8));
}
Yours :
// Fill Temporary Buffer
for(i = 0; i < SPM_PAGESIZE; i += 2){
// Set up little-endian word.
w = (buf[i + 1] << 8)|buf[i] ; // for me, it is better like this
boot_page_fill(page + (uint32_t) i, w); //put w in temporary
buffer
not i
}
// Write page.
boot_page_write((uint32_t)address_toWrite);
while(boot_rww_busy()){
boot_rww_enable();
}
sei();
}
To read :
In fact, you read a byte and not a word so you must make your "for" like
this :
for (i = 0; i < SPM_PAGESIZE; i ++) // i++ and not i+=2
if (pgm_read_byte_far(page + i) != buf[i]) {
ret = 1;
break;
}
You can read your flash and put in a hex file to compare to what you want
to write and
what you really write.
Hope that helps.
Yannick Podgorski
www.kuantic.com
----- Original Message -----
From: "Martin Bammer" <address@hidden>
To: "andi" <address@hidden>
Cc: <address@hidden>
Sent: Monday, February 07, 2005 9:31 AM
Subject: Re: [avr-gcc-list] Problems programming flash
> Hi!
>
> I've put all code into the bootloader section. Fuses are correctly set
> (I
> hope). I can't see the bug :-(
>
> bootloader.elf :
> section size addr
> .data 0xb0 0x800100
> .text 0xefe 0xf000
> .bss 0x208 0x8001b0
> .noinit 0x0 0x8003b8
> .eeprom 0x0 0x810000
> .stab 0x1d40 0x0
> .stabstr 0xc0f 0x0
> Total 0x3b05
>
>
> Disassembled C-function:
>
> uint8_t flash_wr_page(uint32_t page, uint8_t *buf)
> {
> f3f2: bf 92 push r11
> f3f4: cf 92 push r12
> f3f6: df 92 push r13
> f3f8: ef 92 push r14
> f3fa: ff 92 push r15
> f3fc: 0f 93 push r16
> f3fe: 1f 93 push r17
> f400: cf 93 push r28
> f402: df 93 push r29
> f404: 8b 01 movw r16, r22
> f406: 9c 01 movw r18, r24
> f408: 6a 01 movw r12, r20
> uint16_t i, w;
> uint8_t sreg, ret = 0;
> f40a: bb 24 eor r11, r11
>
> sreg = SREG;
> f40c: ef b6 in r14, 0x3f ; 63
> cli();
> f40e: f8 94 cli
> eeprom_busy_wait();
> f410: e1 99 sbic 0x1c, 1 ; 28
> f412: fe cf rjmp .-4 ; 0xf410
> boot_page_erase(page);
> f414: 80 91 68 00 lds r24, 0x0068
> f418: 80 fd sbrc r24, 0
> f41a: fc cf rjmp .-8 ; 0xf414
> f41c: e1 99 sbic 0x1c, 1 ; 28
> f41e: fe cf rjmp .-4 ; 0xf41c
> f420: 83 e0 ldi r24, 0x03 ; 3
> f422: f8 01 movw r30, r16
> f424: 20 93 5b 00 sts 0x005B, r18
> f428: 80 93 68 00 sts 0x0068, r24
> f42c: e8 95 spm
> boot_spm_busy_wait();
> f42e: 80 91 68 00 lds r24, 0x0068
> f432: 99 27 eor r25, r25
> f434: bc 01 movw r22, r24
> f436: 61 70 andi r22, 0x01 ; 1
> f438: 70 70 andi r23, 0x00 ; 0
> f43a: 80 fd sbrc r24, 0
> f43c: f8 cf rjmp .-16 ; 0xf42e
> for (i = 0; i < SPM_PAGESIZE; i += 2) {
> f43e: ab 01 movw r20, r22
> f440: f1 e0 ldi r31, 0x01 ; 1
> f442: ff 2e mov r15, r31
> f444: e6 01 movw r28, r12
> // Set up little-endian word.
> w = buf[i] | (buf[i + 1] << 8);
> f446: 88 81 ld r24, Y
> f448: 68 2f mov r22, r24
> f44a: 77 27 eor r23, r23
> f44c: 89 81 ldd r24, Y+1 ; 0x01
> f44e: 99 27 eor r25, r25
> f450: 98 2f mov r25, r24
> f452: 88 27 eor r24, r24
> f454: 68 2b or r22, r24
> f456: 79 2b or r23, r25
> boot_page_fill(page + i, w);
> f458: 80 91 68 00 lds r24, 0x0068
> f45c: 80 fd sbrc r24, 0
> f45e: fc cf rjmp .-8 ; 0xf458
> f460: e1 99 sbic 0x1c, 1 ; 28
> f462: fe cf rjmp .-4 ; 0xf460
> f464: ca 01 movw r24, r20
> f466: aa 27 eor r26, r26
> f468: bb 27 eor r27, r27
> f46a: 80 0f add r24, r16
> f46c: 91 1f adc r25, r17
> f46e: a2 1f adc r26, r18
> f470: b3 1f adc r27, r19
> f472: 0b 01 movw r0, r22
> f474: fc 01 movw r30, r24
> f476: a0 93 5b 00 sts 0x005B, r26
> f47a: f0 92 68 00 sts 0x0068, r15
> f47e: e8 95 spm
> f480: 11 24 eor r1, r1
> f482: 4e 5f subi r20, 0xFE ; 254
> f484: 5f 4f sbci r21, 0xFF ; 255
> f486: 22 96 adiw r28, 0x02 ; 2
> f488: 4f 3f cpi r20, 0xFF ; 255
> f48a: 51 05 cpc r21, r1
> f48c: e1 f2 breq .-72 ; 0xf446
> f48e: d8 f2 brcs .-74 ; 0xf446
> }
> boot_page_write(page); // Store buffer in flash page.
> f490: 80 91 68 00 lds r24, 0x0068
> f494: 80 fd sbrc r24, 0
> f496: fc cf rjmp .-8 ; 0xf490
> f498: e1 99 sbic 0x1c, 1 ; 28
> f49a: fe cf rjmp .-4 ; 0xf498
> f49c: 85 e0 ldi r24, 0x05 ; 5
> f49e: f8 01 movw r30, r16
> f4a0: 20 93 5b 00 sts 0x005B, r18
> f4a4: 80 93 68 00 sts 0x0068, r24
> f4a8: e8 95 spm
> boot_spm_busy_wait();
> f4aa: 80 91 68 00 lds r24, 0x0068
> f4ae: 80 fd sbrc r24, 0
> f4b0: fc cf rjmp .-8 ; 0xf4aa
>
> // Reenable RWW-section again. We need this if we want to jump back
> // to the application after bootloading.
> boot_rww_enable();
> f4b2: 80 91 68 00 lds r24, 0x0068
> f4b6: 80 fd sbrc r24, 0
> f4b8: fc cf rjmp .-8 ; 0xf4b2
> f4ba: e1 99 sbic 0x1c, 1 ; 28
> f4bc: fe cf rjmp .-4 ; 0xf4ba
> f4be: 81 e1 ldi r24, 0x11 ; 17
> f4c0: 80 93 68 00 sts 0x0068, r24
> f4c4: e8 95 spm
> f4c6: d6 01 movw r26, r12
> f4c8: a9 01 movw r20, r18
> f4ca: 98 01 movw r18, r16
> f4cc: b6 01 movw r22, r12
> f4ce: 61 50 subi r22, 0x01 ; 1
> f4d0: 7f 4f sbci r23, 0xFF ; 255
>
> for (i = 0; i < SPM_PAGESIZE; i += 2)
> if (pgm_read_byte_far(page + i) != buf[i]) {
> f4d2: 4b bf out 0x3b, r20 ; 59
> f4d4: f9 01 movw r30, r18
> f4d6: 97 91 elpm r25, Z+
> f4d8: 8c 91 ld r24, X
> f4da: 12 96 adiw r26, 0x02 ; 2
> f4dc: 98 17 cp r25, r24
> f4de: 19 f0 breq .+6 ; 0xf4e6
> ret = 1;
> f4e0: 11 e0 ldi r17, 0x01 ; 1
> f4e2: b1 2e mov r11, r17
> break;
> f4e4: 07 c0 rjmp .+14 ; 0xf4f4
> f4e6: 2e 5f subi r18, 0xFE ; 254
> f4e8: 3f 4f sbci r19, 0xFF ; 255
> f4ea: 4f 4f sbci r20, 0xFF ; 255
> f4ec: 5f 4f sbci r21, 0xFF ; 255
> f4ee: 6a 17 cp r22, r26
> f4f0: 7b 07 cpc r23, r27
> f4f2: 78 f7 brcc .-34 ; 0xf4d2
> }
>
> // Re-enable interrupts (if they were ever enabled).
> SREG = sreg;
> f4f4: ef be out 0x3f, r14 ; 63
> return ret;
> }
>
>
> Fuses:
> Atmel AVR ATmega128 is found.
> Firmware Version: 1.14
>
> Fuse Low Byte = 0x33
> Fuse High Byte = 0xd0
> Fuse Extended Byte = 0xff
> Calibration Byte = 0xa7 -- Read Only
> Lock Bits = 0xff
> BLB12 -> 1
> BLB11 -> 1
> BLB02 -> 1
> BLB01 -> 1
> LB2 -> 1
> LB1 -> 1
>
>> Hi, Martin
>>
>> If you want to program flash, you have to put the procedure in boot
>> loader
>> section. The way to put the procedure to bootloader is :
>>
>> uint8_t BOOTLOADER_SECTION flash_wr_page(uint32_t page, uint8_t *buf)
>> {
>> //.....routine
>> }
>>
>> Regards,
>>
>> Andi
>>
>>
>> uint8_t flash_wr_page(uint32_t page, uint8_t *buf)
>>
>> ------------------------------------------------------------------------
>>--- ----------- Hi list!
>>
>> I'm trying to write a bootloader for the ATMega128 in C.
>> Everything works fine, but the programming of the flash.
>> I've taken the subroutine from the avr-libc page which is listed
>> below.
>> The version of the avr-libc I'm using is 1.0.5 (Debian Package).
>> What is wrong with the subroutine below?
>>
>> uint8_t flash_wr_page(uint32_t page, uint8_t *buf)
>> {
>> uint16_t i, w;
>> uint8_t sreg, ret = 0;
>>
>> sreg = SREG;
>> cli();
>> eeprom_busy_wait();
>> boot_page_erase(page);
>> boot_spm_busy_wait();
>> for (i = 0; i < SPM_PAGESIZE; i += 2) {
>> // Set up little-endian word.
>> w = buf[i] | (buf[i + 1] << 8);
>> boot_page_fill(page + i, i);
>> }
>> boot_page_write(page); // Store buffer in flash page.
>> boot_spm_busy_wait();
>>
>> // Reenable RWW-section again. We need this if we want to jump
>> back
>> // to the application after bootloading.
>> boot_rww_enable();
>>
>> for (i = 0; i < SPM_PAGESIZE; i += 2)
>> if (pgm_read_byte_far(page + i) != buf[i]) {
>> ret = 1;
>> break;
>> }
>>
>> // Re-enable interrupts (if they were ever enabled).
>> SREG = sreg;
>> return ret;
>> }
>>
>> Cheers, Martin
>
> _______________________________________________
> avr-gcc-list mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list
_______________________________________________
avr-gcc-list mailing list
address@hidden
http://www.avr1.org/mailman/listinfo/avr-gcc-list