diff --git a/src/jtag3.h b/src/jtag3.h index 51914f0..0507d10 100644 --- a/src/jtag3.h +++ b/src/jtag3.h @@ -89,9 +89,12 @@ enum jtag3consts RSP3_FAIL_PDI = 0x1B, RSP3_FAIL_NO_ANSWER = 0x20, RSP3_FAIL_NO_TARGET_POWER = 0x22, - RSP3_FAIL_WRONG_MODE = 0x32, /* CPU running vs. stopped */ - RSP3_FAIL_UNSUPP_MEMORY = 0x34, /* unsupported memory type */ - RSP3_FAIL_WRONG_LENGTH = 0x35, /* wrong lenth for mem access */ + RSP3_FAIL_NOT_ATTACHED = 0x23, /* Must run attach command first */ + RSP3_FAIL_WRONG_MODE = 0x32, /* CPU running vs. stopped */ + RSP3_FAIL_UNSUPP_MEMORY = 0x34, /* unsupported memory type */ + RSP3_FAIL_WRONG_LENGTH = 0x35, /* wrong length for mem access */ + RSP3_FAIL_TIMEOUT = 0x3C, /* A timeout occurred */ + RSP3_FAIL_WRONG_OCD_STATUS = 0x3D, /* wrong OCD status */ RSP3_FAIL_NOT_UNDERSTOOD = 0x91, /* ICE events */ @@ -187,6 +190,7 @@ class jtag3: public jtag unsigned long cached_pc; bool cached_pc_is_valid; bool is_edbg; + bool is_capture; unsigned char flashCache[MAX_FLASH_PAGE_SIZE]; unsigned int flashCachePageAddr; @@ -202,7 +206,8 @@ class jtag3: public jtag jtag3(const char *dev, char *name, enum debugproto prot = PROTO_JTAG, bool nsrst = false, bool xmega = false, - bool edbg = false): + bool edbg = false, + bool capture = false): jtag(dev, name, edbg? EMULATOR_EDBG: EMULATOR_JTAGICE3) { signedIn = debug_active = false; command_sequence = 0; @@ -220,6 +225,7 @@ class jtag3: public jtag device_id = 0; cached_event = NULL; is_edbg = edbg; + is_capture = capture; }; virtual ~jtag3(void); @@ -353,6 +359,8 @@ class jtag3: public jtag /** Update Xmega breakpoints on target **/ void xmegaSendBPs(void); + + void attach(void); }; class jtag3_io_exception: public jtag_io_exception diff --git a/src/jtag3io.cc b/src/jtag3io.cc index f7544dc..4fecabd 100644 --- a/src/jtag3io.cc +++ b/src/jtag3io.cc @@ -56,6 +56,9 @@ jtag3_io_exception::jtag3_io_exception(unsigned int code) case RSP3_FAIL_NO_TARGET_POWER: reason = "No target power present"; break; + case RSP3_FAIL_NOT_ATTACHED: + reason = "Must run attach command first"; break; + case RSP3_FAIL_WRONG_MODE: reason = "wrong mode"; break; @@ -65,6 +68,12 @@ jtag3_io_exception::jtag3_io_exception(unsigned int code) case RSP3_FAIL_WRONG_LENGTH: reason = "wrong length for memory access"; break; + case RSP3_FAIL_TIMEOUT: + reason = "A timeout occurred"; break; + + case RSP3_FAIL_WRONG_OCD_STATUS: + reason = "wrong OCD status (check OCDEN fuse)"; break; + case RSP3_FAIL_NOT_UNDERSTOOD: reason = "command not understood"; break; @@ -537,8 +546,6 @@ void jtag3::startJtagLink(void) // ignore } } - - debug_active = true; } /** Device automatic configuration @@ -651,6 +658,22 @@ void jtag3::deviceAutoConfig(void) } +// Attach to target and stop program +void jtag3::attach(void) +{ + uchar cmd[] = { SCOPE_AVR, CMD3_START_DEBUG, 0, 1 }; + uchar *resp; + int respsize; + bool bp, intr; + + doJtagCommand(cmd, sizeof cmd, "start debugging", resp, respsize); + delete [] resp; + expectEvent(bp, intr); + + debug_active = true; +} + + void jtag3::initJtagBox(void) { statusOut("JTAG config starting.\n"); @@ -683,6 +706,30 @@ void jtag3::initJtagBox(void) deviceAutoConfig(); + // Unconditionally try to attach. Some physical interfaces (DebugWire) + // implicitly attach, but the EDBG reference implies it's always + // necessary. + try + { + attach(); + } + catch (jtag_io_exception& e) + { + bool bp, intr; + + if (e.get_response() != RSP3_FAIL_WRONG_OCD_STATUS) + { + throw; + } + // failed attach can still generate a BREAK + expectEvent(bp, intr); + + // If not doing capture, ignore failure, because + // initJtagOnChipDebugging might take care of it + if (is_capture) { + throw; + } + } // Clear out the breakpoints. deleteAllBreakpoints(); @@ -728,18 +775,16 @@ void jtag3::initJtagOnChipDebugging(unsigned long bitrate) // Ensure on-chip debug enable fuse is enabled ie '0' jtagActivateOcdenFuse(); - uchar timers = 0; // stopped - setJtagParameter(SCOPE_AVR, 3, PARM3_TIMERS_RUNNING, &timers, 1); - - if (proto == PROTO_DW || is_xmega) + if (proto != PROTO_DW && !debug_active) { - uchar cmd[] = { SCOPE_AVR, CMD3_START_DEBUG, 0, 1 }; - uchar *resp; - int respsize; - - doJtagCommand(cmd, sizeof cmd, "start debugging", resp, respsize); - delete [] resp; + // Absorb BREAK from leaving progmode + bool bp, gdb; + expectEvent(bp, gdb); } + debug_active = true; + + uchar timers = 0; // stopped + setJtagParameter(SCOPE_AVR, 3, PARM3_TIMERS_RUNNING, &timers, 1); // Sometimes (like, after just enabling the OCDEN fuse), the first // resetProgram() runs into an error code 0x32. Just retry it once. @@ -749,6 +794,9 @@ void jtag3::initJtagOnChipDebugging(unsigned long bitrate) } catch (jtag_exception &e) { + // Absorb BREAK from failed reset + bool bp, gdb; + expectEvent(bp, gdb); debugOut("retrying reset ...\n"); resetProgram(); } diff --git a/src/jtag3prog.cc b/src/jtag3prog.cc index f725ccc..2c993ed 100644 --- a/src/jtag3prog.cc +++ b/src/jtag3prog.cc @@ -53,6 +53,12 @@ void jtag3::disableProgramming(void) { programmingEnabled = false; doSimpleJtagCommand(CMD3_LEAVE_PROGMODE, "leave progmode"); + // Leaving progmode with OCD active can produce a BREAK + if (debug_active) + { + bool bp, intr; + expectEvent(bp, intr); + } } } diff --git a/src/main.cc b/src/main.cc index 652c19c..fb25c4f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -600,12 +600,12 @@ int main(int argc, char **argv) case JTAG3: theJtagICE = new jtag3(jtagDeviceName, device_name, proto, - apply_nsrst, is_xmega); + apply_nsrst, is_xmega, false, capture); break; case EDBG: theJtagICE = new jtag3(jtagDeviceName, device_name, proto, - apply_nsrst, is_xmega, true); + apply_nsrst, is_xmega, true, capture); break; }