[update] basic testing code using libusb
[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 int 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   return submit_wait(handle->rep_trans);
100 }
101
102
103 /* stlink layer independant interface */
104
105 enum transport_type
106 {
107   TRANSPORT_TYPE_ZERO = 0,
108 #if CONFIG_USE_LIBSG
109   TRANSPORT_TYPE_LIBSG,
110 #endif /* CONFIG_USE_LIBSG */
111 #if CONFIG_USE_LIBUSB
112   TRANSPORT_TYPE_LIBUSB,
113 #endif /* CONFIG_USE_LIBUSB */
114   TRANSPORT_TYPE_INVALID
115 };
116
117 struct stlink
118 {
119   enum transport_type tt;
120   union
121   {
122 #if CONFIG_USE_LIBUSB
123     struct stlink_libusb libusb;
124 #endif /* CONFIG_USE_LIBUSB */
125 #if CONFIG_USE_LIBSG
126     void* libsg;
127 #endif /* CONFIG_USE_LIBSG */
128   } transport;
129 };
130
131 int stlink_initialize(enum transport_type tt)
132 {
133   switch (tt)
134   {
135 #if CONFIG_USE_LIBUSB
136   case TRANSPORT_TYPE_LIBUSB:
137     {
138       if (libusb_ctx != NULL) return -1;
139       if (libusb_init(&libusb_ctx))
140       {
141         printf("libusb_init()\n");
142         return -1;
143       }
144       break ;
145     }
146 #endif /* CONFIG_USE_LIBUSB */
147
148   default: break ;
149   }
150
151   return 0;
152 }
153
154 void stlink_finalize(enum transport_type tt)
155 {
156   switch (tt)
157   {
158 #if CONFIG_USE_LIBUSB
159   case TRANSPORT_TYPE_LIBUSB:
160     {
161       libusb_exit(libusb_ctx);
162       break ;
163     }
164 #endif /* CONFIG_USE_LIBUSB */
165
166   default: break;
167   }
168 }
169
170 #if CONFIG_USE_LIBUSB
171 static int is_stlink_device(libusb_device* dev)
172 {
173   struct libusb_device_descriptor desc;
174
175   if (libusb_get_device_descriptor(dev, &desc))
176     return 0;
177
178   printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct);
179  
180   if (desc.idVendor != 0x0483)
181     return 0;
182
183   if (desc.idProduct != 0x3748)
184     return 0;
185
186   return 1;
187 }
188 #endif /* CONFIG_USE_LIBUSB */
189
190 /* fwd decl */
191 void stlink_close(struct stlink*);
192
193 struct stlink* stlink_quirk_open
194 (enum transport_type tt, const char *dev_name, const int verbose)
195 {
196   struct stlink* sl = NULL;
197
198   sl = malloc(sizeof(struct stlink));
199   if (sl == NULL) goto on_error;
200
201   sl->tt = tt;
202
203   switch (tt)
204   {
205 #if CONFIG_USE_LIBUSB
206   case TRANSPORT_TYPE_LIBUSB:
207     {
208       struct stlink_libusb* const slu = &sl->transport.libusb;
209
210       int error = -1;
211
212       libusb_device** devs = NULL;
213       libusb_device* dev;
214       ssize_t i;
215       ssize_t count;
216
217       count = libusb_get_device_list(libusb_ctx, &devs);
218       if (count < 0)
219       {
220         printf("libusb_get_device_list\n");
221         goto on_libusb_error;
222       }
223
224       for (i = 0; i < count; ++i)
225       {
226         dev = devs[i];
227         if (is_stlink_device(dev)) break;
228       }
229       if (i == count) return NULL;
230
231       if (libusb_open(dev, &slu->usb_handle))
232       {
233         printf("libusb_open()\n");
234         goto on_libusb_error;
235       }
236
237       if (libusb_set_configuration(slu->usb_handle, 1))
238       {
239         printf("libusb_set_configuration()\n");
240         goto on_libusb_error;
241       }
242
243       if (libusb_claim_interface(slu->usb_handle, 0))
244       {
245         printf("libusb_claim_interface()\n");
246         goto on_libusb_error;
247       }
248
249       slu->req_trans = libusb_alloc_transfer(0);
250       if (slu->req_trans == NULL)
251       {
252         printf("libusb_alloc_transfer\n");
253         goto on_libusb_error;
254       }
255
256       slu->rep_trans = libusb_alloc_transfer(0);
257       if (slu->rep_trans == NULL)
258       {
259         printf("libusb_alloc_transfer\n");
260         goto on_libusb_error;
261       }
262
263       slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT;
264       slu->ep_rep = 2 /* ep rep */ | LIBUSB_ENDPOINT_IN;
265
266       /* success */
267       error = 0;
268
269     on_libusb_error:
270       if (devs != NULL) libusb_free_device_list(devs, 1);
271
272       if (error == -1)
273       {
274         stlink_close(sl);
275         return NULL;
276       }
277
278       break ;
279     }
280 #endif /* CONFIG_USE_LIBUSB */
281
282 #if CONFIG_USE_LIBSG
283   case transport_type_libsg:
284     {
285       break ;
286     }
287 #endif /* CONFIG_USE_LIBSG */
288
289   default: break ;
290   }
291
292   /* success */
293   return sl;
294
295  on_error:
296   if (sl != NULL) free(sl);
297   return 0;
298 }
299
300 void stlink_close(struct stlink *sl)
301 {
302   switch (sl->tt)
303   {
304 #if CONFIG_USE_LIBUSB
305   case TRANSPORT_TYPE_LIBUSB:
306     {
307       struct stlink_libusb* const handle = &sl->transport.libusb;
308
309       if (handle->req_trans != NULL)
310         libusb_free_transfer(handle->req_trans);
311
312       if (handle->rep_trans != NULL)
313         libusb_free_transfer(handle->rep_trans);
314
315       if (handle->usb_handle != NULL)
316         libusb_close(handle->usb_handle);
317
318       break ;
319     }
320 #endif /* CONFIG_USE_LIBUSB */
321
322 #if CONFIG_USE_LIBSG
323   case TRANSPORT_TYPE_LIBSG:
324     {
325       break ;
326     }
327 #endif /* CONFIG_USE_LIBSG */
328
329   default: break ;
330   }
331
332   free(sl);
333 }
334
335 void stlink_version(struct stlink* sl)
336 {
337   switch (sl->tt)
338   {
339 #if CONFIG_USE_LIBUSB
340   case TRANSPORT_TYPE_LIBUSB:
341     {
342       struct stlink_libusb* const slu = &sl->transport.libusb;
343
344       unsigned int i;
345       unsigned char buf[6];
346
347       for (i = 0; i < sizeof(buf); ++i) buf[i] = 0;
348
349       buf[0] = 0xf1;
350       if (send_recv(slu, buf, sizeof(buf), buf, sizeof(buf)) == -1)
351       {
352         printf("[!] send_recv\n");
353         return ;
354       }
355
356       for (i = 0; i < 6; ++i) printf("%02x", buf[i]);
357       printf("\n");
358
359       break ;
360     }
361 #endif /* CONFIG_USE_LIBUSB */
362
363   default: break ;
364   }
365 }
366
367 int stlink_current_mode(struct stlink *sl)
368 {
369   return -1;
370 }
371
372 void stlink_enter_swd_mode(struct stlink *sl)
373 {
374 }
375
376 void stlink_enter_jtag_mode(struct stlink *sl)
377 {
378 }
379
380 void stlink_exit_debug_mode(struct stlink *sl)
381 {
382 }
383
384 void stlink_core_id(struct stlink *sl)
385 {
386 }
387
388 void stlink_status(struct stlink *sl)
389 {
390 }
391
392
393 /* main */
394
395 int main(int ac, char** av)
396 {
397   struct stlink* sl;
398
399   stlink_initialize(TRANSPORT_TYPE_LIBUSB);
400   sl = stlink_quirk_open(TRANSPORT_TYPE_LIBUSB, NULL, 0);
401   if (sl != NULL)
402   {
403     stlink_version(sl);
404     stlink_status(sl);
405     stlink_current_mode(sl);
406     stlink_close(sl);
407   }
408   stlink_finalize(TRANSPORT_TYPE_LIBUSB);
409
410   return 0;
411 }