Skip to content

Commit

Permalink
Merge pull request #1538 from stefanrueger/memory-types
Browse files Browse the repository at this point in the history
Introduce memory types in lieu of string comparisons with memory names
  • Loading branch information
stefanrueger committed Nov 3, 2023
2 parents 96b081b + f9920fc commit d8b9b92
Show file tree
Hide file tree
Showing 45 changed files with 1,152 additions and 1,293 deletions.
202 changes: 119 additions & 83 deletions src/avr.c

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions src/avr910.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
{
char cmd[2];

if (str_eq(m->desc, "flash")) {
if (mem_is_flash(m)) {
if (addr & 0x01) {
cmd[0] = 'C'; /* Write Program Mem high byte */
}
Expand All @@ -413,7 +413,7 @@ static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM

addr >>= 1;
}
else if (str_eq(m->desc, "eeprom")) {
else if (mem_is_eeprom(m)) {
cmd[0] = 'D';
}
else {
Expand Down Expand Up @@ -468,11 +468,11 @@ static int avr910_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, cons
static int avr910_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
if (str_eq(m->desc, "flash")) {
if (mem_is_flash(m)) {
return avr910_read_byte_flash(pgm, p, m, addr, value);
}

if (str_eq(m->desc, "eeprom")) {
if (mem_is_eeprom(m)) {
return avr910_read_byte_eeprom(pgm, p, m, addr, value);
}

Expand Down Expand Up @@ -574,9 +574,9 @@ static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR
{
int rval = 0;
if (PDATA(pgm)->use_blockmode == 0) {
if (str_eq(m->desc, "flash")) {
if (mem_is_flash(m)) {
rval = avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
} else if (str_eq(m->desc, "eeprom")) {
} else if (mem_is_eeprom(m)) {
rval = avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes);
} else {
rval = -2;
Expand All @@ -589,7 +589,7 @@ static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR
unsigned int blocksize = PDATA(pgm)->buffersize;
int wr_size;

if (!str_eq(m->desc, "flash") && !str_eq(m->desc, "eeprom"))
if (!mem_is_flash(m) && !mem_is_eeprom(m))
return -2;

if (m->desc[0] == 'e') {
Expand Down Expand Up @@ -640,10 +640,10 @@ static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM

max_addr = addr + n_bytes;

if (str_eq(m->desc, "flash")) {
if (mem_is_flash(m)) {
cmd[0] = 'R';
rd_size = 2; /* read two bytes per addr */
} else if (str_eq(m->desc, "eeprom")) {
} else if (mem_is_eeprom(m)) {
cmd[0] = 'd';
rd_size = 1;
} else {
Expand Down
49 changes: 23 additions & 26 deletions src/avrcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
* int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p);
*
* avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged
* routines are available and if the device memory type is flash, EEPROM,
* bootrow or usersig. The AVRXMEGA memories application, apptable and boot
* are subsumed under flash. Userrow is subsumed under usersig provided
* routines are available and if the device memory is flash, EEPROM, bootrow
* or usersig. The AVRXMEGA memories application, apptable and boot are
* subsumed under flash. Userrow is subsumed under usersig provided
* avrdude.conf has a memory alias from usersig to userrow. In all other
* cases the cached read/write functions fall back to pgm->read_byte() and
* pgm->write_byte(), respectively. Bytewise cached read always gets its data
Expand Down Expand Up @@ -130,7 +130,7 @@ int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) {
return pgm->paged_load && pgm->paged_write &&
mem->page_size > 0 && (mem->page_size & (mem->page_size-1)) == 0 &&
mem->size > 0 && mem->size % mem->page_size == 0 &&
(avr_mem_is_flash_type(mem) || avr_mem_is_eeprom_type(mem) || avr_mem_is_usersig_type(mem));
mem_is_paged_type(mem);
}


Expand Down Expand Up @@ -263,8 +263,8 @@ static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p,


static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) {
AVRMEM *basemem = avr_locate_mem(p,
cp == pgm->cp_flash? "flash": cp == pgm->cp_eeprom? "eeprom": cp == pgm->cp_bootrow? "bootrow": "usersig");
AVRMEM *basemem = cp == pgm->cp_flash? avr_locate_flash(p): cp == pgm->cp_eeprom? avr_locate_eeprom(p):
cp == pgm->cp_bootrow? avr_locate_bootrow(p): avr_locate_usersig(p);

if(!basemem || !avr_has_paged_access(pgm, basemem))
return LIBAVRDUDE_GENERAL_FAILURE;
Expand All @@ -276,7 +276,7 @@ static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) {
cp->copy = cfg_malloc("initCache()", cp->size);
cp->iscached = cfg_malloc("initCache()", cp->size/cp->page_size);

if((pgm->prog_modes & PM_SPM) && avr_mem_is_flash_type(basemem)) { // Could be vector bootloader
if((pgm->prog_modes & PM_SPM) && mem_is_in_flash(basemem)) { // Could be vector bootloader
// Caching the vector page hands over to the progammer that then can patch the reset vector
if(loadCachePage(cp, pgm, p, basemem, 0, 0, 0) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
Expand Down Expand Up @@ -377,10 +377,10 @@ typedef struct {
// Write flash, EEPROM, bootrow and usersig caches to device and free them
int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
CacheDesc_t mems[] = {
{ avr_locate_mem(p, "flash"), pgm->cp_flash, 1, 0, -1, 0 },
{ avr_locate_mem(p, "eeprom"), pgm->cp_eeprom, 0, 1, -1, 0 },
{ avr_locate_mem(p, "bootrow"), pgm->cp_bootrow, 0, 0, -1, 0 },
{ avr_locate_mem(p, "usersig"), pgm->cp_usersig, 0, 0, -1, 0 },
{ avr_locate_flash(p), pgm->cp_flash, 1, 0, -1, 0 },
{ avr_locate_eeprom(p), pgm->cp_eeprom, 0, 1, -1, 0 },
{ avr_locate_bootrow(p), pgm->cp_bootrow, 0, 0, -1, 0 },
{ avr_locate_usersig(p), pgm->cp_usersig, 0, 0, -1, 0 },
};

int chpages = 0;
Expand Down Expand Up @@ -449,7 +449,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
}
}

if(!avr_mem_is_usersig_type(mems[i].mem)) // Only force CE if unable to write to flash/EEPROM
if(!mem_is_user_type(mems[i].mem)) // Only force CE if unable to write to flash/EEPROM
chiperase = 1;
}

Expand All @@ -471,7 +471,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
if(avr_mem_is_usersig_type(mem)) // CE does not affect bootrow/usersig
if(mem_is_user_type(mem)) // CE does not affect bootrow/userrow
continue;

for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size)
Expand All @@ -487,7 +487,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
if(avr_mem_is_usersig_type(mem)) // CE does not affect bootrow/usersig
if(mem_is_user_type(mem)) // CE does not affect bootrow/userrow
continue;

for(int ird = 0, pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) {
Expand Down Expand Up @@ -516,7 +516,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
if(avr_mem_is_usersig_type(mem)) // CE does not affect bootrow/usersig
if(mem_is_user_type(mem)) // CE does not affect bootrow/userrow
continue;

if(mems[i].isflash) {
Expand Down Expand Up @@ -628,9 +628,8 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *
return LIBAVRDUDE_SUCCESS;
}

AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom:
avr_mem_is_flash_type(mem)? pgm->cp_flash:
str_eq(mem->desc, "bootrow")? pgm->cp_bootrow: pgm->cp_usersig;
AVR_Cache *cp = mem_is_eeprom(mem)? pgm->cp_eeprom: mem_is_in_flash(mem)? pgm->cp_flash:
mem_is_bootrow(mem)? pgm->cp_bootrow: pgm->cp_usersig;

if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
Expand Down Expand Up @@ -669,9 +668,8 @@ int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
if(addr >= (unsigned long) mem->size)
return avr_flush_cache(pgm, p);

AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom:
avr_mem_is_flash_type(mem)? pgm->cp_flash:
str_eq(mem->desc, "bootrow")? pgm->cp_bootrow: pgm->cp_usersig;
AVR_Cache *cp = mem_is_eeprom(mem)? pgm->cp_eeprom: mem_is_in_flash(mem)? pgm->cp_flash:
mem_is_bootrow(mem)? pgm->cp_bootrow: pgm->cp_usersig;

if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
Expand Down Expand Up @@ -700,8 +698,8 @@ int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
// Erase the chip and set the cache accordingly
int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) {
CacheDesc_t mems[3] = {
{ avr_locate_mem(p, "flash"), pgm->cp_flash, 1, 0, -1, 0 },
{ avr_locate_mem(p, "eeprom"), pgm->cp_eeprom, 0, 1, -1, 0 },
{ avr_locate_flash(p), pgm->cp_flash, 1, 0, -1, 0 },
{ avr_locate_eeprom(p), pgm->cp_eeprom, 0, 1, -1, 0 },
// bootrow/usersig is unaffected by CE
};
int rc;
Expand Down Expand Up @@ -773,9 +771,8 @@ int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return LIBAVRDUDE_GENERAL_FAILURE;
}

AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom:
avr_mem_is_flash_type(mem)? pgm->cp_flash:
str_eq(mem->desc, "bootrow")? pgm->cp_bootrow: pgm->cp_usersig;
AVR_Cache *cp = mem_is_eeprom(mem)? pgm->cp_eeprom: mem_is_in_flash(mem)? pgm->cp_flash:
mem_is_bootrow(mem)? pgm->cp_bootrow: pgm->cp_usersig;

if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
Expand Down
10 changes: 5 additions & 5 deletions src/avrdude.1
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ device-dependent, the actual configuration can be viewed with the
.Cm part
command in terminal mode.
Typically, a device's memory configuration at least contains
the memory types
the memories
.Ar flash ,
.Ar eeprom ,
.Ar signature
Expand All @@ -786,7 +786,7 @@ will also typically have fuse bytes, which are read/write memories for
configuration of the device and calibration memories that typically
contain read-only factory calibration values.
.Pp
Classic devices may have the following memory types in addition to eeprom, flash, signature and lock:
Classic devices may have the following memories in addition to eeprom, flash, signature and lock:
.Bl -tag -width " calibration" -compact
.It calibration
One or more bytes of RC oscillator calibration data
Expand Down Expand Up @@ -824,7 +824,7 @@ methods only by bootloaders, which has limited use unless the bootloader
jumps to the application directly, i.e., without a WDT reset
.El
.Pp
ATxmega devices have the following memory types in addition to eeprom, flash, signature and lock:
ATxmega devices have the following memories in addition to eeprom, flash, signature and lock:
.Bl -tag -width "calibration" -compact
.It application
Application flash area
Expand Down Expand Up @@ -859,7 +859,7 @@ Volatile register memory;
can read this memory but not write to it using external programming
.El
.Pp
Modern 8-bit AVR devices have the following memory types in addition to eeprom, flash, signature and lock:
Modern 8-bit AVR devices have the following memories in addition to eeprom, flash, signature and lock:
.Bl -tag -width "calibration" -compact
.It fuse0
A.k.a. wdtcfg: watchdog configuration
Expand Down Expand Up @@ -1252,7 +1252,7 @@ on a non-zero verbosity level the line numbers are printed, too.
Display the device signature bytes.
.It Ar part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
specific information including all memories supported by the
device, read/write timing, etc.
.It Ar verbose Op Ar level
Change (when
Expand Down
36 changes: 17 additions & 19 deletions src/avrdude.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ avrdude_conf_version = "@AVRDUDE_FULL_VERSION@";
# # parameters for bootloaders
# autobaud_sync = <num> ; # autobaud detection byte, default 0x30
#
# memory <memtype>
# memory <memstr>
# paged = <yes/no> ; # yes/no (flash only, do not use for EEPROM)
# offset = <num> ; # memory offset
# size = <num> ; # bytes
Expand Down Expand Up @@ -244,13 +244,13 @@ avrdude_conf_version = "@AVRDUDE_FULL_VERSION@";
# NOTES:
# * 'devicecode' is the device code used by the STK500 (see codes
# listed below)
# * Not all memory types will implement all instructions
# * Not all memories will implement all instructions
# * AVR Fuse bits and Lock bits are implemented as a type of memory
# * Example memory types are:
# * Example memories are:
# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high
# fuse), "signature", "calibration", "lock"
# * The memory type specified on the avrdude command line must match
# one of the memory types defined for the specified chip
# * The memory specified on the avrdude command line must match
# one of the memories defined for the specified chip
# * The pwroff_after_write flag causes avrdude to attempt to
# power the device off and back on after an unsuccessful write to
# the affected memory area if VCC programmer pins are defined. If
Expand Down Expand Up @@ -19202,6 +19202,12 @@ part # .avr8x
ocd_base = 0x0f80;
syscfg_base = 0x0f00;

memory "fuses"
size = 10;
offset = 0x1280;
readsize = 1;
;

memory "fuse0"
size = 1;
initval = 0x00;
Expand Down Expand Up @@ -19290,13 +19296,6 @@ part # .avr8x
alias "fuse8";
;

memory "fuses"
size = 10;
page_size = 10;
offset = 0x1280;
readsize = 10;
;

memory "lock"
size = 1;
offset = 0x128a;
Expand Down Expand Up @@ -21436,6 +21435,12 @@ part # .avrdx
ocd_base = 0x0f80;
syscfg_base = 0x0f00;

memory "fuses"
size = 16;
offset = 0x1050;
readsize = 1;
;

memory "fuse0"
size = 1;
initval = 0x00;
Expand Down Expand Up @@ -21524,13 +21529,6 @@ part # .avrdx
alias "fuse8";
;

memory "fuses"
size = 16;
page_size = 16;
offset = 0x1050;
readsize = 16;
;

memory "lock"
size = 4;
offset = 0x1040;
Expand Down
Loading

0 comments on commit d8b9b92

Please sign in to comment.