Bootloader ATmega32 Problem

OP #2183831
Lesenswert?

Hallo zusammen,

ich bin gerade dabei einen Bootloader für den ATmega32 zu schreiben. 
Aktuell habe ich das Problem, dass er mir den Flash Speicher weder 
löscht noch mit Daten beschreibt.


Einstellungen:
Lockbits: 0xFF
Fuses:    0xDAFF

Linker:   -Ttext=0x7000
1
#include <string.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/boot.h>
5
#include <util/delay.h>
6
#include "uart1.h"
7
#include <avr/pgmspace.h>
8

9
#define UART_BAUD 103
10

11

12
unsigned char c;
13
unsigned char temp;
14

15

16
void program_page (uint32_t page, uint8_t *buf)
17
{
18
    uint16_t i;
19
    uint8_t sreg;
20
 
21
    /* Disable interrupts */
22
    sreg = SREG;
23
    cli();
24
 
25
    eeprom_busy_wait ();
26
   uart_putc(page);
27
    boot_page_erase (page);
28
    boot_spm_busy_wait ();      /* Wait until the memory is erased. */
29
   uart_puts("e");
30
    for (i=0; i<SPM_PAGESIZE; i+=2)
31
    {
32
        /* Set up little-endian word. */
33
        uint16_t w = *buf++;
34
        w += (*buf++) << 8;
35
    
36
        boot_page_fill (page + i, w);
37
    }
38
 
39
    boot_page_write (page);     /* Store buffer in flash page.    */
40
    boot_spm_busy_wait();       /* Wait until the memory is written.*/
41
 
42
    /* Reenable RWW-section again. We need this if we want to jump back */
43
    /* to the application after bootloading. */
44
    boot_rww_enable ();
45
 
46
    /* Re-enable interrupts (if they were ever enabled). */
47
    SREG = sreg;
48
}
49

50

51
int main()
52
{
53
uint16_t flash_page = 0;
54

55
uint8_t flash_data[SPM_PAGESIZE];
56
uint8_t c;
57
uint8_t temp;
58

59
    temp = MCUCR;
60
    GICR = temp | (1<<IVCE);
61
    GICR = temp | (1<<IVSEL);
62

63
//Befüllen des Buffers mit Testdaten für eine Page
64
memset(flash_data, 0x1F, sizeof(flash_data));
65

66
    uart_init(UART_BAUD); 
67
    sei();
68

69
uart_puts("Hier ist das Testprogramm zum löschen einer page\n");
70
_delay_ms(2000);
71

72
do
73
{
74
c = uart_getc();
75

76
if(c='d')
77
{
78
program_page((uint16_t)flash_page, flash_data);
79
}
80

81
}
82
while(c!='d');
83
uart_puts("Ende");
84

85
return 0;
86
}

Wenn ich mir das Flashabbild (als iHex) nach dem Ausführen des 
Schreibvorganges anschaue, habe ich im Flashbereich 0x0000 bis 0x6FFF 
den Wert 0xFF stehen. Ab 0x7000 steht der Code des Bootlaoders.

Hoffe es kann mir jemand von euch weiterhelfen.

Vielen Dank!

Gruss

Sebastian
Gast #2184578
Lesenswert?

meine funktionierende version sieht folgendermassen aus ...

c-file:
1
MEMSEG_BOOTLOADER BYTE LoaderStartDownload(void)
2
{
3
  BYTE i,x;
4
  WORD page, data;
5

6
  for(x=0; x<MAX_FLASH_PAGES; x++)
7
  {
8
    //------------------ get program-page from USB-Stick --------------//
9
    if(!LoaderGetNextProgramPage(&page))    // get next program-page from usb-stick
10
    {
11
      LoaderUsbTxStr("C 0");                // pagewrite failed -> close file
12
      return FALSE;
13
    }
14

15
    //----------------------- erase flash-page ------------------------//
16
    eeprom_busy_wait();
17
    boot_page_erase(page);
18
    boot_spm_busy_wait();                   // wait until the memory is erased
19
  
20
    //----------------- fill data to internal page-buffer -------------//
21
    for(i=0; i<SPM_PAGESIZE; i+=2)
22
    {
23
      data  = USB.Tx.data[i];               // little endian
24
      data += ((USB.Tx.data[i+1]) << 8);
25
      boot_page_fill(page + i, data);
26
    }
27

28
    //------------------------ burn page to flash ---------------------//
29
    boot_page_write(page);
30
    boot_spm_busy_wait();                   // wait until the memory is written.
31
    boot_rww_enable();
32
  }
33

34
  LoaderUsbTxStr("C 0");                    // close file
35

36
  return TRUE;
37
}


header-file:
1
#define  __BOOT_PAGE_ERASE            0x03
2
#define  __BOOT_PAGE_WRITE            0x05
3
#define  __BOOT_PAGE_FILL             0x01
4
#define  __BOOT_RWW_ENABLE            0x11
5

6

7

8
#define  eeprom_busy_wait()       while(EECR & 0x02)
9

10
#define  boot_spm_busy_wait()     while(SPMCR & 0x01) 
11

12
#define  boot_page_erase(page)                   \
13
({                                               \
14
    __asm__ __volatile__                         \
15
    (                                            \
16
        "movw r30, %2\n\t"                       \
17
        "sts %0, %1\n\t"                         \
18
        "spm\n\t"                                \
19
        : "=m" (SPMCR)                           \
20
        : "r" ((BYTE)__BOOT_PAGE_ERASE),         \
21
          "r" ((WORD)page)                       \
22
        : "r30", "r31"                           \
23
    );                                           \
24
})
25

26
#define boot_page_fill(address, data)            \
27
({                                               \
28
    __asm__ __volatile__                         \
29
    (                                            \
30
        "movw  r0, %3\n\t"                       \
31
        "movw r30, %2\n\t"                       \
32
        "sts %0, %1\n\t"                         \
33
        "spm\n\t"                                \
34
        "clr  r1\n\t"                            \
35
        : "=m" (SPMCR)                           \
36
        : "r" ((BYTE)__BOOT_PAGE_FILL),          \
37
          "r" ((WORD)address),                   \
38
          "r" ((WORD)data)                       \
39
        : "r0", "r30", "r31"                     \
40
    );                                           \
41
})
42

43
#define boot_page_write(address)                 \
44
({                                               \
45
    __asm__ __volatile__                         \
46
    (                                            \
47
        "movw r30, %2\n\t"                       \
48
        "sts %0, %1\n\t"                         \
49
        "spm\n\t"                                \
50
        :                                        \
51
        : "i" (&SPMCR),                          \
52
          "r" ((BYTE)__BOOT_PAGE_WRITE),         \
53
          "r" ((WORD)address)                    \
54
        : "r30", "r31"                           \
55
    );                                           \
56
})
57

58
#define boot_rww_enable()                        \
59
({                                               \
60
    __asm__ __volatile__                         \
61
    (                                            \
62
        "sts %0, %1\n\t"                         \
63
        "spm\n\t"                                \
64
        :                                        \
65
        : "i" (&SPMCR),                          \
66
          "r" ((BYTE)__BOOT_RWW_ENABLE)          \
67
    );                                           \
68
})


gruss,
neubi

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren