stlink: add read/write 8bit memory
[fw/openocd] / src / jtag / drivers / stlink_usb.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by Mathias Kuester                                 *
3  *   Mathias Kuester <kesmtp@freenet.de>                                   *
4  *                                                                         *
5  *   This code is based on https://github.com/texane/stlink                *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  *   This program is distributed in the hope that it will be useful,       *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15  *   GNU General Public License for more details.                          *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License     *
18  *   along with this program; if not, write to the                         *
19  *   Free Software Foundation, Inc.,                                       *
20  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
21  ***************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 /* project specific includes */
28 #include <helper/binarybuffer.h>
29 #include <jtag/interface.h>
30 #include <jtag/stlink/stlink_layout.h>
31 #include <jtag/stlink/stlink_interface.h>
32 #include <target/target.h>
33
34 #include "libusb_common.h"
35
36 #define ENDPOINT_IN     0x80
37 #define ENDPOINT_OUT    0x00
38
39 #define STLINK_RX_EP    (1|ENDPOINT_IN)
40 #define STLINK_TX_EP    (2|ENDPOINT_OUT)
41 #define STLINK_CMD_SIZE (16)
42 #define STLINK_TX_SIZE  (4*128)
43 #define STLINK_RX_SIZE  (4*128)
44
45 /** */
46 struct stlink_usb_handle_s {
47         /** */
48         struct jtag_libusb_device_handle *fd;
49         /** */
50         struct libusb_transfer *trans;
51         /** */
52         uint8_t txbuf[STLINK_TX_SIZE];
53         /** */
54         uint8_t rxbuf[STLINK_RX_SIZE];
55 };
56
57 #define STLINK_OK                       0x80
58 #define STLINK_FALSE                    0x81
59 #define STLINK_CORE_RUNNING             0x80
60 #define STLINK_CORE_HALTED              0x81
61 #define STLINK_CORE_STAT_UNKNOWN        -1
62
63 #define STLINK_GET_VERSION              0xf1
64 #define STLINK_GET_CURRENT_MODE         0xf5
65
66 #define STLINK_DEBUG_COMMAND            0xF2
67 #define STLINK_DFU_COMMAND              0xF3
68 #define STLINK_DFU_EXIT                 0x07
69
70 #define STLINK_DEV_DFU_MODE             0x00
71 #define STLINK_DEV_MASS_MODE            0x01
72 #define STLINK_DEV_DEBUG_MODE           0x02
73 #define STLINK_DEV_UNKNOWN_MODE         -1
74
75 #define STLINK_DEBUG_ENTER              0x20
76 #define STLINK_DEBUG_EXIT               0x21
77 #define STLINK_DEBUG_READCOREID         0x22
78
79 #define STLINK_DEBUG_GETSTATUS          0x01
80 #define STLINK_DEBUG_FORCEDEBUG         0x02
81 #define STLINK_DEBUG_RESETSYS           0x03
82 #define STLINK_DEBUG_READALLREGS        0x04
83 #define STLINK_DEBUG_READREG            0x05
84 #define STLINK_DEBUG_WRITEREG           0x06
85 #define STLINK_DEBUG_READMEM_32BIT      0x07
86 #define STLINK_DEBUG_WRITEMEM_32BIT     0x08
87 #define STLINK_DEBUG_RUNCORE            0x09
88 #define STLINK_DEBUG_STEPCORE           0x0a
89 #define STLINK_DEBUG_SETFP              0x0b
90 #define STLINK_DEBUG_READMEM_8BIT       0x0c
91 #define STLINK_DEBUG_WRITEMEM_8BIT      0x0d
92 #define STLINK_DEBUG_CLEARFP            0x0e
93 #define STLINK_DEBUG_WRITEDEBUGREG      0x0f
94 #define STLINK_DEBUG_ENTER_SWD          0xa3
95 #define STLINK_DEBUG_ENTER_JTAG         0x00
96
97 #define STLINK_SWD_ENTER                0x30
98 #define STLINK_SWD_READCOREID           0x32
99
100 /** */
101 int stlink_usb_recv(void *handle, const uint8_t *txbuf, int txsize, uint8_t *rxbuf,
102                     int rxsize)
103 {
104         struct stlink_usb_handle_s *h;
105
106         assert(handle != NULL);
107
108         h = (struct stlink_usb_handle_s *)handle;
109
110         if (jtag_libusb_bulk_write(h->fd, STLINK_TX_EP, (char *)txbuf, txsize,
111                                    1000) != txsize) {
112                 return ERROR_FAIL;
113         }
114         if (rxsize && rxbuf) {
115                 if (jtag_libusb_bulk_read(h->fd, STLINK_RX_EP, (char *)rxbuf,
116                                           rxsize, 1000) != rxsize) {
117                         return ERROR_FAIL;
118                 }
119         }
120         return ERROR_OK;
121 }
122
123 /** */
124 void stlink_usb_init_buffer(void *handle)
125 {
126         struct stlink_usb_handle_s *h;
127
128         assert(handle != NULL);
129
130         h = (struct stlink_usb_handle_s *)handle;
131
132         memset(h->txbuf, 0, STLINK_CMD_SIZE);
133 }
134
135 /** */
136 int stlink_usb_version(void *handle)
137 {
138         int res;
139         uint16_t v;
140         struct stlink_usb_handle_s *h;
141
142         assert(handle != NULL);
143
144         h = (struct stlink_usb_handle_s *)handle;
145
146         stlink_usb_init_buffer(handle);
147
148         h->txbuf[0] = STLINK_GET_VERSION;
149
150         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 6);
151
152         if (res != ERROR_OK)
153                 return res;
154
155         v = (h->rxbuf[0] << 8) | h->rxbuf[1];
156
157         LOG_DEBUG("STLINK v%d", (v >> 12) & 0x0f);
158         LOG_DEBUG("JTAG   v%d", (v >> 6) & 0x3f);
159         LOG_DEBUG("SWIM   v%d", v & 0x3f);
160         LOG_DEBUG("VID    %04X", buf_get_u32(h->rxbuf, 16, 16));
161         LOG_DEBUG("PID    %04X", buf_get_u32(h->rxbuf, 32, 16));
162
163         return ERROR_OK;
164 }
165
166 /** */
167 int stlink_usb_current_mode(void *handle, uint8_t *mode)
168 {
169         int res;
170         struct stlink_usb_handle_s *h;
171
172         assert(handle != NULL);
173
174         h = (struct stlink_usb_handle_s *)handle;
175
176         stlink_usb_init_buffer(handle);
177
178         h->txbuf[0] = STLINK_GET_CURRENT_MODE;
179
180         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
181
182         if (res != ERROR_OK)
183                 return res;
184
185         *mode = h->rxbuf[0];
186
187         return ERROR_OK;
188 }
189
190 /** */
191 int stlink_usb_dfu_mode_leave(void *handle)
192 {
193         int res;
194         struct stlink_usb_handle_s *h;
195
196         assert(handle != NULL);
197
198         h = (struct stlink_usb_handle_s *)handle;
199
200         stlink_usb_init_buffer(handle);
201
202         h->txbuf[0] = STLINK_DFU_COMMAND;
203         h->txbuf[1] = STLINK_DFU_EXIT;
204
205         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
206
207         if (res != ERROR_OK)
208                 return res;
209
210         return ERROR_OK;
211 }
212
213 /** */
214 int stlink_usb_swd_mode_enter(void *handle)
215 {
216         int res;
217         struct stlink_usb_handle_s *h;
218
219         assert(handle != NULL);
220
221         h = (struct stlink_usb_handle_s *)handle;
222
223         stlink_usb_init_buffer(handle);
224
225         h->txbuf[0] = STLINK_DEBUG_COMMAND;
226         h->txbuf[1] = STLINK_DEBUG_ENTER;
227         h->txbuf[2] = STLINK_DEBUG_ENTER_SWD;
228
229         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
230         if (res != ERROR_OK)
231                 return res;
232
233         return ERROR_OK;
234 }
235
236 /** */
237 int stlink_usb_debug_mode_leave(void *handle)
238 {
239         int res;
240         struct stlink_usb_handle_s *h;
241
242         assert(handle != NULL);
243
244         h = (struct stlink_usb_handle_s *)handle;
245
246         stlink_usb_init_buffer(handle);
247
248         h->txbuf[0] = STLINK_DEBUG_COMMAND;
249         h->txbuf[1] = STLINK_DEBUG_EXIT;
250
251         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
252         if (res != ERROR_OK)
253                 return res;
254
255         return ERROR_OK;
256 }
257
258 /** */
259 int stlink_usb_init_mode(void *handle)
260 {
261         int res;
262         uint8_t mode;
263
264         assert(handle != NULL);
265
266         res = stlink_usb_current_mode(handle, &mode);
267
268         if (res != ERROR_OK)
269                 return res;
270
271         LOG_DEBUG("MODE: %02X", mode);
272
273         if (mode == STLINK_DEV_DFU_MODE) {
274                 res = stlink_usb_dfu_mode_leave(handle);
275
276                 if (res != ERROR_OK)
277                         return res;
278         }
279
280         res = stlink_usb_current_mode(handle, &mode);
281
282         if (res != ERROR_OK)
283                 return res;
284
285         LOG_DEBUG("MODE: %02X", mode);
286
287         if (mode != STLINK_DEV_DEBUG_MODE) {
288                 res = stlink_usb_swd_mode_enter(handle);
289
290                 if (res != ERROR_OK)
291                         return res;
292         }
293
294         res = stlink_usb_current_mode(handle, &mode);
295
296         if (res != ERROR_OK)
297                 return res;
298
299         LOG_DEBUG("MODE: %02X", mode);
300
301         return ERROR_OK;
302 }
303
304 /** */
305 int stlink_usb_idcode(void *handle, uint32_t *idcode)
306 {
307         int res;
308         struct stlink_usb_handle_s *h;
309
310         assert(handle != NULL);
311
312         h = (struct stlink_usb_handle_s *)handle;
313
314         stlink_usb_init_buffer(handle);
315
316         h->txbuf[0] = STLINK_DEBUG_COMMAND;
317         h->txbuf[1] = STLINK_DEBUG_READCOREID;
318
319         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 4);
320
321         if (res != ERROR_OK)
322                 return res;
323
324         *idcode = le_to_h_u32(h->rxbuf);
325
326         LOG_DEBUG("IDCODE: %08X", *idcode);
327
328         return ERROR_OK;
329 }
330
331 /** */
332 enum target_state stlink_usb_state(void *handle)
333 {
334         int res;
335         struct stlink_usb_handle_s *h;
336
337         assert(handle != NULL);
338
339         h = (struct stlink_usb_handle_s *)handle;
340
341         stlink_usb_init_buffer(handle);
342
343         h->txbuf[0] = STLINK_DEBUG_COMMAND;
344         h->txbuf[1] = STLINK_DEBUG_GETSTATUS;
345
346         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
347
348         if (res != ERROR_OK)
349                 return TARGET_UNKNOWN;
350
351         if (h->rxbuf[0] == STLINK_CORE_RUNNING)
352                 return TARGET_RUNNING;
353         if (h->rxbuf[0] == STLINK_CORE_HALTED)
354                 return TARGET_HALTED;
355
356         return TARGET_UNKNOWN;
357 }
358
359 /** */
360 int stlink_usb_reset(void *handle)
361 {
362         int res;
363         struct stlink_usb_handle_s *h;
364
365         assert(handle != NULL);
366
367         h = (struct stlink_usb_handle_s *)handle;
368
369         stlink_usb_init_buffer(handle);
370
371         h->txbuf[0] = STLINK_DEBUG_COMMAND;
372         h->txbuf[1] = STLINK_DEBUG_RESETSYS;
373
374         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
375
376         if (res != ERROR_OK)
377                 return res;
378
379         LOG_DEBUG("RESET: %08X", h->rxbuf[0]);
380
381         return ERROR_OK;
382 }
383
384 /** */
385 int stlink_usb_run(void *handle)
386 {
387         int res;
388         struct stlink_usb_handle_s *h;
389
390         assert(handle != NULL);
391
392         h = (struct stlink_usb_handle_s *)handle;
393
394         stlink_usb_init_buffer(handle);
395
396         h->txbuf[0] = STLINK_DEBUG_COMMAND;
397         h->txbuf[1] = STLINK_DEBUG_RUNCORE;
398
399         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
400
401         if (res != ERROR_OK)
402                 return res;
403
404         return ERROR_OK;
405 }
406
407 /** */
408 int stlink_usb_halt(void *handle)
409 {
410         int res;
411         struct stlink_usb_handle_s *h;
412
413         assert(handle != NULL);
414
415         h = (struct stlink_usb_handle_s *)handle;
416
417         stlink_usb_init_buffer(handle);
418
419         h->txbuf[0] = STLINK_DEBUG_COMMAND;
420         h->txbuf[1] = STLINK_DEBUG_FORCEDEBUG;
421
422         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
423
424         if (res != ERROR_OK)
425                 return res;
426
427         return ERROR_OK;
428 }
429
430 /** */
431 int stlink_usb_step(void *handle)
432 {
433         int res;
434         struct stlink_usb_handle_s *h;
435
436         assert(handle != NULL);
437
438         h = (struct stlink_usb_handle_s *)handle;
439
440         stlink_usb_init_buffer(handle);
441
442         h->txbuf[0] = STLINK_DEBUG_COMMAND;
443         h->txbuf[1] = STLINK_DEBUG_STEPCORE;
444
445         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
446
447         if (res != ERROR_OK)
448                 return res;
449
450         return ERROR_OK;
451 }
452
453 /** */
454 int stlink_usb_read_regs(void *handle)
455 {
456         int res;
457         struct stlink_usb_handle_s *h;
458
459         assert(handle != NULL);
460
461         h = (struct stlink_usb_handle_s *)handle;
462
463         stlink_usb_init_buffer(handle);
464
465         h->txbuf[0] = STLINK_DEBUG_COMMAND;
466         h->txbuf[1] = STLINK_DEBUG_READALLREGS;
467
468         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 84);
469
470         if (res != ERROR_OK)
471                 return res;
472
473         return ERROR_OK;
474 }
475
476 /** */
477 int stlink_usb_read_reg(void *handle, int num, uint32_t *val)
478 {
479         int res;
480         struct stlink_usb_handle_s *h;
481
482         assert(handle != NULL);
483
484         h = (struct stlink_usb_handle_s *)handle;
485
486         stlink_usb_init_buffer(handle);
487
488         h->txbuf[0] = STLINK_DEBUG_COMMAND;
489         h->txbuf[1] = STLINK_DEBUG_READREG;
490         h->txbuf[2] = num;
491
492         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 4);
493
494         if (res != ERROR_OK)
495                 return res;
496
497         *val = le_to_h_u32(h->rxbuf);
498
499         return ERROR_OK;
500 }
501
502 /** */
503 int stlink_usb_write_reg(void *handle, int num, uint32_t val)
504 {
505         int res;
506         struct stlink_usb_handle_s *h;
507
508         assert(handle != NULL);
509
510         h = (struct stlink_usb_handle_s *)handle;
511
512         stlink_usb_init_buffer(handle);
513
514         h->txbuf[0] = STLINK_DEBUG_COMMAND;
515         h->txbuf[1] = STLINK_DEBUG_WRITEREG;
516         h->txbuf[2] = num;
517         h_u32_to_le(h->txbuf + 3, val);
518
519         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
520
521         if (res != ERROR_OK)
522                 return res;
523
524         return ERROR_OK;
525 }
526
527 /** */
528 int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len,
529                           uint8_t *buffer)
530 {
531         int res;
532         uint16_t read_len = len;
533         struct stlink_usb_handle_s *h;
534
535         assert(handle != NULL);
536
537         h = (struct stlink_usb_handle_s *)handle;
538
539         stlink_usb_init_buffer(handle);
540
541         h->txbuf[0] = STLINK_DEBUG_COMMAND;
542         h->txbuf[1] = STLINK_DEBUG_READMEM_8BIT;
543         h_u32_to_le(h->txbuf + 2, addr);
544         h_u16_to_le(h->txbuf + 2 + 4, len);
545
546         /* we need to fix read length for single bytes */
547         if (read_len == 1)
548                 read_len++;
549
550         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, read_len);
551
552         if (res != ERROR_OK)
553                 return res;
554
555         memcpy(buffer, h->rxbuf, len);
556
557         return ERROR_OK;
558 }
559
560 /** */
561 int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len,
562                            const uint8_t *buffer)
563 {
564         int res;
565         struct stlink_usb_handle_s *h;
566
567         assert(handle != NULL);
568
569         h = (struct stlink_usb_handle_s *)handle;
570
571         stlink_usb_init_buffer(handle);
572
573         h->txbuf[0] = STLINK_DEBUG_COMMAND;
574         h->txbuf[1] = STLINK_DEBUG_WRITEMEM_8BIT;
575         h_u32_to_le(h->txbuf + 2, addr);
576         h_u16_to_le(h->txbuf + 2 + 4, len);
577
578         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
579
580         if (res != ERROR_OK)
581                 return res;
582
583         res = stlink_usb_recv(handle, (uint8_t *) buffer, len, 0, 0);
584
585         if (res != ERROR_OK)
586                 return res;
587
588         return ERROR_OK;
589 }
590
591 /** */
592 int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,
593                           uint32_t *buffer)
594 {
595         int res;
596         struct stlink_usb_handle_s *h;
597
598         assert(handle != NULL);
599
600         h = (struct stlink_usb_handle_s *)handle;
601
602         stlink_usb_init_buffer(handle);
603
604         len *= 4;
605
606         h->txbuf[0] = STLINK_DEBUG_COMMAND;
607         h->txbuf[1] = STLINK_DEBUG_READMEM_32BIT;
608         h_u32_to_le(h->txbuf + 2, addr);
609         h_u16_to_le(h->txbuf + 2 + 4, len);
610
611         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, len);
612
613         if (res != ERROR_OK)
614                 return res;
615
616         memcpy(buffer, h->rxbuf, len);
617
618         return ERROR_OK;
619 }
620
621 /** */
622 int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,
623                            const uint32_t *buffer)
624 {
625         int res;
626         struct stlink_usb_handle_s *h;
627
628         assert(handle != NULL);
629
630         h = (struct stlink_usb_handle_s *)handle;
631
632         stlink_usb_init_buffer(handle);
633
634         len *= 4;
635
636         h->txbuf[0] = STLINK_DEBUG_COMMAND;
637         h->txbuf[1] = STLINK_DEBUG_WRITEMEM_32BIT;
638         h_u32_to_le(h->txbuf + 2, addr);
639         h_u16_to_le(h->txbuf + 2 + 4, len);
640
641         res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
642
643         if (res != ERROR_OK)
644                 return res;
645
646         res = stlink_usb_recv(handle, (uint8_t *) buffer, len, 0, 0);
647
648         if (res != ERROR_OK)
649                 return res;
650
651         return ERROR_OK;
652 }
653
654 /** */
655 int stlink_usb_open(struct stlink_interface_param_s *param, void **fd)
656 {
657         struct stlink_usb_handle_s *h;
658
659         LOG_DEBUG("stlink_usb_open");
660
661         h = malloc(sizeof(struct stlink_usb_handle_s));
662
663         if (h == 0) {
664                 LOG_DEBUG("stlink_open_usb: malloc failed");
665                 return ERROR_FAIL;
666         }
667
668         const uint16_t vids[] = { param->vid, 0 };
669         const uint16_t pids[] = { param->pid, 0 };
670
671         LOG_DEBUG("stlink_open_usb: vid: %04x pid: %04x", param->vid,
672                   param->pid);
673
674         if (jtag_libusb_open(vids, pids, &h->fd) != ERROR_OK) {
675                 LOG_ERROR("stlink_open_usb: open failed");
676                 return ERROR_FAIL;
677         }
678
679         jtag_libusb_set_configuration(h->fd, 0);
680
681         if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) {
682                 LOG_DEBUG("stlink_open_usb: claim failed");
683                 return ERROR_FAIL;
684         }
685
686         stlink_usb_init_mode(h);
687
688         stlink_usb_version(h);
689
690         *fd = h;
691
692         return ERROR_OK;
693 }
694
695 /** */
696 struct stlink_layout_api_s stlink_layout_api = {
697         /** */
698         .open = stlink_usb_open,
699         /** */
700         .idcode = stlink_usb_idcode,
701         /** */
702         .state = stlink_usb_state,
703         /** */
704         .reset = stlink_usb_reset,
705         /** */
706         .run = stlink_usb_run,
707         /** */
708         .halt = stlink_usb_halt,
709         /** */
710         .step = stlink_usb_step,
711         /** */
712         .read_regs = stlink_usb_read_regs,
713         /** */
714         .read_reg = stlink_usb_read_reg,
715         /** */
716         .write_reg = stlink_usb_write_reg,
717         /** */
718         .read_mem8 = stlink_usb_read_mem8,
719         /** */
720         .write_mem8 = stlink_usb_write_mem8,
721         /** */
722         .read_mem32 = stlink_usb_read_mem32,
723         /** */
724         .write_mem32 = stlink_usb_write_mem32,
725 };