avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Problems programming flash


From: Yannick PODGORSKI
Subject: Re: [avr-gcc-list] Problems programming flash
Date: Mon, 7 Feb 2005 10:40:19 +0100

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]