static int stlink_usb_step(void *handle) { 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_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); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_STEPCORE; 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; }
static int stlink_usb_halt(void *handle) { int res; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); if (h->jtag_api == STLINK_JTAG_API_V2) { res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN); if (res == ERROR_OK && h->trace.enabled) stlink_usb_trace_disable(handle); return res; } stlink_usb_init_buffer(handle, h->rx_ep, 2); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_FORCEDEBUG; 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; }
static int stlink_usb_run(void *handle) { int res; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); if (h->jtag_api == STLINK_JTAG_API_V2) { res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_DEBUGEN); /* Try to start tracing, if requested */ if (res == ERROR_OK && h->trace.source_hz && !h->trace.enabled) { if (stlink_usb_trace_enable(handle) == ERROR_OK) LOG_DEBUG("Tracing: enabled\n"); else LOG_ERROR("Tracing: enable failed\n"); } return res; } stlink_usb_init_buffer(handle, h->rx_ep, 2); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_RUNCORE; 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; }
static int stlink_configure_target_trace_port(void *handle) { int res; uint32_t reg; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); /* configure the TPI */ /* enable the trace subsystem */ res = stlink_usb_v2_read_debug_reg(handle, DCB_DEMCR, ®); if (res != ERROR_OK) goto out; res = stlink_usb_write_debug_reg(handle, DCB_DEMCR, TRCENA|reg); if (res != ERROR_OK) goto out; /* set the TPI clock prescaler */ res = stlink_usb_write_debug_reg(handle, TPI_ACPR, h->trace.prescale); if (res != ERROR_OK) goto out; /* select the pin protocol. The STLinkv2 only supports asynchronous * UART emulation (NRZ) mode, so that's what we pick. */ res = stlink_usb_write_debug_reg(handle, TPI_SPPR, 0x02); if (res != ERROR_OK) goto out; /* disable continuous formatting */ res = stlink_usb_write_debug_reg(handle, TPI_FFCR, (1<<8)); if (res != ERROR_OK) goto out; /* configure the ITM */ /* unlock access to the ITM registers */ res = stlink_usb_write_debug_reg(handle, ITM_LAR, 0xC5ACCE55); if (res != ERROR_OK) goto out; /* enable trace with ATB ID 1 */ res = stlink_usb_write_debug_reg(handle, ITM_TCR, (1<<16)|(1<<0)|(1<<2)); if (res != ERROR_OK) goto out; /* trace privilege */ res = stlink_usb_write_debug_reg(handle, ITM_TPR, 1); if (res != ERROR_OK) goto out; /* trace port enable (port 0) */ res = stlink_usb_write_debug_reg(handle, ITM_TER, (1<<0)); if (res != ERROR_OK) goto out; res = ERROR_OK; out: return res; }
static int stlink_usb_halt(void *handle) { 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_V2) return stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN); stlink_usb_init_buffer(handle, STLINK_RX_EP, 2); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_FORCEDEBUG; 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; }