Merge pull request #1205 from janegilruud/jtag3-tpi-jer
Added TPI support for Microchip tools
This commit is contained in:
commit
9bd4dee254
|
@ -372,6 +372,9 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
AVRMEM *mem = mems[i].mem;
|
||||
AVR_Cache *cp = mems[i].cp;
|
||||
|
||||
if(!mem)
|
||||
continue;
|
||||
|
||||
if(!cp->cont) // Ensure cache is initialised from now on
|
||||
if(initCache(cp, pgm, p) < 0) {
|
||||
if(quell_progress)
|
||||
|
@ -380,7 +383,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
return LIBAVRDUDE_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
if(chiperase || !mem || mems[i].zopaddr < 0)
|
||||
if(chiperase || mems[i].zopaddr < 0)
|
||||
continue;
|
||||
|
||||
int n=mems[i].zopaddr;
|
||||
|
|
|
@ -2131,6 +2131,19 @@ programmer
|
|||
hvupdi_support = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# xplainedmini_tpi
|
||||
#------------------------------------------------------------
|
||||
|
||||
programmer
|
||||
id = "xplainedmini_tpi";
|
||||
desc = "Atmel AVR XplainedMini in TPI mode";
|
||||
type = "jtagice3_tpi";
|
||||
prog_modes = PM_TPI;
|
||||
connection_type = usb;
|
||||
usbpid = 0x2145;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# atmelice
|
||||
#------------------------------------------------------------
|
||||
|
@ -2197,6 +2210,19 @@ programmer
|
|||
usbpid = 0x2141;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# atmelice_tpi
|
||||
#------------------------------------------------------------
|
||||
|
||||
programmer
|
||||
id = "atmelice_tpi";
|
||||
desc = "Atmel-ICE (ARM/AVR) in TPI mode";
|
||||
type = "jtagice3_tpi";
|
||||
prog_modes = PM_TPI;
|
||||
connection_type = usb;
|
||||
usbpid = 0x2141;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# powerdebugger
|
||||
#------------------------------------------------------------
|
||||
|
@ -2263,6 +2289,19 @@ programmer
|
|||
usbpid = 0x2144;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# powerdebugger_tpi
|
||||
#------------------------------------------------------------
|
||||
|
||||
programmer
|
||||
id = "powerdebugger_tpi";
|
||||
desc = "Atmel PowerDebugger (ARM/AVR) in TPI mode";
|
||||
type = "jtagice3_tpi";
|
||||
prog_modes = PM_TPI;
|
||||
connection_type = usb;
|
||||
usbpid = 0x2144;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# pickit4_updi
|
||||
#------------------------------------------------------------
|
||||
|
@ -2303,6 +2342,19 @@ programmer
|
|||
usbpid = 0x2177, 0x2178, 0x2179;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# pickit4_tpi
|
||||
#------------------------------------------------------------
|
||||
|
||||
programmer
|
||||
id = "pickit4_tpi";
|
||||
desc = "MPLAB(R) PICkit 4 in TPI mode";
|
||||
type = "jtagice3_tpi";
|
||||
prog_modes = PM_TPI;
|
||||
connection_type = usb;
|
||||
usbpid = 0x2177, 0x2178, 0x2179;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# snap_updi
|
||||
#------------------------------------------------------------
|
||||
|
@ -2343,6 +2395,19 @@ programmer
|
|||
usbpid = 0x2180, 0x217f, 0x2181;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# snap_tpi
|
||||
#------------------------------------------------------------
|
||||
|
||||
programmer
|
||||
id = "snap_tpi";
|
||||
desc = "MPLAB(R) SNAP in TPI mode";
|
||||
type = "jtagice3_tpi";
|
||||
prog_modes = PM_TPI;
|
||||
connection_type = usb;
|
||||
usbpid = 0x2180, 0x217f, 0x2181;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# pkobn_updi
|
||||
#------------------------------------------------------------
|
||||
|
@ -13440,12 +13505,6 @@ part
|
|||
offset = 0x3f00;
|
||||
;
|
||||
|
||||
memory "lockbits"
|
||||
size = 1;
|
||||
page_size = 16;
|
||||
offset = 0x3f00;
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
page_size = 16;
|
||||
|
@ -13539,6 +13598,14 @@ part parent ".reduced_core_tiny"
|
|||
offset = 0x4000;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
page_size = 16;
|
||||
n_word_writes = 2;
|
||||
offset = 0x3f40;
|
||||
blocksize = 4;
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -13559,6 +13626,14 @@ part parent ".reduced_core_tiny"
|
|||
offset = 0x4000;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
page_size = 16;
|
||||
n_word_writes = 4;
|
||||
offset = 0x3f40;
|
||||
blocksize = 4;
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -13578,6 +13653,12 @@ part parent ".reduced_core_tiny"
|
|||
offset = 0x4000;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "sigrow"
|
||||
size = 16;
|
||||
page_size = 16;
|
||||
offset = 0x3fc6;
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -13597,6 +13678,12 @@ part parent ".reduced_core_tiny"
|
|||
offset = 0x4000;
|
||||
blocksize = 128;
|
||||
;
|
||||
|
||||
memory "sigrow"
|
||||
size = 16;
|
||||
page_size = 16;
|
||||
offset = 0x3fc6;
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
|
566
src/jtag3.c
566
src/jtag3.c
|
@ -89,6 +89,7 @@ struct pdata
|
|||
#define PGM_FL_IS_JTAG (0x0004)
|
||||
#define PGM_FL_IS_EDBG (0x0008)
|
||||
#define PGM_FL_IS_UPDI (0x0010)
|
||||
#define PGM_FL_IS_TPI (0x0020)
|
||||
|
||||
static int jtag3_open(PROGRAMMER *pgm, const char *port);
|
||||
static int jtag3_edbg_prepare(const PROGRAMMER *pgm);
|
||||
|
@ -164,6 +165,22 @@ u16_to_b2(unsigned char *b, unsigned short l)
|
|||
b[1] = (l >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
u32_to_b4_big_endian(unsigned char *b, unsigned long l)
|
||||
{
|
||||
b[0] = (l >> 24) & 0xff;
|
||||
b[1] = (l >> 16) & 0xff;
|
||||
b[2] = (l >> 8) & 0xff;
|
||||
b[3] = l & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
u16_to_b2_big_endian(unsigned char *b, unsigned short l)
|
||||
{
|
||||
b[0] = (l >> 8) & 0xff;
|
||||
b[1] = l & 0xff;
|
||||
}
|
||||
|
||||
static bool matches(const char *s, const char *pat)
|
||||
{
|
||||
return strncmp(s, pat, strlen(pat)) == 0;
|
||||
|
@ -238,8 +255,7 @@ static void jtag3_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len)
|
|||
{
|
||||
char reason[50];
|
||||
sprintf(reason, "0x%02x", data[3]);
|
||||
switch (data[3])
|
||||
{
|
||||
switch (data[3]) {
|
||||
case RSP3_FAIL_NO_ANSWER:
|
||||
strcpy(reason, "target does not answer");
|
||||
break;
|
||||
|
@ -274,8 +290,7 @@ static void jtag3_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len)
|
|||
}
|
||||
msg_info(", reason: %s\n", reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
msg_info(", unspecified reason\n");
|
||||
}
|
||||
break;
|
||||
|
@ -297,12 +312,10 @@ static void jtag3_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len)
|
|||
break;
|
||||
|
||||
case RSP3_PC:
|
||||
if (len < 7)
|
||||
{
|
||||
if (len < 7) {
|
||||
msg_info("PC reply too short\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
unsigned long pc = (data[6] << 24) | (data[5] << 16)
|
||||
| (data[4] << 8) | data[3];
|
||||
msg_info("PC 0x%0lx\n", pc);
|
||||
|
@ -410,8 +423,6 @@ static void jtag3_prevent(const PROGRAMMER *pgm, unsigned char *data, size_t len
|
|||
msg_info("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
|
||||
unsigned char *buf;
|
||||
|
||||
|
@ -421,8 +432,7 @@ int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
|
|||
msg_debug("\n");
|
||||
pmsg_debug("jtag3_send(): sending %lu bytes\n", (unsigned long) len);
|
||||
|
||||
if ((buf = malloc(len + 4)) == NULL)
|
||||
{
|
||||
if ((buf = malloc(len + 4)) == NULL) {
|
||||
pmsg_error("out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
@ -448,8 +458,7 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le
|
|||
unsigned char status[USBDEV_MAX_XFER_3];
|
||||
int rv;
|
||||
|
||||
if (verbose >= 4)
|
||||
{
|
||||
if (verbose >= 4) {
|
||||
memset(buf, 0, USBDEV_MAX_XFER_3);
|
||||
memset(status, 0, USBDEV_MAX_XFER_3);
|
||||
}
|
||||
|
@ -460,13 +469,11 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le
|
|||
/* 4 bytes overhead for CMD, fragment #, and length info */
|
||||
int max_xfer = pgm->fd.usb.max_xfer;
|
||||
int nfragments = (len + max_xfer - 1) / max_xfer;
|
||||
if (nfragments > 1)
|
||||
{
|
||||
if (nfragments > 1) {
|
||||
pmsg_debug("jtag3_edbg_send(): fragmenting into %d packets\n", nfragments);
|
||||
}
|
||||
int frag;
|
||||
for (frag = 0; frag < nfragments; frag++)
|
||||
{
|
||||
for (frag = 0; frag < nfragments; frag++) {
|
||||
int this_len;
|
||||
|
||||
/* All fragments have the (CMSIS-DAP layer) CMD, the fragment
|
||||
|
@ -474,8 +481,7 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le
|
|||
buf[0] = EDBG_VENDOR_AVR_CMD;
|
||||
buf[1] = ((frag + 1) << 4) | nfragments;
|
||||
|
||||
if (frag == 0)
|
||||
{
|
||||
if (frag == 0) {
|
||||
/* Only first fragment has TOKEN and seq#, thus four bytes
|
||||
* less payload than subsequent fragments. */
|
||||
this_len = len < max_xfer - 8? len: max_xfer - 8;
|
||||
|
@ -486,8 +492,7 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le
|
|||
u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
|
||||
memcpy(buf + 8, data, this_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
this_len = len < max_xfer - 4? len: max_xfer - 4;
|
||||
buf[2] = (this_len) >> 8;
|
||||
buf[3] = (this_len) & 0xff;
|
||||
|
@ -506,8 +511,7 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le
|
|||
return -1;
|
||||
}
|
||||
if (status[0] != EDBG_VENDOR_AVR_CMD ||
|
||||
(frag == nfragments - 1 && status[1] != 0x01))
|
||||
{
|
||||
(frag == nfragments - 1 && status[1] != 0x01)) {
|
||||
/* what to do in this case? */
|
||||
pmsg_notice("jtag3_edbg_send(): unexpected response 0x%02x, 0x%02x\n", status[0], status[1]);
|
||||
}
|
||||
|
@ -802,8 +806,7 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) {
|
|||
}
|
||||
|
||||
int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
|
||||
unsigned char **resp, const char *descr)
|
||||
{
|
||||
unsigned char **resp, const char *descr) {
|
||||
int status;
|
||||
unsigned char c;
|
||||
|
||||
|
@ -824,8 +827,8 @@ int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen
|
|||
|
||||
c = (*resp)[1] & RSP3_STATUS_MASK;
|
||||
if (c != RSP3_OK) {
|
||||
if ((c == RSP3_FAILED) && ((*resp)[3] == RSP3_FAIL_OCD_LOCKED ||
|
||||
(*resp)[3] == RSP3_FAIL_CRC_FAILURE)) {
|
||||
if ((c == RSP3_FAILED) &&
|
||||
((*resp)[3] == RSP3_FAIL_OCD_LOCKED || (*resp)[3] == RSP3_FAIL_CRC_FAILURE)) {
|
||||
pmsg_error("device is locked; chip erase required to unlock\n");
|
||||
} else {
|
||||
pmsg_notice("bad response to %s command: 0x%02x\n", descr, c);
|
||||
|
@ -918,9 +921,7 @@ static int jtag3_unlock_erase_key(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
* There is no chip erase functionality in debugWire mode.
|
||||
*/
|
||||
static int jtag3_chip_erase_dw(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
|
||||
pmsg_error("chip erase not supported in debugWire mode\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1067,8 +1068,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
else
|
||||
PDATA(pgm)->set_sck = jtag3_set_sck_mega_jtag;
|
||||
}
|
||||
if (pgm->bitclock != 0.0 && PDATA(pgm)->set_sck != NULL)
|
||||
{
|
||||
if (pgm->bitclock != 0.0 && PDATA(pgm)->set_sck != NULL) {
|
||||
unsigned int clock = 1E-3 / pgm->bitclock; /* kHz */
|
||||
pmsg_notice2("jtag3_initialize(): "
|
||||
"trying to set JTAG clock to %u kHz\n", clock);
|
||||
|
@ -1078,8 +1078,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
return -1;
|
||||
}
|
||||
jtag3_print_parms1(pgm, progbuf, stderr);
|
||||
if (conn == PARM3_CONN_JTAG)
|
||||
{
|
||||
if (conn == PARM3_CONN_JTAG) {
|
||||
pmsg_notice2("jtag3_initialize(): "
|
||||
"trying to set JTAG daisy-chain info to %d,%d,%d,%d\n",
|
||||
PDATA(pgm)->jtagchain[0], PDATA(pgm)->jtagchain[1],
|
||||
|
@ -1089,8 +1088,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
}
|
||||
|
||||
/* set device descriptor data */
|
||||
if ((p->prog_modes & PM_PDI))
|
||||
{
|
||||
if ((p->prog_modes & PM_PDI)) {
|
||||
struct xmega_device_desc xd;
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
@ -1134,8 +1132,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
|
||||
return -1;
|
||||
}
|
||||
else if ((p->prog_modes & PM_UPDI))
|
||||
{
|
||||
else if ((p->prog_modes & PM_UPDI)) {
|
||||
struct updi_device_desc xd;
|
||||
LNODEID ln;
|
||||
AVRMEM *m;
|
||||
|
@ -1144,11 +1141,9 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
u16_to_b2(xd.ocd_base_addr, p->ocd_base);
|
||||
xd.hvupdi_variant = p->hvupdi_variant;
|
||||
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln))
|
||||
{
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strcmp(m->desc, "flash") == 0)
|
||||
{
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
u16_to_b2(xd.prog_base, m->offset&0xFFFF);
|
||||
xd.prog_base_msb = m->offset>>16;
|
||||
|
||||
|
@ -1166,8 +1161,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
else
|
||||
xd.address_mode = UPDI_ADDRESS_MODE_16BIT;
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0)
|
||||
{
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
PDATA(pgm)->eeprom_pagesize = m->page_size;
|
||||
xd.eeprom_page_size = m->page_size;
|
||||
|
||||
|
@ -1175,24 +1169,20 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
u16_to_b2(xd.eeprom_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0)
|
||||
{
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
u16_to_b2(xd.user_sig_bytes, m->size);
|
||||
u16_to_b2(xd.user_sig_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "signature") == 0)
|
||||
{
|
||||
else if (strcmp(m->desc, "signature") == 0) {
|
||||
u16_to_b2(xd.signature_base, m->offset);
|
||||
xd.device_id[0] = p->signature[1];
|
||||
xd.device_id[1] = p->signature[2];
|
||||
}
|
||||
else if (strcmp(m->desc, "fuses") == 0)
|
||||
{
|
||||
else if (strcmp(m->desc, "fuses") == 0) {
|
||||
xd.fuses_bytes = m->size;
|
||||
u16_to_b2(xd.fuses_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "lock") == 0)
|
||||
{
|
||||
else if (strcmp(m->desc, "lock") == 0) {
|
||||
u16_to_b2(xd.lockbits_base, m->offset);
|
||||
}
|
||||
}
|
||||
|
@ -1250,8 +1240,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
|||
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
struct mega_device_desc md;
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
@ -1412,8 +1401,7 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
|
|||
|
||||
if (matches(extended_param, "jtagchain=")) {
|
||||
unsigned int ub, ua, bb, ba;
|
||||
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
|
||||
!= 4) {
|
||||
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba) != 4) {
|
||||
pmsg_error("invalid JTAG chain '%s'\n", extended_param);
|
||||
rv = -1;
|
||||
continue;
|
||||
|
@ -1541,8 +1529,7 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pgm->fd.usb.eep == 0)
|
||||
{
|
||||
if (pgm->fd.usb.eep == 0) {
|
||||
/* The event EP has been deleted by usb_open(), so we are
|
||||
running on a CMSIS-DAP device, using EDBG protocol */
|
||||
pgm->flag |= PGM_FL_IS_EDBG;
|
||||
|
@ -1613,8 +1600,7 @@ static int jtag3_open_updi(PROGRAMMER *pgm, const char *port) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void jtag3_close(PROGRAMMER * pgm)
|
||||
{
|
||||
void jtag3_close(PROGRAMMER * pgm) {
|
||||
unsigned char buf[4], *resp;
|
||||
|
||||
pmsg_notice2("jtag3_close()\n");
|
||||
|
@ -1644,8 +1630,7 @@ void jtag3_close(PROGRAMMER * pgm)
|
|||
}
|
||||
|
||||
static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned int addr)
|
||||
{
|
||||
unsigned int addr) {
|
||||
unsigned char cmd[8], *resp;
|
||||
|
||||
pmsg_notice2("jtag3_page_erase(.., %s, 0x%x)\n", m->desc, addr);
|
||||
|
@ -1692,8 +1677,7 @@ static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
|
|||
|
||||
static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
unsigned int addr, unsigned int n_bytes) {
|
||||
unsigned int block_size;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
unsigned char *cmd;
|
||||
|
@ -1711,7 +1695,8 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
|
|||
if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
|
||||
return -1;
|
||||
|
||||
if (page_size == 0) page_size = 256;
|
||||
if (page_size == 0)
|
||||
page_size = 256;
|
||||
|
||||
if ((cmd = malloc(page_size + 13)) == NULL) {
|
||||
pmsg_error("out of memory\n");
|
||||
|
@ -1799,8 +1784,7 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM
|
|||
|
||||
static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
unsigned int addr, unsigned int n_bytes) {
|
||||
unsigned int block_size;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
unsigned char cmd[12];
|
||||
|
@ -1882,8 +1866,7 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME
|
|||
}
|
||||
|
||||
static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
unsigned long addr, unsigned char * value) {
|
||||
unsigned char cmd[12];
|
||||
unsigned char *resp, *cache_ptr = NULL;
|
||||
int status, unsupp = 0;
|
||||
|
@ -2053,8 +2036,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
|
|||
}
|
||||
|
||||
static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
unsigned long addr, unsigned char data) {
|
||||
unsigned char cmd[14];
|
||||
unsigned char *resp;
|
||||
unsigned char *cache_ptr = 0;
|
||||
|
@ -2196,8 +2178,7 @@ static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v) {
|
|||
*/
|
||||
int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope,
|
||||
unsigned char section, unsigned char parm,
|
||||
unsigned char *value, unsigned char length)
|
||||
{
|
||||
unsigned char *value, unsigned char length) {
|
||||
int status;
|
||||
unsigned char buf[6], *resp, c;
|
||||
char descr[60];
|
||||
|
@ -2236,8 +2217,7 @@ int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope,
|
|||
*/
|
||||
int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
|
||||
unsigned char section, unsigned char parm,
|
||||
unsigned char *value, unsigned char length)
|
||||
{
|
||||
unsigned char *value, unsigned char length) {
|
||||
int status;
|
||||
unsigned char *buf, *resp;
|
||||
char descr[60];
|
||||
|
@ -2247,8 +2227,7 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
|
|||
sprintf(descr, "set parameter (scope 0x%02x, section %d, parm %d)",
|
||||
scope, section, parm);
|
||||
|
||||
if ((buf = malloc(6 + length)) == NULL)
|
||||
{
|
||||
if ((buf = malloc(6 + length)) == NULL) {
|
||||
pmsg_error("out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -2348,8 +2327,7 @@ static void jtag3_display(const PROGRAMMER *pgm, const char *p) {
|
|||
resp[status - 3] = 0;
|
||||
|
||||
msg_info("%sICE HW version : %d\n", p, parms[0]);
|
||||
msg_info("%sICE FW version : %d.%02d (rel. %d)\n", p,
|
||||
parms[1], parms[2],
|
||||
msg_info("%sICE FW version : %d.%02d (rel. %d)\n", p, parms[1], parms[2],
|
||||
(parms[3] | (parms[4] << 8)));
|
||||
msg_info("%sSerial number : %s", p, resp);
|
||||
free(resp);
|
||||
|
@ -2441,6 +2419,8 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
|||
}
|
||||
}
|
||||
|
||||
// Print clocks if programmer typ is not TPI
|
||||
if (strcmp(pgm->type, "JTAGICE3_TPI")) {
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
|
||||
return;
|
||||
|
||||
|
@ -2469,6 +2449,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
|||
fmsg_out(fp, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n", p, b2_to_u16(buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void jtag3_print_parms(const PROGRAMMER *pgm, FILE *fp) {
|
||||
jtag3_print_parms1(pgm, "", fp);
|
||||
|
@ -2513,6 +2494,403 @@ static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const
|
|||
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 if (strcmp(mem->desc, "sigrow") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_LOCKBITS;
|
||||
} else {
|
||||
memtype = XPRG_MEM_TYPE_APPL;
|
||||
}
|
||||
return memtype;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the data as a JTAGICE3 encapsulated TPI packet.
|
||||
*/
|
||||
static int jtag3_send_tpi(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
|
||||
unsigned char *cmdbuf;
|
||||
int rv;
|
||||
|
||||
if ((cmdbuf = malloc(len + 1)) == NULL) {
|
||||
pmsg_error("jtag3_send_tpi(): out of memory for command packet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cmdbuf[0] = SCOPE_AVR_TPI;
|
||||
memcpy(cmdbuf + 1, data, len);
|
||||
|
||||
msg_trace("[TPI send] ");
|
||||
for (size_t i=1; i<=len; i++)
|
||||
msg_trace("0x%02x ", cmdbuf[i]);
|
||||
msg_trace("\n");
|
||||
|
||||
rv = jtag3_send(pgm, cmdbuf, len + 1);
|
||||
free(cmdbuf);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int jtag3_recv_tpi(const PROGRAMMER *pgm, unsigned char **msg) {
|
||||
int rv;
|
||||
|
||||
rv = jtag3_recv(pgm, msg);
|
||||
|
||||
if (rv <= 0) {
|
||||
pmsg_error("jtag3_recv_tpi(): unable to receive\n");
|
||||
return -1;
|
||||
}
|
||||
rv = rv - 1;
|
||||
memcpy(*msg, *msg + 1, rv);
|
||||
|
||||
msg_trace("[TPI recv] ");
|
||||
for (size_t i=0; i<rv; i++)
|
||||
msg_trace("0x%02x ", (*msg)[i]);
|
||||
msg_trace("\n");
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int jtag3_command_tpi(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
|
||||
unsigned char **resp, const char *descr) {
|
||||
int status;
|
||||
unsigned char c;
|
||||
|
||||
jtag3_send_tpi(pgm, cmd, cmdlen);
|
||||
|
||||
status = jtag3_recv_tpi(pgm, resp);
|
||||
if (status <= 0) {
|
||||
msg_notice2("\n");
|
||||
pmsg_notice2("TPI %s command: timeout/error communicating with programmer (status %d)\n", descr, status);
|
||||
return LIBAVRDUDE_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
c = (*resp)[1];
|
||||
if (c != XPRG_ERR_OK) {
|
||||
pmsg_error("[TPI] command %s FAILED! Status: 0x%02x\n", descr, c);
|
||||
status = (*resp)[3];
|
||||
free(*resp);
|
||||
resp = 0;
|
||||
return LIBAVRDUDE_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
unsigned char cmd[3];
|
||||
unsigned char* resp;
|
||||
int status;
|
||||
|
||||
pmsg_notice2("jtag3_initialize_tpi() start\n");
|
||||
|
||||
cmd[0] = XPRG_CMD_ENTER_PROGMODE;
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Enter Progmode")) < 0)
|
||||
return -1;
|
||||
free(resp);
|
||||
|
||||
cmd[0] = XPRG_CMD_SET_PARAM;
|
||||
cmd[1] = XPRG_PARAM_NVMCMD_ADDR;
|
||||
cmd[2] = TPI_NVMCMD_ADDRESS;
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCMD")) < 0)
|
||||
return -1;
|
||||
free(resp);
|
||||
|
||||
cmd[0] = XPRG_CMD_SET_PARAM;
|
||||
cmd[1] = XPRG_PARAM_NVMCSR_ADDR;
|
||||
cmd[2] = TPI_NVMCSR_ADDRESS;
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCSR")) < 0)
|
||||
return -1;
|
||||
free(resp);
|
||||
|
||||
jtag3_print_parms(pgm, stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jtag3_enable_tpi(PROGRAMMER *pgm, const AVRPART *p) {
|
||||
pmsg_notice2("jtag3_enable_tpi() is empty. No action necessary.\n");
|
||||
}
|
||||
|
||||
static void jtag3_disable_tpi(const PROGRAMMER *pgm) {
|
||||
unsigned char cmd[1];
|
||||
unsigned char* resp;
|
||||
int status;
|
||||
|
||||
cmd[0] = XPRG_CMD_LEAVE_PROGMODE;
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Leave Progmode")) < 0)
|
||||
return;
|
||||
free(resp);
|
||||
}
|
||||
|
||||
static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||
unsigned long addr, unsigned char * value) {
|
||||
int status;
|
||||
const size_t len = 8;
|
||||
unsigned char cmd[8]; // Using "len" as array length causes msvc build jobs to fail with error C2057: expected constant expression
|
||||
unsigned char* resp;
|
||||
unsigned long paddr = 0UL;
|
||||
|
||||
msg_notice2("\n");
|
||||
pmsg_notice2("jtag3_read_byte_tpi(.., %s, 0x%lx, ...)\n", mem->desc, addr);
|
||||
|
||||
paddr = mem->offset + addr;
|
||||
|
||||
cmd[0] = XPRG_CMD_READ_MEM;
|
||||
cmd[1] = tpi_get_memtype(mem);
|
||||
u32_to_b4_big_endian((cmd+2), paddr); // Address
|
||||
u16_to_b2_big_endian((cmd+6), 1); // Size
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Read Byte")) < 0)
|
||||
return -1;
|
||||
*value = resp[2];
|
||||
free(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jtag3_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
||||
unsigned long addr) {
|
||||
const size_t len = 6;
|
||||
unsigned char cmd[6]; // Using "len" as array length causes msvc build jobs to fail with error C2057: expected constant expression
|
||||
unsigned char* resp;
|
||||
int status;
|
||||
unsigned long paddr = 0UL;
|
||||
|
||||
cmd[0] = XPRG_CMD_ERASE;
|
||||
if (strcmp(mem->desc, "fuse") == 0) {
|
||||
cmd[1] = XPRG_ERASE_CONFIG;
|
||||
} else if (strcmp(mem->desc, "flash") == 0) {
|
||||
cmd[1] = XPRG_ERASE_APP;
|
||||
} else {
|
||||
pmsg_error("jtag3_erase_tpi() unsupported memory: %s\n", mem->desc);
|
||||
return -1;
|
||||
}
|
||||
paddr = (mem->offset + addr) | 0x01; // An erase is triggered by an access to the hi-byte
|
||||
u32_to_b4_big_endian((cmd+2), paddr);
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Erase")) < 0)
|
||||
return -1;
|
||||
free(resp);
|
||||
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;
|
||||
size_t data_size = 2;
|
||||
unsigned char cmd[17];
|
||||
unsigned char* resp;
|
||||
int status;
|
||||
unsigned long paddr = 0UL;
|
||||
|
||||
status = jtag3_erase_tpi(pgm, p, mem, addr);
|
||||
if (status < 0) {
|
||||
pmsg_error("error in communication, received status 0x%02x\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
paddr = mem->offset + addr;
|
||||
|
||||
if (mem->n_word_writes != 0) {
|
||||
if (mem->n_word_writes == 2) {
|
||||
len = 13;
|
||||
data_size = 4;
|
||||
}
|
||||
else if (mem->n_word_writes == 4) {
|
||||
len = 17;
|
||||
data_size = 8;
|
||||
}
|
||||
}
|
||||
|
||||
cmd[0] = XPRG_CMD_WRITE_MEM;
|
||||
cmd[1] = tpi_get_memtype(mem);
|
||||
cmd[2] = 0; // Page Mode - Not used
|
||||
u32_to_b4_big_endian((cmd+3), paddr); // Address
|
||||
u16_to_b2_big_endian((cmd+7), data_size); // Size
|
||||
cmd[9] = data;
|
||||
cmd[10] = 0xFF; // len = 11 if no n_word_writes
|
||||
cmd[11] = 0xFF;
|
||||
cmd[12] = 0xFF; // len = 13 if n_word_writes == 2
|
||||
cmd[13] = 0xFF;
|
||||
cmd[14] = 0xFF;
|
||||
cmd[15] = 0xFF;
|
||||
cmd[16] = 0xFF; // len = 17 if n_word_writes == 4
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Write Byte")) < 0)
|
||||
return -1;
|
||||
free(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
const size_t len = 6;
|
||||
unsigned char cmd[6]; // Using "len" as array length causes msvc build jobs to fail with error C2057: expected constant expression
|
||||
unsigned char* resp;
|
||||
int status;
|
||||
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;
|
||||
}
|
||||
|
||||
// An erase is triggered by an access to the hi-byte
|
||||
paddr = m->offset | 0x01;
|
||||
|
||||
cmd[0] = XPRG_CMD_ERASE;
|
||||
cmd[1] = XPRG_ERASE_CHIP;
|
||||
u32_to_b4_big_endian((cmd+2), paddr);
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Chip Erase")) < 0)
|
||||
return -1;
|
||||
free(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jtag3_open_tpi(PROGRAMMER *pgm, const char *port) {
|
||||
pmsg_notice2("jtag3_open_tpi()\n");
|
||||
|
||||
if (jtag3_open_common(pgm, port) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jtag3_close_tpi(PROGRAMMER *pgm) {
|
||||
pmsg_notice2("jtag3_close_tpi() is empty. No action necessary.\n");
|
||||
}
|
||||
|
||||
static int jtag3_paged_load_tpi(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
const AVRMEM *m, unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes) {
|
||||
unsigned int block_size = 0;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
unsigned char cmd[8];
|
||||
unsigned char *resp;
|
||||
int status;
|
||||
long otimeout = serial_recv_timeout;
|
||||
|
||||
msg_notice2("\n");
|
||||
pmsg_notice2("jtag3_paged_load_tpi(.., %s, %d, 0x%04x, %d)\n",
|
||||
m->desc, page_size, addr, n_bytes);
|
||||
|
||||
if(m->offset)
|
||||
imsg_notice2("mapped to address: 0x%04x\n", (addr+m->offset));
|
||||
|
||||
cmd[0] = XPRG_CMD_READ_MEM;
|
||||
cmd[1] = tpi_get_memtype(m);
|
||||
|
||||
if(m->blocksize > page_size)
|
||||
page_size = m->blocksize;
|
||||
|
||||
serial_recv_timeout = 100;
|
||||
for (; addr < maxaddr; addr += page_size) {
|
||||
if ((maxaddr - addr) < page_size)
|
||||
block_size = maxaddr - addr;
|
||||
else
|
||||
block_size = page_size;
|
||||
pmsg_debug("jtag3_paged_load_tpi(): "
|
||||
"block_size at addr 0x%x is %d\n", addr, block_size);
|
||||
|
||||
u32_to_b4_big_endian((cmd+2), addr + m->offset); // Address
|
||||
u16_to_b2_big_endian((cmd+6), block_size); // Size
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, 8, &resp, "Read Memory")) < 0)
|
||||
return -1;
|
||||
|
||||
if (resp[1] != XPRG_ERR_OK ||
|
||||
status < block_size + 2) {
|
||||
pmsg_error("wrong/short reply to read memory command\n");
|
||||
serial_recv_timeout = otimeout;
|
||||
free(resp);
|
||||
return -1;
|
||||
}
|
||||
memcpy(m->buf + addr, resp + 2, status - 2);
|
||||
free(resp);
|
||||
}
|
||||
serial_recv_timeout = otimeout;
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
static int jtag3_paged_write_tpi(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
const AVRMEM *m, unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes) {
|
||||
unsigned int block_size;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
unsigned char *cmd;
|
||||
unsigned char *resp;
|
||||
int status;
|
||||
long otimeout = serial_recv_timeout;
|
||||
|
||||
msg_notice2("\n");
|
||||
pmsg_notice2("jtag3_paged_write_tpi(.., %s, %d, 0x%04x, %d)\n", m->desc, page_size, addr, n_bytes);
|
||||
|
||||
if(m->offset)
|
||||
imsg_notice2("mapped to address: 0x%04x\n", (addr+m->offset));
|
||||
|
||||
if (page_size == 0)
|
||||
page_size = m->page_size;
|
||||
|
||||
if ((cmd = malloc(page_size + 9)) == NULL) {
|
||||
pmsg_error("out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[0] = XPRG_CMD_WRITE_MEM;
|
||||
cmd[1] = tpi_get_memtype(m);
|
||||
cmd[2] = 0; // Page Mode; Not used - ignored
|
||||
|
||||
serial_recv_timeout = 100;
|
||||
for (; addr < maxaddr; addr += page_size) {
|
||||
if ((maxaddr - addr) < page_size)
|
||||
block_size = maxaddr - addr;
|
||||
else
|
||||
block_size = page_size;
|
||||
pmsg_debug("jtag3_paged_write(): "
|
||||
"block_size at addr 0x%x is %d\n", addr, block_size);
|
||||
|
||||
u32_to_b4_big_endian((cmd+3), addr + m->offset); // Address
|
||||
u16_to_b2_big_endian((cmd+7), page_size); // Size
|
||||
|
||||
/*
|
||||
* If a partial page has been requested, set the remainder to 0xff.
|
||||
* (Maybe we should rather read back the existing contents instead
|
||||
* before? Doesn't matter much, as bits cannot be written to 1 anyway.)
|
||||
*/
|
||||
memset(cmd + 9, 0xff, page_size);
|
||||
memcpy(cmd + 9, m->buf + addr, block_size);
|
||||
|
||||
if ((status = jtag3_command_tpi(pgm, cmd, page_size + 9,
|
||||
&resp, "Write Memory")) < 0) {
|
||||
free(cmd);
|
||||
serial_recv_timeout = otimeout;
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(resp);
|
||||
}
|
||||
|
||||
free(cmd);
|
||||
serial_recv_timeout = otimeout;
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
|
||||
const char jtag3_desc[] = "Atmel JTAGICE3";
|
||||
|
||||
|
@ -2677,3 +3055,33 @@ void jtag3_updi_initpgm(PROGRAMMER *pgm) {
|
|||
}
|
||||
}
|
||||
|
||||
const char jtag3_tpi_desc[] = "Atmel JTAGICE3 in TPI mode";
|
||||
|
||||
void jtag3_tpi_initpgm(PROGRAMMER *pgm) {
|
||||
strcpy(pgm->type, "JTAGICE3_TPI");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = jtag3_initialize_tpi;
|
||||
pgm->display = jtag3_display;
|
||||
pgm->enable = jtag3_enable_tpi;
|
||||
pgm->disable = jtag3_disable_tpi;
|
||||
pgm->program_enable = jtag3_program_enable_dummy;
|
||||
pgm->chip_erase = jtag3_chip_erase_tpi;
|
||||
pgm->open = jtag3_open_tpi;
|
||||
pgm->close = jtag3_close_tpi;
|
||||
pgm->read_byte = jtag3_read_byte_tpi;
|
||||
pgm->write_byte = jtag3_write_byte_tpi;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = jtag3_paged_write_tpi;
|
||||
pgm->paged_load = jtag3_paged_load_tpi;
|
||||
pgm->print_parms = jtag3_print_parms;
|
||||
pgm->setup = jtag3_setup;
|
||||
pgm->teardown = jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
pgm->flag = PGM_FL_IS_TPI;
|
||||
}
|
||||
|
|
|
@ -44,10 +44,12 @@ extern const char jtag3_desc[];
|
|||
extern const char jtag3_dw_desc[];
|
||||
extern const char jtag3_pdi_desc[];
|
||||
extern const char jtag3_updi_desc[];
|
||||
extern const char jtag3_tpi_desc[];
|
||||
void jtag3_initpgm(PROGRAMMER *pgm);
|
||||
void jtag3_dw_initpgm(PROGRAMMER *pgm);
|
||||
void jtag3_pdi_initpgm(PROGRAMMER *pgm);
|
||||
void jtag3_updi_initpgm(PROGRAMMER *pgm);
|
||||
void jtag3_tpi_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
/*
|
||||
* These functions are referenced from stk500v2.c for JTAGICE3 in
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
#define SCOPE_GENERAL 0x01
|
||||
#define SCOPE_AVR_ISP 0x11
|
||||
#define SCOPE_AVR 0x12
|
||||
#define SCOPE_AVR_TPI 0x14
|
||||
|
||||
/* Info scope */
|
||||
#define CMD3_GET_INFO 0x00
|
||||
|
@ -314,6 +315,60 @@
|
|||
#define UPDI_ADDRESS_MODE_24BIT 1
|
||||
#define FUSES_SYSCFG0_OFFSET 5
|
||||
|
||||
// TPI Protocol commands
|
||||
#define XPRG_CMD_ENTER_PROGMODE 0x01
|
||||
#define XPRG_CMD_LEAVE_PROGMODE 0x02
|
||||
#define XPRG_CMD_ERASE 0x03
|
||||
#define XPRG_CMD_WRITE_MEM 0x04
|
||||
#define XPRG_CMD_READ_MEM 0x05
|
||||
#define XPRG_CMD_CRC 0x06
|
||||
#define XPRG_CMD_SET_PARAM 0x07
|
||||
|
||||
// TPI Protocol responses
|
||||
// Success
|
||||
#define XPRG_ERR_OK 0x00
|
||||
// Errors
|
||||
#define XPRG_ERR_FAILED 0x01
|
||||
#define XPRG_ERR_COLLISION 0x02
|
||||
#define XPRG_ERR_TIMEOUT 0x03
|
||||
#define XPRG_ERR_ILLEGAL_PARAM 0x04
|
||||
#define XPRG_ERR_UNKNOWN_COMMAND 0x10
|
||||
|
||||
// TPI Memory types
|
||||
#define XPRG_MEM_TYPE_APPL 0x01
|
||||
#define XPRG_MEM_TYPE_BOOT 0x02
|
||||
#define XPRG_MEM_TYPE_EEPROM 0x03
|
||||
#define XPRG_MEM_TYPE_FUSE 0x04
|
||||
#define XPRG_MEM_TYPE_LOCKBITS 0x05
|
||||
#define XPRG_MEM_TYPE_USERSIG 0x06
|
||||
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 0x07
|
||||
|
||||
// TPI Erase modes
|
||||
#define XPRG_ERASE_CHIP 0x01
|
||||
#define XPRG_ERASE_APP 0x02
|
||||
#define XPRG_ERASE_BOOT 0x03
|
||||
#define XPRG_ERASE_EEPROM 0x04
|
||||
#define XPRG_ERASE_APP_PAGE 0x05
|
||||
#define XPRG_ERASE_BOOT_PAGE 0x06
|
||||
#define XPRG_ERASE_EEPROM_PAGE 0x07
|
||||
#define XPRG_ERASE_USERSIG 0x08
|
||||
// Erase types for Tiny XPROG
|
||||
#define XPRG_ERASE_CONFIG 0x09
|
||||
|
||||
// TPI Parameters
|
||||
// XPROG parameters of different sizes
|
||||
// 4-byte address
|
||||
#define XPRG_PARAM_NVMBASE 0x01
|
||||
// 2-byte page size
|
||||
#define XPRG_PARAM_EEPPAGESIZE 0x02
|
||||
// tiny TPI, 1-byte address
|
||||
#define XPRG_PARAM_NVMCMD_ADDR 0x03
|
||||
#define XPRG_PARAM_NVMCSR_ADDR 0x04
|
||||
|
||||
#define TPI_NVMCMD_ADDRESS 0x33
|
||||
#define TPI_NVMCSR_ADDRESS 0x32
|
||||
|
||||
|
||||
#if !defined(JTAG3_PRIVATE_EXPORTED)
|
||||
|
||||
struct mega_device_desc {
|
||||
|
|
|
@ -87,6 +87,7 @@ const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call th
|
|||
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, // "JTAGICE3_UPDI"
|
||||
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, // "JTAGICE3_DW"
|
||||
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, // "JTAG3_ISP"
|
||||
{"jtagice3_tpi", jtag3_tpi_initpgm, jtag3_tpi_desc}, // "JTAGICE3_TPI"
|
||||
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, // "linuxgpio"
|
||||
{"linuxspi", linuxspi_initpgm, linuxspi_desc}, // LINUXSPI
|
||||
{"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0"
|
||||
|
|
|
@ -3605,18 +3605,18 @@ static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p)
|
|||
return -1;
|
||||
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_TPI_3;
|
||||
buf[1] = XPRG_PARAM_NVMCMD_ADDR;
|
||||
buf[2] = 51;
|
||||
if (stk600_xprog_command(pgm, buf, 3, 2) < 0) {
|
||||
pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_TPI_3) failed\n");
|
||||
pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMCMD_ADDR) failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = XPRG_CMD_SET_PARAM;
|
||||
buf[1] = XPRG_PARAM_TPI_4;
|
||||
buf[1] = XPRG_PARAM_NVMCSR_ADDR;
|
||||
buf[2] = 50;
|
||||
if (stk600_xprog_command(pgm, buf, 3, 2) < 0) {
|
||||
pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_TPI_4) failed\n");
|
||||
pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMCSR_ADDR) failed\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -223,35 +223,6 @@
|
|||
#define XPRG_MODE_JTAG 1
|
||||
#define XPRG_MODE_TPI 2
|
||||
|
||||
// XPROG commands
|
||||
#define XPRG_CMD_ENTER_PROGMODE 0x01
|
||||
#define XPRG_CMD_LEAVE_PROGMODE 0x02
|
||||
#define XPRG_CMD_ERASE 0x03
|
||||
#define XPRG_CMD_WRITE_MEM 0x04
|
||||
#define XPRG_CMD_READ_MEM 0x05
|
||||
#define XPRG_CMD_CRC 0x06
|
||||
#define XPRG_CMD_SET_PARAM 0x07
|
||||
|
||||
// Memory types
|
||||
#define XPRG_MEM_TYPE_APPL 1
|
||||
#define XPRG_MEM_TYPE_BOOT 2
|
||||
#define XPRG_MEM_TYPE_EEPROM 3
|
||||
#define XPRG_MEM_TYPE_FUSE 4
|
||||
#define XPRG_MEM_TYPE_LOCKBITS 5
|
||||
#define XPRG_MEM_TYPE_USERSIG 6
|
||||
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
|
||||
|
||||
// Erase types
|
||||
#define XPRG_ERASE_CHIP 1
|
||||
#define XPRG_ERASE_APP 2
|
||||
#define XPRG_ERASE_BOOT 3
|
||||
#define XPRG_ERASE_EEPROM 4
|
||||
#define XPRG_ERASE_APP_PAGE 5
|
||||
#define XPRG_ERASE_BOOT_PAGE 6
|
||||
#define XPRG_ERASE_EEPROM_PAGE 7
|
||||
#define XPRG_ERASE_USERSIG 8
|
||||
#define XPRG_ERASE_CONFIG 9 // TPI only, prepare fuse write
|
||||
|
||||
// Write mode flags
|
||||
#define XPRG_MEM_WRITE_ERASE 0
|
||||
#define XPRG_MEM_WRITE_WRITE 1
|
||||
|
@ -261,22 +232,6 @@
|
|||
#define XPRG_CRC_BOOT 2
|
||||
#define XPRG_CRC_FLASH 3
|
||||
|
||||
// Error codes
|
||||
#define XPRG_ERR_OK 0
|
||||
#define XPRG_ERR_FAILED 1
|
||||
#define XPRG_ERR_COLLISION 2
|
||||
#define XPRG_ERR_TIMEOUT 3
|
||||
|
||||
// XPROG parameters of different sizes
|
||||
// 4-byte address
|
||||
#define XPRG_PARAM_NVMBASE 0x01
|
||||
// 2-byte page size
|
||||
#define XPRG_PARAM_EEPPAGESIZE 0x02
|
||||
// 1-byte, undocumented TPI param
|
||||
#define XPRG_PARAM_TPI_3 0x03
|
||||
// 1-byte, undocumented TPI param
|
||||
#define XPRG_PARAM_TPI_4 0x04
|
||||
|
||||
// *****************[ STK answer constants ]***************************
|
||||
|
||||
#define ANSWER_CKSUM_ERROR 0xB0
|
||||
|
|
Loading…
Reference in New Issue