Skip to content

Commit

Permalink
Merge pull request #1480 from stefanrueger/sib
Browse files Browse the repository at this point in the history
Provide sib memory for AVR8X parts
  • Loading branch information
stefanrueger authored Aug 4, 2023
2 parents 77c3b0f + 3a1e9c0 commit fbbcec3
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/avr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1405,6 +1405,7 @@ const char *avr_mem_order[100] = {
"tempsense", "signature", "prodsig", "sernum",
"calibration", "osccal16", "osccal20", "osc16err",
"osc20err", "usersig", "userrow", "data",
"sib",
};

void avr_add_mem_order(const char *str) {
Expand Down
2 changes: 2 additions & 0 deletions src/avrdude.1
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,8 @@ Temperature sensor calibration values
.It userrow
Extra page of EEPROM memory that can be used for firmware settings; this
memory is not erased during a chip erase
.It sib
Special system information block memory with information about AVR family, chip revision etc.
.El
.Pp
The
Expand Down
10 changes: 10 additions & 0 deletions src/avrdude.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -18664,6 +18664,11 @@ part
# SRAM, only used to supply the offset
offset = 0x1000000;
;

memory "sib"
size = 32;
readsize = 1;
;
;

#------------------------------------------------------------
Expand Down Expand Up @@ -20846,6 +20851,11 @@ part
# SRAM, only used to supply the offset
offset = 0x1000000;
;

memory "sib"
size = 32;
readsize = 1;
;
;

#------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/doc/avrdude.texi
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,8 @@ Temperature sensor calibration values
@item userrow
Extra page of EEPROM memory that can be used for firmware settings; this
memory is not erased during a chip erase
@item sib
Special system information block memory with information about AVR family, chip revision etc.

@end table

Expand Down
78 changes: 60 additions & 18 deletions src/jtag3.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ struct pdata
bool vtarg_set;
double vtarg_data;

/* SIB string cache */
char sib_string[AVR_SIBLEN];

/* Function to set the appropriate clock parameter */
int (*set_sck)(const PROGRAMMER *, unsigned char *);
};
Expand Down Expand Up @@ -1430,6 +1433,12 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {

free(resp);

if (pgm->read_sib) {
if (pgm->read_sib(pgm, p, PDATA(pgm)->sib_string) < 0) {
pmsg_warning("cannot read SIB string from target %s\n", p->desc);
}
}

PDATA(pgm)->boot_start = ULONG_MAX;
if (p->prog_modes & PM_PDI) {
// Find the border between application and boot area
Expand Down Expand Up @@ -1887,7 +1896,7 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM

block_size = jtag3_memaddr(pgm, p, m, addr);
if(block_size != addr)
msg_notice2(" mapped to address: 0x%04x\n", block_size);
imsg_notice2("mapped to address: 0x%04x\n", block_size);
block_size = 0;

if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
Expand Down Expand Up @@ -1995,7 +2004,7 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME

block_size = jtag3_memaddr(pgm, p, m, addr);
if(block_size != addr)
msg_notice2(" mapped to address: 0x%04x\n", block_size);
imsg_notice2("mapped to address: 0x%04x\n", block_size);
block_size = 0;

if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
Expand Down Expand Up @@ -2080,10 +2089,20 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
pmsg_notice2("jtag3_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr);

paddr = jtag3_memaddr(pgm, p, mem, addr);
if(paddr != addr)
msg_notice2(" mapped to address: 0x%lx\n", paddr);
if (paddr != addr)
imsg_notice2("mapped to address: 0x%lx\n", paddr);
paddr = 0;

if (mem->size < 1) {
pmsg_error("cannot read byte from %s %s owing to its size %d\n", p->desc, mem->desc, mem->size);
return -1;
}
if (addr >= (unsigned long) mem->size) {
pmsg_error("cannot read byte from %s %s as address 0x%04lx outside range [0, 0x%04x]\n",
p->desc, mem->desc, addr, mem->size-1);
return -1;
}

if (!(pgm->flag & PGM_FL_IS_DW))
if ((status = jtag3_program_enable(pgm)) < 0)
return status;
Expand Down Expand Up @@ -2153,6 +2172,18 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
cmd[3] = MTYPE_OSCCAL_BYTE;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (str_eq(mem->desc, "sib")) {
if(addr >= AVR_SIBLEN) {
pmsg_error("cannot read byte from %s sib as address 0x%04lx outside range [0, 0x%04x]\n",
p->desc, addr, AVR_SIBLEN-1);
return -1;
}
if(!*PDATA(pgm)->sib_string) {
pmsg_error("cannot read byte from %s sib as memory not initialised\n", p->desc);
return -1;
}
*value = PDATA(pgm)->sib_string[addr];
return 0;
} else if (strcmp(mem->desc, "signature") == 0) {
static unsigned char signature_cache[2];

Expand Down Expand Up @@ -2252,7 +2283,16 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME

mapped_addr = jtag3_memaddr(pgm, p, mem, addr);
if(mapped_addr != addr)
msg_notice2(" mapped to address: 0x%lx\n", mapped_addr);
imsg_notice2("mapped to address: 0x%lx\n", mapped_addr);

if(mem->size < 1) {
pmsg_error("cannot write byte to %s %s owing to its size %d\n", p->desc, mem->desc, mem->size);
return -1;
} else if(addr >= (unsigned long) mem->size) {
pmsg_error("cannot write byte to %s %s as address 0x%04lx outside range [0, 0x%04x]\n",
p->desc, mem->desc, addr, mem->size-1);
return -1;
}

cmd[0] = SCOPE_AVR;
cmd[1] = CMD3_WRITE_MEMORY;
Expand Down Expand Up @@ -2294,24 +2334,26 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[3] = MTYPE_PRODSIG;
} else if (str_starts(mem->desc, "lock")) {
cmd[3] = MTYPE_LOCK_BITS;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "calibration") == 0) {
cmd[3] = MTYPE_OSCCAL_BYTE;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "signature") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
}

if (unsupp)
return -1;
// Read-only memories or unsupported by debugWire
if(str_eq(mem->desc, "calibration") || str_eq(mem->desc, "osc16err") ||
str_eq(mem->desc, "osccal16") || str_eq(mem->desc, "osc20err") ||
str_eq(mem->desc, "osccal20") || str_eq(mem->desc, "prodsig") ||
str_eq(mem->desc, "sernum") || str_eq(mem->desc, "sib") ||
str_eq(mem->desc, "signature") || str_eq(mem->desc, "temperature") || unsupp) {
unsigned char is;
if(jtag3_read_byte(pgm, p, mem, addr, &is) >= 0 && is == data)
return 0;
if (unsupp && pgm->flag & PGM_FL_IS_DW)
pmsg_error("debugWire interface does not support writing to memory %s\n", mem->desc);
else
pmsg_error("cannot write to read-only memory %s %s\n", p->desc, mem->desc);
return -1;
}

if (pagesize != 0) {
/* flash or EEPROM write: use paged algorithm */
Expand Down
2 changes: 1 addition & 1 deletion src/libavrdude.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ typedef struct opcode {
#define HAS_VAREF_ADJ 32

#define AVR_FAMILYIDLEN 7
#define AVR_SIBLEN 16
#define AVR_SIBLEN 32
#define CTL_STACK_SIZE 32
#define FLASH_INSTR_SIZE 3
#define EEPROM_INSTR_SIZE 20
Expand Down
41 changes: 41 additions & 0 deletions src/serialupdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,15 +673,43 @@ static int serialupdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
return -1;
}

#define Return(...) do { pmsg_error(__VA_ARGS__); msg_error("\n"); return -1; } while (0)

static int serialupdi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value)
{
pmsg_debug("%s(%s, 0x%04lx)\n", __func__, mem->desc, addr);
if(mem->size < 1)
Return("cannot read byte from %s %s owing to its size %d", p->desc, mem->desc, mem->size);

if(addr >= (unsigned long) mem->size)
Return("cannot read byte from %s %s as address 0x%04lx outside range [0, 0x%04x]",
p->desc, mem->desc, addr, mem->size-1);

if(str_eq(mem->desc, "sib")) {
if(addr >= SIB_INFO_STRING_LENGTH)
Return("cannot read byte from %s sib as address 0x%04lx outside range [0, 0x%04x]",
p->desc, addr, SIB_INFO_STRING_LENGTH-1);
if(!*updi_get_sib_info(pgm)->sib_string) // This should never happen
Return("cannot read byte from %s sib as memory not initialised", p->desc);
*value = updi_get_sib_info(pgm)->sib_string[addr];
return 0;
}

return updi_read_byte(pgm, mem->offset + addr, value);
}

static int serialupdi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
pmsg_debug("%s(%s, 0x%04lx, 0x%02x)\n", __func__, mem->desc, addr, value);
if(mem->size < 1)
Return("cannot write byte to %s %s owing to its size %d", p->desc, mem->desc, mem->size);

if(addr >= (unsigned long) mem->size)
Return("cannot write byte to %s %s as address 0x%04lx outside range [0, 0x%04x]",
p->desc, mem->desc, addr, mem->size-1);

if (strstr(mem->desc, "fuse") != 0) {
return updi_nvm_write_fuse(pgm, p, mem->offset + addr, value);
}
Expand All @@ -698,6 +726,19 @@ static int serialupdi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const
buffer[0]=value;
return updi_nvm_write_flash(pgm, p, mem->offset + addr, buffer, 1);
}
// Read-only memories
if(str_eq(mem->desc, "osc16err") || str_eq(mem->desc, "osccal16") ||
str_eq(mem->desc, "osc20err") || str_eq(mem->desc, "osccal20") ||
str_eq(mem->desc, "prodsig") || str_eq(mem->desc, "sernum") ||
str_eq(mem->desc, "signature") || str_eq(mem->desc, "sib")) {

unsigned char is;
if(serialupdi_read_byte(pgm, p, mem, addr, &is) >= 0 && is == value)
return 0;

Return("cannot write to read-only memory %s %s", p->desc, mem->desc);
}

return updi_write_byte(pgm, mem->offset + addr, value);
}

Expand Down

0 comments on commit fbbcec3

Please sign in to comment.