* Bit 7: nRESET
*/
+#define SWJ_PIN_TCK (1<<0)
+#define SWJ_PIN_TMS (1<<1)
+#define SWJ_PIN_TDI (1<<2)
+#define SWJ_PIN_TDO (1<<3)
+#define SWJ_PIN_TRST (1<<5)
+#define SWJ_PIN_SRST (1<<7)
+
/* CMSIS-DAP SWD Commands */
#define CMD_DAP_SWD_CONFIGURE 0x13
static int queued_retval;
+static uint8_t output_pins = SWJ_PIN_SRST | SWJ_PIN_TRST;
+
static struct cmsis_dap *cmsis_dap_handle;
static int cmsis_dap_usb_open(void)
int packet_size = PACKET_SIZE;
/* atmel cmsis-dap uses 512 byte reports */
+ /* except when it doesn't e.g. with mEDBG on SAMD10 Xplained
+ * board */
/* TODO: HID report descriptor should be parsed instead of
* hardcoding a match by VID */
- if (target_vid == 0x03eb)
+ if (target_vid == 0x03eb && target_pid != 0x2145)
packet_size = 512 + 1;
cmsis_dap_handle->packet_buffer = malloc(packet_size);
{
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
- LOG_DEBUG("Executing %d queued transactions", pending_transfer_count);
+ LOG_DEBUG_IO("Executing %d queued transactions", pending_transfer_count);
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
uint8_t cmd = pending_transfers[i].cmd;
uint32_t data = pending_transfers[i].data;
- LOG_DEBUG("%s %s reg %x %"PRIx32,
+ LOG_DEBUG_IO("%s %s reg %x %"PRIx32,
cmd & SWD_CMD_APnDP ? "AP" : "DP",
cmd & SWD_CMD_RnW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1, data);
uint32_t tmp = data;
idx += 4;
- LOG_DEBUG("Read result: %"PRIx32, data);
+ LOG_DEBUG_IO("Read result: %"PRIx32, data);
/* Imitate posted AP reads */
if ((pending_transfers[i].cmd & SWD_CMD_APnDP) ||
if (retval == ERROR_OK) {
LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
- (d & (0x01 << 0)) ? 1 : 0, /* Bit 0: SWCLK/TCK */
- (d & (0x01 << 1)) ? 1 : 0, /* Bit 1: SWDIO/TMS */
- (d & (0x01 << 2)) ? 1 : 0, /* Bit 2: TDI */
- (d & (0x01 << 3)) ? 1 : 0, /* Bit 3: TDO */
- (d & (0x01 << 5)) ? 1 : 0, /* Bit 5: nTRST */
- (d & (0x01 << 7)) ? 1 : 0); /* Bit 7: nRESET */
+ (d & SWJ_PIN_TCK) ? 1 : 0,
+ (d & SWJ_PIN_TMS) ? 1 : 0,
+ (d & SWJ_PIN_TDI) ? 1 : 0,
+ (d & SWJ_PIN_TDO) ? 1 : 0,
+ (d & SWJ_PIN_TRST) ? 1 : 0,
+ (d & SWJ_PIN_SRST) ? 1 : 0);
}
return retval;
unsigned int s_len;
int retval;
- /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */
- cmsis_dap_cmd_DAP_Disconnect();
+ if ((output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST)) == (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
+ /* Following workaround deasserts reset on most adapters.
+ * Do not reconnect if a reset line is active!
+ * Reconnecting would break connecting under reset. */
- /* When we are reconnecting, DAP_Connect needs to be rerun, at
- * least on Keil ULINK-ME */
- retval = cmsis_dap_cmd_DAP_Connect(seq == LINE_RESET || seq == JTAG_TO_SWD ?
- CONNECT_SWD : CONNECT_JTAG);
- if (retval != ERROR_OK)
- return retval;
+ /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */
+ cmsis_dap_cmd_DAP_Disconnect();
+
+ /* When we are reconnecting, DAP_Connect needs to be rerun, at
+ * least on Keil ULINK-ME */
+ retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
+ if (retval != ERROR_OK)
+ return retval;
+ }
switch (seq) {
case LINE_RESET:
return ERROR_FAIL;
}
- return cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
+ retval = cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* Atmel EDBG needs renew clock setting after SWJ_Sequence
+ * otherwise default frequency is used */
+ return cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
}
static int cmsis_dap_swd_open(void)
{
int retval;
- if (cmsis_dap_handle == NULL) {
- /* SWD init */
- retval = cmsis_dap_usb_open();
- if (retval != ERROR_OK)
- return retval;
-
- retval = cmsis_dap_get_caps_info();
- if (retval != ERROR_OK)
- return retval;
- }
-
if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
LOG_ERROR("CMSIS-DAP: SWD not supported");
return ERROR_JTAG_DEVICE_ERROR;
int retval;
uint8_t *data;
+ retval = cmsis_dap_usb_open();
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = cmsis_dap_get_caps_info();
+ if (retval != ERROR_OK)
+ return retval;
+
if (swd_mode) {
retval = cmsis_dap_swd_open();
if (retval != ERROR_OK)
}
if (cmsis_dap_handle == NULL) {
-
- /* JTAG init */
- retval = cmsis_dap_usb_open();
- if (retval != ERROR_OK)
- return retval;
-
- retval = cmsis_dap_get_caps_info();
- if (retval != ERROR_OK)
- return retval;
-
/* Connect in JTAG mode */
if (!(cmsis_dap_handle->caps & INFO_CAPS_JTAG)) {
LOG_ERROR("CMSIS-DAP: JTAG not supported");
retval = cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0);
if (retval != ERROR_OK)
return ERROR_FAIL;
- /* Data Phase (bit 2) must be set to 1 if sticky overrun
- * detection is enabled */
- retval = cmsis_dap_cmd_DAP_SWD_Configure(0); /* 1 TRN, no Data Phase */
- if (retval != ERROR_OK)
- return ERROR_FAIL;
+
+ if (swd_mode) {
+ /* Data Phase (bit 2) must be set to 1 if sticky overrun
+ * detection is enabled */
+ retval = cmsis_dap_cmd_DAP_SWD_Configure(0); /* 1 TRN, no Data Phase */
+ if (retval != ERROR_OK)
+ return ERROR_FAIL;
+ }
retval = cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */
if (retval != ERROR_OK)
static void cmsis_dap_execute_reset(struct jtag_command *cmd)
{
- int retval = cmsis_dap_cmd_DAP_SWJ_Pins(cmd->cmd.reset->srst ? 0 : (1 << 7), \
- (1 << 7), 0, NULL);
+ /* Set both TRST and SRST even if they're not enabled as
+ * there's no way to tristate them */
+
+ output_pins = 0;
+ if (!cmd->cmd.reset->srst)
+ output_pins |= SWJ_PIN_SRST;
+ if (!cmd->cmd.reset->trst)
+ output_pins |= SWJ_PIN_TRST;
+
+ int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins,
+ SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
LOG_ERROR("CMSIS-DAP: Interface reset failed");
}
static int cmsis_dap_speed(int speed)
{
- if (speed > DAP_MAX_CLOCK) {
- LOG_INFO("reduce speed request: %dkHz to %dkHz maximum", speed, DAP_MAX_CLOCK);
- speed = DAP_MAX_CLOCK;
- }
+ if (speed > DAP_MAX_CLOCK)
+ LOG_INFO("High speed (adapter_khz %d) may be limited by adapter firmware.", speed);
if (speed == 0) {
- LOG_INFO("RTCK not supported");
+ LOG_ERROR("RTCK not supported. Set nonzero adapter_khz.");
return ERROR_JTAG_NOT_IMPLEMENTED;
}