7 #include <libusb-1.0/libusb.h>
10 /* endianess related */
11 static inline unsigned int is_bigendian(void)
13 static volatile const unsigned int i = 1;
14 return *(volatile const char*) &i == 0;
17 static void write_uint32(unsigned char* buf, uint32_t ui)
19 if (!is_bigendian()) { // le -> le (don't swap)
20 buf[0] = ((unsigned char*) &ui)[0];
21 buf[1] = ((unsigned char*) &ui)[1];
22 buf[2] = ((unsigned char*) &ui)[2];
23 buf[3] = ((unsigned char*) &ui)[3];
25 buf[0] = ((unsigned char*) &ui)[3];
26 buf[1] = ((unsigned char*) &ui)[2];
27 buf[2] = ((unsigned char*) &ui)[1];
28 buf[3] = ((unsigned char*) &ui)[0];
32 static void write_uint16(unsigned char* buf, uint16_t ui)
34 if (!is_bigendian()) { // le -> le (don't swap)
35 buf[0] = ((unsigned char*) &ui)[0];
36 buf[1] = ((unsigned char*) &ui)[1];
38 buf[0] = ((unsigned char*) &ui)[1];
39 buf[1] = ((unsigned char*) &ui)[0];
43 static uint32_t read_uint32(const unsigned char *c, const int pt)
46 char *p = (char *) &ui;
48 if (!is_bigendian()) { // le -> le (don't swap)
62 static uint16_t read_uint16(const unsigned char *c, const int pt)
65 char *p = (char *) &ui;
67 if (!is_bigendian()) { // le -> le (don't swap)
77 /* libusb transport layer */
79 libusb_context* libusb_ctx = NULL;
83 libusb_device_handle* usb_handle;
84 struct libusb_transfer* req_trans;
85 struct libusb_transfer* rep_trans;
92 #define TRANS_FLAGS_IS_DONE (1 << 0)
93 #define TRANS_FLAGS_HAS_ERROR (1 << 1)
94 volatile unsigned long flags;
97 static void on_trans_done(struct libusb_transfer* trans)
99 struct trans_ctx* const ctx = trans->user_data;
101 if (trans->status != LIBUSB_TRANSFER_COMPLETED)
102 ctx->flags |= TRANS_FLAGS_HAS_ERROR;
104 ctx->flags |= TRANS_FLAGS_IS_DONE;
108 static int submit_wait(struct libusb_transfer* trans)
110 struct timeval start;
113 struct trans_ctx trans_ctx;
114 enum libusb_error error;
118 /* brief intrusion inside the libusb interface */
119 trans->callback = on_trans_done;
120 trans->user_data = &trans_ctx;
122 if ((error = libusb_submit_transfer(trans)))
124 printf("libusb_submit_transfer(%d)\n", error);
128 gettimeofday(&start, NULL);
130 while (trans_ctx.flags == 0)
132 struct timeval timeout;
135 if (libusb_handle_events_timeout(libusb_ctx, &timeout))
137 printf("libusb_handle_events()\n");
141 gettimeofday(&now, NULL);
142 timersub(&now, &start, &diff);
143 if (diff.tv_sec >= 3)
145 printf("libusb_handle_events() timeout\n");
150 if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR)
152 printf("libusb_handle_events() | has_error\n");
159 static ssize_t send_recv
161 struct stlink_libusb* handle,
162 unsigned char* txbuf, size_t txsize,
163 unsigned char* rxbuf, size_t rxsize
166 /* note: txbuf and rxbuf can point to the same area */
168 libusb_fill_bulk_transfer
178 printf("submit_wait(req)\n");
180 if (submit_wait(handle->req_trans)) return -1;
182 /* read the response */
184 libusb_fill_bulk_transfer
194 printf("submit_wait(rep)\n");
196 if (submit_wait(handle->rep_trans)) return -1;
198 return handle->rep_trans->actual_length;
202 /* stlink layer independant interface */
206 TRANSPORT_TYPE_ZERO = 0,
208 TRANSPORT_TYPE_LIBSG,
209 #endif /* CONFIG_USE_LIBSG */
210 #if CONFIG_USE_LIBUSB
211 TRANSPORT_TYPE_LIBUSB,
212 #endif /* CONFIG_USE_LIBUSB */
213 TRANSPORT_TYPE_INVALID
218 enum transport_type tt;
221 #if CONFIG_USE_LIBUSB
222 struct stlink_libusb libusb;
223 #endif /* CONFIG_USE_LIBUSB */
226 #endif /* CONFIG_USE_LIBSG */
229 unsigned char q_buf[64];
231 /* layer independant */
235 int stlink_initialize(enum transport_type tt)
239 #if CONFIG_USE_LIBUSB
240 case TRANSPORT_TYPE_LIBUSB:
242 if (libusb_ctx != NULL) return -1;
243 if (libusb_init(&libusb_ctx))
245 printf("libusb_init()\n");
250 #endif /* CONFIG_USE_LIBUSB */
258 void stlink_finalize(enum transport_type tt)
262 #if CONFIG_USE_LIBUSB
263 case TRANSPORT_TYPE_LIBUSB:
265 libusb_exit(libusb_ctx);
268 #endif /* CONFIG_USE_LIBUSB */
274 #if CONFIG_USE_LIBUSB
275 static int is_stlink_device(libusb_device* dev)
277 struct libusb_device_descriptor desc;
279 if (libusb_get_device_descriptor(dev, &desc))
282 printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct);
284 if (desc.idVendor != 0x0483)
287 if (desc.idProduct != 0x3748)
292 #endif /* CONFIG_USE_LIBUSB */
295 void stlink_close(struct stlink*);
297 struct stlink* stlink_quirk_open
298 (enum transport_type tt, const char *dev_name, const int verbose)
300 struct stlink* sl = NULL;
302 sl = malloc(sizeof(struct stlink));
303 if (sl == NULL) goto on_error;
309 #if CONFIG_USE_LIBUSB
310 case TRANSPORT_TYPE_LIBUSB:
312 struct stlink_libusb* const slu = &sl->transport.libusb;
316 libusb_device** devs = NULL;
322 count = libusb_get_device_list(libusb_ctx, &devs);
325 printf("libusb_get_device_list\n");
326 goto on_libusb_error;
329 for (i = 0; i < count; ++i)
332 if (is_stlink_device(dev)) break;
334 if (i == count) return NULL;
336 if (libusb_open(dev, &slu->usb_handle))
338 printf("libusb_open()\n");
339 goto on_libusb_error;
342 if (libusb_get_configuration(slu->usb_handle, &config))
344 /* this may fail for a previous configured device */
345 printf("libusb_get_configuration()\n");
346 goto on_libusb_error;
351 printf("setting new configuration (%d -> 1)\n", config);
352 if (libusb_set_configuration(slu->usb_handle, 1))
354 /* this may fail for a previous configured device */
355 printf("libusb_set_configuration()\n");
356 goto on_libusb_error;
360 if (libusb_claim_interface(slu->usb_handle, 0))
362 printf("libusb_claim_interface()\n");
363 goto on_libusb_error;
366 slu->req_trans = libusb_alloc_transfer(0);
367 if (slu->req_trans == NULL)
369 printf("libusb_alloc_transfer\n");
370 goto on_libusb_error;
373 slu->rep_trans = libusb_alloc_transfer(0);
374 if (slu->rep_trans == NULL)
376 printf("libusb_alloc_transfer\n");
377 goto on_libusb_error;
380 slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
381 slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
383 /* libusb_reset_device(slu->usb_handle); */
389 if (devs != NULL) libusb_free_device_list(devs, 1);
399 #endif /* CONFIG_USE_LIBUSB */
402 case transport_type_libsg:
406 #endif /* CONFIG_USE_LIBSG */
415 if (sl != NULL) free(sl);
419 void stlink_close(struct stlink *sl)
423 #if CONFIG_USE_LIBUSB
424 case TRANSPORT_TYPE_LIBUSB:
426 struct stlink_libusb* const handle = &sl->transport.libusb;
428 if (handle->req_trans != NULL)
429 libusb_free_transfer(handle->req_trans);
431 if (handle->rep_trans != NULL)
432 libusb_free_transfer(handle->rep_trans);
434 if (handle->usb_handle != NULL)
435 libusb_close(handle->usb_handle);
439 #endif /* CONFIG_USE_LIBUSB */
442 case TRANSPORT_TYPE_LIBSG:
446 #endif /* CONFIG_USE_LIBSG */
454 void stlink_version(struct stlink* sl)
458 #if CONFIG_USE_LIBUSB
459 case TRANSPORT_TYPE_LIBUSB:
461 struct stlink_libusb* const slu = &sl->transport.libusb;
462 unsigned char* const buf = sl->q_buf;
465 memset(buf, 0, sizeof(sl->q_buf));
466 buf[0] = STLINK_GET_VERSION;
469 size = send_recv(slu, buf, 16, buf, sizeof(sl->q_buf));
472 printf("[!] send_recv\n");
479 for (i = 0; i < size; ++i) printf("%02x", buf[i]);
486 #endif /* CONFIG_USE_LIBUSB */
492 int stlink_current_mode(struct stlink *sl)
498 #if CONFIG_USE_LIBUSB
499 case TRANSPORT_TYPE_LIBUSB:
501 struct stlink_libusb* const slu = &sl->transport.libusb;
502 unsigned char* const buf = sl->q_buf;
505 memset(buf, 0, sizeof(sl->q_buf));
507 buf[0] = STLINK_GET_CURRENT_MODE;
509 size = send_recv(slu, buf, 16, buf, sizeof(sl->q_buf));
512 printf("[!] send_recv\n");
519 printf("mode == 0x%x\n", mode);
524 #endif /* CONFIG_USE_LIBUSB */
532 void stlink_core_id(struct stlink *sl)
536 #if CONFIG_USE_LIBUSB
537 case TRANSPORT_TYPE_LIBUSB:
539 struct stlink_libusb* const slu = &sl->transport.libusb;
540 unsigned char* const buf = sl->q_buf;
543 memset(buf, 0, sizeof(sl->q_buf));
545 buf[0] = STLINK_DEBUG_READCOREID;
547 size = send_recv(slu, buf, sizeof(sl->q_buf), buf, sizeof(sl->q_buf));
550 printf("[!] send_recv\n");
554 sl->core_id = read_uint32(buf, 0);
557 printf("core_id == 0x%x\n", sl->core_id);
562 #endif /* CONFIG_USE_LIBUSB */
568 void stlink_status(struct stlink *sl)
572 #if CONFIG_USE_LIBUSB
573 case TRANSPORT_TYPE_LIBUSB:
575 struct stlink_libusb* const slu = &sl->transport.libusb;
576 unsigned char* const buf = sl->q_buf;
579 memset(buf, 0, sizeof(sl->q_buf));
581 buf[0] = STLINK_DEBUG_GETSTATUS;
583 size = send_recv(slu, buf, sizeof(sl->q_buf), buf, sizeof(sl->q_buf));
586 printf("[!] send_recv\n");
590 /* todo: stlink_core_stat */
593 printf("status == 0x%x\n", buf[0]);
598 #endif /* CONFIG_USE_LIBUSB */
604 void stlink_enter_swd_mode(struct stlink *sl)
608 #if CONFIG_USE_LIBUSB
609 case TRANSPORT_TYPE_LIBUSB:
611 struct stlink_libusb* const slu = &sl->transport.libusb;
612 unsigned char* const buf = sl->q_buf;
615 memset(buf, 0, sizeof(sl->q_buf));
617 buf[0] = STLINK_DEBUG_ENTER;
618 buf[1] = STLINK_DEBUG_ENTER_SWD;
620 size = send_recv(slu, buf, sizeof(sl->q_buf), buf, sizeof(sl->q_buf));
623 printf("[!] send_recv\n");
629 #endif /* CONFIG_USE_LIBUSB */
635 void stlink_exit_dfu_mode(struct stlink *sl)
639 #if CONFIG_USE_LIBUSB
640 case TRANSPORT_TYPE_LIBUSB:
642 struct stlink_libusb* const slu = &sl->transport.libusb;
643 unsigned char* const buf = sl->q_buf;
646 memset(buf, 0, sizeof(sl->q_buf));
648 buf[0] = STLINK_DFU_COMMAND;
649 buf[1] = STLINK_DFU_EXIT;
651 size = send_recv(slu, buf, sizeof(sl->q_buf), buf, sizeof(sl->q_buf));
654 printf("[!] send_recv\n");
660 #endif /* CONFIG_USE_LIBUSB */
666 void stlink_reset(struct stlink *sl)
670 #if CONFIG_USE_LIBUSB
671 case TRANSPORT_TYPE_LIBUSB:
673 struct stlink_libusb* const slu = &sl->transport.libusb;
674 unsigned char* const buf = sl->q_buf;
677 memset(buf, 0, sizeof(sl->q_buf));
679 buf[0] = STLINK_DEBUG_RESETSYS;
681 size = send_recv(slu, buf, 2, buf, sizeof(sl->q_buf));
684 printf("[!] send_recv\n");
690 #endif /* CONFIG_USE_LIBUSB */
696 void stlink_enter_jtag_mode(struct stlink *sl)
700 void stlink_exit_debug_mode(struct stlink *sl)
707 int main(int ac, char** av)
711 stlink_initialize(TRANSPORT_TYPE_LIBUSB);
712 sl = stlink_quirk_open(TRANSPORT_TYPE_LIBUSB, NULL, 0);
715 printf("-- version\n");
718 printf("-- exit_dfu_mode\n");
719 stlink_exit_dfu_mode(sl);
721 printf("-- enter_swd_mode\n");
722 stlink_enter_swd_mode(sl);
724 printf("-- current_mode\n");
725 stlink_current_mode(sl);
727 printf("-- core_id\n");
730 printf("-- status\n");
733 printf("-- reset\n");
736 printf("-- status\n");
741 stlink_finalize(TRANSPORT_TYPE_LIBUSB);