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

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)