Got added support for reading and writing fuses, and chiperase.
This commit is contained in:
parent
5dc2545716
commit
f9a2bd0327
153
src/jtag3.c
153
src/jtag3.c
|
@ -2491,6 +2491,27 @@ static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char tpi_get_memtype(const AVRMEM *mem) {
|
||||||
|
unsigned char memtype;
|
||||||
|
if (strcmp(mem->desc, "fuse") == 0) {
|
||||||
|
memtype = XPRG_MEM_TYPE_FUSE;
|
||||||
|
} else if (strcmp(mem->desc, "lock") == 0) {
|
||||||
|
memtype = XPRG_MEM_TYPE_LOCKBITS;
|
||||||
|
} else if (strcmp(mem->desc, "calibration") == 0) {
|
||||||
|
memtype = XPRG_MEM_TYPE_LOCKBITS;
|
||||||
|
} else if (strcmp(mem->desc, "signature") == 0) {
|
||||||
|
memtype = XPRG_MEM_TYPE_LOCKBITS;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memtype = XPRG_MEM_TYPE_APPL;
|
||||||
|
}
|
||||||
|
return memtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void tpi_print_error_status(unsigned char error) {
|
||||||
|
// pmsg_error("error communicating with programmer, received status 0x%02x\n", error);
|
||||||
|
// }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the data as a JTAGICE3 encapsulated TPI packet.
|
* Send the data as a JTAGICE3 encapsulated TPI packet.
|
||||||
*/
|
*/
|
||||||
|
@ -2588,7 +2609,6 @@ static void jtag3_enable_tpi(PROGRAMMER *pgm, const AVRPART *p) {
|
||||||
|
|
||||||
static void jtag3_disable_tpi(const PROGRAMMER *pgm) {
|
static void jtag3_disable_tpi(const PROGRAMMER *pgm) {
|
||||||
unsigned char cmdbuf[4];
|
unsigned char cmdbuf[4];
|
||||||
int result;
|
|
||||||
|
|
||||||
cmdbuf[0] = XPRG_CMD_LEAVE_PROGMODE;
|
cmdbuf[0] = XPRG_CMD_LEAVE_PROGMODE;
|
||||||
|
|
||||||
|
@ -2601,39 +2621,17 @@ static void jtag3_disable_tpi(const PROGRAMMER *pgm) {
|
||||||
|
|
||||||
static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||||
unsigned long addr, unsigned char * value) {
|
unsigned long addr, unsigned char * value) {
|
||||||
int result, pollidx;
|
int result;
|
||||||
unsigned char buf[8];
|
|
||||||
unsigned long paddr = 0UL, *paddr_ptr = NULL;
|
|
||||||
unsigned int pagesize = 0;
|
|
||||||
unsigned char *cache_ptr = NULL;
|
|
||||||
OPCODE *op;
|
|
||||||
size_t len = 8;
|
size_t len = 8;
|
||||||
|
unsigned char buf[len];
|
||||||
|
unsigned long paddr = 0UL;
|
||||||
|
|
||||||
pmsg_notice2("jtag3_read_byte_tpi(.., %s, 0x%lx, ...)\n", mem->desc, addr);
|
pmsg_notice2("jtag3_read_byte_tpi(.., %s, 0x%lx, ...)\n", mem->desc, addr);
|
||||||
|
|
||||||
|
paddr = mem->offset + addr;
|
||||||
|
|
||||||
buf[0] = XPRG_CMD_READ_MEM;
|
buf[0] = XPRG_CMD_READ_MEM;
|
||||||
|
buf[1] = tpi_get_memtype(mem);
|
||||||
if (strcmp(mem->desc, "lfuse") == 0 ||
|
|
||||||
strcmp(mem->desc, "fuse") == 0) {
|
|
||||||
buf[1] = XPRG_MEM_TYPE_FUSE;
|
|
||||||
addr = 0;
|
|
||||||
} else if (strcmp(mem->desc, "hfuse") == 0) {
|
|
||||||
buf[1] = XPRG_MEM_TYPE_FUSE;
|
|
||||||
addr = 1;
|
|
||||||
} else if (strcmp(mem->desc, "efuse") == 0) {
|
|
||||||
buf[1] = XPRG_MEM_TYPE_FUSE;
|
|
||||||
addr = 2;
|
|
||||||
} else if (strcmp(mem->desc, "lock") == 0) {
|
|
||||||
buf[1] = XPRG_MEM_TYPE_LOCKBITS;
|
|
||||||
paddr = mem->offset + addr;
|
|
||||||
} else if (strcmp(mem->desc, "calibration") == 0) {
|
|
||||||
buf[1] = XPRG_MEM_TYPE_LOCKBITS;
|
|
||||||
paddr = mem->offset + addr;
|
|
||||||
} else if (strcmp(mem->desc, "signature") == 0) {
|
|
||||||
buf[1] = XPRG_MEM_TYPE_LOCKBITS;
|
|
||||||
paddr = mem->offset + addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32_to_b4_big_endian((buf+2), paddr); // Address
|
u32_to_b4_big_endian((buf+2), paddr); // Address
|
||||||
u16_to_b2_big_endian((buf+6), 1); // Size
|
u16_to_b2_big_endian((buf+6), 1); // Size
|
||||||
|
|
||||||
|
@ -2642,17 +2640,106 @@ static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AV
|
||||||
|
|
||||||
result = jtag3_recv_tpi(pgm, buf);
|
result = jtag3_recv_tpi(pgm, buf);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
pmsg_error("timeout/error communicating with programmer\n");
|
pmsg_error("error in communication, received status 0x%02x\n", result);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*value = buf[2];
|
*value = buf[2];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) {
|
static int jtag3_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||||
pmsg_error("jtag3_chip_erase_tpi() not implemented\n");
|
unsigned long addr) {
|
||||||
|
size_t len = 6;
|
||||||
|
unsigned char buf[len];
|
||||||
|
int result;
|
||||||
|
unsigned long paddr = 0UL;
|
||||||
|
|
||||||
|
buf[0] = XPRG_CMD_ERASE;
|
||||||
|
if (strcmp(mem->desc, "fuse") == 0) {
|
||||||
|
buf[1] = XPRG_ERASE_CONFIG;
|
||||||
|
} else if (strcmp(mem->desc, "flash") == 0) {
|
||||||
|
buf[1] = XPRG_ERASE_APP;
|
||||||
|
} else {
|
||||||
|
pmsg_error("jtag3_erase_tpi() unsupported memory: %s\n", mem->desc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
paddr = (mem->offset + addr) | 0x01; // An erase is triggered by an access to the hi-byte
|
||||||
|
u32_to_b4_big_endian((buf+2), paddr);
|
||||||
|
|
||||||
|
if (jtag3_send_tpi(pgm, buf, len) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
result = jtag3_recv_tpi(pgm, buf);
|
||||||
|
if (result < 0) {
|
||||||
|
pmsg_error("error in communication, received status 0x%02x\n", result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||||
|
unsigned long addr, unsigned char data) {
|
||||||
|
size_t len = 11;
|
||||||
|
unsigned char buf[len];
|
||||||
|
int result;
|
||||||
|
unsigned long paddr = 0UL;
|
||||||
|
|
||||||
|
result = jtag3_erase_tpi(pgm, p, mem, addr);
|
||||||
|
if (result < 0) {
|
||||||
|
pmsg_error("error in communication, received status 0x%02x\n", result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddr = mem->offset + addr;
|
||||||
|
|
||||||
|
buf[0] = XPRG_CMD_WRITE_MEM;
|
||||||
|
buf[1] = tpi_get_memtype(mem);
|
||||||
|
buf[2] = 0; // Page Mode - Not used
|
||||||
|
u32_to_b4_big_endian((buf+3), paddr); // Address
|
||||||
|
u16_to_b2_big_endian((buf+7), 2); // Size
|
||||||
|
buf[9] = data;
|
||||||
|
buf[10] = 0x00;
|
||||||
|
|
||||||
|
if (jtag3_send_tpi(pgm, buf, len) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
result = jtag3_recv_tpi(pgm, buf);
|
||||||
|
if (result < 0) {
|
||||||
|
pmsg_error("error in communication, received status 0x%02x\n", result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||||
|
size_t len = 6;
|
||||||
|
unsigned char buf[len];
|
||||||
|
int result;
|
||||||
|
unsigned long paddr = 0UL;
|
||||||
|
|
||||||
|
AVRMEM *m = avr_locate_mem(p, "flash");
|
||||||
|
if (m == NULL) {
|
||||||
|
pmsg_error("no flash memory for part %s\n", p->desc);
|
||||||
|
return LIBAVRDUDE_GENERAL_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddr = m->offset | 0x01;
|
||||||
|
|
||||||
|
buf[0] = XPRG_CMD_ERASE;
|
||||||
|
buf[1] = XPRG_ERASE_CHIP;
|
||||||
|
// An erase is triggered by an access to the hi-byte
|
||||||
|
u32_to_b4_big_endian((buf+2), paddr);
|
||||||
|
|
||||||
|
if (jtag3_send_tpi(pgm, buf, len) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
result = jtag3_recv_tpi(pgm, buf);
|
||||||
|
if (result < 0) {
|
||||||
|
pmsg_error("error in communication, received status 0x%02x\n", result);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int jtag3_open_tpi(PROGRAMMER *pgm, const char *port) {
|
static int jtag3_open_tpi(PROGRAMMER *pgm, const char *port) {
|
||||||
pmsg_notice2("jtag3_open_tpi()\n");
|
pmsg_notice2("jtag3_open_tpi()\n");
|
||||||
|
@ -2847,7 +2934,7 @@ void jtag3_tpi_initpgm(PROGRAMMER *pgm) {
|
||||||
pgm->open = jtag3_open_tpi;
|
pgm->open = jtag3_open_tpi;
|
||||||
pgm->close = jtag3_close_tpi;
|
pgm->close = jtag3_close_tpi;
|
||||||
pgm->read_byte = jtag3_read_byte_tpi;
|
pgm->read_byte = jtag3_read_byte_tpi;
|
||||||
pgm->write_byte = jtag3_write_byte;
|
pgm->write_byte = jtag3_write_byte_tpi;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* optional functions
|
* optional functions
|
||||||
|
|
Loading…
Reference in New Issue