* Copyright (C) 2011-2012 by Mathias Kuester *
* Mathias Kuester <kesmtp@freenet.de> *
* *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
* This code is based on https://github.com/texane/stlink *
* *
* This program is free software; you can redistribute it and/or modify *
#define STLINK_CMD_SIZE_V1 (10)
enum stlink_jtag_api_version {
- STLINK_JTAG_API_V1 = 0,
+ STLINK_JTAG_API_V1 = 1,
STLINK_JTAG_API_V2,
};
};
#define STLINK_DEBUG_ERR_OK 0x80
-#define STLINK_DEBUG_ERR_FAULT 0x81
+#define STLINK_DEBUG_ERR_FAULT 0x81
+#define STLINK_SWD_AP_WAIT 0x10
+#define STLINK_SWD_DP_WAIT 0x14
+
#define STLINK_CORE_RUNNING 0x80
#define STLINK_CORE_HALTED 0x81
#define STLINK_CORE_STAT_UNKNOWN -1
h->pid = buf_get_u32(h->databuf, 32, 16);
/* set the supported jtag api version
- * V1 doesn't support API V2 at all
- * V2 support API V2 since JTAG V13
+ * API V2 is supported since JTAG V11
*/
- if ((h->version.stlink == 2) && (h->version.jtag > 12))
+ if (h->version.jtag >= 11)
h->version.jtag_api_max = STLINK_JTAG_API_V2;
else
h->version.jtag_api_max = STLINK_JTAG_API_V1;
if (status & S_HALT)
return TARGET_HALTED;
+ else if (status & S_RESET_ST)
+ return TARGET_RESET;
return TARGET_RUNNING;
}
LOG_DEBUG("RESET: 0x%08X", h->databuf[0]);
+ /* the following is not a error under swd (using hardware srst), so return success */
+ if (h->databuf[0] == STLINK_SWD_AP_WAIT || h->databuf[0] == STLINK_SWD_DP_WAIT)
+ return ERROR_OK;
+
+ return h->databuf[0] == STLINK_DEBUG_ERR_OK ? ERROR_OK : ERROR_FAIL;
+}
+
+static int stlink_usb_assert_srst(void *handle, int srst)
+{
+ int res;
+ struct stlink_usb_handle_s *h;
+
+ assert(handle != NULL);
+
+ h = (struct stlink_usb_handle_s *)handle;
+
+ if (h->jtag_api == STLINK_JTAG_API_V1)
+ return ERROR_COMMAND_NOTFOUND;
+
+ stlink_usb_init_buffer(handle, STLINK_RX_EP, 2);
+
+ h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
+ h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_DRIVE_NRST;
+ h->cmdbuf[h->cmdidx++] = srst;
+
+ res = stlink_usb_xfer(handle, h->databuf, 2);
+
+ if (res != ERROR_OK)
+ return res;
+
return h->databuf[0] == STLINK_DEBUG_ERR_OK ? ERROR_OK : ERROR_FAIL;
}
h = (struct stlink_usb_handle_s *)handle;
- if (h->jtag_api == STLINK_JTAG_API_V2)
- return stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_STEP|C_DEBUGEN);
+ if (h->jtag_api == STLINK_JTAG_API_V2) {
+ /* TODO: this emulates the v1 api, it should really use a similar auto mask isr
+ * that the cortex-m3 currently does. */
+ stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_MASKINTS|C_DEBUGEN);
+ stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_STEP|C_MASKINTS|C_DEBUGEN);
+ return stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN);
+ }
stlink_usb_init_buffer(handle, STLINK_RX_EP, 2);
{
int err;
struct stlink_usb_handle_s *h;
+ enum stlink_jtag_api_version api;
LOG_DEBUG("stlink_usb_open");
return err;
}
- /* set the used jtag api */
- h->jtag_api = STLINK_JTAG_API_V1;
+ api = h->version.jtag_api_max;
+
+ /* check that user has not requested certain api version
+ * and if they have check it is supported */
+ if ((param->api != 0) && (param->api <= h->version.jtag_api_max)) {
+ api = param->api;
+ LOG_INFO("using stlink api v%d", api);
+ }
+
+ /* set the used jtag api, this will default to the newest supported version */
+ h->jtag_api = api;
/* initialize the debug hardware */
err = stlink_usb_init_mode(h);
/** */
.reset = stlink_usb_reset,
/** */
+ .assert_srst = stlink_usb_assert_srst,
+ /** */
.run = stlink_usb_run,
/** */
.halt = stlink_usb_halt,
.read_mem32 = stlink_usb_read_mem32,
/** */
.write_mem32 = stlink_usb_write_mem32,
+ /** */
+ .write_debug_reg = stlink_usb_write_debug_reg
};