#include <sys/stat.h>
#include <sys/mman.h>
-// sgutils2 (apt-get install libsgutils2-dev)
-#include <scsi/sg_lib.h>
-#include <scsi/sg_pt.h>
-
#include "stlink-common.h"
#include "stlink-sg.h"
+#include "uglylogging.h"
+#define LOG_TAG __FILE__
+#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args)
+#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args)
+#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
+#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
// Suspends execution of the calling process for
// (at least) ms milliseconds.
// E.g. make the valgrind happy.
static void clear_buf(stlink_t *sl) {
- DD(sl, "*** clear_buf ***\n");
+ DLOG("*** clear_buf ***\n");
for (size_t i = 0; i < sizeof (sl->q_buf); i++)
sl->q_buf[i] = 0;
void _stlink_sg_close(stlink_t *sl) {
if (sl) {
+#if FINISHED_WITH_SG
struct stlink_libsg *slsg = sl->backend_data;
scsi_pt_close_device(slsg->sg_fd);
- // CAUTION!? s this right?
free(slsg);
- free(sl);
+#endif
}
}
//TODO rewrite/cleanup, save the error in sl
+#if FINISHED_WITH_SG
static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
struct stlink_libsg *sl = stl->backend_data;
const int e = sl->do_scsi_pt_err;
}
const int duration = get_scsi_pt_duration_ms(ptvp);
if ((stl->verbose > 1) && (duration >= 0))
- DD(stl, " duration=%d ms\n", duration);
+ DLOG(" duration=%d ms\n", duration);
// XXX stlink fw sends broken residue, so ignore it and use the known q_len
// "usb-storage quirks=483:3744:r"
switch (cat) {
case SCSI_PT_RESULT_GOOD:
if (stl->verbose && (resid > 0))
- DD(stl, " notice: requested %d bytes but "
+ DLOG(" notice: requested %d bytes but "
"got %d bytes, ignore [broken] residue = %d\n",
stl->q_len, dsize, resid);
break;
sg_get_scsi_status_str(
get_scsi_pt_status_response(ptvp), sizeof (buf),
buf);
- DD(stl, " scsi status: %s\n", buf);
+ DLOG(" scsi status: %s\n", buf);
}
return;
case SCSI_PT_RESULT_SENSE:
if (stl->verbose) {
sg_get_sense_str("", sl->sense_buf, slen, (stl->verbose
> 1), sizeof (buf), buf);
- DD(stl, "%s", buf);
+ DLOG("%s", buf);
}
if (stl->verbose && (resid > 0)) {
if ((stl->verbose) || (stl->q_len > 0))
- DD(stl, " requested %d bytes but "
+ DLOG(" requested %d bytes but "
"got %d bytes\n", stl->q_len, dsize);
}
return;
// The 'host_status' field has the following values:
// [0x07] Internal error detected in the host adapter.
// This may not be fatal (and the command may have succeeded).
- DD(stl, " transport: %s", buf);
+ DLOG(" transport: %s", buf);
}
return;
case SCSI_PT_RESULT_OS_ERR:
if (stl->verbose) {
get_scsi_pt_os_err_str(ptvp, sizeof (buf), buf);
- DD(stl, " os: %s", buf);
+ DLOG(" os: %s", buf);
}
return;
default:
"category (%d)\n", cat);
}
}
+#endif
void stlink_q(stlink_t *sl) {
+#if FINISHED_WITH_SG
struct stlink_libsg* sg = sl->backend_data;
- DD(sl, "CDB[");
+ DLOG("CDB[");
for (int i = 0; i < CDB_SL; i++)
- DD(sl, " 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]);
- DD(sl, "]\n");
+ DLOG(" 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]);
+ DLOG("]\n");
// Get control command descriptor of scsi structure,
// (one object per command!!)
stlink_confirm_inq(sl, ptvp);
// TODO recycle: clear_scsi_pt_obj(struct sg_pt_base * objp);
destruct_scsi_pt_obj(ptvp);
+#endif
}
// TODO thinking, cleanup
switch (stl->q_buf[0]) {
case STLINK_OK:
- DD(stl, " %s: ok\n", txt);
+ DLOG(" %s: ok\n", txt);
return;
case STLINK_FALSE:
- DD(stl, " %s: false\n", txt);
+ DLOG(" %s: false\n", txt);
return;
default:
- DD(stl, " %s: unknown\n", txt);
+ DLOG(" %s: unknown\n", txt);
}
}
+
void _stlink_sg_version(stlink_t *stl) {
struct stlink_libsg *sl = stl->backend_data;
- D(stl, "\n*** stlink_version ***\n");
+ DLOG("\n*** stlink_version ***\n");
clear_cdb(sl);
sl->cdb_cmd_blk[0] = STLINK_GET_VERSION;
stl->q_len = 6;
void _stlink_sg_enter_jtag_mode(stlink_t *sl) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_enter_jtag_mode ***\n");
+ DLOG("\n*** stlink_enter_jtag_mode ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER;
sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG;
void _stlink_sg_exit_dfu_mode(stlink_t *sl) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_exit_dfu_mode ***\n");
+ DLOG("\n*** stlink_exit_dfu_mode ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND;
sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT;
void _stlink_sg_status(stlink_t *sl) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_status ***\n");
+ DLOG("\n*** stlink_status ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS;
sl->q_len = 2;
void _stlink_sg_force_debug(stlink_t *sl) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_force_debug ***\n");
+ DLOG("\n*** stlink_force_debug ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG;
sl->q_len = 2;
void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) {
struct stlink_libsg *sg = sl->backend_data;
+
+ /* unused */
+ regp = regp;
+
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS;
sl->q_len = 84;
for (int i = 0; i < 16; i++) {
sg->reg.r[i] = read_uint32(sl->q_buf, 4 * i);
if (sl->verbose > 1)
- DD(sl, "r%2d = 0x%08x\n", i, sg->reg.r[i]);
+ DLOG("r%2d = 0x%08x\n", i, sg->reg.r[i]);
}
sg->reg.xpsr = read_uint32(sl->q_buf, 64);
sg->reg.main_sp = read_uint32(sl->q_buf, 68);
if (sl->verbose < 2)
return;
- DD(sl, "xpsr = 0x%08x\n", sg->reg.xpsr);
- DD(sl, "main_sp = 0x%08x\n", sg->reg.main_sp);
- DD(sl, "process_sp = 0x%08x\n", sg->reg.process_sp);
- DD(sl, "rw = 0x%08x\n", sg->reg.rw);
- DD(sl, "rw2 = 0x%08x\n", sg->reg.rw2);
+ DLOG("xpsr = 0x%08x\n", sg->reg.xpsr);
+ DLOG("main_sp = 0x%08x\n", sg->reg.main_sp);
+ DLOG("process_sp = 0x%08x\n", sg->reg.process_sp);
+ DLOG("rw = 0x%08x\n", sg->reg.rw);
+ DLOG("rw2 = 0x%08x\n", sg->reg.rw2);
}
// Read an arm-core register, the index must be in the range 0..20.
stlink_print_data(sl);
uint32_t r = read_uint32(sl->q_buf, 0);
- DD(sl, "r_idx (%2d) = 0x%08x\n", r_idx, r);
+ DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r);
switch (r_idx) {
case 16:
void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_write_dreg ***\n");
+ DLOG("\n*** stlink_write_dreg ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG;
// 2-5: address of reg of the debug module
void _stlink_sg_run(stlink_t *sl) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_run ***\n");
+ DLOG("\n*** stlink_run ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE;
sl->q_len = 2;
// see Cortex-M3 Technical Reference Manual
// TODO make delegate!
void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) {
- D(sl, "\n*** stlink_set_hw_bp ***\n");
+ DLOG("\n*** stlink_set_hw_bp ***\n");
struct stlink_libsg *sg = sl->backend_data;
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP;
// TODO make delegate!
void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) {
struct stlink_libsg *sg = sl->backend_data;
- D(sl, "\n*** stlink_clr_hw_bp ***\n");
+ DLOG("\n*** stlink_clr_hw_bp ***\n");
clear_cdb(sg);
sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP;
sg->cdb_cmd_blk[2] = fp_nr;
_stlink_sg_force_debug
};
-stlink_t* stlink_open(const char *dev_name, const int verbose) {
- fprintf(stderr, "\n*** stlink_open [%s] ***\n", dev_name);
- int sg_fd = scsi_pt_open_device(dev_name, RDWR, verbose);
- if (sg_fd < 0) {
- fprintf(stderr, "error opening device: %s: %s\n", dev_name,
- safe_strerror(-sg_fd));
+#if using_stm8_stuff_XXXX
+stlink *stlink_open(libusb_context *usb_context)
+{
+ stlink *stl = malloc(sizeof(stlink));
+ stl->handle = libusb_open_device_with_vid_pid(usb_context, USB_VID_ST, USB_PID_STLINK);
+ if (stl->handle == NULL) {
+ free(stl);
+ return NULL;
+ }
+
+ libusb_device *dev = libusb_get_device(stl->handle);
+ struct libusb_config_descriptor *conf_desc;
+ int ret = libusb_get_config_descriptor(dev, 0, &conf_desc);
+ if (ret != LIBUSB_SUCCESS) {
+ libusb_close(stl->handle);
+ free(stl);
return NULL;
}
+ for (int i = 0; i < conf_desc->bNumInterfaces; i++) {
+ printf("interface %d\n", i);
+ for (int j = 0; j < conf_desc->interface[i].num_altsetting; j++) {
+ for (int k = 0; k < conf_desc->interface[i].altsetting[j].bNumEndpoints; k++) {
+ const struct libusb_endpoint_descriptor *endpoint;
+ endpoint = &conf_desc->interface[i].altsetting[j].endpoint[k];
+ if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
+ stl->endpoint_in = endpoint->bEndpointAddress;
+ printf("Found IN endpoint\n");
+ } else {
+ stl->endpoint_out = endpoint->bEndpointAddress;
+ printf("Found OUT endpoint\n");
+ }
+ }
+ }
+ }
+ libusb_free_config_descriptor(conf_desc);
+
+ ret = libusb_kernel_driver_active(stl->handle, 0);
+ if (ret == 1) {
+ printf("kernel driver active\n");
+ } else if (ret == 0) {
+ //printf("kernel driver not active\n");
+ } else {
+ fprintf(stderr, "libusb_kernel_driver_active = %d\n", ret);
+ }
+ ret = libusb_claim_interface(stl->handle, 0);
+ if (ret != LIBUSB_SUCCESS) {
+ fprintf(stderr, "claiming interface failed: %d\n", ret);
+ libusb_close(stl->handle);
+ free(stl);
+ return NULL;
+ }
+
+ return stl;
+}
+#endif
+
+static stlink_t* stlink_open(const char *dev_name, const int verbose) {
+ fprintf(stderr, "\n*** stlink_open [%s] ***\n", dev_name);
+
stlink_t *sl = malloc(sizeof (stlink_t));
struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg));
if (sl == NULL || slsg == NULL) {
- fprintf(stderr, "Couldn't malloc stlink and stlink_sg structures out of memory!\n");
+ WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n");
+ return NULL;
+ }
+
+ if (libusb_init(&(slsg->libusb_ctx))) {
+ WLOG("failed to init libusb context, wrong version of libraries?\n");
+ free(sl);
+ free(slsg);
return NULL;
}
+
+ slsg->handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID);
+ if (slsg->handle == NULL) {
+ WLOG("Failed to find an stlink v1 by VID:PID\n");
+ free(sl);
+ free(slsg);
+ return NULL;
+ }
+
+ DLOG("Successfully opened stlinkv1 by libusb :)\n");
+
sl->verbose = verbose;
sl->backend_data = slsg;
sl->backend = &_stlink_sg_backend;
- slsg->sg_fd = sg_fd;
sl->core_stat = STLINK_CORE_STAT_UNKNOWN;
- slsg->core_id = 0;
slsg->q_addr = 0;
clear_buf(sl);
-stlink_t* stlink_quirk_open(const char *dev_name, const int verbose) {
-
+stlink_t* stlink_v1_open(const char *dev_name, const int verbose) {
+ ugly_init(verbose);
stlink_t *sl = stlink_open(dev_name, verbose);
if (sl == NULL) {
fputs("Error: could not open stlink device\n", stderr);
stlink_version(sl);
struct stlink_libsg *sg = sl->backend_data;
- if (sg->st_vid != USB_ST_VID || sg->stlink_pid != USB_STLINK_PID) {
+ if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) {
fprintf(stderr, "Error: the device %s is not a stlink\n",
dev_name);
fprintf(stderr, " VID: got %04x expect %04x \n",
- sg->st_vid, USB_ST_VID);
+ sl->version.st_vid, USB_ST_VID);
fprintf(stderr, " PID: got %04x expect %04x \n",
- sg->stlink_pid, USB_STLINK_PID);
+ sl->version.stlink_pid, USB_STLINK_PID);
return NULL;
}
- D(sl, "\n*** stlink_force_open ***\n");
+ DLOG("\n*** stlink_force_open ***\n");
switch (stlink_current_mode(sl)) {
case STLINK_DEV_MASS_MODE:
return sl;
// TODO go to mass?
return sl;
}
- DD(sl, "\n*** switch the stlink to mass mode ***\n");
+ DLOG("\n*** switch the stlink to mass mode ***\n");
_stlink_sg_exit_dfu_mode(sl);
// exit the dfu mode -> the device is gone
- DD(sl, "\n*** reopen the stlink device ***\n");
+ DLOG("\n*** reopen the stlink device ***\n");
delay(1000);
stlink_close(sl);
delay(5000);