[fix] bad endpoints used
[fw/stlink] / stm32l / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <libusb-1.0/libusb.h>
5
6 /* libusb transport layer */
7
8 libusb_context* libusb_ctx =  NULL;
9
10 struct stlink_libusb
11 {
12   libusb_device_handle* usb_handle;
13   struct libusb_transfer* req_trans;
14   struct libusb_transfer* rep_trans;
15   unsigned int ep_req;
16   unsigned int ep_rep;
17 };
18
19 struct trans_ctx
20 {
21 #define TRANS_FLAGS_IS_DONE (1 << 0)
22 #define TRANS_FLAGS_HAS_ERROR (1 << 1)
23   volatile unsigned long flags;
24 };
25
26 static void on_trans_done(struct libusb_transfer* trans)
27 {
28   struct trans_ctx* const ctx = trans->user_data;
29
30   if (trans->status != LIBUSB_TRANSFER_COMPLETED)
31     ctx->flags |= TRANS_FLAGS_HAS_ERROR;
32
33   ctx->flags = TRANS_FLAGS_IS_DONE;
34 }
35
36
37 static int submit_wait(struct libusb_transfer* trans)
38 {
39   struct trans_ctx trans_ctx;
40   enum libusb_error error;
41
42   trans_ctx.flags = 0;
43
44   /* brief intrusion inside the libusb interface */
45   trans->callback = on_trans_done;
46   trans->user_data = &trans_ctx;
47
48   if ((error = libusb_submit_transfer(trans)))
49   {
50     printf("libusb_submit_transfer(%d)\n", error);
51     return -1;
52   }
53
54   while (!(trans_ctx.flags & TRANS_FLAGS_IS_DONE))
55   {
56     if (libusb_handle_events(NULL))
57     {
58       printf("libusb_handle_events()\n");
59       return -1;
60     }
61   }
62
63   return 0;
64 }
65
66 static ssize_t send_recv
67 (
68  struct stlink_libusb* handle,
69  unsigned char* txbuf, size_t txsize,
70  unsigned char* rxbuf, size_t rxsize
71 )
72 {
73  /* note: txbuf and rxbuf can point to the same area */
74
75   libusb_fill_bulk_transfer
76   (
77    handle->req_trans,
78    handle->usb_handle,
79    handle->ep_req,
80    txbuf, txsize,
81    NULL, NULL,
82    0
83   );
84
85   if (submit_wait(handle->req_trans)) return -1;
86
87   /* read the response */
88
89   libusb_fill_bulk_transfer
90   (
91    handle->rep_trans,
92    handle->usb_handle,
93    handle->ep_rep,
94    rxbuf, rxsize,
95    NULL, NULL,
96    0
97   );
98
99   if (submit_wait(handle->rep_trans)) return -1;
100   return handle->rep_trans->actual_length;
101 }
102
103
104 /* stlink layer independant interface */
105
106 enum transport_type
107 {
108   TRANSPORT_TYPE_ZERO = 0,
109 #if CONFIG_USE_LIBSG
110   TRANSPORT_TYPE_LIBSG,
111 #endif /* CONFIG_USE_LIBSG */
112 #if CONFIG_USE_LIBUSB
113   TRANSPORT_TYPE_LIBUSB,
114 #endif /* CONFIG_USE_LIBUSB */
115   TRANSPORT_TYPE_INVALID
116 };
117
118 struct stlink
119 {
120   enum transport_type tt;
121   union
122   {
123 #if CONFIG_USE_LIBUSB
124     struct stlink_libusb libusb;
125 #endif /* CONFIG_USE_LIBUSB */
126 #if CONFIG_USE_LIBSG
127     void* libsg;
128 #endif /* CONFIG_USE_LIBSG */
129   } transport;
130 };
131
132 int stlink_initialize(enum transport_type tt)
133 {
134   switch (tt)
135   {
136 #if CONFIG_USE_LIBUSB
137   case TRANSPORT_TYPE_LIBUSB:
138     {
139       if (libusb_ctx != NULL) return -1;
140       if (libusb_init(&libusb_ctx))
141       {
142         printf("libusb_init()\n");
143         return -1;
144       }
145       break ;
146     }
147 #endif /* CONFIG_USE_LIBUSB */
148
149   default: break ;
150   }
151
152   return 0;
153 }
154
155 void stlink_finalize(enum transport_type tt)
156 {
157   switch (tt)
158   {
159 #if CONFIG_USE_LIBUSB
160   case TRANSPORT_TYPE_LIBUSB:
161     {
162       libusb_exit(libusb_ctx);
163       break ;
164     }
165 #endif /* CONFIG_USE_LIBUSB */
166
167   default: break;
168   }
169 }
170
171 #if CONFIG_USE_LIBUSB
172 static int is_stlink_device(libusb_device* dev)
173 {
174   struct libusb_device_descriptor desc;
175
176   if (libusb_get_device_descriptor(dev, &desc))
177     return 0;
178
179   printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct);
180  
181   if (desc.idVendor != 0x0483)
182     return 0;
183
184   if (desc.idProduct != 0x3748)
185     return 0;
186
187   return 1;
188 }
189 #endif /* CONFIG_USE_LIBUSB */
190
191 /* fwd decl */
192 void stlink_close(struct stlink*);
193
194 struct stlink* stlink_quirk_open
195 (enum transport_type tt, const char *dev_name, const int verbose)
196 {
197   struct stlink* sl = NULL;
198
199   sl = malloc(sizeof(struct stlink));
200   if (sl == NULL) goto on_error;
201
202   sl->tt = tt;
203
204   switch (tt)
205   {
206 #if CONFIG_USE_LIBUSB
207   case TRANSPORT_TYPE_LIBUSB:
208     {
209       struct stlink_libusb* const slu = &sl->transport.libusb;
210
211       int error = -1;
212
213       libusb_device** devs = NULL;
214       libusb_device* dev;
215       ssize_t i;
216       ssize_t count;
217
218       count = libusb_get_device_list(libusb_ctx, &devs);
219       if (count < 0)
220       {
221         printf("libusb_get_device_list\n");
222         goto on_libusb_error;
223       }
224
225       for (i = 0; i < count; ++i)
226       {
227         dev = devs[i];
228         if (is_stlink_device(dev)) break;
229       }
230       if (i == count) return NULL;
231
232       if (libusb_open(dev, &slu->usb_handle))
233       {
234         printf("libusb_open()\n");
235         goto on_libusb_error;
236       }
237
238       if (libusb_set_configuration(slu->usb_handle, 1))
239       {
240         printf("libusb_set_configuration()\n");
241         goto on_libusb_error;
242       }
243
244       if (libusb_claim_interface(slu->usb_handle, 0))
245       {
246         printf("libusb_claim_interface()\n");
247         goto on_libusb_error;
248       }
249
250       slu->req_trans = libusb_alloc_transfer(0);
251       if (slu->req_trans == NULL)
252       {
253         printf("libusb_alloc_transfer\n");
254         goto on_libusb_error;
255       }
256
257       slu->rep_trans = libusb_alloc_transfer(0);
258       if (slu->rep_trans == NULL)
259       {
260         printf("libusb_alloc_transfer\n");
261         goto on_libusb_error;
262       }
263
264       slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
265       slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
266
267       /* success */
268       error = 0;
269
270     on_libusb_error:
271       if (devs != NULL) libusb_free_device_list(devs, 1);
272
273       if (error == -1)
274       {
275         stlink_close(sl);
276         return NULL;
277       }
278
279       break ;
280     }
281 #endif /* CONFIG_USE_LIBUSB */
282
283 #if CONFIG_USE_LIBSG
284   case transport_type_libsg:
285     {
286       break ;
287     }
288 #endif /* CONFIG_USE_LIBSG */
289
290   default: break ;
291   }
292
293   /* success */
294   return sl;
295
296  on_error:
297   if (sl != NULL) free(sl);
298   return 0;
299 }
300
301 void stlink_close(struct stlink *sl)
302 {
303   switch (sl->tt)
304   {
305 #if CONFIG_USE_LIBUSB
306   case TRANSPORT_TYPE_LIBUSB:
307     {
308       struct stlink_libusb* const handle = &sl->transport.libusb;
309
310       if (handle->req_trans != NULL)
311         libusb_free_transfer(handle->req_trans);
312
313       if (handle->rep_trans != NULL)
314         libusb_free_transfer(handle->rep_trans);
315
316       if (handle->usb_handle != NULL)
317         libusb_close(handle->usb_handle);
318
319       break ;
320     }
321 #endif /* CONFIG_USE_LIBUSB */
322
323 #if CONFIG_USE_LIBSG
324   case TRANSPORT_TYPE_LIBSG:
325     {
326       break ;
327     }
328 #endif /* CONFIG_USE_LIBSG */
329
330   default: break ;
331   }
332
333   free(sl);
334 }
335
336 void stlink_version(struct stlink* sl)
337 {
338   switch (sl->tt)
339   {
340 #if CONFIG_USE_LIBUSB
341   case TRANSPORT_TYPE_LIBUSB:
342     {
343       struct stlink_libusb* const slu = &sl->transport.libusb;
344
345       ssize_t size;
346       unsigned int i;
347       unsigned char buf[64];
348
349       for (i = 0; i < sizeof(buf); ++i) buf[i] = 0;
350
351       buf[0] = 0xf1;
352       buf[1] = 0x80;
353
354       size = send_recv(slu, buf, sizeof(buf), buf, sizeof(buf));
355       if (size == -1)
356       {
357         printf("[!] send_recv\n");
358         return ;
359       }
360
361       for (i = 0; i < size; ++i) printf("%02x", buf[i]);
362       printf("\n");
363
364       break ;
365     }
366 #endif /* CONFIG_USE_LIBUSB */
367
368   default: break ;
369   }
370 }
371
372 int stlink_current_mode(struct stlink *sl)
373 {
374   return -1;
375 }
376
377 void stlink_enter_swd_mode(struct stlink *sl)
378 {
379 }
380
381 void stlink_enter_jtag_mode(struct stlink *sl)
382 {
383 }
384
385 void stlink_exit_debug_mode(struct stlink *sl)
386 {
387 }
388
389 void stlink_core_id(struct stlink *sl)
390 {
391 }
392
393 void stlink_status(struct stlink *sl)
394 {
395 }
396
397
398 /* main */
399
400 int main(int ac, char** av)
401 {
402   struct stlink* sl;
403
404   stlink_initialize(TRANSPORT_TYPE_LIBUSB);
405   sl = stlink_quirk_open(TRANSPORT_TYPE_LIBUSB, NULL, 0);
406   if (sl != NULL)
407   {
408     stlink_version(sl);
409     stlink_status(sl);
410     stlink_current_mode(sl);
411     stlink_close(sl);
412   }
413   stlink_finalize(TRANSPORT_TYPE_LIBUSB);
414
415   return 0;
416 }