jtag/drivers: give ANGIE a new PID after renumeration
[openocd.git] / src / jtag / drivers / angie.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /***************************************************************************
3 File : angie.c *
4 Contents : OpenOCD driver code for NanoXplore USB-JTAG ANGIE *
5 adapter hardware. *
6 Based on openULINK driver code by: Martin Schmoelzer. *
7 Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. *
8 <aboudjelida@nanoxplore.com> *
9 <ahmederrachedbjld@gmail.com> *
10 ***************************************************************************/
11
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <math.h>
19 #include "helper/system.h"
20 #include <helper/types.h>
21 #include <jtag/interface.h>
22 #include <jtag/commands.h>
23 #include <target/image.h>
24 #include <libusb.h>
25 #include "libusb_helper.h"
26 #include "angie/include/msgtypes.h"
27
28 /** USB Vendor ID of ANGIE device in unconfigured state (no firmware loaded
29 * yet) or with its firmware. */
30 #define ANGIE_VID 0x584e
31
32 /** USB Product ID of ANGIE device in unconfigured state (no firmware loaded
33 * yet) or with its firmware. */
34 #define ANGIE_PID 0x414F
35 #define ANGIE_PID_2 0x424e
36 #define ANGIE_PID_3 0x4255
37 #define ANGIE_PID_4 0x4355
38 #define ANGIE_PID_5 0x4a55
39
40 /** Address of EZ-USB ANGIE CPU Control & Status register. This register can be
41 * written by issuing a Control EP0 vendor request. */
42 #define CPUCS_REG 0xE600
43
44 /** USB Control EP0 bRequest: "Firmware Load". */
45 #define REQUEST_FIRMWARE_LOAD 0xA0
46
47 /** Value to write into CPUCS to put EZ-USB ANGIE into reset. */
48 #define CPU_RESET 0x01
49
50 /** Value to write into CPUCS to put EZ-USB ANGIE out of reset. */
51 #define CPU_START 0x00
52
53 /** Base address of firmware in EZ-USB ANGIE code space. */
54 #define FIRMWARE_ADDR 0x0000
55
56 /** USB interface number */
57 #define USB_INTERFACE 0
58
59 /** Delay (in microseconds) to wait while EZ-USB performs ReNumeration. */
60 #define ANGIE_RENUMERATION_DELAY_US 1500000
61
62 /** Default location of ANGIE firmware image. */
63 #define ANGIE_FIRMWARE_FILE PKGDATADIR "/angie/angie_firmware.bin"
64
65 /** Default location of ANGIE firmware image. */
66 #define ANGIE_BITSTREAM_FILE PKGDATADIR "/angie/angie_bitstream.bit"
67
68 /** Maximum size of a single firmware section. Entire EZ-USB ANGIE code space = 16kB */
69 #define SECTION_BUFFERSIZE 16384
70
71 /** Tuning of OpenOCD SCAN commands split into multiple ANGIE commands. */
72 #define SPLIT_SCAN_THRESHOLD 10
73
74 /** ANGIE hardware type */
75 enum angie_type {
76 ANGIE,
77 };
78
79 enum angie_payload_direction {
80 PAYLOAD_DIRECTION_OUT,
81 PAYLOAD_DIRECTION_IN
82 };
83
84 enum angie_delay_type {
85 DELAY_CLOCK_TCK,
86 DELAY_CLOCK_TMS,
87 DELAY_SCAN_IN,
88 DELAY_SCAN_OUT,
89 DELAY_SCAN_IO
90 };
91
92 /**
93 * ANGIE command (ANGIE command queue element).
94 *
95 * For the OUT direction payload, things are quite easy: Payload is stored
96 * in a rather small array (up to 63 bytes), the payload is always allocated
97 * by the function generating the command and freed by angie_clear_queue().
98 *
99 * For the IN direction payload, things get a little bit more complicated:
100 * The maximum IN payload size for a single command is 64 bytes. Assume that
101 * a single OpenOCD command needs to scan 256 bytes. This results in the
102 * generation of four ANGIE commands. The function generating these
103 * commands shall allocate an uint8_t[256] array. Each command's #payload_in
104 * pointer shall point to the corresponding offset where IN data shall be
105 * placed, while #payload_in_start shall point to the first element of the 256
106 * byte array.
107 * - first command: #payload_in_start + 0
108 * - second command: #payload_in_start + 64
109 * - third command: #payload_in_start + 128
110 * - fourth command: #payload_in_start + 192
111 *
112 * The last command sets #needs_postprocessing to true.
113 */
114 struct angie_cmd {
115 uint8_t id; /**< ANGIE command ID */
116
117 uint8_t *payload_out; /**< Pointer where OUT payload shall be stored */
118 uint8_t payload_out_size; /**< OUT direction payload size for this command */
119
120 uint8_t *payload_in_start; /**< Pointer to first element of IN payload array */
121 uint8_t *payload_in; /**< Pointer where IN payload shall be stored */
122 uint8_t payload_in_size; /**< IN direction payload size for this command */
123
124 /** Indicates if this command needs post-processing */
125 bool needs_postprocessing;
126
127 /** Indicates if angie_clear_queue() should free payload_in_start */
128 bool free_payload_in_start;
129
130 /** Pointer to corresponding OpenOCD command for post-processing */
131 struct jtag_command *cmd_origin;
132
133 struct angie_cmd *next; /**< Pointer to next command (linked list) */
134 };
135
136 /** Describes one driver instance */
137 struct angie {
138 struct libusb_context *libusb_ctx;
139 struct libusb_device_handle *usb_device_handle;
140 enum angie_type type;
141
142 unsigned int ep_in; /**< IN endpoint number */
143 unsigned int ep_out; /**< OUT endpoint number */
144
145 /* delay value for "SLOW_CLOCK commands" in [0:255] range in units of 4 us;
146 -1 means no need for delay */
147 int delay_scan_in; /**< Delay value for SCAN_IN commands */
148 int delay_scan_out; /**< Delay value for SCAN_OUT commands */
149 int delay_scan_io; /**< Delay value for SCAN_IO commands */
150 int delay_clock_tck; /**< Delay value for CLOCK_TMS commands */
151 int delay_clock_tms; /**< Delay value for CLOCK_TCK commands */
152
153 int commands_in_queue; /**< Number of commands in queue */
154 struct angie_cmd *queue_start; /**< Pointer to first command in queue */
155 struct angie_cmd *queue_end; /**< Pointer to last command in queue */
156 };
157
158 /**************************** Function Prototypes *****************************/
159
160 /* USB helper functions */
161 static int angie_usb_open(struct angie *device);
162 static int angie_usb_close(struct angie *device);
163
164 /* ANGIE MCU (Cypress EZ-USB) specific functions */
165 static int angie_cpu_reset(struct angie *device, char reset_bit);
166 static int angie_load_firmware_and_renumerate(struct angie *device, const char *filename,
167 uint32_t delay_us);
168 static int angie_load_firmware(struct angie *device, const char *filename);
169 static int angie_load_bitstream(struct angie *device, const char *filename);
170
171 static int angie_write_firmware_section(struct angie *device,
172 struct image *firmware_image, int section_index);
173
174 /* Generic helper functions */
175 static void angie_dump_signal_states(uint8_t input_signals, uint8_t output_signals);
176
177 /* ANGIE command generation helper functions */
178 static int angie_allocate_payload(struct angie_cmd *angie_cmd, int size,
179 enum angie_payload_direction direction);
180
181 /* ANGIE command queue helper functions */
182 static int angie_get_queue_size(struct angie *device,
183 enum angie_payload_direction direction);
184 static void angie_clear_queue(struct angie *device);
185 static int angie_append_queue(struct angie *device, struct angie_cmd *angie_cmd);
186 static int angie_execute_queued_commands(struct angie *device, int timeout_ms);
187
188 static void angie_dump_queue(struct angie *device);
189
190 static int angie_append_scan_cmd(struct angie *device,
191 enum scan_type scan_type,
192 int scan_size_bits,
193 uint8_t *tdi,
194 uint8_t *tdo_start,
195 uint8_t *tdo,
196 uint8_t tms_count_start,
197 uint8_t tms_sequence_start,
198 uint8_t tms_count_end,
199 uint8_t tms_sequence_end,
200 struct jtag_command *origin,
201 bool postprocess);
202 static int angie_append_clock_tms_cmd(struct angie *device, uint8_t count,
203 uint8_t sequence);
204 static int angie_append_clock_tck_cmd(struct angie *device, uint16_t count);
205 static int angie_append_get_signals_cmd(struct angie *device);
206 static int angie_append_set_signals_cmd(struct angie *device, uint8_t low,
207 uint8_t high);
208 static int angie_append_sleep_cmd(struct angie *device, uint32_t us);
209 static int angie_append_configure_tck_cmd(struct angie *device,
210 int delay_scan_in,
211 int delay_scan_out,
212 int delay_scan_io,
213 int delay_tck,
214 int delay_tms);
215 static int angie_append_test_cmd(struct angie *device);
216
217 /* ANGIE TCK frequency helper functions */
218 static int angie_calculate_delay(enum angie_delay_type type, long f, int *delay);
219
220 /* Interface between ANGIE and OpenOCD */
221 static void angie_set_end_state(tap_state_t endstate);
222 static int angie_queue_statemove(struct angie *device);
223
224 static int angie_queue_scan(struct angie *device, struct jtag_command *cmd);
225 static int angie_queue_tlr_reset(struct angie *device, struct jtag_command *cmd);
226 static int angie_queue_runtest(struct angie *device, struct jtag_command *cmd);
227 static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd);
228 static int angie_queue_sleep(struct angie *device, struct jtag_command *cmd);
229 static int angie_queue_stableclocks(struct angie *device, struct jtag_command *cmd);
230
231 static int angie_post_process_scan(struct angie_cmd *angie_cmd);
232 static int angie_post_process_queue(struct angie *device);
233
234 /* adapter driver functions */
235 static int angie_execute_queue(void);
236 static int angie_khz(int khz, int *jtag_speed);
237 static int angie_speed(int speed);
238 static int angie_speed_div(int speed, int *khz);
239 static int angie_init(void);
240 static int angie_quit(void);
241 static int angie_reset(int trst, int srst);
242
243 /****************************** Global Variables ******************************/
244
245 static struct angie *angie_handle;
246
247 /**************************** USB helper functions ****************************/
248
249 /**
250 * Opens the ANGIE device
251 *
252 * @param device pointer to struct angie identifying ANGIE driver instance.
253 * @return on success: ERROR_OK
254 * @return on failure: ERROR_FAIL
255 */
256 static int angie_usb_open(struct angie *device)
257 {
258 struct libusb_device_handle *usb_device_handle;
259 const uint16_t vids[] = {ANGIE_VID, ANGIE_VID, ANGIE_VID, ANGIE_VID, ANGIE_VID, 0};
260 const uint16_t pids[] = {ANGIE_PID, ANGIE_PID_2, ANGIE_PID_3, ANGIE_PID_4, ANGIE_PID_5, 0};
261
262 int ret = jtag_libusb_open(vids, pids, NULL, &usb_device_handle, NULL);
263
264 if (ret != ERROR_OK)
265 return ret;
266
267 device->usb_device_handle = usb_device_handle;
268 device->type = ANGIE;
269
270 return ERROR_OK;
271 }
272
273 /**
274 * Releases the ANGIE interface and closes the USB device handle.
275 *
276 * @param device pointer to struct angie identifying ANGIE driver instance.
277 * @return on success: ERROR_OK
278 * @return on failure: ERROR_FAIL
279 */
280 static int angie_usb_close(struct angie *device)
281 {
282 if (device->usb_device_handle) {
283 if (libusb_release_interface(device->usb_device_handle, 0) != 0)
284 return ERROR_FAIL;
285
286 jtag_libusb_close(device->usb_device_handle);
287 device->usb_device_handle = NULL;
288 }
289 return ERROR_OK;
290 }
291
292 /******************* ANGIE CPU (EZ-USB) specific functions ********************/
293
294 /**
295 * Writes '0' or '1' to the CPUCS register, putting the EZ-USB CPU into reset
296 * or out of reset.
297 *
298 * @param device pointer to struct angie identifying ANGIE driver instance.
299 * @param reset_bit 0 to put CPU into reset, 1 to put CPU out of reset.
300 * @return on success: ERROR_OK
301 * @return on failure: ERROR_FAIL
302 */
303 static int angie_cpu_reset(struct angie *device, char reset_bit)
304 {
305 return jtag_libusb_control_transfer(device->usb_device_handle,
306 (LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
307 REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, LIBUSB_TIMEOUT_MS, NULL);
308 }
309
310 /**
311 * Puts the ANGIE's EZ-USB microcontroller into reset state, downloads
312 * the firmware image, resumes the microcontroller and re-enumerates
313 * USB devices.
314 *
315 * @param device pointer to struct angie identifying ANGIE driver instance.
316 * The usb_handle member will be modified during re-enumeration.
317 * @param filename path to the Intel HEX file containing the firmware image.
318 * @param delay_us the delay to wait for the device to re-enumerate.
319 * @return on success: ERROR_OK
320 * @return on failure: ERROR_FAIL
321 */
322 static int angie_load_firmware_and_renumerate(struct angie *device,
323 const char *filename, uint32_t delay_us)
324 {
325 int ret;
326
327 /* Basic process: After downloading the firmware, the ANGIE will disconnect
328 * itself and re-connect after a short amount of time so we have to close
329 * the handle and re-enumerate USB devices */
330
331 ret = angie_load_firmware(device, filename);
332 if (ret != ERROR_OK)
333 return ret;
334
335 ret = angie_usb_close(device);
336 if (ret != ERROR_OK)
337 return ret;
338
339 usleep(delay_us);
340
341 return angie_usb_open(device);
342 }
343
344 /**
345 * Downloads a firmware image to the ANGIE's EZ-USB microcontroller
346 * over the USB bus.
347 *
348 * @param device pointer to struct angie identifying ANGIE driver instance.
349 * @param filename an absolute or relative path to the Intel HEX file
350 * containing the firmware image.
351 * @return on success: ERROR_OK
352 * @return on failure: ERROR_FAIL
353 */
354 static int angie_load_firmware(struct angie *device, const char *filename)
355 {
356 struct image angie_firmware_image;
357 int ret;
358
359 ret = angie_cpu_reset(device, CPU_RESET);
360 if (ret != ERROR_OK) {
361 LOG_ERROR("Could not halt ANGIE CPU");
362 return ret;
363 }
364
365 angie_firmware_image.base_address = 0;
366 angie_firmware_image.base_address_set = false;
367
368 ret = image_open(&angie_firmware_image, filename, "bin");
369 if (ret != ERROR_OK) {
370 LOG_ERROR("Could not load firmware image");
371 return ret;
372 }
373
374 /* Download all sections in the image to ANGIE */
375 for (unsigned int i = 0; i < angie_firmware_image.num_sections; i++) {
376 ret = angie_write_firmware_section(device, &angie_firmware_image, i);
377 if (ret != ERROR_OK)
378 return ret;
379 }
380
381 image_close(&angie_firmware_image);
382
383 ret = angie_cpu_reset(device, CPU_START);
384 if (ret != ERROR_OK) {
385 LOG_ERROR("Could not restart ANGIE CPU");
386 return ret;
387 }
388
389 return ERROR_OK;
390 }
391
392 /**
393 * Downloads a bitstream file to the ANGIE's FPGA through the EZ-USB microcontroller
394 * over the USB bus.
395 *
396 * @param device pointer to struct angie identifying ANGIE driver instance.
397 * @param filename an absolute or relative path to the Xilinx .bit file
398 * containing the bitstream data.
399 * @return on success: ERROR_OK
400 * @return on failure: ERROR_FAIL
401 */
402 static int angie_load_bitstream(struct angie *device, const char *filename)
403 {
404 int ret, transferred;
405 const char *bitstream_file_path = filename;
406 FILE *bitstream_file = NULL;
407 char *bitstream_data = NULL;
408 size_t bitstream_size = 0;
409 uint8_t gpifcnt[4];
410
411 /* Open the bitstream file */
412 bitstream_file = fopen(bitstream_file_path, "rb");
413 if (!bitstream_file) {
414 LOG_ERROR("Failed to open bitstream file: %s\n", bitstream_file_path);
415 return ERROR_FAIL;
416 }
417
418 /* Get the size of the bitstream file */
419 fseek(bitstream_file, 0, SEEK_END);
420 bitstream_size = ftell(bitstream_file);
421 fseek(bitstream_file, 0, SEEK_SET);
422
423 /* Allocate memory for the bitstream data */
424 bitstream_data = malloc(bitstream_size);
425 if (!bitstream_data) {
426 LOG_ERROR("Failed to allocate memory for bitstream data.");
427 fclose(bitstream_file);
428 return ERROR_FAIL;
429 }
430
431 /* Read the bitstream data from the file */
432 if (fread(bitstream_data, 1, bitstream_size, bitstream_file) != bitstream_size) {
433 LOG_ERROR("Failed to read bitstream data.");
434 free(bitstream_data);
435 fclose(bitstream_file);
436 return ERROR_FAIL;
437 }
438
439 h_u32_to_be(gpifcnt, bitstream_size);
440
441 /* CFGopen */
442 ret = jtag_libusb_control_transfer(device->usb_device_handle,
443 0x00, 0xB0, 0, 0, (char *)gpifcnt, 4, LIBUSB_TIMEOUT_MS, &transferred);
444 if (ret != ERROR_OK) {
445 LOG_ERROR("Failed opencfg");
446 /* Abort if libusb sent less data than requested */
447 return ERROR_FAIL;
448 }
449
450 /* Send the bitstream data to the microcontroller */
451 int actual_length = 0;
452 ret = jtag_libusb_bulk_write(device->usb_device_handle, 0x02, bitstream_data, bitstream_size, 1000, &actual_length);
453 if (ret != ERROR_OK) {
454 LOG_ERROR("Failed to send bitstream data: %s", libusb_strerror(ret));
455 free(bitstream_data);
456 fclose(bitstream_file);
457 return ERROR_FAIL;
458 }
459
460 LOG_INFO("Bitstream sent successfully.");
461
462 /* Clean up */
463 free(bitstream_data);
464 fclose(bitstream_file);
465
466 /* CFGclose */
467 transferred = 0;
468 ret = jtag_libusb_control_transfer(device->usb_device_handle,
469 0x00, 0xB1, 0, 0, NULL, 0, LIBUSB_TIMEOUT_MS, &transferred);
470 if (ret != ERROR_OK) {
471 LOG_INFO("error cfgclose");
472 /* Abort if libusb sent less data than requested */
473 return ERROR_FAIL;
474 }
475 return ERROR_OK;
476 }
477
478 /**
479 * Send one contiguous firmware section to the ANGIE's EZ-USB microcontroller
480 * over the USB bus.
481 *
482 * @param device pointer to struct angie identifying ANGIE driver instance.
483 * @param firmware_image pointer to the firmware image that contains the section
484 * which should be sent to the ANGIE's EZ-USB microcontroller.
485 * @param section_index index of the section within the firmware image.
486 * @return on success: ERROR_OK
487 * @return on failure: ERROR_FAIL
488 */
489 static int angie_write_firmware_section(struct angie *device,
490 struct image *firmware_image, int section_index)
491 {
492 int addr, bytes_remaining, chunk_size;
493 uint8_t data[SECTION_BUFFERSIZE];
494 uint8_t *data_ptr = data;
495 uint16_t size;
496 size_t size_read;
497 int ret, transferred;
498
499 size = (uint16_t)firmware_image->sections[section_index].size;
500 addr = (uint16_t)firmware_image->sections[section_index].base_address;
501
502 LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04" PRIx16 ")", section_index, addr,
503 size);
504
505 /* Copy section contents to local buffer */
506 ret = image_read_section(firmware_image, section_index, 0, size, data,
507 &size_read);
508
509 if (ret != ERROR_OK)
510 return ret;
511 if (size_read != size)
512 return ERROR_FAIL;
513
514 bytes_remaining = size;
515
516 /* Send section data in chunks of up to 64 bytes to ANGIE */
517 while (bytes_remaining > 0) {
518 if (bytes_remaining > 64)
519 chunk_size = 64;
520 else
521 chunk_size = bytes_remaining;
522
523 ret = jtag_libusb_control_transfer(device->usb_device_handle,
524 (LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
525 REQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (char *)data_ptr,
526 chunk_size, LIBUSB_TIMEOUT_MS, &transferred);
527
528 if (ret != ERROR_OK)
529 return ret;
530
531 if (transferred != chunk_size) {
532 /* Abort if libusb sent less data than requested */
533 return ERROR_FAIL;
534 }
535
536 bytes_remaining -= chunk_size;
537 addr += chunk_size;
538 data_ptr += chunk_size;
539 }
540
541 return ERROR_OK;
542 }
543
544 /************************** Generic helper functions **************************/
545
546 /**
547 * Print state of interesting signals via LOG_INFO().
548 *
549 * @param input_signals input signal states as returned by CMD_GET_SIGNALS
550 * @param output_signals output signal states as returned by CMD_GET_SIGNALS
551 */
552 static void angie_dump_signal_states(uint8_t input_signals, uint8_t output_signals)
553 {
554 LOG_INFO("ANGIE signal states: TDI: %i, TDO: %i, TMS: %i, TCK: %i, TRST: %i "
555 "SRST: %i",
556 (output_signals & SIGNAL_TDI ? 1 : 0),
557 (input_signals & SIGNAL_TDO ? 1 : 0),
558 (output_signals & SIGNAL_TMS ? 1 : 0),
559 (output_signals & SIGNAL_TCK ? 1 : 0),
560 (output_signals & SIGNAL_TRST ? 1 : 0),
561 (output_signals & SIGNAL_SRST ? 1 : 0));
562 }
563
564 /**************** ANGIE command generation helper functions ***************/
565
566 /**
567 * Allocate and initialize space in memory for ANGIE command payload.
568 *
569 * @param angie_cmd pointer to command whose payload should be allocated.
570 * @param size the amount of memory to allocate (bytes).
571 * @param direction which payload to allocate.
572 * @return on success: ERROR_OK
573 * @return on failure: ERROR_FAIL
574 */
575 static int angie_allocate_payload(struct angie_cmd *angie_cmd, int size,
576 enum angie_payload_direction direction)
577 {
578 uint8_t *payload;
579
580 payload = calloc(size, sizeof(uint8_t));
581
582 if (!payload) {
583 LOG_ERROR("Could not allocate ANGIE command payload: out of memory");
584 return ERROR_FAIL;
585 }
586
587 switch (direction) {
588 case PAYLOAD_DIRECTION_OUT:
589 if (angie_cmd->payload_out) {
590 LOG_ERROR("BUG: Duplicate payload allocation for ANGIE command");
591 free(payload);
592 return ERROR_FAIL;
593 }
594 angie_cmd->payload_out = payload;
595 angie_cmd->payload_out_size = size;
596 break;
597 case PAYLOAD_DIRECTION_IN:
598 if (angie_cmd->payload_in_start) {
599 LOG_ERROR("BUG: Duplicate payload allocation for ANGIE command");
600 free(payload);
601 return ERROR_FAIL;
602 }
603
604 angie_cmd->payload_in_start = payload;
605 angie_cmd->payload_in = payload;
606 angie_cmd->payload_in_size = size;
607
608 /* By default, free payload_in_start in angie_clear_queue(). Commands
609 * that do not want this behavior (e. g. split scans) must turn it off
610 * separately! */
611 angie_cmd->free_payload_in_start = true;
612
613 break;
614 }
615
616 return ERROR_OK;
617 }
618
619 /****************** ANGIE command queue helper functions ******************/
620
621 /**
622 * Get the current number of bytes in the queue, including command IDs.
623 *
624 * @param device pointer to struct angie identifying ANGIE driver instance.
625 * @param direction the transfer direction for which to get byte count.
626 * @return the number of bytes currently stored in the queue for the specified
627 * direction.
628 */
629 static int angie_get_queue_size(struct angie *device,
630 enum angie_payload_direction direction)
631 {
632 struct angie_cmd *current = device->queue_start;
633 int sum = 0;
634
635 while (current) {
636 switch (direction) {
637 case PAYLOAD_DIRECTION_OUT:
638 sum += current->payload_out_size + 1; /* + 1 byte for Command ID */
639 break;
640 case PAYLOAD_DIRECTION_IN:
641 sum += current->payload_in_size;
642 break;
643 }
644
645 current = current->next;
646 }
647
648 return sum;
649 }
650
651 /**
652 * Clear the ANGIE command queue.
653 *
654 * @param device pointer to struct angie identifying ANGIE driver instance.
655 */
656 static void angie_clear_queue(struct angie *device)
657 {
658 struct angie_cmd *current = device->queue_start;
659 struct angie_cmd *next = NULL;
660
661 while (current) {
662 /* Save pointer to next element */
663 next = current->next;
664
665 /* Free payloads: OUT payload can be freed immediately */
666 free(current->payload_out);
667 current->payload_out = NULL;
668
669 /* IN payload MUST be freed ONLY if no other commands use the
670 * payload_in_start buffer */
671 if (current->free_payload_in_start) {
672 free(current->payload_in_start);
673 current->payload_in_start = NULL;
674 current->payload_in = NULL;
675 }
676
677 /* Free queue element */
678 free(current);
679
680 /* Proceed with next element */
681 current = next;
682 }
683
684 device->commands_in_queue = 0;
685 device->queue_start = NULL;
686 device->queue_end = NULL;
687 }
688
689 /**
690 * Add a command to the ANGIE command queue.
691 *
692 * @param device pointer to struct angie identifying ANGIE driver instance.
693 * @param angie_cmd pointer to command that shall be appended to the ANGIE
694 * command queue.
695 * @return on success: ERROR_OK
696 * @return on failure: ERROR_FAIL
697 */
698 static int angie_append_queue(struct angie *device, struct angie_cmd *angie_cmd)
699 {
700 int newsize_out, newsize_in;
701 int ret = ERROR_OK;
702
703 newsize_out = angie_get_queue_size(device, PAYLOAD_DIRECTION_OUT) + 1
704 + angie_cmd->payload_out_size;
705
706 newsize_in = angie_get_queue_size(device, PAYLOAD_DIRECTION_IN)
707 + angie_cmd->payload_in_size;
708
709 /* Check if the current command can be appended to the queue */
710 if (newsize_out > 64 || newsize_in > 64) {
711 /* New command does not fit. Execute all commands in queue before starting
712 * new queue with the current command as first entry. */
713 ret = angie_execute_queued_commands(device, LIBUSB_TIMEOUT_MS);
714
715 if (ret == ERROR_OK)
716 ret = angie_post_process_queue(device);
717
718 if (ret == ERROR_OK)
719 angie_clear_queue(device);
720 }
721
722 if (!device->queue_start) {
723 /* Queue was empty */
724 device->commands_in_queue = 1;
725
726 device->queue_start = angie_cmd;
727 device->queue_end = angie_cmd;
728 } else {
729 /* There are already commands in the queue */
730 device->commands_in_queue++;
731
732 device->queue_end->next = angie_cmd;
733 device->queue_end = angie_cmd;
734 }
735
736 if (ret != ERROR_OK)
737 angie_clear_queue(device);
738
739 return ret;
740 }
741
742 /**
743 * Sends all queued ANGIE commands to the ANGIE for execution.
744 *
745 * @param device pointer to struct angie identifying ANGIE driver instance.
746 * @param timeout_ms
747 * @return on success: ERROR_OK
748 * @return on failure: ERROR_FAIL
749 */
750 static int angie_execute_queued_commands(struct angie *device, int timeout_ms)
751 {
752 struct angie_cmd *current;
753 int ret, i, index_out, index_in, count_out, count_in, transferred;
754 uint8_t buffer[64];
755
756 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
757 angie_dump_queue(device);
758
759 index_out = 0;
760 count_out = 0;
761 count_in = 0;
762
763 for (current = device->queue_start; current; current = current->next) {
764 /* Add command to packet */
765 buffer[index_out] = current->id;
766 index_out++;
767 count_out++;
768
769 for (i = 0; i < current->payload_out_size; i++)
770 buffer[index_out + i] = current->payload_out[i];
771 index_out += current->payload_out_size;
772 count_in += current->payload_in_size;
773 count_out += current->payload_out_size;
774 }
775
776 /* Send packet to ANGIE */
777 ret = jtag_libusb_bulk_write(device->usb_device_handle, device->ep_out,
778 (char *)buffer, count_out, timeout_ms, &transferred);
779 if (ret != ERROR_OK)
780 return ret;
781 if (transferred != count_out)
782 return ERROR_FAIL;
783
784 /* Wait for response if commands contain IN payload data */
785 if (count_in > 0) {
786 ret = jtag_libusb_bulk_write(device->usb_device_handle, device->ep_in,
787 (char *)buffer, count_in, timeout_ms, &transferred);
788 if (ret != ERROR_OK)
789 return ret;
790 if (transferred != count_in)
791 return ERROR_FAIL;
792
793 /* Write back IN payload data */
794 index_in = 0;
795 for (current = device->queue_start; current; current = current->next) {
796 for (i = 0; i < current->payload_in_size; i++) {
797 current->payload_in[i] = buffer[index_in];
798 index_in++;
799 }
800 }
801 }
802 return ERROR_OK;
803 }
804
805 /**
806 * Convert an ANGIE command ID (\a id) to a human-readable string.
807 *
808 * @param id the ANGIE command ID.
809 * @return the corresponding human-readable string.
810 */
811 static const char *angie_cmd_id_string(uint8_t id)
812 {
813 switch (id) {
814 case CMD_SCAN_IN:
815 return "CMD_SCAN_IN";
816 case CMD_SLOW_SCAN_IN:
817 return "CMD_SLOW_SCAN_IN";
818 case CMD_SCAN_OUT:
819 return "CMD_SCAN_OUT";
820 case CMD_SLOW_SCAN_OUT:
821 return "CMD_SLOW_SCAN_OUT";
822 case CMD_SCAN_IO:
823 return "CMD_SCAN_IO";
824 case CMD_SLOW_SCAN_IO:
825 return "CMD_SLOW_SCAN_IO";
826 case CMD_CLOCK_TMS:
827 return "CMD_CLOCK_TMS";
828 case CMD_SLOW_CLOCK_TMS:
829 return "CMD_SLOW_CLOCK_TMS";
830 case CMD_CLOCK_TCK:
831 return "CMD_CLOCK_TCK";
832 case CMD_SLOW_CLOCK_TCK:
833 return "CMD_SLOW_CLOCK_TCK";
834 case CMD_SLEEP_US:
835 return "CMD_SLEEP_US";
836 case CMD_SLEEP_MS:
837 return "CMD_SLEEP_MS";
838 case CMD_GET_SIGNALS:
839 return "CMD_GET_SIGNALS";
840 case CMD_SET_SIGNALS:
841 return "CMD_SET_SIGNALS";
842 case CMD_CONFIGURE_TCK_FREQ:
843 return "CMD_CONFIGURE_TCK_FREQ";
844 case CMD_SET_LEDS:
845 return "CMD_SET_LEDS";
846 case CMD_TEST:
847 return "CMD_TEST";
848 default:
849 return "CMD_UNKNOWN";
850 }
851 }
852
853 /**
854 * Print one ANGIE command to stdout.
855 *
856 * @param angie_cmd pointer to ANGIE command.
857 */
858 static void angie_dump_command(struct angie_cmd *angie_cmd)
859 {
860 char hex[64 * 3];
861 for (int i = 0; i < angie_cmd->payload_out_size; i++)
862 sprintf(hex + 3 * i, "%02" PRIX8 " ", angie_cmd->payload_out[i]);
863
864 hex[3 * angie_cmd->payload_out_size - 1] = 0;
865 LOG_DEBUG_IO(" %-22s | OUT size = %" PRIi8 ", bytes = %s",
866 angie_cmd_id_string(angie_cmd->id), angie_cmd->payload_out_size, hex);
867
868 LOG_DEBUG_IO("\n | IN size = %" PRIi8 "\n", angie_cmd->payload_in_size);
869 }
870
871 /**
872 * Print the ANGIE command queue to stdout.
873 *
874 * @param device pointer to struct angie identifying ANGIE driver instance.
875 */
876 static void angie_dump_queue(struct angie *device)
877 {
878 struct angie_cmd *current;
879
880 LOG_DEBUG_IO("ANGIE command queue:\n");
881
882 for (current = device->queue_start; current; current = current->next)
883 angie_dump_command(current);
884 }
885
886 /**
887 * Perform JTAG scan
888 *
889 * Creates and appends a JTAG scan command to the ANGIE command queue.
890 * A JTAG scan consists of three steps:
891 * - Move to the desired SHIFT state, depending on scan type (IR/DR scan).
892 * - Shift TDI data into the JTAG chain, optionally reading the TDO pin.
893 * - Move to the desired end state.
894 *
895 * @param device pointer to struct angie identifying ANGIE driver instance.
896 * @param scan_type the type of the scan (IN, OUT, IO (bidirectional)).
897 * @param scan_size_bits number of bits to shift into the JTAG chain.
898 * @param tdi pointer to array containing TDI data.
899 * @param tdo_start pointer to first element of array where TDO data shall be
900 * stored. See #angie_cmd for details.
901 * @param tdo pointer to array where TDO data shall be stored
902 * @param tms_count_start number of TMS state transitions to perform BEFORE
903 * shifting data into the JTAG chain.
904 * @param tms_sequence_start sequence of TMS state transitions that will be
905 * performed BEFORE shifting data into the JTAG chain.
906 * @param tms_count_end number of TMS state transitions to perform AFTER
907 * shifting data into the JTAG chain.
908 * @param tms_sequence_end sequence of TMS state transitions that will be
909 * performed AFTER shifting data into the JTAG chain.
910 * @param origin pointer to OpenOCD command that generated this scan command.
911 * @param postprocess whether this command needs to be post-processed after
912 * execution.
913 * @return on success: ERROR_OK
914 * @return on failure: ERROR_FAIL
915 */
916 static int angie_append_scan_cmd(struct angie *device, enum scan_type scan_type,
917 int scan_size_bits, uint8_t *tdi, uint8_t *tdo_start, uint8_t *tdo,
918 uint8_t tms_count_start, uint8_t tms_sequence_start, uint8_t tms_count_end,
919 uint8_t tms_sequence_end, struct jtag_command *origin, bool postprocess)
920 {
921 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
922 int ret, i, scan_size_bytes;
923 uint8_t bits_last_byte;
924
925 if (!cmd)
926 return ERROR_FAIL;
927
928 /* Check size of command. USB buffer can hold 64 bytes, 1 byte is command ID,
929 * 5 bytes are setup data -> 58 remaining payload bytes for TDI data */
930 if (scan_size_bits > (58 * 8)) {
931 LOG_ERROR("BUG: Tried to create CMD_SCAN_IO ANGIE command with too"
932 " large payload");
933 free(cmd);
934 return ERROR_FAIL;
935 }
936
937 scan_size_bytes = DIV_ROUND_UP(scan_size_bits, 8);
938
939 bits_last_byte = scan_size_bits % 8;
940 if (bits_last_byte == 0)
941 bits_last_byte = 8;
942
943 /* Allocate out_payload depending on scan type */
944 switch (scan_type) {
945 case SCAN_IN:
946 if (device->delay_scan_in < 0)
947 cmd->id = CMD_SCAN_IN;
948 else
949 cmd->id = CMD_SLOW_SCAN_IN;
950 ret = angie_allocate_payload(cmd, 5, PAYLOAD_DIRECTION_IN);
951 break;
952 case SCAN_OUT:
953 if (device->delay_scan_out < 0)
954 cmd->id = CMD_SCAN_OUT;
955 else
956 cmd->id = CMD_SLOW_SCAN_OUT;
957 ret = angie_allocate_payload(cmd, scan_size_bytes + 5, PAYLOAD_DIRECTION_OUT);
958 break;
959 case SCAN_IO:
960 if (device->delay_scan_io < 0)
961 cmd->id = CMD_SCAN_IO;
962 else
963 cmd->id = CMD_SLOW_SCAN_IO;
964 ret = angie_allocate_payload(cmd, scan_size_bytes + 5, PAYLOAD_DIRECTION_OUT);
965 break;
966 default:
967 LOG_ERROR("BUG: 'append scan cmd' encountered an unknown scan type");
968 ret = ERROR_FAIL;
969 break;
970 }
971
972 if (ret != ERROR_OK) {
973 free(cmd);
974 return ret;
975 }
976
977 /* Build payload_out that is common to all scan types */
978 cmd->payload_out[0] = scan_size_bytes & 0xFF;
979 cmd->payload_out[1] = bits_last_byte & 0xFF;
980 cmd->payload_out[2] = ((tms_count_start & 0x0F) << 4) | (tms_count_end & 0x0F);
981 cmd->payload_out[3] = tms_sequence_start;
982 cmd->payload_out[4] = tms_sequence_end;
983
984 /* Setup payload_out for types with OUT transfer */
985 if (scan_type == SCAN_OUT || scan_type == SCAN_IO) {
986 for (i = 0; i < scan_size_bytes; i++)
987 cmd->payload_out[i + 5] = tdi[i];
988 }
989
990 /* Setup payload_in pointers for types with IN transfer */
991 if (scan_type == SCAN_IN || scan_type == SCAN_IO) {
992 cmd->payload_in_start = tdo_start;
993 cmd->payload_in = tdo;
994 cmd->payload_in_size = scan_size_bytes;
995 }
996
997 cmd->needs_postprocessing = postprocess;
998 cmd->cmd_origin = origin;
999
1000 /* For scan commands, we free payload_in_start only when the command is
1001 * the last in a series of split commands or a stand-alone command */
1002 cmd->free_payload_in_start = postprocess;
1003
1004 return angie_append_queue(device, cmd);
1005 }
1006
1007 /**
1008 * Perform TAP state transitions
1009 *
1010 * @param device pointer to struct angie identifying ANGIE driver instance.
1011 * @param count defines the number of TCK clock cycles generated (up to 8).
1012 * @param sequence defines the TMS pin levels for each state transition. The
1013 * Least-Significant Bit is read first.
1014 * @return on success: ERROR_OK
1015 * @return on failure: ERROR_FAIL
1016 */
1017 static int angie_append_clock_tms_cmd(struct angie *device, uint8_t count,
1018 uint8_t sequence)
1019 {
1020 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1021 int ret;
1022
1023 if (!cmd) {
1024 LOG_ERROR("Out of memory");
1025 return ERROR_FAIL;
1026 }
1027
1028 if (device->delay_clock_tms < 0)
1029 cmd->id = CMD_CLOCK_TMS;
1030 else
1031 cmd->id = CMD_SLOW_CLOCK_TMS;
1032
1033 /* CMD_CLOCK_TMS has two OUT payload bytes and zero IN payload bytes */
1034 ret = angie_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);
1035 if (ret != ERROR_OK) {
1036 free(cmd);
1037 return ret;
1038 }
1039
1040 cmd->payload_out[0] = count;
1041 cmd->payload_out[1] = sequence;
1042
1043 return angie_append_queue(device, cmd);
1044 }
1045
1046 /**
1047 * Generate a defined amount of TCK clock cycles
1048 *
1049 * All other JTAG signals are left unchanged.
1050 *
1051 * @param device pointer to struct angie identifying ANGIE driver instance.
1052 * @param count the number of TCK clock cycles to generate.
1053 * @return on success: ERROR_OK
1054 * @return on failure: ERROR_FAIL
1055 */
1056 static int angie_append_clock_tck_cmd(struct angie *device, uint16_t count)
1057 {
1058 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1059 int ret;
1060
1061 if (!cmd) {
1062 LOG_ERROR("Out of memory");
1063 return ERROR_FAIL;
1064 }
1065
1066 if (device->delay_clock_tck < 0)
1067 cmd->id = CMD_CLOCK_TCK;
1068 else
1069 cmd->id = CMD_SLOW_CLOCK_TCK;
1070
1071 /* CMD_CLOCK_TCK has two OUT payload bytes and zero IN payload bytes */
1072 ret = angie_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);
1073 if (ret != ERROR_OK) {
1074 free(cmd);
1075 return ret;
1076 }
1077
1078 cmd->payload_out[0] = count & 0xff;
1079 cmd->payload_out[1] = (count >> 8) & 0xff;
1080
1081 return angie_append_queue(device, cmd);
1082 }
1083
1084 /**
1085 * Read JTAG signals.
1086 *
1087 * @param device pointer to struct angie identifying ANGIE driver instance.
1088 * @return on success: ERROR_OK
1089 * @return on failure: ERROR_FAIL
1090 */
1091 static int angie_append_get_signals_cmd(struct angie *device)
1092 {
1093 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1094 int ret;
1095
1096 if (!cmd) {
1097 LOG_ERROR("Out of memory");
1098 return ERROR_FAIL;
1099 }
1100
1101 cmd->id = CMD_GET_SIGNALS;
1102 cmd->needs_postprocessing = true;
1103
1104 /* CMD_GET_SIGNALS has two IN payload bytes */
1105 ret = angie_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_IN);
1106
1107 if (ret != ERROR_OK) {
1108 free(cmd);
1109 return ret;
1110 }
1111
1112 return angie_append_queue(device, cmd);
1113 }
1114
1115 /**
1116 * Arbitrarily set JTAG output signals.
1117 *
1118 * @param device pointer to struct angie identifying ANGIE driver instance.
1119 * @param low defines which signals will be de-asserted. Each bit corresponds
1120 * to a JTAG signal:
1121 * - SIGNAL_TDI
1122 * - SIGNAL_TMS
1123 * - SIGNAL_TCK
1124 * - SIGNAL_TRST
1125 * - SIGNAL_BRKIN
1126 * - SIGNAL_RESET
1127 * - SIGNAL_OCDSE
1128 * @param high defines which signals will be asserted.
1129 * @return on success: ERROR_OK
1130 * @return on failure: ERROR_FAIL
1131 */
1132 static int angie_append_set_signals_cmd(struct angie *device, uint8_t low,
1133 uint8_t high)
1134 {
1135 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1136 int ret;
1137
1138 if (!cmd) {
1139 LOG_ERROR("Out of memory");
1140 return ERROR_FAIL;
1141 }
1142
1143 cmd->id = CMD_SET_SIGNALS;
1144
1145 /* CMD_SET_SIGNALS has two OUT payload bytes and zero IN payload bytes */
1146 ret = angie_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);
1147
1148 if (ret != ERROR_OK) {
1149 free(cmd);
1150 return ret;
1151 }
1152
1153 cmd->payload_out[0] = low;
1154 cmd->payload_out[1] = high;
1155
1156 return angie_append_queue(device, cmd);
1157 }
1158
1159 /**
1160 * Sleep for a pre-defined number of microseconds
1161 *
1162 * @param device pointer to struct angie identifying ANGIE driver instance.
1163 * @param us the number microseconds to sleep.
1164 * @return on success: ERROR_OK
1165 * @return on failure: ERROR_FAIL
1166 */
1167 static int angie_append_sleep_cmd(struct angie *device, uint32_t us)
1168 {
1169 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1170 int ret;
1171
1172 if (!cmd) {
1173 LOG_ERROR("Out of memory");
1174 return ERROR_FAIL;
1175 }
1176
1177 cmd->id = CMD_SLEEP_US;
1178
1179 /* CMD_SLEEP_US has two OUT payload bytes and zero IN payload bytes */
1180 ret = angie_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);
1181
1182 if (ret != ERROR_OK) {
1183 free(cmd);
1184 return ret;
1185 }
1186
1187 cmd->payload_out[0] = us & 0x00ff;
1188 cmd->payload_out[1] = (us >> 8) & 0x00ff;
1189
1190 return angie_append_queue(device, cmd);
1191 }
1192
1193 /**
1194 * Set TCK delay counters
1195 *
1196 * @param device pointer to struct angie identifying ANGIE driver instance.
1197 * @param delay_scan_in delay count top value in jtag_slow_scan_in() function.
1198 * @param delay_scan_out delay count top value in jtag_slow_scan_out() function.
1199 * @param delay_scan_io delay count top value in jtag_slow_scan_io() function.
1200 * @param delay_tck delay count top value in jtag_clock_tck() function.
1201 * @param delay_tms delay count top value in jtag_slow_clock_tms() function.
1202 * @return on success: ERROR_OK
1203 * @return on failure: ERROR_FAIL
1204 */
1205 static int angie_append_configure_tck_cmd(struct angie *device, int delay_scan_in,
1206 int delay_scan_out, int delay_scan_io, int delay_tck, int delay_tms)
1207 {
1208 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1209 int ret;
1210
1211 if (!cmd) {
1212 LOG_ERROR("Out of memory");
1213 return ERROR_FAIL;
1214 }
1215
1216 cmd->id = CMD_CONFIGURE_TCK_FREQ;
1217
1218 /* CMD_CONFIGURE_TCK_FREQ has five OUT payload bytes and zero
1219 * IN payload bytes */
1220 ret = angie_allocate_payload(cmd, 5, PAYLOAD_DIRECTION_OUT);
1221 if (ret != ERROR_OK) {
1222 free(cmd);
1223 return ret;
1224 }
1225
1226 if (delay_scan_in < 0)
1227 cmd->payload_out[0] = 0;
1228 else
1229 cmd->payload_out[0] = (uint8_t)delay_scan_in;
1230
1231 if (delay_scan_out < 0)
1232 cmd->payload_out[1] = 0;
1233 else
1234 cmd->payload_out[1] = (uint8_t)delay_scan_out;
1235
1236 if (delay_scan_io < 0)
1237 cmd->payload_out[2] = 0;
1238 else
1239 cmd->payload_out[2] = (uint8_t)delay_scan_io;
1240
1241 if (delay_tck < 0)
1242 cmd->payload_out[3] = 0;
1243 else
1244 cmd->payload_out[3] = (uint8_t)delay_tck;
1245
1246 if (delay_tms < 0)
1247 cmd->payload_out[4] = 0;
1248 else
1249 cmd->payload_out[4] = (uint8_t)delay_tms;
1250
1251 return angie_append_queue(device, cmd);
1252 }
1253
1254 /**
1255 * Test command. Used to check if the ANGIE device is ready to accept new
1256 * commands.
1257 *
1258 * @param device pointer to struct angie identifying ANGIE driver instance.
1259 * @return on success: ERROR_OK
1260 * @return on failure: ERROR_FAIL
1261 */
1262 static int angie_append_test_cmd(struct angie *device)
1263 {
1264 struct angie_cmd *cmd = calloc(1, sizeof(struct angie_cmd));
1265 int ret;
1266
1267 if (!cmd) {
1268 LOG_ERROR("Out of memory");
1269 return ERROR_FAIL;
1270 }
1271
1272 cmd->id = CMD_TEST;
1273
1274 /* CMD_TEST has one OUT payload byte and zero IN payload bytes */
1275 ret = angie_allocate_payload(cmd, 1, PAYLOAD_DIRECTION_OUT);
1276 if (ret != ERROR_OK) {
1277 free(cmd);
1278 return ret;
1279 }
1280
1281 cmd->payload_out[0] = 0xAA;
1282
1283 return angie_append_queue(device, cmd);
1284 }
1285
1286 /****************** ANGIE TCK frequency helper functions ******************/
1287
1288 /**
1289 * Calculate delay values for a given TCK frequency.
1290 *
1291 * The ANGIE firmware uses five different speed values for different
1292 * commands. These speed values are calculated in these functions.
1293 *
1294 * The five different commands which support variable TCK frequency are
1295 * implemented twice in the firmware:
1296 * 1. Maximum possible frequency without any artificial delay
1297 * 2. Variable frequency with artificial linear delay loop
1298 *
1299 * To set the ANGIE to maximum frequency, it is only necessary to use the
1300 * corresponding command IDs. To set the ANGIE to a lower frequency, the
1301 * delay loop top values have to be calculated first. Then, a
1302 * CMD_CONFIGURE_TCK_FREQ command needs to be sent to the ANGIE device.
1303 *
1304 * The delay values are described by linear equations:
1305 * t = k * x + d
1306 * (t = period, k = constant, x = delay value, d = constant)
1307 *
1308 * Thus, the delay can be calculated as in the following equation:
1309 * x = (t - d) / k
1310 *
1311 * The constants in these equations have been determined and validated by
1312 * measuring the frequency resulting from different delay values.
1313 *
1314 * @param type for which command to calculate the delay value.
1315 * @param f TCK frequency for which to calculate the delay value in Hz.
1316 * @param delay where to store resulting delay value.
1317 * @return on success: ERROR_OK
1318 * @return on failure: ERROR_FAIL
1319 */
1320 static int angie_calculate_delay(enum angie_delay_type type, long f, int *delay)
1321 {
1322 float t_us, x, x_ceil;
1323
1324 /* Calculate period of requested TCK frequency */
1325 t_us = 1000000.0 / f;
1326
1327 switch (type) {
1328 case DELAY_CLOCK_TCK:
1329 x = (t_us - 6.0) / 4;
1330 break;
1331 case DELAY_CLOCK_TMS:
1332 x = (t_us - 8.5) / 4;
1333 break;
1334 case DELAY_SCAN_IN:
1335 x = (t_us - 8.8308) / 4;
1336 break;
1337 case DELAY_SCAN_OUT:
1338 x = (t_us - 10.527) / 4;
1339 break;
1340 case DELAY_SCAN_IO:
1341 x = (t_us - 13.132) / 4;
1342 break;
1343 default:
1344 return ERROR_FAIL;
1345 break;
1346 }
1347
1348 /* Check if the delay value is negative. This happens when a frequency is
1349 * requested that is too high for the delay loop implementation. In this
1350 * case, set delay value to zero. */
1351 if (x < 0)
1352 x = 0;
1353
1354 /* We need to convert the exact delay value to an integer. Therefore, we
1355 * round the exact value UP to ensure that the resulting frequency is NOT
1356 * higher than the requested frequency. */
1357 x_ceil = ceilf(x);
1358
1359 /* Check if the value is within limits */
1360 if (x_ceil > 255)
1361 return ERROR_FAIL;
1362
1363 *delay = (int)x_ceil;
1364
1365 return ERROR_OK;
1366 }
1367
1368 /**
1369 * Calculate frequency for a given delay value.
1370 *
1371 * Similar to the #angie_calculate_delay function, this function calculates the
1372 * TCK frequency for a given delay value by using linear equations of the form:
1373 * t = k * x + d
1374 * (t = period, k = constant, x = delay value, d = constant)
1375 *
1376 * @param type for which command to calculate the delay value.
1377 * @param delay value for which to calculate the resulting TCK frequency.
1378 * @return the resulting TCK frequency
1379 */
1380 static long angie_calculate_frequency(enum angie_delay_type type, int delay)
1381 {
1382 float t_us, f_float;
1383
1384 if (delay > 255)
1385 return 0;
1386
1387 switch (type) {
1388 case DELAY_CLOCK_TCK:
1389 if (delay < 0)
1390 t_us = 2.666;
1391 else
1392 t_us = (4.0 * delay) + 6.0;
1393 break;
1394 case DELAY_CLOCK_TMS:
1395 if (delay < 0)
1396 t_us = 5.666;
1397 else
1398 t_us = (4.0 * delay) + 8.5;
1399 break;
1400 case DELAY_SCAN_IN:
1401 if (delay < 0)
1402 t_us = 5.5;
1403 else
1404 t_us = (4.0 * delay) + 8.8308;
1405 break;
1406 case DELAY_SCAN_OUT:
1407 if (delay < 0)
1408 t_us = 7.0;
1409 else
1410 t_us = (4.0 * delay) + 10.527;
1411 break;
1412 case DELAY_SCAN_IO:
1413 if (delay < 0)
1414 t_us = 9.926;
1415 else
1416 t_us = (4.0 * delay) + 13.132;
1417 break;
1418 default:
1419 return 0;
1420 }
1421
1422 f_float = 1000000.0 / t_us;
1423 return roundf(f_float);
1424 }
1425
1426 /******************* Interface between ANGIE and OpenOCD ******************/
1427
1428 /**
1429 * Sets the end state follower (see interface.h) if \a endstate is a stable
1430 * state.
1431 *
1432 * @param endstate the state the end state follower should be set to.
1433 */
1434 static void angie_set_end_state(tap_state_t endstate)
1435 {
1436 if (tap_is_state_stable(endstate))
1437 tap_set_end_state(endstate);
1438 else
1439 LOG_ERROR("BUG: %s is not a valid end state", tap_state_name(endstate));
1440 }
1441
1442 /**
1443 * Move from the current TAP state to the current TAP end state.
1444 *
1445 * @param device pointer to struct angie identifying ANGIE driver instance.
1446 * @return on success: ERROR_OK
1447 * @return on failure: ERROR_FAIL
1448 */
1449 static int angie_queue_statemove(struct angie *device)
1450 {
1451 uint8_t tms_sequence, tms_count;
1452 int ret;
1453
1454 if (tap_get_state() == tap_get_end_state()) {
1455 /* Do nothing if we are already there */
1456 return ERROR_OK;
1457 }
1458
1459 tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());
1460 tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
1461
1462 ret = angie_append_clock_tms_cmd(device, tms_count, tms_sequence);
1463
1464 if (ret == ERROR_OK)
1465 tap_set_state(tap_get_end_state());
1466
1467 return ret;
1468 }
1469
1470 /**
1471 * Perform a scan operation on a JTAG register.
1472 *
1473 * @param device pointer to struct angie identifying ANGIE driver instance.
1474 * @param cmd pointer to the command that shall be executed.
1475 * @return on success: ERROR_OK
1476 * @return on failure: ERROR_FAIL
1477 */
1478 static int angie_queue_scan(struct angie *device, struct jtag_command *cmd)
1479 {
1480 uint32_t scan_size_bits, scan_size_bytes, bits_last_scan;
1481 uint32_t scans_max_payload, bytecount;
1482 uint8_t *tdi_buffer_start = NULL, *tdi_buffer = NULL;
1483 uint8_t *tdo_buffer_start = NULL, *tdo_buffer = NULL;
1484
1485 uint8_t first_tms_count, first_tms_sequence;
1486 uint8_t last_tms_count, last_tms_sequence;
1487
1488 uint8_t tms_count_pause, tms_sequence_pause;
1489 uint8_t tms_count_resume, tms_sequence_resume;
1490
1491 uint8_t tms_count_start, tms_sequence_start;
1492 uint8_t tms_count_end, tms_sequence_end;
1493
1494 enum scan_type type;
1495 int ret;
1496
1497 /* Determine scan size */
1498 scan_size_bits = jtag_scan_size(cmd->cmd.scan);
1499 scan_size_bytes = DIV_ROUND_UP(scan_size_bits, 8);
1500
1501 /* Determine scan type (IN/OUT/IO) */
1502 type = jtag_scan_type(cmd->cmd.scan);
1503
1504 /* Determine number of scan commands with maximum payload */
1505 scans_max_payload = scan_size_bytes / 58;
1506
1507 /* Determine size of last shift command */
1508 bits_last_scan = scan_size_bits - (scans_max_payload * 58 * 8);
1509
1510 /* Allocate TDO buffer if required */
1511 if (type == SCAN_IN || type == SCAN_IO) {
1512 tdo_buffer_start = calloc(sizeof(uint8_t), scan_size_bytes);
1513
1514 if (!tdo_buffer_start)
1515 return ERROR_FAIL;
1516
1517 tdo_buffer = tdo_buffer_start;
1518 }
1519
1520 /* Fill TDI buffer if required */
1521 if (type == SCAN_OUT || type == SCAN_IO) {
1522 jtag_build_buffer(cmd->cmd.scan, &tdi_buffer_start);
1523 tdi_buffer = tdi_buffer_start;
1524 }
1525
1526 /* Get TAP state transitions */
1527 if (cmd->cmd.scan->ir_scan) {
1528 angie_set_end_state(TAP_IRSHIFT);
1529 first_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
1530 first_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());
1531
1532 tap_set_state(TAP_IRSHIFT);
1533 tap_set_end_state(cmd->cmd.scan->end_state);
1534 last_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
1535 last_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());
1536
1537 /* TAP state transitions for split scans */
1538 tms_count_pause = tap_get_tms_path_len(TAP_IRSHIFT, TAP_IRPAUSE);
1539 tms_sequence_pause = tap_get_tms_path(TAP_IRSHIFT, TAP_IRPAUSE);
1540 tms_count_resume = tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRSHIFT);
1541 tms_sequence_resume = tap_get_tms_path(TAP_IRPAUSE, TAP_IRSHIFT);
1542 } else {
1543 angie_set_end_state(TAP_DRSHIFT);
1544 first_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
1545 first_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());
1546
1547 tap_set_state(TAP_DRSHIFT);
1548 tap_set_end_state(cmd->cmd.scan->end_state);
1549 last_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
1550 last_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());
1551
1552 /* TAP state transitions for split scans */
1553 tms_count_pause = tap_get_tms_path_len(TAP_DRSHIFT, TAP_DRPAUSE);
1554 tms_sequence_pause = tap_get_tms_path(TAP_DRSHIFT, TAP_DRPAUSE);
1555 tms_count_resume = tap_get_tms_path_len(TAP_DRPAUSE, TAP_DRSHIFT);
1556 tms_sequence_resume = tap_get_tms_path(TAP_DRPAUSE, TAP_DRSHIFT);
1557 }
1558
1559 /* Generate scan commands */
1560 bytecount = scan_size_bytes;
1561 while (bytecount > 0) {
1562 if (bytecount == scan_size_bytes) {
1563 /* This is the first scan */
1564 tms_count_start = first_tms_count;
1565 tms_sequence_start = first_tms_sequence;
1566 } else {
1567 /* Resume from previous scan */
1568 tms_count_start = tms_count_resume;
1569 tms_sequence_start = tms_sequence_resume;
1570 }
1571
1572 if (bytecount > 58) { /* Full scan, at least one scan will follow */
1573 tms_count_end = tms_count_pause;
1574 tms_sequence_end = tms_sequence_pause;
1575
1576 ret = angie_append_scan_cmd(device,
1577 type,
1578 58 * 8,
1579 tdi_buffer,
1580 tdo_buffer_start,
1581 tdo_buffer,
1582 tms_count_start,
1583 tms_sequence_start,
1584 tms_count_end,
1585 tms_sequence_end,
1586 cmd,
1587 false);
1588
1589 bytecount -= 58;
1590
1591 /* Update TDI and TDO buffer pointers */
1592 if (tdi_buffer_start)
1593 tdi_buffer += 58;
1594 if (tdo_buffer_start)
1595 tdo_buffer += 58;
1596 } else if (bytecount == 58) { /* Full scan, no further scans */
1597 tms_count_end = last_tms_count;
1598 tms_sequence_end = last_tms_sequence;
1599
1600 ret = angie_append_scan_cmd(device,
1601 type,
1602 58 * 8,
1603 tdi_buffer,
1604 tdo_buffer_start,
1605 tdo_buffer,
1606 tms_count_start,
1607 tms_sequence_start,
1608 tms_count_end,
1609 tms_sequence_end,
1610 cmd,
1611 true);
1612
1613 bytecount = 0;
1614 } else {/* Scan with less than maximum payload, no further scans */
1615 tms_count_end = last_tms_count;
1616 tms_sequence_end = last_tms_sequence;
1617
1618 ret = angie_append_scan_cmd(device,
1619 type,
1620 bits_last_scan,
1621 tdi_buffer,
1622 tdo_buffer_start,
1623 tdo_buffer,
1624 tms_count_start,
1625 tms_sequence_start,
1626 tms_count_end,
1627 tms_sequence_end,
1628 cmd,
1629 true);
1630
1631 bytecount = 0;
1632 }
1633
1634 if (ret != ERROR_OK) {
1635 free(tdi_buffer_start);
1636 free(tdo_buffer_start);
1637 return ret;
1638 }
1639 }
1640
1641 free(tdi_buffer_start);
1642
1643 /* Set current state to the end state requested by the command */
1644 tap_set_state(cmd->cmd.scan->end_state);
1645
1646 return ERROR_OK;
1647 }
1648
1649 /**
1650 * Move the TAP into the Test Logic Reset state.
1651 *
1652 * @param device pointer to struct angie identifying ANGIE driver instance.
1653 * @param cmd pointer to the command that shall be executed.
1654 * @return on success: ERROR_OK
1655 * @return on failure: ERROR_FAIL
1656 */
1657 static int angie_queue_tlr_reset(struct angie *device, struct jtag_command *cmd)
1658 {
1659 int ret = angie_append_clock_tms_cmd(device, 5, 0xff);
1660
1661 if (ret == ERROR_OK)
1662 tap_set_state(TAP_RESET);
1663
1664 return ret;
1665 }
1666
1667 /**
1668 * Run Test.
1669 *
1670 * Generate TCK clock cycles while remaining
1671 * in the Run-Test/Idle state.
1672 *
1673 * @param device pointer to struct angie identifying ANGIE driver instance.
1674 * @param cmd pointer to the command that shall be executed.
1675 * @return on success: ERROR_OK
1676 * @return on failure: ERROR_FAIL
1677 */
1678 static int angie_queue_runtest(struct angie *device, struct jtag_command *cmd)
1679 {
1680 int ret;
1681
1682 /* Only perform statemove if the TAP currently isn't in the TAP_IDLE state */
1683 if (tap_get_state() != TAP_IDLE) {
1684 angie_set_end_state(TAP_IDLE);
1685 angie_queue_statemove(device);
1686 }
1687
1688 /* Generate the clock cycles */
1689 ret = angie_append_clock_tck_cmd(device, cmd->cmd.runtest->num_cycles);
1690 if (ret != ERROR_OK)
1691 return ret;
1692
1693 /* Move to end state specified in command */
1694 if (cmd->cmd.runtest->end_state != tap_get_state()) {
1695 tap_set_end_state(cmd->cmd.runtest->end_state);
1696 angie_queue_statemove(device);
1697 }
1698
1699 return ERROR_OK;
1700 }
1701
1702 /**
1703 * Execute a JTAG_RESET command
1704 *
1705 * @param device
1706 * @param trst indicate if trst signal is activated.
1707 * @param srst indicate if srst signal is activated.
1708 * @return on success: ERROR_OK
1709 * @return on failure: ERROR_FAIL
1710 */
1711 static int angie_reset(int trst, int srst)
1712 {
1713 struct angie *device = angie_handle;
1714 uint8_t low = 0, high = 0;
1715
1716 if (trst) {
1717 tap_set_state(TAP_RESET);
1718 low |= SIGNAL_TRST;
1719 } else {
1720 high |= SIGNAL_TRST;
1721 }
1722
1723 if (srst)
1724 low |= SIGNAL_SRST;
1725 else
1726 high |= SIGNAL_SRST;
1727
1728 int ret = angie_append_set_signals_cmd(device, low, high);
1729 if (ret != ERROR_OK)
1730 return ret;
1731
1732 ret = angie_execute_queued_commands(device, LIBUSB_TIMEOUT_MS);
1733 if (ret != ERROR_OK)
1734 return ret;
1735
1736 angie_clear_queue(device);
1737
1738 return ERROR_OK;
1739 }
1740
1741 /**
1742 * Move to one TAP state or several states in succession.
1743 *
1744 * @param device pointer to struct angie identifying ANGIE driver instance.
1745 * @param cmd pointer to the command that shall be executed.
1746 * @return on success: ERROR_OK
1747 * @return on failure: ERROR_FAIL
1748 */
1749 static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd)
1750 {
1751 int ret, i, num_states, batch_size, state_count;
1752 tap_state_t *path;
1753 uint8_t tms_sequence;
1754
1755 num_states = cmd->cmd.pathmove->num_states;
1756 path = cmd->cmd.pathmove->path;
1757 state_count = 0;
1758
1759 while (num_states > 0) {
1760 tms_sequence = 0;
1761
1762 /* Determine batch size */
1763 if (num_states >= 8)
1764 batch_size = 8;
1765 else
1766 batch_size = num_states;
1767
1768 for (i = 0; i < batch_size; i++) {
1769 if (tap_state_transition(tap_get_state(), false) == path[state_count]) {
1770 /* Append '0' transition: clear bit 'i' in tms_sequence */
1771 buf_set_u32(&tms_sequence, i, 1, 0x0);
1772 } else if (tap_state_transition(tap_get_state(), true)
1773 == path[state_count]) {
1774 /* Append '1' transition: set bit 'i' in tms_sequence */
1775 buf_set_u32(&tms_sequence, i, 1, 0x1);
1776 } else {
1777 /* Invalid state transition */
1778 LOG_ERROR("BUG: %s -> %s isn't a valid TAP state transition",
1779 tap_state_name(tap_get_state()),
1780 tap_state_name(path[state_count]));
1781 return ERROR_FAIL;
1782 }
1783
1784 tap_set_state(path[state_count]);
1785 state_count++;
1786 num_states--;
1787 }
1788
1789 /* Append CLOCK_TMS command to ANGIE command queue */
1790 LOG_INFO("pathmove batch: count = %i, sequence = 0x%" PRIx8 "", batch_size, tms_sequence);
1791 ret = angie_append_clock_tms_cmd(angie_handle, batch_size, tms_sequence);
1792 if (ret != ERROR_OK)
1793 return ret;
1794 }
1795
1796 return ERROR_OK;
1797 }
1798
1799 /**
1800 * Sleep for a specific amount of time.
1801 *
1802 * @param device pointer to struct angie identifying ANGIE driver instance.
1803 * @param cmd pointer to the command that shall be executed.
1804 * @return on success: ERROR_OK
1805 * @return on failure: ERROR_FAIL
1806 */
1807 static int angie_queue_sleep(struct angie *device, struct jtag_command *cmd)
1808 {
1809 /* IMPORTANT! Due to the time offset in command execution introduced by
1810 * command queueing, this needs to be implemented in the ANGIE device */
1811 return angie_append_sleep_cmd(device, cmd->cmd.sleep->us);
1812 }
1813
1814 /**
1815 * Generate TCK cycles while remaining in a stable state.
1816 *
1817 * @param device pointer to struct angie identifying ANGIE driver instance.
1818 * @param cmd pointer to the command that shall be executed.
1819 */
1820 static int angie_queue_stableclocks(struct angie *device, struct jtag_command *cmd)
1821 {
1822 int ret;
1823 unsigned int num_cycles;
1824
1825 if (!tap_is_state_stable(tap_get_state())) {
1826 LOG_ERROR("JTAG_STABLECLOCKS: state not stable");
1827 return ERROR_FAIL;
1828 }
1829
1830 num_cycles = cmd->cmd.stableclocks->num_cycles;
1831
1832 /* TMS stays either high (Test Logic Reset state) or low (all other states) */
1833 if (tap_get_state() == TAP_RESET)
1834 ret = angie_append_set_signals_cmd(device, 0, SIGNAL_TMS);
1835 else
1836 ret = angie_append_set_signals_cmd(device, SIGNAL_TMS, 0);
1837
1838 if (ret != ERROR_OK)
1839 return ret;
1840
1841 while (num_cycles > 0) {
1842 if (num_cycles > 0xFFFF) {
1843 /* ANGIE CMD_CLOCK_TCK can generate up to 0xFFFF (uint16_t) cycles */
1844 ret = angie_append_clock_tck_cmd(device, 0xFFFF);
1845 num_cycles -= 0xFFFF;
1846 } else {
1847 ret = angie_append_clock_tck_cmd(device, num_cycles);
1848 num_cycles = 0;
1849 }
1850
1851 if (ret != ERROR_OK)
1852 return ret;
1853 }
1854
1855 return ERROR_OK;
1856 }
1857
1858 /**
1859 * Post-process JTAG_SCAN command
1860 *
1861 * @param angie_cmd pointer to ANGIE command that shall be processed.
1862 * @return on success: ERROR_OK
1863 * @return on failure: ERROR_FAIL
1864 */
1865 static int angie_post_process_scan(struct angie_cmd *angie_cmd)
1866 {
1867 struct jtag_command *cmd = angie_cmd->cmd_origin;
1868 int ret;
1869
1870 switch (jtag_scan_type(cmd->cmd.scan)) {
1871 case SCAN_IN:
1872 case SCAN_IO:
1873 ret = jtag_read_buffer(angie_cmd->payload_in_start, cmd->cmd.scan);
1874 break;
1875 case SCAN_OUT:
1876 /* Nothing to do for OUT scans */
1877 ret = ERROR_OK;
1878 break;
1879 default:
1880 LOG_ERROR("BUG: angie post process scan encountered an unknown JTAG scan type");
1881 ret = ERROR_FAIL;
1882 break;
1883 }
1884
1885 return ret;
1886 }
1887
1888 /**
1889 * Perform post-processing of commands after ANGIE queue has been executed.
1890 *
1891 * @param device pointer to struct angie identifying ANGIE driver instance.
1892 * @return on success: ERROR_OK
1893 * @return on failure: ERROR_FAIL
1894 */
1895 static int angie_post_process_queue(struct angie *device)
1896 {
1897 struct angie_cmd *current;
1898 struct jtag_command *openocd_cmd;
1899 int ret;
1900
1901 current = device->queue_start;
1902
1903 while (current) {
1904 openocd_cmd = current->cmd_origin;
1905
1906 /* Check if a corresponding OpenOCD command is stored for this
1907 * ANGIE command */
1908 if (current->needs_postprocessing && openocd_cmd) {
1909 switch (openocd_cmd->type) {
1910 case JTAG_SCAN:
1911 ret = angie_post_process_scan(current);
1912 break;
1913 case JTAG_TLR_RESET:
1914 case JTAG_RUNTEST:
1915 case JTAG_PATHMOVE:
1916 case JTAG_SLEEP:
1917 case JTAG_STABLECLOCKS:
1918 /* Nothing to do for these commands */
1919 ret = ERROR_OK;
1920 break;
1921 default:
1922 ret = ERROR_FAIL;
1923 LOG_ERROR("BUG: angie post process queue encountered unknown JTAG "
1924 "command type");
1925 break;
1926 }
1927
1928 if (ret != ERROR_OK)
1929 return ret;
1930 }
1931
1932 current = current->next;
1933 }
1934
1935 return ERROR_OK;
1936 }
1937
1938 /**************************** JTAG driver functions ***************************/
1939
1940 /**
1941 * Executes the JTAG Command Queue.
1942 *
1943 * This is done in three stages: First, all OpenOCD commands are processed into
1944 * queued ANGIE commands. Next, the ANGIE command queue is sent to the
1945 * ANGIE device and data received from the ANGIE device is cached. Finally,
1946 * the post-processing function writes back data to the corresponding OpenOCD
1947 * commands.
1948 *
1949 * @return on success: ERROR_OK
1950 * @return on failure: ERROR_FAIL
1951 */
1952 static int angie_execute_queue(void)
1953 {
1954 struct jtag_command *cmd = jtag_command_queue;
1955 int ret;
1956
1957 while (cmd) {
1958 switch (cmd->type) {
1959 case JTAG_SCAN:
1960 ret = angie_queue_scan(angie_handle, cmd);
1961 break;
1962 case JTAG_TLR_RESET:
1963 ret = angie_queue_tlr_reset(angie_handle, cmd);
1964 break;
1965 case JTAG_RUNTEST:
1966 ret = angie_queue_runtest(angie_handle, cmd);
1967 break;
1968 case JTAG_PATHMOVE:
1969 ret = angie_queue_pathmove(angie_handle, cmd);
1970 break;
1971 case JTAG_SLEEP:
1972 ret = angie_queue_sleep(angie_handle, cmd);
1973 break;
1974 case JTAG_STABLECLOCKS:
1975 ret = angie_queue_stableclocks(angie_handle, cmd);
1976 break;
1977 default:
1978 ret = ERROR_FAIL;
1979 LOG_ERROR("BUG: encountered unknown JTAG command type");
1980 break;
1981 }
1982
1983 if (ret != ERROR_OK)
1984 return ret;
1985
1986 cmd = cmd->next;
1987 }
1988
1989 if (angie_handle->commands_in_queue > 0) {
1990 ret = angie_execute_queued_commands(angie_handle, LIBUSB_TIMEOUT_MS);
1991 if (ret != ERROR_OK)
1992 return ret;
1993
1994 ret = angie_post_process_queue(angie_handle);
1995 if (ret != ERROR_OK)
1996 return ret;
1997
1998 angie_clear_queue(angie_handle);
1999 }
2000
2001 return ERROR_OK;
2002 }
2003
2004 /**
2005 * Set the TCK frequency of the ANGIE adapter.
2006 *
2007 * @param khz desired JTAG TCK frequency.
2008 * @param jtag_speed where to store corresponding adapter-specific speed value.
2009 * @return on success: ERROR_OK
2010 * @return on failure: ERROR_FAIL
2011 */
2012 static int angie_khz(int khz, int *jtag_speed)
2013 {
2014 int ret;
2015
2016 if (khz == 0) {
2017 LOG_ERROR("RCLK not supported");
2018 return ERROR_FAIL;
2019 }
2020
2021 /* CLOCK_TCK commands are decoupled from others. Therefore, the frequency
2022 * setting can be done independently from all other commands. */
2023 if (khz >= 375) {
2024 angie_handle->delay_clock_tck = -1;
2025 } else {
2026 ret = angie_calculate_delay(DELAY_CLOCK_TCK, khz * 1000,
2027 &angie_handle->delay_clock_tck);
2028 if (ret != ERROR_OK)
2029 return ret;
2030 }
2031
2032 /* SCAN_{IN,OUT,IO} commands invoke CLOCK_TMS commands. Therefore, if the
2033 * requested frequency goes below the maximum frequency for SLOW_CLOCK_TMS
2034 * commands, all SCAN commands MUST also use the variable frequency
2035 * implementation! */
2036 if (khz >= 176) {
2037 angie_handle->delay_clock_tms = -1;
2038 angie_handle->delay_scan_in = -1;
2039 angie_handle->delay_scan_out = -1;
2040 angie_handle->delay_scan_io = -1;
2041 } else {
2042 ret = angie_calculate_delay(DELAY_CLOCK_TMS, khz * 1000,
2043 &angie_handle->delay_clock_tms);
2044 if (ret != ERROR_OK)
2045 return ret;
2046
2047 ret = angie_calculate_delay(DELAY_SCAN_IN, khz * 1000,
2048 &angie_handle->delay_scan_in);
2049 if (ret != ERROR_OK)
2050 return ret;
2051
2052 ret = angie_calculate_delay(DELAY_SCAN_OUT, khz * 1000,
2053 &angie_handle->delay_scan_out);
2054 if (ret != ERROR_OK)
2055 return ret;
2056
2057 ret = angie_calculate_delay(DELAY_SCAN_IO, khz * 1000,
2058 &angie_handle->delay_scan_io);
2059 if (ret != ERROR_OK)
2060 return ret;
2061 }
2062
2063 LOG_DEBUG_IO("ANGIE TCK setup: delay_tck = %i (%li Hz),",
2064 angie_handle->delay_clock_tck,
2065 angie_calculate_frequency(DELAY_CLOCK_TCK, angie_handle->delay_clock_tck));
2066 LOG_DEBUG_IO(" delay_tms = %i (%li Hz),",
2067 angie_handle->delay_clock_tms,
2068 angie_calculate_frequency(DELAY_CLOCK_TMS, angie_handle->delay_clock_tms));
2069 LOG_DEBUG_IO(" delay_scan_in = %i (%li Hz),",
2070 angie_handle->delay_scan_in,
2071 angie_calculate_frequency(DELAY_SCAN_IN, angie_handle->delay_scan_in));
2072 LOG_DEBUG_IO(" delay_scan_out = %i (%li Hz),",
2073 angie_handle->delay_scan_out,
2074 angie_calculate_frequency(DELAY_SCAN_OUT, angie_handle->delay_scan_out));
2075 LOG_DEBUG_IO(" delay_scan_io = %i (%li Hz),",
2076 angie_handle->delay_scan_io,
2077 angie_calculate_frequency(DELAY_SCAN_IO, angie_handle->delay_scan_io));
2078
2079 /* Configure the ANGIE device with the new delay values */
2080 ret = angie_append_configure_tck_cmd(angie_handle,
2081 angie_handle->delay_scan_in,
2082 angie_handle->delay_scan_out,
2083 angie_handle->delay_scan_io,
2084 angie_handle->delay_clock_tck,
2085 angie_handle->delay_clock_tms);
2086
2087 if (ret != ERROR_OK)
2088 return ret;
2089
2090 *jtag_speed = khz;
2091
2092 return ERROR_OK;
2093 }
2094
2095 /**
2096 * Set the TCK frequency of the ANGIE adapter.
2097 *
2098 * Because of the way the TCK frequency is set up in the ANGIE firmware,
2099 * there are five different speed settings. To simplify things, the
2100 * adapter-specific speed setting value is identical to the TCK frequency in
2101 * khz.
2102 *
2103 * @param speed desired adapter-specific speed value.
2104 * @return on success: ERROR_OK
2105 * @return on failure: ERROR_FAIL
2106 */
2107 static int angie_speed(int speed)
2108 {
2109 int dummy;
2110
2111 return angie_khz(speed, &dummy);
2112 }
2113
2114 /**
2115 * Convert adapter-specific speed value to corresponding TCK frequency in kHz.
2116 *
2117 * Because of the way the TCK frequency is set up in the ANGIE firmware,
2118 * there are five different speed settings. To simplify things, the
2119 * adapter-specific speed setting value is identical to the TCK frequency in
2120 * khz.
2121 *
2122 * @param speed adapter-specific speed value.
2123 * @param khz where to store corresponding TCK frequency in kHz.
2124 * @return on success: ERROR_OK
2125 * @return on failure: ERROR_FAIL
2126 */
2127 static int angie_speed_div(int speed, int *khz)
2128 {
2129 *khz = speed;
2130
2131 return ERROR_OK;
2132 }
2133
2134 /**
2135 * Initiates the firmware download to the ANGIE adapter and prepares
2136 * the USB handle.
2137 *
2138 * @return on success: ERROR_OK
2139 * @return on failure: ERROR_FAIL
2140 */
2141 static int angie_init(void)
2142 {
2143 int ret, transferred;
2144 char str_manufacturer[20];
2145 bool download_firmware = false;
2146 char dummy[64];
2147 uint8_t input_signals, output_signals;
2148
2149 angie_handle = calloc(1, sizeof(struct angie));
2150
2151 if (!angie_handle) {
2152 LOG_ERROR("Out of memory");
2153 return ERROR_FAIL;
2154 }
2155
2156 ret = angie_usb_open(angie_handle);
2157 if (ret != ERROR_OK) {
2158 LOG_ERROR("Could not open ANGIE device");
2159 free(angie_handle);
2160 angie_handle = NULL;
2161 return ret;
2162 }
2163
2164 /* Get String Descriptor to determine if firmware needs to be loaded */
2165 ret = libusb_get_string_descriptor_ascii(angie_handle->usb_device_handle, 1, (unsigned char *)str_manufacturer, 20);
2166 if (ret < 0) {
2167 /* Could not get descriptor -> Unconfigured or original Keil firmware */
2168 download_firmware = true;
2169 } else {
2170 /* We got a String Descriptor, check if it is the correct one */
2171 if (strncmp(str_manufacturer, "NanoXplore, SAS.", 16) != 0)
2172 download_firmware = true;
2173 }
2174
2175 if (download_firmware) {
2176 LOG_INFO("Loading ANGIE firmware. This is reversible by power-cycling ANGIE device.");
2177
2178 if (libusb_claim_interface(angie_handle->usb_device_handle, 0) != ERROR_OK)
2179 LOG_ERROR("Could not claim interface");
2180
2181 ret = angie_load_firmware_and_renumerate(angie_handle,
2182 ANGIE_FIRMWARE_FILE, ANGIE_RENUMERATION_DELAY_US);
2183 if (ret != ERROR_OK) {
2184 LOG_ERROR("Could not download firmware and re-numerate ANGIE");
2185 angie_quit();
2186 return ret;
2187 }
2188 ret = angie_load_bitstream(angie_handle, ANGIE_BITSTREAM_FILE);
2189 if (ret != ERROR_OK) {
2190 LOG_ERROR("Could not download bitstream");
2191 angie_quit();
2192 return ret;
2193 }
2194 } else {
2195 LOG_INFO("ANGIE device is already running ANGIE firmware");
2196 }
2197
2198 /* Get ANGIE USB IN/OUT endpoints and claim the interface */
2199 ret = jtag_libusb_choose_interface(angie_handle->usb_device_handle,
2200 &angie_handle->ep_in, &angie_handle->ep_out, -1, -1, -1, -1);
2201 if (ret != ERROR_OK) {
2202 angie_quit();
2203 return ret;
2204 }
2205
2206 /* Initialize ANGIE command queue */
2207 angie_clear_queue(angie_handle);
2208
2209 /* Issue one test command with short timeout */
2210 ret = angie_append_test_cmd(angie_handle);
2211 if (ret != ERROR_OK) {
2212 angie_quit();
2213 return ret;
2214 }
2215
2216 ret = angie_execute_queued_commands(angie_handle, 200);
2217 if (ret != ERROR_OK) {
2218 /* Sending test command failed. The ANGIE device may be forever waiting for
2219 * the host to fetch an USB Bulk IN packet (e. g. OpenOCD crashed or was
2220 * shut down by the user via Ctrl-C. Try to retrieve this Bulk IN packet. */
2221
2222 ret = jtag_libusb_bulk_write(angie_handle->usb_device_handle, angie_handle->ep_in,
2223 dummy, 64, 200, &transferred);
2224
2225 if (ret != ERROR_OK || transferred == 0) {
2226 /* Bulk IN transfer failed -> unrecoverable error condition */
2227 LOG_ERROR("Cannot communicate with ANGIE device. Disconnect ANGIE from "
2228 "the USB port and re-connect, then re-run OpenOCD");
2229 angie_quit();
2230 return ERROR_FAIL;
2231 }
2232 /* Successfully received Bulk IN packet -> continue */
2233 LOG_INFO("Recovered from lost Bulk IN packet");
2234 }
2235
2236 angie_clear_queue(angie_handle);
2237
2238 ret = angie_append_get_signals_cmd(angie_handle);
2239 if (ret != ERROR_OK) {
2240 angie_quit();
2241 return ret;
2242 }
2243
2244 ret = angie_execute_queued_commands(angie_handle, 200);
2245 if (ret != ERROR_OK) {
2246 angie_quit();
2247 return ret;
2248 }
2249
2250 /* Post-process the single CMD_GET_SIGNALS command */
2251 input_signals = angie_handle->queue_start->payload_in[0];
2252 output_signals = angie_handle->queue_start->payload_in[1];
2253 angie_dump_signal_states(input_signals, output_signals);
2254
2255 angie_clear_queue(angie_handle);
2256
2257 return ERROR_OK;
2258 }
2259
2260 /**
2261 * Closes the USB handle for the ANGIE device.
2262 *
2263 * @return on success: ERROR_OK
2264 * @return on failure: ERROR_FAIL
2265 */
2266 static int angie_quit(void)
2267 {
2268 int ret = angie_usb_close(angie_handle);
2269 free(angie_handle);
2270 angie_handle = NULL;
2271
2272 return ret;
2273 }
2274
2275 static struct jtag_interface angie_interface = {
2276 .execute_queue = angie_execute_queue,
2277 };
2278
2279 struct adapter_driver angie_adapter_driver = {
2280 .name = "angie",
2281 .transports = jtag_only,
2282
2283 .init = angie_init,
2284 .quit = angie_quit,
2285 .reset = angie_reset,
2286 .speed = angie_speed,
2287 .khz = angie_khz,
2288 .speed_div = angie_speed_div,
2289
2290 .jtag_ops = &angie_interface,
2291 };

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)