From 7f6c42846cfffcf0fdaff4aecdf5b5426dab955f Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Tue, 12 Jan 2010 15:42:40 +0000 Subject: [PATCH] Various fixes for Xmega devices. * avrdude.conf.in: Correctly declare EEPROM page sizes for all Xmega devices (0x20 instead of 0x100). * avr.c: If a memory region has a page size declared, try using the paged IO routines regardless of the target memory name. Xmega EEPROM requires to be written in paged mode. Correctly use a long (rather than unsigned long) variable to evaluate the success status of the paged mode write attempt. * stk500v2.c: Don't apply TIF space offsets twice (bug #27995: AVRDUDE 5.8svn fails to program and read XMEGA); use stk500v2_loadaddr() prior to paged mode (EEPROM and flash) writes, otherwise programming of flash areas will fail; while being there, check the return value of stk500v2_loadaddr() everywhere; use the correct write/erase mode bits (same as AVR Studio does). git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@907 81a1dc3b-b13d-400b-aceb-764788c761c2 --- ChangeLog | 17 +++++++++++ avr.c | 57 +++++++++++++----------------------- avrdude.conf.in | 28 +++++++++--------- stk500v2.c | 78 +++++++++++++++++++++++++------------------------ 4 files changed, 92 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8d593a72..ee21e2a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2010-01-12 Joerg Wunsch + + Various fixes for Xmega devices. + * avrdude.conf.in: Correctly declare EEPROM page sizes for + all Xmega devices (0x20 instead of 0x100). + * avr.c: If a memory region has a page size declared, try + using the paged IO routines regardless of the target memory + name. Xmega EEPROM requires to be written in paged mode. + Correctly use a long (rather than unsigned long) variable to + evaluate the success status of the paged mode write attempt. + * stk500v2.c: Don't apply TIF space offsets twice (bug #27995: + AVRDUDE 5.8svn fails to program and read XMEGA); use + stk500v2_loadaddr() prior to paged mode (EEPROM and flash) writes, + otherwise programming of flash areas will fail; while being there, + check the return value of stk500v2_loadaddr() everywhere; use the + correct write/erase mode bits (same as AVR Studio does). + 2010-01-12 Michal Ludvig * buspirate.c: Initialise firmware version to v0.0 diff --git a/avr.c b/avr.c index e7f2f737..6fd8bc7a 100644 --- a/avr.c +++ b/avr.c @@ -171,26 +171,18 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, */ memset(buf, 0xff, size); - if ((strcmp(mem->desc, "eeprom")==0) || - (strcmp(mem->desc, "flash")==0) || - (strcmp(mem->desc, "application")==0) || - (strcmp(mem->desc, "apptable")==0) || - (strcmp(mem->desc, "boot")==0) || - (strcmp(mem->desc, "usersig")==0) || - (strcmp(mem->desc, "prodsig")==0)) { - if (pgm->paged_load != NULL && mem->page_size != 0) { - /* - * the programmer supports a paged mode read, perhaps more - * efficiently than we can read it directly, so use its routine - * instead - */ - rc = pgm->paged_load(pgm, p, mem, mem->page_size, size); - if (rc >= 0) { - if (strcasecmp(mem->desc, "flash") == 0) - return avr_mem_hiaddr(mem); - else - return rc; - } + if (pgm->paged_load != NULL && mem->page_size != 0) { + /* + * the programmer supports a paged mode read, perhaps more + * efficiently than we can read it directly, so use its routine + * instead + */ + rc = pgm->paged_load(pgm, p, mem, mem->page_size, size); + if (rc >= 0) { + if (strcasecmp(mem->desc, "flash") == 0) + return avr_mem_hiaddr(mem); + else + return rc; } } @@ -545,7 +537,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, { int rc; int wsize; - unsigned long i; + long i; unsigned char data; int werror; AVRMEM * m; @@ -574,21 +566,14 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, progbuf, wsize); } - if ((strcmp(m->desc, "application")==0) || - (strcmp(m->desc, "apptable")==0) || - (strcmp(m->desc, "boot")==0) || - (strcmp(m->desc, "flash")==0) || - (strcmp(m->desc, "prodsig")==0) || - (strcmp(m->desc, "usersig")==0)) { - if (pgm->paged_write != NULL && m->page_size != 0) { - /* - * the programmer supports a paged mode write, perhaps more - * efficiently than we can read it directly, so use its routine - * instead - */ - if ((i = pgm->paged_write(pgm, p, m, m->page_size, size)) >= 0) - return i; - } + if (pgm->paged_write != NULL && m->page_size != 0) { + /* + * the programmer supports a paged mode write, perhaps more + * efficiently than we can read it directly, so use its routine + * instead + */ + if ((i = pgm->paged_write(pgm, p, m, m->page_size, size)) >= 0) + return i; } if (pgm->write_setup) { diff --git a/avrdude.conf.in b/avrdude.conf.in index c69df82d..51ca2bcf 100644 --- a/avrdude.conf.in +++ b/avrdude.conf.in @@ -13737,7 +13737,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -13834,7 +13834,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -13931,7 +13931,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14028,7 +14028,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14125,7 +14125,7 @@ part memory "eeprom" size = 0x1000; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14222,7 +14222,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14319,7 +14319,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14416,7 +14416,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14513,7 +14513,7 @@ part memory "eeprom" size = 0x1000; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14610,7 +14610,7 @@ part memory "eeprom" size = 0x1000; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14707,7 +14707,7 @@ part memory "eeprom" size = 0x0400; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14804,7 +14804,7 @@ part memory "eeprom" size = 0x0400; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14901,7 +14901,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; @@ -14998,7 +14998,7 @@ part memory "eeprom" size = 0x0800; offset = 0x08c0000; - page_size = 0x100; + page_size = 0x20; readsize = 0x100; ; diff --git a/stk500v2.c b/stk500v2.c index b9211c33..6ff3ba75 100644 --- a/stk500v2.c +++ b/stk500v2.c @@ -1456,7 +1456,8 @@ static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, buf[2] = pagesize & 0xff; /* flash and EEPROM reads require the load address command */ - stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)); + if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0) + return -1; } else { buf[1] = addr; } @@ -1612,7 +1613,8 @@ static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, memcpy(buf + 5, cache_ptr, pagesize); /* flash and EEPROM reads require the load address command */ - stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)); + if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0) + return -1; } else { buf[1] = addr; buf[2] = data; @@ -1781,7 +1783,8 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, buf[2] = block_size & 0xff; if((last_addr==UINT_MAX)||(last_addr+block_size != addr)){ - stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)); + if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + return -1; } last_addr=addr; @@ -1877,7 +1880,8 @@ static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, buf[2] = page_size & 0xff; if ((last_addr == UINT_MAX) || (last_addr + block_size != addr)) { - stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)); + if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + return -1; } last_addr=addr; @@ -1996,7 +2000,8 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, // when crossing a 64 KB boundary in flash. if (hiaddr != (addr & ~0xFFFF)) { hiaddr = addr & ~0xFFFF; - stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)); + if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + return -1; } result = stk500v2_command(pgm,buf,4,sizeof(buf)); @@ -2075,7 +2080,8 @@ static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, // when crossing a 64 KB boundary in flash. if (hiaddr != (addr & ~0xFFFF)) { hiaddr = addr & ~0xFFFF; - stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)); + if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + return -1; } result = stk500v2_command(pgm, buf, 3, sizeof(buf)); @@ -3085,29 +3091,18 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, { unsigned char b[10]; - /* - * Fancy offsets everywhere. - * This is probably what AVR079 means when writing about the - * "TIF address space". - */ if (strcmp(mem->desc, "flash") == 0) { b[1] = XPRG_MEM_TYPE_APPL; - addr += 0x00800000; } else if (strcmp(mem->desc, "boot") == 0) { b[1] = XPRG_MEM_TYPE_BOOT; - addr += 0x00800000; } else if (strcmp(mem->desc, "eeprom") == 0) { b[1] = XPRG_MEM_TYPE_EEPROM; - addr += 0x008c0000; } else if (strcmp(mem->desc, "lockbits") == 0) { b[1] = XPRG_MEM_TYPE_LOCKBITS; - addr += 0x008f0000; } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) { b[1] = XPRG_MEM_TYPE_FUSE; - addr += 0x008f0000; } else if (strcmp(mem->desc, "usersig") == 0) { b[1] = XPRG_MEM_TYPE_USERSIG; - addr += 0x008e0000; } else { fprintf(stderr, "%s: stk600_xprog_write_byte(): unknown memory \"%s\"\n", @@ -3140,35 +3135,22 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, { unsigned char b[8]; - /* - * Fancy offsets everywhere. - * This is probably what AVR079 means when writing about the - * "TIF address space". - */ if (strcmp(mem->desc, "flash") == 0) { b[1] = XPRG_MEM_TYPE_APPL; - addr += 0x00800000; } else if (strcmp(mem->desc, "boot") == 0) { b[1] = XPRG_MEM_TYPE_BOOT; - addr += 0x00800000; } else if (strcmp(mem->desc, "eeprom") == 0) { b[1] = XPRG_MEM_TYPE_EEPROM; - addr += 0x008c0000; } else if (strcmp(mem->desc, "signature") == 0) { b[1] = XPRG_MEM_TYPE_APPL; - addr += 0x01000000; } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) { b[1] = XPRG_MEM_TYPE_FUSE; - addr += 0x008f0000; } else if (strcmp(mem->desc, "lockbits") == 0) { b[1] = XPRG_MEM_TYPE_LOCKBITS; - addr += 0x008f0000; } else if (strcmp(mem->desc, "calibration") == 0) { b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION; - addr += 0x008e0000; } else if (strcmp(mem->desc, "usersig") == 0) { b[1] = XPRG_MEM_TYPE_USERSIG; - addr += 0x008e0000; } else { fprintf(stderr, "%s: stk600_xprog_read_byte(): unknown memory \"%s\"\n", @@ -3203,6 +3185,7 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned int offset; unsigned char memtype; int n_bytes_orig = n_bytes; + unsigned long use_ext_addr = 0; /* * The XPROG read command supports at most 256 bytes in one @@ -3218,19 +3201,23 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, */ if (strcmp(mem->desc, "flash") == 0) { memtype = XPRG_MEM_TYPE_APPL; - addr = 0x00800000; + if (mem->size > 64 * 1024) + use_ext_addr = (1UL << 31); } else if (strcmp(mem->desc, "boot") == 0) { memtype = XPRG_MEM_TYPE_BOOT; - addr = 0x00800000; + // Do we have to consider the total amount of flash + // instead to decide whether to use extended addressing? + if (mem->size > 64 * 1024) + use_ext_addr = (1UL << 31); } else if (strcmp(mem->desc, "eeprom") == 0) { memtype = XPRG_MEM_TYPE_EEPROM; - addr = 0x008c0000; } else { fprintf(stderr, "%s: stk600_xprog_paged_load(): unknown paged memory \"%s\"\n", progname, mem->desc); return -1; } + addr = mem->offset; if ((b = malloc(page_size + 2)) == NULL) { fprintf(stderr, @@ -3239,6 +3226,9 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, return -1; } + if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) + return -1; + offset = 0; while (n_bytes != 0) { report_progress(offset, n_bytes_orig, NULL); @@ -3278,6 +3268,8 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned char memtype; int n_bytes_orig = n_bytes; size_t writesize; + unsigned long use_ext_addr = 0; + unsigned char writemode; /* * The XPROG read command supports at most 256 bytes in one @@ -3297,19 +3289,26 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, */ if (strcmp(mem->desc, "flash") == 0) { memtype = XPRG_MEM_TYPE_APPL; - addr = 0x00800000; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + if (mem->size > 64 * 1024) + use_ext_addr = (1UL << 31); } else if (strcmp(mem->desc, "boot") == 0) { memtype = XPRG_MEM_TYPE_BOOT; - addr = 0x00800000; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + // Do we have to consider the total amount of flash + // instead to decide whether to use extended addressing? + if (mem->size > 64 * 1024) + use_ext_addr = (1UL << 31); } else if (strcmp(mem->desc, "eeprom") == 0) { memtype = XPRG_MEM_TYPE_EEPROM; - addr = 0x008c0000; + writemode = (1 << XPRG_MEM_WRITE_WRITE) | (1 << XPRG_MEM_WRITE_ERASE); } else { fprintf(stderr, "%s: stk600_xprog_paged_write(): unknown paged memory \"%s\"\n", progname, mem->desc); return -1; } + addr = mem->offset; if ((b = malloc(page_size + 9)) == NULL) { fprintf(stderr, @@ -3318,6 +3317,9 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, return -1; } + if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) + return -1; + offset = 0; while (n_bytes != 0) { report_progress(offset, n_bytes_orig, NULL); @@ -3349,7 +3351,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, b[0] = XPRG_CMD_WRITE_MEM; b[1] = memtype; if (chunk + 256 == page_size) { - b[2] = 3; /* last chunk: erase page | write page */ + b[2] = writemode; /* last chunk */ } else { b[2] = 0; /* initial/intermediate chunk: just download */ } @@ -3386,7 +3388,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, } b[0] = XPRG_CMD_WRITE_MEM; b[1] = memtype; - b[2] = 3; /* erase page | write page */ + b[2] = writemode; b[3] = addr >> 24; b[4] = addr >> 16; b[5] = addr >> 8;