usbtoxxx: remove warning by reducing scope of variable
[openocd.git] / src / jtag / drivers / versaloon / usbtoxxx / usbtoxxx.c
1 /***************************************************************************
2 * Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <string.h>
24
25 #include "../versaloon_include.h"
26 #include "../versaloon.h"
27 #include "../versaloon_internal.h"
28 #include "usbtoxxx.h"
29 #include "usbtoxxx_internal.h"
30
31 #define N_A "n/a"
32 const char* types_name[96] =
33 {
34 "usbtousart", "usbtospi", "usbtoi2c", "usbtogpio", "usbtocan", "usbtopwm",
35 "usbtoadc", "usbtodac",
36 "usbtomicrowire", "usbtoswim", "usbtodusi", N_A, N_A, N_A, "usbtopower", "usbtodelay",
37 N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A,
38 N_A, N_A, N_A, N_A, N_A, N_A, N_A,
39 "usbtojtagll", "usbtojtaghl", "usbtoissp", "usbtoc2", "usbtosbw",
40 "usbtolpcicp", "usbtoswd", "usbtojtagraw",
41 "usbtobdm", N_A, N_A, N_A, N_A, N_A, N_A, N_A,
42 N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A,
43 "usbtomsp430jtag", N_A, N_A, N_A, N_A, N_A, N_A, N_A,
44 "usbtopower", "usbtodelay", "usbtopoll", N_A, N_A, N_A, N_A, N_A,
45 N_A, N_A, N_A, N_A, N_A, N_A, N_A, "usbtoall"
46 };
47
48 uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN];
49
50 #define usbtoxxx_get_type_name(type) \
51 types_name[((type) - VERSALOON_USB_TO_XXX_CMD_START) \
52 % (sizeof(types_name) / sizeof(types_name[0]))]
53
54 static uint8_t type_pre = 0;
55 static uint16_t usbtoxxx_buffer_index = 0;
56 static uint16_t usbtoxxx_current_cmd_index = 0;
57 static uint8_t *usbtoxxx_buffer = NULL;
58
59 uint16_t collect_index = 0;
60 uint8_t collect_cmd;
61 static uint8_t poll_nesting = 0;
62
63 struct usbtoxxx_context_t
64 {
65 uint8_t type_pre;
66 uint8_t *usbtoxxx_buffer;
67 uint16_t usbtoxxx_current_cmd_index;
68 uint16_t usbtoxxx_buffer_index;
69 uint16_t versaloon_pending_idx;
70 };
71 static struct usbtoxxx_context_t poll_context;
72
73 static void usbtoxxx_save_context(struct usbtoxxx_context_t *c)
74 {
75 c->type_pre = type_pre;
76 c->usbtoxxx_buffer = usbtoxxx_buffer;
77 c->usbtoxxx_buffer_index = usbtoxxx_buffer_index;
78 c->usbtoxxx_current_cmd_index = usbtoxxx_current_cmd_index;
79 c->versaloon_pending_idx = versaloon_pending_idx;
80 }
81
82 static void usbtoxxx_pop_context(struct usbtoxxx_context_t *c)
83 {
84 type_pre = c->type_pre;
85 usbtoxxx_buffer = c->usbtoxxx_buffer;
86 usbtoxxx_buffer_index = c->usbtoxxx_buffer_index;
87 usbtoxxx_current_cmd_index = c->usbtoxxx_current_cmd_index;
88 versaloon_pending_idx = c->versaloon_pending_idx;
89 }
90
91 RESULT usbtoxxx_validate_current_command_type(void)
92 {
93 if (type_pre > 0)
94 {
95 // not the first command
96 if (NULL == usbtoxxx_buffer)
97 {
98 LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(usbtoxxx_buffer));
99 return ERRCODE_INVALID_BUFFER;
100 }
101
102 usbtoxxx_buffer[0] = type_pre;
103 SET_LE_U16(&usbtoxxx_buffer[1], usbtoxxx_current_cmd_index);
104
105 usbtoxxx_buffer_index += usbtoxxx_current_cmd_index;
106 }
107 else
108 {
109 // first command
110 usbtoxxx_buffer_index = 3;
111 }
112
113 // prepare for next command
114 usbtoxxx_current_cmd_index = 3;
115 usbtoxxx_buffer = versaloon_buf + usbtoxxx_buffer_index;
116
117 collect_index = 0;
118 collect_cmd = 0;
119
120 return ERROR_OK;
121 }
122
123
124
125 RESULT usbtoxxx_execute_command(void)
126 {
127 uint16_t i;
128 uint16_t inlen;
129 RESULT result = ERROR_OK;
130
131 if (poll_nesting)
132 {
133 LOG_BUG(ERRMSG_INVALID_USAGE, "USB_TO_POLL");
134 versaloon_free_want_pos();
135 return ERROR_FAIL;
136 }
137
138 if (ERROR_OK != usbtoxxx_validate_current_command_type())
139 {
140 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
141 versaloon_free_want_pos();
142 return ERRCODE_FAILURE_OPERATION;
143 }
144 if (3 == usbtoxxx_buffer_index)
145 {
146 versaloon_free_want_pos();
147 return ERROR_OK;
148 }
149
150 versaloon_buf[0] = USB_TO_ALL;
151 SET_LE_U16(&versaloon_buf[1], usbtoxxx_buffer_index);
152
153 if (ERROR_OK != versaloon_send_command(usbtoxxx_buffer_index, &inlen))
154 {
155 versaloon_free_want_pos();
156 return ERROR_FAIL;
157 }
158
159 // process return data
160 usbtoxxx_buffer_index = 0;
161 for (i = 0; i < versaloon_pending_idx; i++)
162 {
163 // check result
164 if ((0 == i) || !((versaloon_pending[i].collect)
165 && (versaloon_pending[i - 1].collect)
166 && (versaloon_pending[i].cmd
167 == versaloon_pending[i - 1].cmd)))
168 {
169 if (USB_TO_XXX_CMD_NOT_SUPPORT
170 == versaloon_buf[usbtoxxx_buffer_index])
171 {
172 LOG_ERROR(ERRMSG_NOT_SUPPORT_BY,
173 usbtoxxx_get_type_name(versaloon_pending[i].type),
174 "current dongle");
175 result = ERROR_FAIL;
176 break;
177 }
178 else if (USB_TO_XXX_OK != versaloon_buf[usbtoxxx_buffer_index])
179 {
180 LOG_ERROR("%s command 0x%02x failed with 0x%02x",
181 usbtoxxx_get_type_name(versaloon_pending[i].type),
182 versaloon_pending[i].cmd,
183 versaloon_buf[usbtoxxx_buffer_index]);
184 result = ERROR_FAIL;
185 break;
186 }
187 usbtoxxx_buffer_index++;
188 }
189
190 // get result data
191 if (versaloon_pending[i].pos != NULL)
192 {
193 uint8_t processed = 0;
194
195 if (versaloon_pending[i].callback != NULL)
196 {
197 versaloon_pending[i].callback(&versaloon_pending[i],
198 versaloon_buf + usbtoxxx_buffer_index, &processed);
199 }
200 if (!processed)
201 {
202 struct versaloon_want_pos_t *tmp;
203
204 tmp = versaloon_pending[i].pos;
205 while (tmp != NULL)
206 {
207 if ((tmp->buff != NULL) && (tmp->size > 0))
208 {
209 memcpy(tmp->buff, versaloon_buf + usbtoxxx_buffer_index
210 + tmp->offset, tmp->size);
211 }
212 struct versaloon_want_pos_t *free_tmp;
213 free_tmp = tmp;
214 tmp = tmp->next;
215 free(free_tmp);
216 }
217 versaloon_pending[i].pos = NULL;
218 }
219 }
220 else if ((versaloon_pending[i].want_data_size > 0)
221 && (versaloon_pending[i].data_buffer != NULL))
222 {
223 uint8_t processed = 0;
224
225 if (versaloon_pending[i].callback != NULL)
226 {
227 versaloon_pending[i].callback(&versaloon_pending[i],
228 versaloon_buf + usbtoxxx_buffer_index, &processed);
229 }
230 if (!processed)
231 {
232 memcpy(versaloon_pending[i].data_buffer,
233 versaloon_buf + usbtoxxx_buffer_index
234 + versaloon_pending[i].want_data_pos,
235 versaloon_pending[i].want_data_size);
236 }
237 }
238 usbtoxxx_buffer_index += versaloon_pending[i].actual_data_size;
239 if (usbtoxxx_buffer_index > inlen)
240 {
241 LOG_BUG("%s command 0x%02x process error",
242 usbtoxxx_get_type_name(versaloon_pending[i].type),
243 versaloon_pending[i].cmd);
244 result = ERROR_FAIL;
245 break;
246 }
247 }
248
249 // data is not the right size
250 if (inlen != usbtoxxx_buffer_index)
251 {
252 LOG_ERROR(ERRMSG_INVALID_TARGET, "length of return data");
253 result = ERROR_FAIL;
254 }
255
256 if (versaloon_pending_idx > 0)
257 {
258 versaloon_pending_idx = 0;
259 }
260 else
261 {
262 // no receive data, avoid collision
263 sleep_ms(10);
264 }
265
266 type_pre = 0;
267 collect_cmd = 0;
268 collect_index = 0;
269 versaloon_free_want_pos();
270 return result;
271 }
272
273 RESULT usbtoxxx_init(void)
274 {
275 versaloon_pending_idx = 0;
276
277 if ((ERROR_OK != usbtoinfo_get_abilities(usbtoxxx_abilities)) ||
278 (ERROR_OK != usbtoxxx_execute_command()))
279 {
280 return ERROR_FAIL;
281 }
282 LOG_INFO("USB_TO_XXX abilities: 0x%08X:0x%08X:0x%08X",
283 GET_LE_U32(&usbtoxxx_abilities[0]),
284 GET_LE_U32(&usbtoxxx_abilities[4]),
285 GET_LE_U32(&usbtoxxx_abilities[8]));
286 return ERROR_OK;
287 }
288
289 RESULT usbtoxxx_fini(void)
290 {
291 usbtoxxx_buffer = NULL;
292 type_pre = 0;
293 return ERROR_OK;
294 }
295
296 bool usbtoxxx_interface_supported(uint8_t cmd)
297 {
298 if ((cmd < VERSALOON_USB_TO_XXX_CMD_START) ||
299 (cmd > VERSALOON_USB_TO_XXX_CMD_END))
300 {
301 return false;
302 }
303
304 cmd -= VERSALOON_USB_TO_XXX_CMD_START;
305 return (usbtoxxx_abilities[cmd / 8] & (1 << (cmd % 8))) > 0;
306 }
307
308
309
310 RESULT usbtoxxx_ensure_buffer_size(uint16_t cmdlen)
311 {
312 // check free space, commit if not enough
313 if (((usbtoxxx_buffer_index + usbtoxxx_current_cmd_index + cmdlen)
314 >= versaloon_buf_size)
315 || (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER))
316 {
317 struct usbtoxxx_context_t context_tmp;
318 uint8_t poll_nesting_tmp = 0;
319
320 memset(&context_tmp, 0, sizeof(context_tmp));
321 if (poll_nesting)
322 {
323 if (0 == poll_context.type_pre)
324 {
325 LOG_BUG("USB_TO_POLL toooooo long");
326 return ERROR_OK;
327 }
328
329 usbtoxxx_save_context(&context_tmp);
330 usbtoxxx_pop_context(&poll_context);
331 poll_nesting_tmp = poll_nesting;
332 poll_nesting = 0;
333 }
334
335 if (usbtoxxx_execute_command() != ERROR_OK)
336 {
337 return ERROR_FAIL;
338 }
339
340 if (poll_nesting_tmp)
341 {
342 uint16_t newlen, oldlen;
343
344 newlen = context_tmp.versaloon_pending_idx
345 - poll_context.versaloon_pending_idx;
346 memcpy(&versaloon_pending[0],
347 &versaloon_pending[poll_context.versaloon_pending_idx],
348 sizeof(versaloon_pending[0]) * newlen);
349 context_tmp.versaloon_pending_idx = newlen;
350 oldlen = poll_context.usbtoxxx_buffer_index
351 + poll_context.usbtoxxx_current_cmd_index;
352 newlen = context_tmp.usbtoxxx_buffer_index
353 + context_tmp.usbtoxxx_current_cmd_index;
354 memcpy(versaloon_buf + 3, versaloon_buf + oldlen, newlen - oldlen);
355 oldlen -= 3;
356 context_tmp.usbtoxxx_buffer -= oldlen;
357 context_tmp.usbtoxxx_buffer_index -= oldlen;
358 usbtoxxx_pop_context(&context_tmp);
359 poll_nesting = poll_nesting_tmp;
360 }
361 }
362 return ERROR_OK;
363 }
364
365 RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf,
366 uint16_t cmdlen, uint16_t retlen, uint8_t *wantbuf,
367 uint16_t wantpos, uint16_t wantlen, uint8_t collect)
368 {
369 uint16_t len_tmp;
370
371 // 3 more bytes by usbtoxxx_validate_current_command_type
372 // 3 more bytes when ((0 == collect_index) || (collect_cmd != cmd))
373 if (ERROR_OK != usbtoxxx_ensure_buffer_size(cmdlen + 6))
374 {
375 return ERROR_FAIL;
376 }
377
378 if ((type_pre != type) || (NULL == usbtoxxx_buffer))
379 {
380 if (ERROR_OK != usbtoxxx_validate_current_command_type())
381 {
382 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
383 return ERRCODE_FAILURE_OPERATION;
384 }
385 type_pre = type;
386 }
387
388 if ((0 == collect_index) || (collect_cmd != cmd))
389 {
390 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = cmd;
391
392 if (collect)
393 {
394 collect_index = usbtoxxx_current_cmd_index;
395 collect_cmd = cmd;
396 }
397 else
398 {
399 collect_index = 0;
400 collect_cmd = 0;
401 }
402 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], cmdlen);
403 usbtoxxx_current_cmd_index += 2;
404 }
405 else
406 {
407 len_tmp = GET_LE_U16(&usbtoxxx_buffer[collect_index]) + cmdlen;
408 SET_LE_U16(&usbtoxxx_buffer[collect_index], len_tmp);
409 }
410
411 if (cmdbuf != NULL)
412 {
413 memcpy(usbtoxxx_buffer + usbtoxxx_current_cmd_index, cmdbuf, cmdlen);
414 usbtoxxx_current_cmd_index += cmdlen;
415 }
416
417 return versaloon_add_pending(type, cmd, retlen, wantpos, wantlen,
418 wantbuf, collect);
419 }
420
421
422
423
424
425 RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN])
426 {
427 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3))
428 {
429 return ERROR_FAIL;
430 }
431
432 if (ERROR_OK != usbtoxxx_validate_current_command_type())
433 {
434 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
435 return ERRCODE_FAILURE_OPERATION;
436 }
437 type_pre = USB_TO_INFO;
438
439 return versaloon_add_pending(USB_TO_INFO, 0, USB_TO_XXX_ABILITIES_LEN, 0,
440 USB_TO_XXX_ABILITIES_LEN, abilities, 0);
441 }
442
443
444
445
446 RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us)
447 {
448 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5))
449 {
450 return ERROR_FAIL;
451 }
452 if (!poll_nesting)
453 {
454 usbtoxxx_save_context(&poll_context);
455 }
456
457 if (ERROR_OK != usbtoxxx_validate_current_command_type())
458 {
459 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
460 return ERRCODE_FAILURE_OPERATION;
461 }
462 poll_nesting++;
463 type_pre = USB_TO_POLL;
464
465 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_START;
466 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], retry_cnt);
467 usbtoxxx_current_cmd_index += 2;
468 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], interval_us);
469 usbtoxxx_current_cmd_index += 2;
470
471 return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0);
472 }
473
474 RESULT usbtopoll_end(void)
475 {
476 if (!poll_nesting)
477 {
478 LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
479 return ERRCODE_FAILURE_OPERATION;
480 }
481 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 1))
482 {
483 return ERROR_FAIL;
484 }
485
486 if (ERROR_OK != usbtoxxx_validate_current_command_type())
487 {
488 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
489 return ERRCODE_FAILURE_OPERATION;
490 }
491
492 poll_nesting--;
493 type_pre = USB_TO_POLL;
494
495 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_END;
496
497 return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0);
498 }
499
500 RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size,
501 uint32_t mask, uint32_t value)
502 {
503 uint8_t i;
504
505 if (size > 4)
506 {
507 LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__);
508 return ERRCODE_INVALID_PARAMETER;
509 }
510 if (!poll_nesting)
511 {
512 LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
513 return ERRCODE_FAILURE_OPERATION;
514 }
515 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size))
516 {
517 return ERROR_FAIL;
518 }
519
520 if (ERROR_OK != usbtoxxx_validate_current_command_type())
521 {
522 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
523 return ERRCODE_FAILURE_OPERATION;
524 }
525
526 type_pre = USB_TO_POLL;
527
528 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKOK;
529 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);
530 usbtoxxx_current_cmd_index += 2;
531 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size;
532 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ;
533 for (i =0; i < size; i++)
534 {
535 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF;
536 }
537 for (i =0; i < size; i++)
538 {
539 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF;
540 }
541
542 return ERROR_OK;
543 }
544
545 RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size,
546 uint32_t mask, uint32_t value)
547 {
548 uint8_t i;
549
550 if (size > 4)
551 {
552 LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__);
553 return ERRCODE_INVALID_PARAMETER;
554 }
555 if (!poll_nesting)
556 {
557 LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
558 return ERRCODE_FAILURE_OPERATION;
559 }
560 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size))
561 {
562 return ERROR_FAIL;
563 }
564
565 if (ERROR_OK != usbtoxxx_validate_current_command_type())
566 {
567 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
568 return ERRCODE_FAILURE_OPERATION;
569 }
570
571 type_pre = USB_TO_POLL;
572
573 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKFAIL;
574 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);
575 usbtoxxx_current_cmd_index += 2;
576 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size;
577 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ;
578 for (i =0; i < size; i++)
579 {
580 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF;
581 }
582 for (i =0; i < size; i++)
583 {
584 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF;
585 }
586
587 return ERROR_OK;
588 }
589
590 RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff)
591 {
592 if (!poll_nesting)
593 {
594 LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
595 return ERRCODE_FAILURE_OPERATION;
596 }
597 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5 + size))
598 {
599 return ERROR_FAIL;
600 }
601
602 if (ERROR_OK != usbtoxxx_validate_current_command_type())
603 {
604 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
605 return ERRCODE_FAILURE_OPERATION;
606 }
607
608 type_pre = USB_TO_POLL;
609
610 usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_VERIFYBUFF;
611 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);
612 usbtoxxx_current_cmd_index += 2;
613 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], size);
614 usbtoxxx_current_cmd_index += 2;
615 memcpy(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], buff, size);
616 usbtoxxx_current_cmd_index += size;
617
618 return ERROR_OK;
619 }
620
621
622
623
624 RESULT usbtodelay_delay(uint16_t dly)
625 {
626 if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 2))
627 {
628 return ERROR_FAIL;
629 }
630
631 if (ERROR_OK != usbtoxxx_validate_current_command_type())
632 {
633 LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
634 return ERRCODE_FAILURE_OPERATION;
635 }
636 type_pre = USB_TO_DELAY;
637
638 SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], dly);
639 usbtoxxx_current_cmd_index += 2;
640
641 return versaloon_add_pending(USB_TO_DELAY, 0, 0, 0, 0, NULL, 0);
642 }
643
644 RESULT usbtodelay_delayms(uint16_t ms)
645 {
646 return usbtodelay_delay(ms | 0x8000);
647 }
648
649 RESULT usbtodelay_delayus(uint16_t us)
650 {
651 return usbtodelay_delay(us & 0x7FFF);
652 }
653

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)