Determine the device parameters explicit after running
[fw/stlink] / src / stlink-sg.c
index 062e83dbdbeb4bc2993fece091cf4f29fbd442d3..991bc878b5bb77ccb82ec8fd28bcb6ee73ed4fb6 100644 (file)
@@ -143,7 +143,7 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end
 
     uint32_t rsig = read_uint32(csw, 0);
     uint32_t rtag = read_uint32(csw, 4);
-    uint32_t residue = read_uint32(csw, 8);
+    /* uint32_t residue = read_uint32(csw, 8); */
 #define USB_CSW_SIGNATURE 0x53425355  // 'U' 'S' 'B' 'S' (reversed)
     if (rsig != USB_CSW_SIGNATURE) {
         WLOG("status signature was invalid: %#x\n", rsig);
@@ -299,7 +299,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out,
     unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) {
     int ret;
     int real_transferred;
-    int try;
+    int try = 0;
     do {
         ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length,
                                    &real_transferred, SG_TIMEOUT_MSEC);
@@ -537,6 +537,19 @@ void _stlink_sg_reset(stlink_t *sl) {
     stlink_stat(sl, "core reset");
 }
 
+// Arm-core reset -> halted state.
+
+void _stlink_sg_jtag_reset(stlink_t *sl, int value) {
+    struct stlink_libsg *sg = sl->backend_data;
+    clear_cdb(sg);
+    sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST;
+    sg->cdb_cmd_blk[2] = (value)?0:1;
+    sl->q_len = 3;
+    sg->q_addr = 2;
+    stlink_q(sl);
+    stlink_stat(sl, "core reset");
+}
+
 // Arm-core status: halted or running.
 
 void _stlink_sg_status(stlink_t *sl) {
@@ -792,6 +805,34 @@ void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
     stlink_print_data(sl);
 }
 
+// Write one DWORD data to memory
+
+void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) {
+    struct stlink_libsg *sg = sl->backend_data;
+    clear_cdb(sg);
+    sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT;
+    // 2-5: addr
+    write_uint32(sg->cdb_cmd_blk + 2, addr);
+    write_uint32(sg->cdb_cmd_blk + 6, data);
+    sl->q_len = 2;
+    stlink_q(sl);
+
+}
+
+// Read one DWORD data from memory
+
+uint32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr) {
+    struct stlink_libsg *sg = sl->backend_data;
+    clear_cdb(sg);
+    sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT;
+    // 2-5: addr
+    write_uint32(sg->cdb_cmd_blk + 2, addr);
+    sl->q_len = 8;
+    stlink_q(sl);
+
+    return read_uint32(sl->q_buf, 4);
+}
+
 // Exit the jtag or swd mode and enter the mass mode.
 
 void _stlink_sg_exit_debug_mode(stlink_t *stl) {
@@ -820,10 +861,13 @@ stlink_backend_t _stlink_sg_backend = {
     _stlink_sg_exit_dfu_mode,
     _stlink_sg_core_id,
     _stlink_sg_reset,
+    _stlink_sg_jtag_reset,
     _stlink_sg_run,
     _stlink_sg_status,
     _stlink_sg_version,
+    _stlink_sg_read_debug32,
     _stlink_sg_read_mem32,
+    _stlink_sg_write_debug32,
     _stlink_sg_write_mem32,
     _stlink_sg_write_mem8,
     _stlink_sg_read_all_regs,
@@ -857,6 +901,7 @@ static stlink_t* stlink_open(const int verbose) {
     if (slsg->usb_handle == NULL) {
         WLOG("Failed to find an stlink v1 by VID:PID\n");
         libusb_close(slsg->usb_handle);
+        libusb_exit(slsg->libusb_ctx);
         free(sl);
         free(slsg);
         return NULL;
@@ -871,6 +916,7 @@ static stlink_t* stlink_open(const int verbose) {
         if (r < 0) {
             WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
             libusb_close(slsg->usb_handle);
+            libusb_exit(slsg->libusb_ctx);
             free(sl);
             free(slsg);
             return NULL;
@@ -883,6 +929,7 @@ static stlink_t* stlink_open(const int verbose) {
         /* this may fail for a previous configured device */
         WLOG("libusb_get_configuration()\n");
         libusb_close(slsg->usb_handle);
+        libusb_exit(slsg->libusb_ctx);
         free(sl);
         free(slsg);
         return NULL;
@@ -897,6 +944,7 @@ static stlink_t* stlink_open(const int verbose) {
             /* this may fail for a previous configured device */
             WLOG("libusb_set_configuration() failed\n");
             libusb_close(slsg->usb_handle);
+            libusb_exit(slsg->libusb_ctx);
             free(sl);
             free(slsg);
             return NULL;
@@ -906,6 +954,7 @@ static stlink_t* stlink_open(const int verbose) {
     if (libusb_claim_interface(slsg->usb_handle, 0)) {
         WLOG("libusb_claim_interface() failed\n");
         libusb_close(slsg->usb_handle);
+        libusb_exit(slsg->libusb_ctx);
         free(sl);
         free(slsg);
         return NULL;
@@ -976,7 +1025,6 @@ stlink_t* stlink_v1_open(const int verbose) {
     }
     // by now, it _must_ be fully open and in a useful mode....
        stlink_enter_swd_mode(sl);
-    stlink_load_device_params(sl);
     ILOG("Successfully opened a stlink v1 debugger\n");
     return sl;
 }