static int stlink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) { int res; struct stlink_usb_handle_s *h; assert(handle != NULL); h = (struct stlink_usb_handle_s *)handle; stlink_usb_init_buffer(handle, STLINK_RX_EP, 2); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; if (h->jtag_api == STLINK_JTAG_API_V1) h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_WRITEDEBUGREG; else h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; h_u32_to_le(h->cmdbuf+h->cmdidx, val); h->cmdidx += 4; 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_v2_read_debug_reg(void *handle, uint32_t addr, uint32_t *val) { struct stlink_usb_handle_s *h; int res; assert(handle != NULL); h = (struct stlink_usb_handle_s *)handle; stlink_usb_init_buffer(handle, STLINK_RX_EP, 8); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READDEBUGREG; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; res = stlink_usb_xfer(handle, h->databuf, 8); if (res != ERROR_OK) return res; *val = le_to_h_u32(h->databuf + 4); return h->databuf[0] == STLINK_DEBUG_ERR_OK ? ERROR_OK : ERROR_FAIL; }
static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer) { int res; uint16_t read_len = len; struct stlink_usb_handle_s *h; assert(handle != NULL); h = (struct stlink_usb_handle_s *)handle; stlink_usb_init_buffer(handle, STLINK_RX_EP, read_len); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_8BIT; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; /* we need to fix read length for single bytes */ if (read_len == 1) read_len++; res = stlink_usb_xfer(handle, h->databuf, read_len); if (res != ERROR_OK) return res; memcpy(buffer, h->databuf, len); return stlink_usb_get_rw_status(handle); }
static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; struct stlink_usb_handle_s *h; assert(handle != NULL); h = (struct stlink_usb_handle_s *)handle; len *= 4; stlink_usb_init_buffer(handle, STLINK_TX_EP, len); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; res = stlink_usb_xfer(handle, buffer, len); if (res != ERROR_OK) return res; return stlink_usb_get_rw_status(handle); }
static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); /* data must be a multiple of 4 and word aligned */ if (len % 4 || addr % 4) { LOG_DEBUG("Invalid data alignment"); return ERROR_TARGET_UNALIGNED_ACCESS; } stlink_usb_init_buffer(handle, h->tx_ep, len); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; res = stlink_usb_xfer(handle, buffer, len); if (res != ERROR_OK) return res; return stlink_usb_get_rw_status(handle); }
static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); /* max 8bit read/write is 64bytes */ if (len > STLINK_MAX_RW8) { LOG_DEBUG("max buffer length exceeded"); return ERROR_FAIL; } stlink_usb_init_buffer(handle, h->tx_ep, len); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_8BIT; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; res = stlink_usb_xfer(handle, buffer, len); if (res != ERROR_OK) return res; return stlink_usb_get_rw_status(handle); }
static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) { uint8_t buf[4]; /* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32(). * I guess all supported chips are little-endian anyway. */ h_u32_to_le(buf, val); return icdi_usb_write_mem(handle, addr, 4, 1, buf); }
static int stlink_usb_trace_enable(void *handle) { int res; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); if (h->version.jtag >= STLINK_TRACE_MIN_VERSION) { uint32_t trace_hz; res = stlink_configure_target_trace_port(handle); if (res != ERROR_OK) LOG_ERROR("Unable to configure tracing on target\n"); trace_hz = h->trace.prescale > 0 ? h->trace.source_hz / (h->trace.prescale + 1) : h->trace.source_hz; stlink_usb_init_buffer(handle, h->rx_ep, 10); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_START_TRACE_RX; h_u16_to_le(h->cmdbuf+h->cmdidx, (uint16_t)STLINK_TRACE_SIZE); h->cmdidx += 2; h_u32_to_le(h->cmdbuf+h->cmdidx, trace_hz); h->cmdidx += 4; res = stlink_usb_xfer(handle, h->databuf, 2); if (res == ERROR_OK) { h->trace.enabled = true; LOG_DEBUG("Tracing: recording at %" PRIu32 "Hz\n", trace_hz); /* We need the trace read function to be called at a * high-enough frequency to ensure reasonable * "timeliness" in processing ITM/DWT data. * TODO: An alternative could be using the asynchronous * features of the libusb-1.0 API to queue up one or more * reads in advance and requeue them once they are * completed. */ target_register_timer_callback(stlink_usb_trace_read_callback, 1, 1, handle); } } else { LOG_ERROR("Tracing is not supported by this version."); res = ERROR_FAIL; } return res; }
static int icdi_usb_write_reg(void *handle, int num, uint32_t val) { int result; char cmd[20]; uint8_t buf[4]; h_u32_to_le(buf, val); int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num); hexify(cmd + cmd_len, buf, 4, sizeof(cmd)); result = icdi_send_cmd(handle, cmd); if (result != ERROR_OK) return result; /* check result */ result = icdi_get_cmd_result(handle); if (result != ERROR_OK) { LOG_ERROR("register write failed: 0x%x", result); return ERROR_FAIL; } return result; }
static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer) { int res; uint16_t read_len = len; struct stlink_usb_handle_s *h = handle; assert(handle != NULL); /* max 8bit read/write is 64bytes */ if (len > STLINK_MAX_RW8) { LOG_DEBUG("max buffer length exceeded"); return ERROR_FAIL; } stlink_usb_init_buffer(handle, h->rx_ep, read_len); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_8BIT; h_u32_to_le(h->cmdbuf+h->cmdidx, addr); h->cmdidx += 4; h_u16_to_le(h->cmdbuf+h->cmdidx, len); h->cmdidx += 2; /* we need to fix read length for single bytes */ if (read_len == 1) read_len++; res = stlink_usb_xfer(handle, h->databuf, read_len); if (res != ERROR_OK) return res; memcpy(buffer, h->databuf, len); return stlink_usb_get_rw_status(handle); }
/* read JTAG buffer into little-endian u32 */ int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field) { h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf)); return ERROR_OK; }