1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /***************************************************************************
4 Contents : OpenOCD driver code for NanoXplore USB-JTAG ANGIE *
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 ***************************************************************************/
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>
25 #include "libusb_helper.h"
26 #include "angie/include/msgtypes.h"
28 /** USB Vendor ID of ANGIE device in unconfigured state (no firmware loaded
29 * yet) or with its firmware. */
30 #define ANGIE_VID 0x584e
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
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
44 /** USB Control EP0 bRequest: "Firmware Load". */
45 #define REQUEST_FIRMWARE_LOAD 0xA0
47 /** Value to write into CPUCS to put EZ-USB ANGIE into reset. */
48 #define CPU_RESET 0x01
50 /** Value to write into CPUCS to put EZ-USB ANGIE out of reset. */
51 #define CPU_START 0x00
53 /** Base address of firmware in EZ-USB ANGIE code space. */
54 #define FIRMWARE_ADDR 0x0000
56 /** USB interface number */
57 #define USB_INTERFACE 0
59 /** Delay (in microseconds) to wait while EZ-USB performs ReNumeration. */
60 #define ANGIE_RENUMERATION_DELAY_US 1500000
62 /** Default location of ANGIE firmware image. */
63 #define ANGIE_FIRMWARE_FILE PKGDATADIR "/angie/angie_firmware.bin"
65 /** Default location of ANGIE firmware image. */
66 #define ANGIE_BITSTREAM_FILE PKGDATADIR "/angie/angie_bitstream.bit"
68 /** Maximum size of a single firmware section. Entire EZ-USB ANGIE code space = 16kB */
69 #define SECTION_BUFFERSIZE 16384
71 /** Tuning of OpenOCD SCAN commands split into multiple ANGIE commands. */
72 #define SPLIT_SCAN_THRESHOLD 10
74 /** ANGIE hardware type */
79 enum angie_payload_direction
{
80 PAYLOAD_DIRECTION_OUT
,
84 enum angie_delay_type
{
93 * ANGIE command (ANGIE command queue element).
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().
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
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
112 * The last command sets #needs_postprocessing to true.
115 uint8_t id
; /**< ANGIE command ID */
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 */
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 */
124 /** Indicates if this command needs post-processing */
125 bool needs_postprocessing
;
127 /** Indicates if angie_clear_queue() should free payload_in_start */
128 bool free_payload_in_start
;
130 /** Pointer to corresponding OpenOCD command for post-processing */
131 struct jtag_command
*cmd_origin
;
133 struct angie_cmd
*next
; /**< Pointer to next command (linked list) */
136 /** Describes one driver instance */
138 struct libusb_context
*libusb_ctx
;
139 struct libusb_device_handle
*usb_device_handle
;
140 enum angie_type type
;
142 unsigned int ep_in
; /**< IN endpoint number */
143 unsigned int ep_out
; /**< OUT endpoint number */
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 */
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 */
158 /**************************** Function Prototypes *****************************/
160 /* USB helper functions */
161 static int angie_usb_open(struct angie
*device
);
162 static int angie_usb_close(struct angie
*device
);
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
,
168 static int angie_load_firmware(struct angie
*device
, const char *filename
);
169 static int angie_load_bitstream(struct angie
*device
, const char *filename
);
171 static int angie_write_firmware_section(struct angie
*device
,
172 struct image
*firmware_image
, int section_index
);
174 /* Generic helper functions */
175 static void angie_dump_signal_states(uint8_t input_signals
, uint8_t output_signals
);
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
);
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
);
188 static void angie_dump_queue(struct angie
*device
);
190 static int angie_append_scan_cmd(struct angie
*device
,
191 enum scan_type scan_type
,
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
,
202 static int angie_append_clock_tms_cmd(struct angie
*device
, uint8_t count
,
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
,
208 static int angie_append_sleep_cmd(struct angie
*device
, uint32_t us
);
209 static int angie_append_configure_tck_cmd(struct angie
*device
,
215 static int angie_append_test_cmd(struct angie
*device
);
217 /* ANGIE TCK frequency helper functions */
218 static int angie_calculate_delay(enum angie_delay_type type
, long f
, int *delay
);
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
);
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
);
231 static int angie_post_process_scan(struct angie_cmd
*angie_cmd
);
232 static int angie_post_process_queue(struct angie
*device
);
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
);
243 /****************************** Global Variables ******************************/
245 static struct angie
*angie_handle
;
247 /**************************** USB helper functions ****************************/
250 * Opens the ANGIE device
252 * @param device pointer to struct angie identifying ANGIE driver instance.
253 * @return on success: ERROR_OK
254 * @return on failure: ERROR_FAIL
256 static int angie_usb_open(struct angie
*device
)
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};
262 int ret
= jtag_libusb_open(vids
, pids
, NULL
, &usb_device_handle
, NULL
);
267 device
->usb_device_handle
= usb_device_handle
;
268 device
->type
= ANGIE
;
274 * Releases the ANGIE interface and closes the USB device handle.
276 * @param device pointer to struct angie identifying ANGIE driver instance.
277 * @return on success: ERROR_OK
278 * @return on failure: ERROR_FAIL
280 static int angie_usb_close(struct angie
*device
)
282 if (device
->usb_device_handle
) {
283 if (libusb_release_interface(device
->usb_device_handle
, 0) != 0)
286 jtag_libusb_close(device
->usb_device_handle
);
287 device
->usb_device_handle
= NULL
;
292 /******************* ANGIE CPU (EZ-USB) specific functions ********************/
295 * Writes '0' or '1' to the CPUCS register, putting the EZ-USB CPU into reset
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
303 static int angie_cpu_reset(struct angie
*device
, char reset_bit
)
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
);
311 * Puts the ANGIE's EZ-USB microcontroller into reset state, downloads
312 * the firmware image, resumes the microcontroller and re-enumerates
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
322 static int angie_load_firmware_and_renumerate(struct angie
*device
,
323 const char *filename
, uint32_t delay_us
)
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 */
331 ret
= angie_load_firmware(device
, filename
);
335 ret
= angie_usb_close(device
);
341 return angie_usb_open(device
);
345 * Downloads a firmware image to the ANGIE's EZ-USB microcontroller
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
354 static int angie_load_firmware(struct angie
*device
, const char *filename
)
356 struct image angie_firmware_image
;
359 ret
= angie_cpu_reset(device
, CPU_RESET
);
360 if (ret
!= ERROR_OK
) {
361 LOG_ERROR("Could not halt ANGIE CPU");
365 angie_firmware_image
.base_address
= 0;
366 angie_firmware_image
.base_address_set
= false;
368 ret
= image_open(&angie_firmware_image
, filename
, "bin");
369 if (ret
!= ERROR_OK
) {
370 LOG_ERROR("Could not load firmware image");
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
);
381 image_close(&angie_firmware_image
);
383 ret
= angie_cpu_reset(device
, CPU_START
);
384 if (ret
!= ERROR_OK
) {
385 LOG_ERROR("Could not restart ANGIE CPU");
393 * Downloads a bitstream file to the ANGIE's FPGA through the EZ-USB microcontroller
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
402 static int angie_load_bitstream(struct angie
*device
, const char *filename
)
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;
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
);
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
);
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
);
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
);
439 h_u32_to_be(gpifcnt
, bitstream_size
);
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 */
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
);
460 LOG_INFO("Bitstream sent successfully.");
463 free(bitstream_data
);
464 fclose(bitstream_file
);
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 */
479 * Send one contiguous firmware section to the ANGIE's EZ-USB microcontroller
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
489 static int angie_write_firmware_section(struct angie
*device
,
490 struct image
*firmware_image
, int section_index
)
492 int addr
, bytes_remaining
, chunk_size
;
493 uint8_t data
[SECTION_BUFFERSIZE
];
494 uint8_t *data_ptr
= data
;
497 int ret
, transferred
;
499 size
= (uint16_t)firmware_image
->sections
[section_index
].size
;
500 addr
= (uint16_t)firmware_image
->sections
[section_index
].base_address
;
502 LOG_DEBUG("section %02i at addr 0x%04x (size 0x%04" PRIx16
")", section_index
, addr
,
505 /* Copy section contents to local buffer */
506 ret
= image_read_section(firmware_image
, section_index
, 0, size
, data
,
511 if (size_read
!= size
)
514 bytes_remaining
= size
;
516 /* Send section data in chunks of up to 64 bytes to ANGIE */
517 while (bytes_remaining
> 0) {
518 if (bytes_remaining
> 64)
521 chunk_size
= bytes_remaining
;
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
);
531 if (transferred
!= chunk_size
) {
532 /* Abort if libusb sent less data than requested */
536 bytes_remaining
-= chunk_size
;
538 data_ptr
+= chunk_size
;
544 /************************** Generic helper functions **************************/
547 * Print state of interesting signals via LOG_INFO().
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
552 static void angie_dump_signal_states(uint8_t input_signals
, uint8_t output_signals
)
554 LOG_INFO("ANGIE signal states: TDI: %i, TDO: %i, TMS: %i, TCK: %i, TRST: %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));
564 /**************** ANGIE command generation helper functions ***************/
567 * Allocate and initialize space in memory for ANGIE command payload.
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
575 static int angie_allocate_payload(struct angie_cmd
*angie_cmd
, int size
,
576 enum angie_payload_direction direction
)
580 payload
= calloc(size
, sizeof(uint8_t));
583 LOG_ERROR("Could not allocate ANGIE command payload: out of memory");
588 case PAYLOAD_DIRECTION_OUT
:
589 if (angie_cmd
->payload_out
) {
590 LOG_ERROR("BUG: Duplicate payload allocation for ANGIE command");
594 angie_cmd
->payload_out
= payload
;
595 angie_cmd
->payload_out_size
= size
;
597 case PAYLOAD_DIRECTION_IN
:
598 if (angie_cmd
->payload_in_start
) {
599 LOG_ERROR("BUG: Duplicate payload allocation for ANGIE command");
604 angie_cmd
->payload_in_start
= payload
;
605 angie_cmd
->payload_in
= payload
;
606 angie_cmd
->payload_in_size
= size
;
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
611 angie_cmd
->free_payload_in_start
= true;
619 /****************** ANGIE command queue helper functions ******************/
622 * Get the current number of bytes in the queue, including command IDs.
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
629 static int angie_get_queue_size(struct angie
*device
,
630 enum angie_payload_direction direction
)
632 struct angie_cmd
*current
= device
->queue_start
;
637 case PAYLOAD_DIRECTION_OUT
:
638 sum
+= current
->payload_out_size
+ 1; /* + 1 byte for Command ID */
640 case PAYLOAD_DIRECTION_IN
:
641 sum
+= current
->payload_in_size
;
645 current
= current
->next
;
652 * Clear the ANGIE command queue.
654 * @param device pointer to struct angie identifying ANGIE driver instance.
656 static void angie_clear_queue(struct angie
*device
)
658 struct angie_cmd
*current
= device
->queue_start
;
659 struct angie_cmd
*next
= NULL
;
662 /* Save pointer to next element */
663 next
= current
->next
;
665 /* Free payloads: OUT payload can be freed immediately */
666 free(current
->payload_out
);
667 current
->payload_out
= NULL
;
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
;
677 /* Free queue element */
680 /* Proceed with next element */
684 device
->commands_in_queue
= 0;
685 device
->queue_start
= NULL
;
686 device
->queue_end
= NULL
;
690 * Add a command to the ANGIE command queue.
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
695 * @return on success: ERROR_OK
696 * @return on failure: ERROR_FAIL
698 static int angie_append_queue(struct angie
*device
, struct angie_cmd
*angie_cmd
)
700 int newsize_out
, newsize_in
;
703 newsize_out
= angie_get_queue_size(device
, PAYLOAD_DIRECTION_OUT
) + 1
704 + angie_cmd
->payload_out_size
;
706 newsize_in
= angie_get_queue_size(device
, PAYLOAD_DIRECTION_IN
)
707 + angie_cmd
->payload_in_size
;
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
);
716 ret
= angie_post_process_queue(device
);
719 angie_clear_queue(device
);
722 if (!device
->queue_start
) {
723 /* Queue was empty */
724 device
->commands_in_queue
= 1;
726 device
->queue_start
= angie_cmd
;
727 device
->queue_end
= angie_cmd
;
729 /* There are already commands in the queue */
730 device
->commands_in_queue
++;
732 device
->queue_end
->next
= angie_cmd
;
733 device
->queue_end
= angie_cmd
;
737 angie_clear_queue(device
);
743 * Sends all queued ANGIE commands to the ANGIE for execution.
745 * @param device pointer to struct angie identifying ANGIE driver instance.
747 * @return on success: ERROR_OK
748 * @return on failure: ERROR_FAIL
750 static int angie_execute_queued_commands(struct angie
*device
, int timeout_ms
)
752 struct angie_cmd
*current
;
753 int ret
, i
, index_out
, index_in
, count_out
, count_in
, transferred
;
756 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO
))
757 angie_dump_queue(device
);
763 for (current
= device
->queue_start
; current
; current
= current
->next
) {
764 /* Add command to packet */
765 buffer
[index_out
] = current
->id
;
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
;
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
);
781 if (transferred
!= count_out
)
784 /* Wait for response if commands contain IN payload data */
786 ret
= jtag_libusb_bulk_write(device
->usb_device_handle
, device
->ep_in
,
787 (char *)buffer
, count_in
, timeout_ms
, &transferred
);
790 if (transferred
!= count_in
)
793 /* Write back IN payload data */
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
];
806 * Convert an ANGIE command ID (\a id) to a human-readable string.
808 * @param id the ANGIE command ID.
809 * @return the corresponding human-readable string.
811 static const char *angie_cmd_id_string(uint8_t id
)
815 return "CMD_SCAN_IN";
816 case CMD_SLOW_SCAN_IN
:
817 return "CMD_SLOW_SCAN_IN";
819 return "CMD_SCAN_OUT";
820 case CMD_SLOW_SCAN_OUT
:
821 return "CMD_SLOW_SCAN_OUT";
823 return "CMD_SCAN_IO";
824 case CMD_SLOW_SCAN_IO
:
825 return "CMD_SLOW_SCAN_IO";
827 return "CMD_CLOCK_TMS";
828 case CMD_SLOW_CLOCK_TMS
:
829 return "CMD_SLOW_CLOCK_TMS";
831 return "CMD_CLOCK_TCK";
832 case CMD_SLOW_CLOCK_TCK
:
833 return "CMD_SLOW_CLOCK_TCK";
835 return "CMD_SLEEP_US";
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";
845 return "CMD_SET_LEDS";
849 return "CMD_UNKNOWN";
854 * Print one ANGIE command to stdout.
856 * @param angie_cmd pointer to ANGIE command.
858 static void angie_dump_command(struct angie_cmd
*angie_cmd
)
861 for (int i
= 0; i
< angie_cmd
->payload_out_size
; i
++)
862 sprintf(hex
+ 3 * i
, "%02" PRIX8
" ", angie_cmd
->payload_out
[i
]);
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
);
868 LOG_DEBUG_IO("\n | IN size = %" PRIi8
"\n", angie_cmd
->payload_in_size
);
872 * Print the ANGIE command queue to stdout.
874 * @param device pointer to struct angie identifying ANGIE driver instance.
876 static void angie_dump_queue(struct angie
*device
)
878 struct angie_cmd
*current
;
880 LOG_DEBUG_IO("ANGIE command queue:\n");
882 for (current
= device
->queue_start
; current
; current
= current
->next
)
883 angie_dump_command(current
);
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.
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
913 * @return on success: ERROR_OK
914 * @return on failure: ERROR_FAIL
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
)
921 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
922 int ret
, i
, scan_size_bytes
;
923 uint8_t bits_last_byte
;
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"
937 scan_size_bytes
= DIV_ROUND_UP(scan_size_bits
, 8);
939 bits_last_byte
= scan_size_bits
% 8;
940 if (bits_last_byte
== 0)
943 /* Allocate out_payload depending on scan type */
946 if (device
->delay_scan_in
< 0)
947 cmd
->id
= CMD_SCAN_IN
;
949 cmd
->id
= CMD_SLOW_SCAN_IN
;
950 ret
= angie_allocate_payload(cmd
, 5, PAYLOAD_DIRECTION_IN
);
953 if (device
->delay_scan_out
< 0)
954 cmd
->id
= CMD_SCAN_OUT
;
956 cmd
->id
= CMD_SLOW_SCAN_OUT
;
957 ret
= angie_allocate_payload(cmd
, scan_size_bytes
+ 5, PAYLOAD_DIRECTION_OUT
);
960 if (device
->delay_scan_io
< 0)
961 cmd
->id
= CMD_SCAN_IO
;
963 cmd
->id
= CMD_SLOW_SCAN_IO
;
964 ret
= angie_allocate_payload(cmd
, scan_size_bytes
+ 5, PAYLOAD_DIRECTION_OUT
);
967 LOG_ERROR("BUG: 'append scan cmd' encountered an unknown scan type");
972 if (ret
!= ERROR_OK
) {
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
;
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
];
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
;
997 cmd
->needs_postprocessing
= postprocess
;
998 cmd
->cmd_origin
= origin
;
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
;
1004 return angie_append_queue(device
, cmd
);
1008 * Perform TAP state transitions
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
1017 static int angie_append_clock_tms_cmd(struct angie
*device
, uint8_t count
,
1020 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1024 LOG_ERROR("Out of memory");
1028 if (device
->delay_clock_tms
< 0)
1029 cmd
->id
= CMD_CLOCK_TMS
;
1031 cmd
->id
= CMD_SLOW_CLOCK_TMS
;
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
) {
1040 cmd
->payload_out
[0] = count
;
1041 cmd
->payload_out
[1] = sequence
;
1043 return angie_append_queue(device
, cmd
);
1047 * Generate a defined amount of TCK clock cycles
1049 * All other JTAG signals are left unchanged.
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
1056 static int angie_append_clock_tck_cmd(struct angie
*device
, uint16_t count
)
1058 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1062 LOG_ERROR("Out of memory");
1066 if (device
->delay_clock_tck
< 0)
1067 cmd
->id
= CMD_CLOCK_TCK
;
1069 cmd
->id
= CMD_SLOW_CLOCK_TCK
;
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
) {
1078 cmd
->payload_out
[0] = count
& 0xff;
1079 cmd
->payload_out
[1] = (count
>> 8) & 0xff;
1081 return angie_append_queue(device
, cmd
);
1085 * Read JTAG signals.
1087 * @param device pointer to struct angie identifying ANGIE driver instance.
1088 * @return on success: ERROR_OK
1089 * @return on failure: ERROR_FAIL
1091 static int angie_append_get_signals_cmd(struct angie
*device
)
1093 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1097 LOG_ERROR("Out of memory");
1101 cmd
->id
= CMD_GET_SIGNALS
;
1102 cmd
->needs_postprocessing
= true;
1104 /* CMD_GET_SIGNALS has two IN payload bytes */
1105 ret
= angie_allocate_payload(cmd
, 2, PAYLOAD_DIRECTION_IN
);
1107 if (ret
!= ERROR_OK
) {
1112 return angie_append_queue(device
, cmd
);
1116 * Arbitrarily set JTAG output signals.
1118 * @param device pointer to struct angie identifying ANGIE driver instance.
1119 * @param low defines which signals will be de-asserted. Each bit corresponds
1128 * @param high defines which signals will be asserted.
1129 * @return on success: ERROR_OK
1130 * @return on failure: ERROR_FAIL
1132 static int angie_append_set_signals_cmd(struct angie
*device
, uint8_t low
,
1135 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1139 LOG_ERROR("Out of memory");
1143 cmd
->id
= CMD_SET_SIGNALS
;
1145 /* CMD_SET_SIGNALS has two OUT payload bytes and zero IN payload bytes */
1146 ret
= angie_allocate_payload(cmd
, 2, PAYLOAD_DIRECTION_OUT
);
1148 if (ret
!= ERROR_OK
) {
1153 cmd
->payload_out
[0] = low
;
1154 cmd
->payload_out
[1] = high
;
1156 return angie_append_queue(device
, cmd
);
1160 * Sleep for a pre-defined number of microseconds
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
1167 static int angie_append_sleep_cmd(struct angie
*device
, uint32_t us
)
1169 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1173 LOG_ERROR("Out of memory");
1177 cmd
->id
= CMD_SLEEP_US
;
1179 /* CMD_SLEEP_US has two OUT payload bytes and zero IN payload bytes */
1180 ret
= angie_allocate_payload(cmd
, 2, PAYLOAD_DIRECTION_OUT
);
1182 if (ret
!= ERROR_OK
) {
1187 cmd
->payload_out
[0] = us
& 0x00ff;
1188 cmd
->payload_out
[1] = (us
>> 8) & 0x00ff;
1190 return angie_append_queue(device
, cmd
);
1194 * Set TCK delay counters
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
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
)
1208 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1212 LOG_ERROR("Out of memory");
1216 cmd
->id
= CMD_CONFIGURE_TCK_FREQ
;
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
) {
1226 if (delay_scan_in
< 0)
1227 cmd
->payload_out
[0] = 0;
1229 cmd
->payload_out
[0] = (uint8_t)delay_scan_in
;
1231 if (delay_scan_out
< 0)
1232 cmd
->payload_out
[1] = 0;
1234 cmd
->payload_out
[1] = (uint8_t)delay_scan_out
;
1236 if (delay_scan_io
< 0)
1237 cmd
->payload_out
[2] = 0;
1239 cmd
->payload_out
[2] = (uint8_t)delay_scan_io
;
1242 cmd
->payload_out
[3] = 0;
1244 cmd
->payload_out
[3] = (uint8_t)delay_tck
;
1247 cmd
->payload_out
[4] = 0;
1249 cmd
->payload_out
[4] = (uint8_t)delay_tms
;
1251 return angie_append_queue(device
, cmd
);
1255 * Test command. Used to check if the ANGIE device is ready to accept new
1258 * @param device pointer to struct angie identifying ANGIE driver instance.
1259 * @return on success: ERROR_OK
1260 * @return on failure: ERROR_FAIL
1262 static int angie_append_test_cmd(struct angie
*device
)
1264 struct angie_cmd
*cmd
= calloc(1, sizeof(struct angie_cmd
));
1268 LOG_ERROR("Out of memory");
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
) {
1281 cmd
->payload_out
[0] = 0xAA;
1283 return angie_append_queue(device
, cmd
);
1286 /****************** ANGIE TCK frequency helper functions ******************/
1289 * Calculate delay values for a given TCK frequency.
1291 * The ANGIE firmware uses five different speed values for different
1292 * commands. These speed values are calculated in these functions.
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
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.
1304 * The delay values are described by linear equations:
1306 * (t = period, k = constant, x = delay value, d = constant)
1308 * Thus, the delay can be calculated as in the following equation:
1311 * The constants in these equations have been determined and validated by
1312 * measuring the frequency resulting from different delay values.
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
1320 static int angie_calculate_delay(enum angie_delay_type type
, long f
, int *delay
)
1322 float t_us
, x
, x_ceil
;
1324 /* Calculate period of requested TCK frequency */
1325 t_us
= 1000000.0 / f
;
1328 case DELAY_CLOCK_TCK
:
1329 x
= (t_us
- 6.0) / 4;
1331 case DELAY_CLOCK_TMS
:
1332 x
= (t_us
- 8.5) / 4;
1335 x
= (t_us
- 8.8308) / 4;
1337 case DELAY_SCAN_OUT
:
1338 x
= (t_us
- 10.527) / 4;
1341 x
= (t_us
- 13.132) / 4;
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. */
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. */
1359 /* Check if the value is within limits */
1363 *delay
= (int)x_ceil
;
1369 * Calculate frequency for a given delay value.
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:
1374 * (t = period, k = constant, x = delay value, d = constant)
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
1380 static long angie_calculate_frequency(enum angie_delay_type type
, int delay
)
1382 float t_us
, f_float
;
1388 case DELAY_CLOCK_TCK
:
1392 t_us
= (4.0 * delay
) + 6.0;
1394 case DELAY_CLOCK_TMS
:
1398 t_us
= (4.0 * delay
) + 8.5;
1404 t_us
= (4.0 * delay
) + 8.8308;
1406 case DELAY_SCAN_OUT
:
1410 t_us
= (4.0 * delay
) + 10.527;
1416 t_us
= (4.0 * delay
) + 13.132;
1422 f_float
= 1000000.0 / t_us
;
1423 return roundf(f_float
);
1426 /******************* Interface between ANGIE and OpenOCD ******************/
1429 * Sets the end state follower (see interface.h) if \a endstate is a stable
1432 * @param endstate the state the end state follower should be set to.
1434 static void angie_set_end_state(tap_state_t endstate
)
1436 if (tap_is_state_stable(endstate
))
1437 tap_set_end_state(endstate
);
1439 LOG_ERROR("BUG: %s is not a valid end state", tap_state_name(endstate
));
1443 * Move from the current TAP state to the current TAP end state.
1445 * @param device pointer to struct angie identifying ANGIE driver instance.
1446 * @return on success: ERROR_OK
1447 * @return on failure: ERROR_FAIL
1449 static int angie_queue_statemove(struct angie
*device
)
1451 uint8_t tms_sequence
, tms_count
;
1454 if (tap_get_state() == tap_get_end_state()) {
1455 /* Do nothing if we are already there */
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());
1462 ret
= angie_append_clock_tms_cmd(device
, tms_count
, tms_sequence
);
1464 if (ret
== ERROR_OK
)
1465 tap_set_state(tap_get_end_state());
1471 * Perform a scan operation on a JTAG register.
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
1478 static int angie_queue_scan(struct angie
*device
, struct jtag_command
*cmd
)
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
;
1485 uint8_t first_tms_count
, first_tms_sequence
;
1486 uint8_t last_tms_count
, last_tms_sequence
;
1488 uint8_t tms_count_pause
, tms_sequence_pause
;
1489 uint8_t tms_count_resume
, tms_sequence_resume
;
1491 uint8_t tms_count_start
, tms_sequence_start
;
1492 uint8_t tms_count_end
, tms_sequence_end
;
1494 enum scan_type type
;
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);
1501 /* Determine scan type (IN/OUT/IO) */
1502 type
= jtag_scan_type(cmd
->cmd
.scan
);
1504 /* Determine number of scan commands with maximum payload */
1505 scans_max_payload
= scan_size_bytes
/ 58;
1507 /* Determine size of last shift command */
1508 bits_last_scan
= scan_size_bits
- (scans_max_payload
* 58 * 8);
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
);
1514 if (!tdo_buffer_start
)
1517 tdo_buffer
= tdo_buffer_start
;
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
;
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());
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());
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
);
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());
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());
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
);
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
;
1567 /* Resume from previous scan */
1568 tms_count_start
= tms_count_resume
;
1569 tms_sequence_start
= tms_sequence_resume
;
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
;
1576 ret
= angie_append_scan_cmd(device
,
1591 /* Update TDI and TDO buffer pointers */
1592 if (tdi_buffer_start
)
1594 if (tdo_buffer_start
)
1596 } else if (bytecount
== 58) { /* Full scan, no further scans */
1597 tms_count_end
= last_tms_count
;
1598 tms_sequence_end
= last_tms_sequence
;
1600 ret
= angie_append_scan_cmd(device
,
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
;
1618 ret
= angie_append_scan_cmd(device
,
1634 if (ret
!= ERROR_OK
) {
1635 free(tdi_buffer_start
);
1636 free(tdo_buffer_start
);
1641 free(tdi_buffer_start
);
1643 /* Set current state to the end state requested by the command */
1644 tap_set_state(cmd
->cmd
.scan
->end_state
);
1650 * Move the TAP into the Test Logic Reset state.
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
1657 static int angie_queue_tlr_reset(struct angie
*device
, struct jtag_command
*cmd
)
1659 int ret
= angie_append_clock_tms_cmd(device
, 5, 0xff);
1661 if (ret
== ERROR_OK
)
1662 tap_set_state(TAP_RESET
);
1670 * Generate TCK clock cycles while remaining
1671 * in the Run-Test/Idle state.
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
1678 static int angie_queue_runtest(struct angie
*device
, struct jtag_command
*cmd
)
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
);
1688 /* Generate the clock cycles */
1689 ret
= angie_append_clock_tck_cmd(device
, cmd
->cmd
.runtest
->num_cycles
);
1690 if (ret
!= ERROR_OK
)
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
);
1703 * Execute a JTAG_RESET command
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
1711 static int angie_reset(int trst
, int srst
)
1713 struct angie
*device
= angie_handle
;
1714 uint8_t low
= 0, high
= 0;
1717 tap_set_state(TAP_RESET
);
1720 high
|= SIGNAL_TRST
;
1726 high
|= SIGNAL_SRST
;
1728 int ret
= angie_append_set_signals_cmd(device
, low
, high
);
1729 if (ret
!= ERROR_OK
)
1732 ret
= angie_execute_queued_commands(device
, LIBUSB_TIMEOUT_MS
);
1733 if (ret
!= ERROR_OK
)
1736 angie_clear_queue(device
);
1742 * Move to one TAP state or several states in succession.
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
1749 static int angie_queue_pathmove(struct angie
*device
, struct jtag_command
*cmd
)
1751 int ret
, i
, num_states
, batch_size
, state_count
;
1753 uint8_t tms_sequence
;
1755 num_states
= cmd
->cmd
.pathmove
->num_states
;
1756 path
= cmd
->cmd
.pathmove
->path
;
1759 while (num_states
> 0) {
1762 /* Determine batch size */
1763 if (num_states
>= 8)
1766 batch_size
= num_states
;
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);
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
]));
1784 tap_set_state(path
[state_count
]);
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
)
1800 * Sleep for a specific amount of time.
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
1807 static int angie_queue_sleep(struct angie
*device
, struct jtag_command
*cmd
)
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
);
1815 * Generate TCK cycles while remaining in a stable state.
1817 * @param device pointer to struct angie identifying ANGIE driver instance.
1818 * @param cmd pointer to the command that shall be executed.
1820 static int angie_queue_stableclocks(struct angie
*device
, struct jtag_command
*cmd
)
1823 unsigned int num_cycles
;
1825 if (!tap_is_state_stable(tap_get_state())) {
1826 LOG_ERROR("JTAG_STABLECLOCKS: state not stable");
1830 num_cycles
= cmd
->cmd
.stableclocks
->num_cycles
;
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
);
1836 ret
= angie_append_set_signals_cmd(device
, SIGNAL_TMS
, 0);
1838 if (ret
!= ERROR_OK
)
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;
1847 ret
= angie_append_clock_tck_cmd(device
, num_cycles
);
1851 if (ret
!= ERROR_OK
)
1859 * Post-process JTAG_SCAN command
1861 * @param angie_cmd pointer to ANGIE command that shall be processed.
1862 * @return on success: ERROR_OK
1863 * @return on failure: ERROR_FAIL
1865 static int angie_post_process_scan(struct angie_cmd
*angie_cmd
)
1867 struct jtag_command
*cmd
= angie_cmd
->cmd_origin
;
1870 switch (jtag_scan_type(cmd
->cmd
.scan
)) {
1873 ret
= jtag_read_buffer(angie_cmd
->payload_in_start
, cmd
->cmd
.scan
);
1876 /* Nothing to do for OUT scans */
1880 LOG_ERROR("BUG: angie post process scan encountered an unknown JTAG scan type");
1889 * Perform post-processing of commands after ANGIE queue has been executed.
1891 * @param device pointer to struct angie identifying ANGIE driver instance.
1892 * @return on success: ERROR_OK
1893 * @return on failure: ERROR_FAIL
1895 static int angie_post_process_queue(struct angie
*device
)
1897 struct angie_cmd
*current
;
1898 struct jtag_command
*openocd_cmd
;
1901 current
= device
->queue_start
;
1904 openocd_cmd
= current
->cmd_origin
;
1906 /* Check if a corresponding OpenOCD command is stored for this
1908 if (current
->needs_postprocessing
&& openocd_cmd
) {
1909 switch (openocd_cmd
->type
) {
1911 ret
= angie_post_process_scan(current
);
1913 case JTAG_TLR_RESET
:
1917 case JTAG_STABLECLOCKS
:
1918 /* Nothing to do for these commands */
1923 LOG_ERROR("BUG: angie post process queue encountered unknown JTAG "
1928 if (ret
!= ERROR_OK
)
1932 current
= current
->next
;
1938 /**************************** JTAG driver functions ***************************/
1941 * Executes the JTAG Command Queue.
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
1949 * @return on success: ERROR_OK
1950 * @return on failure: ERROR_FAIL
1952 static int angie_execute_queue(void)
1954 struct jtag_command
*cmd
= jtag_command_queue
;
1958 switch (cmd
->type
) {
1960 ret
= angie_queue_scan(angie_handle
, cmd
);
1962 case JTAG_TLR_RESET
:
1963 ret
= angie_queue_tlr_reset(angie_handle
, cmd
);
1966 ret
= angie_queue_runtest(angie_handle
, cmd
);
1969 ret
= angie_queue_pathmove(angie_handle
, cmd
);
1972 ret
= angie_queue_sleep(angie_handle
, cmd
);
1974 case JTAG_STABLECLOCKS
:
1975 ret
= angie_queue_stableclocks(angie_handle
, cmd
);
1979 LOG_ERROR("BUG: encountered unknown JTAG command type");
1983 if (ret
!= ERROR_OK
)
1989 if (angie_handle
->commands_in_queue
> 0) {
1990 ret
= angie_execute_queued_commands(angie_handle
, LIBUSB_TIMEOUT_MS
);
1991 if (ret
!= ERROR_OK
)
1994 ret
= angie_post_process_queue(angie_handle
);
1995 if (ret
!= ERROR_OK
)
1998 angie_clear_queue(angie_handle
);
2005 * Set the TCK frequency of the ANGIE adapter.
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
2012 static int angie_khz(int khz
, int *jtag_speed
)
2017 LOG_ERROR("RCLK not supported");
2021 /* CLOCK_TCK commands are decoupled from others. Therefore, the frequency
2022 * setting can be done independently from all other commands. */
2024 angie_handle
->delay_clock_tck
= -1;
2026 ret
= angie_calculate_delay(DELAY_CLOCK_TCK
, khz
* 1000,
2027 &angie_handle
->delay_clock_tck
);
2028 if (ret
!= ERROR_OK
)
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! */
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;
2042 ret
= angie_calculate_delay(DELAY_CLOCK_TMS
, khz
* 1000,
2043 &angie_handle
->delay_clock_tms
);
2044 if (ret
!= ERROR_OK
)
2047 ret
= angie_calculate_delay(DELAY_SCAN_IN
, khz
* 1000,
2048 &angie_handle
->delay_scan_in
);
2049 if (ret
!= ERROR_OK
)
2052 ret
= angie_calculate_delay(DELAY_SCAN_OUT
, khz
* 1000,
2053 &angie_handle
->delay_scan_out
);
2054 if (ret
!= ERROR_OK
)
2057 ret
= angie_calculate_delay(DELAY_SCAN_IO
, khz
* 1000,
2058 &angie_handle
->delay_scan_io
);
2059 if (ret
!= ERROR_OK
)
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
));
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
);
2087 if (ret
!= ERROR_OK
)
2096 * Set the TCK frequency of the ANGIE adapter.
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
2103 * @param speed desired adapter-specific speed value.
2104 * @return on success: ERROR_OK
2105 * @return on failure: ERROR_FAIL
2107 static int angie_speed(int speed
)
2111 return angie_khz(speed
, &dummy
);
2115 * Convert adapter-specific speed value to corresponding TCK frequency in kHz.
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
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
2127 static int angie_speed_div(int speed
, int *khz
)
2135 * Initiates the firmware download to the ANGIE adapter and prepares
2138 * @return on success: ERROR_OK
2139 * @return on failure: ERROR_FAIL
2141 static int angie_init(void)
2143 int ret
, transferred
;
2144 char str_manufacturer
[20];
2145 bool download_firmware
= false;
2147 uint8_t input_signals
, output_signals
;
2149 angie_handle
= calloc(1, sizeof(struct angie
));
2151 if (!angie_handle
) {
2152 LOG_ERROR("Out of memory");
2156 ret
= angie_usb_open(angie_handle
);
2157 if (ret
!= ERROR_OK
) {
2158 LOG_ERROR("Could not open ANGIE device");
2160 angie_handle
= NULL
;
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);
2167 /* Could not get descriptor -> Unconfigured or original Keil firmware */
2168 download_firmware
= true;
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;
2175 if (download_firmware
) {
2176 LOG_INFO("Loading ANGIE firmware. This is reversible by power-cycling ANGIE device.");
2178 if (libusb_claim_interface(angie_handle
->usb_device_handle
, 0) != ERROR_OK
)
2179 LOG_ERROR("Could not claim interface");
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");
2188 ret
= angie_load_bitstream(angie_handle
, ANGIE_BITSTREAM_FILE
);
2189 if (ret
!= ERROR_OK
) {
2190 LOG_ERROR("Could not download bitstream");
2195 LOG_INFO("ANGIE device is already running ANGIE firmware");
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
) {
2206 /* Initialize ANGIE command queue */
2207 angie_clear_queue(angie_handle
);
2209 /* Issue one test command with short timeout */
2210 ret
= angie_append_test_cmd(angie_handle
);
2211 if (ret
!= ERROR_OK
) {
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. */
2222 ret
= jtag_libusb_bulk_write(angie_handle
->usb_device_handle
, angie_handle
->ep_in
,
2223 dummy
, 64, 200, &transferred
);
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");
2232 /* Successfully received Bulk IN packet -> continue */
2233 LOG_INFO("Recovered from lost Bulk IN packet");
2236 angie_clear_queue(angie_handle
);
2238 ret
= angie_append_get_signals_cmd(angie_handle
);
2239 if (ret
!= ERROR_OK
) {
2244 ret
= angie_execute_queued_commands(angie_handle
, 200);
2245 if (ret
!= ERROR_OK
) {
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
);
2255 angie_clear_queue(angie_handle
);
2261 * Closes the USB handle for the ANGIE device.
2263 * @return on success: ERROR_OK
2264 * @return on failure: ERROR_FAIL
2266 static int angie_quit(void)
2268 int ret
= angie_usb_close(angie_handle
);
2270 angie_handle
= NULL
;
2275 static struct jtag_interface angie_interface
= {
2276 .execute_queue
= angie_execute_queue
,
2279 struct adapter_driver angie_adapter_driver
= {
2281 .transports
= jtag_only
,
2285 .reset
= angie_reset
,
2286 .speed
= angie_speed
,
2288 .speed_div
= angie_speed_div
,
2290 .jtag_ops
= &angie_interface
,
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)