OpenOCD
ftdi.c File Reference

JTAG adapters based on the FT2232 full and high speed USB parts are popular low cost JTAG debug solutions. More...

Include dependency graph for ftdi.c:

Go to the source code of this file.

Data Structures

struct  signal
 
struct  swd_cmd_queue_entry
 

Macros

#define JTAG_MODE   (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
 
#define JTAG_MODE_ALT   (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)
 
#define MAX_USB_IDS   8
 
#define SWD_MODE   (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
 

Functions

 COMMAND_HANDLER (ftdi_handle_channel_command)
 
 COMMAND_HANDLER (ftdi_handle_device_desc_command)
 
 COMMAND_HANDLER (ftdi_handle_get_signal_command)
 
 COMMAND_HANDLER (ftdi_handle_layout_init_command)
 
 COMMAND_HANDLER (ftdi_handle_layout_signal_command)
 
 COMMAND_HANDLER (ftdi_handle_set_signal_command)
 
 COMMAND_HANDLER (ftdi_handle_tdo_sample_edge_command)
 
 COMMAND_HANDLER (ftdi_handle_vid_pid_command)
 
static int create_default_signal (const char *name, uint16_t data_mask)
 
static struct signalcreate_signal (const char *name)
 
static int create_signals (void)
 
static struct signalfind_signal_by_name (const char *name)
 
static void ftdi_end_state (tap_state_t state)
 
static void ftdi_execute_command (struct jtag_command *cmd)
 
static void ftdi_execute_pathmove (struct jtag_command *cmd)
 
static int ftdi_execute_queue (void)
 
static void ftdi_execute_runtest (struct jtag_command *cmd)
 
static void ftdi_execute_scan (struct jtag_command *cmd)
 
static void ftdi_execute_sleep (struct jtag_command *cmd)
 
static void ftdi_execute_stableclocks (struct jtag_command *cmd)
 
static void ftdi_execute_statemove (struct jtag_command *cmd)
 
static void ftdi_execute_tms (struct jtag_command *cmd)
 Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG (or SWD) state machine. More...
 
static int ftdi_get_signal (const struct signal *s, uint16_t *value_out)
 
static int ftdi_initialize (void)
 
static int ftdi_khz (int khz, int *jtag_speed)
 
static int ftdi_quit (void)
 
static int ftdi_reset (int trst, int srst)
 
static int ftdi_set_signal (const struct signal *s, char value)
 
static int ftdi_speed (int speed)
 
static int ftdi_speed_div (int speed, int *khz)
 
static int ftdi_swd_init (void)
 
static void ftdi_swd_queue_cmd (uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
 
static void ftdi_swd_read_reg (uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
 
static int ftdi_swd_run_queue (void)
 Flush the MPSSE queue and process the SWD transaction queue. More...
 
static void ftdi_swd_swdio_en (bool enable)
 
static int ftdi_swd_switch_seq (enum swd_special_seq seq)
 
static void ftdi_swd_write_reg (uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
 
static void move_to_state (tap_state_t goal_state)
 Function move_to_state moves the TAP controller from the current state to a goal_state through a path given by tap_get_tms_path(). More...
 

Variables

static uint16_t direction
 
static int freq
 
struct adapter_driver ftdi_adapter_driver
 
static uint8_t ftdi_channel
 
static const struct command_registration ftdi_command_handlers []
 
static char * ftdi_device_desc
 
static struct jtag_interface ftdi_interface
 
static uint8_t ftdi_jtag_mode = JTAG_MODE
 
static uint16_t ftdi_pid [MAX_USB_IDS+1] = { 0 }
 
static const struct command_registration ftdi_subcommand_handlers []
 
static const struct swd_driver ftdi_swd
 
static const char *const ftdi_transports [] = { "jtag", "swd", NULL }
 
static uint16_t ftdi_vid [MAX_USB_IDS+1] = { 0 }
 
static uint16_t jtag_direction_init
 
static uint16_t jtag_output_init
 
static struct mpsse_ctxmpsse_ctx
 
static uint16_t output
 
static int queued_retval
 
static struct signalsignals
 
static struct swd_cmd_queue_entryswd_cmd_queue
 
static size_t swd_cmd_queue_alloced
 
static size_t swd_cmd_queue_length
 
static bool swd_mode
 

Detailed Description

JTAG adapters based on the FT2232 full and high speed USB parts are popular low cost JTAG debug solutions.

Many FT2232 based JTAG adapters are discrete, but development boards may integrate them as alternatives to more capable (and expensive) third party JTAG pods.

JTAG uses only one of the two communications channels ("MPSSE engines") on these devices. Adapters based on FT4232 parts have four ports/channels (A/B/C/D), instead of just two (A/B).

Especially on development boards integrating one of these chips (as opposed to discrete pods/dongles), the additional channels can be used for a variety of purposes, but OpenOCD only uses one channel at a time.

  • As a USB-to-serial adapter for the target's console UART ... which may be able to support ROM boot loaders that load initial firmware images to flash (or SRAM).
  • On systems which support ARM's SWD in addition to JTAG, or instead of it, that second port can be used for reading SWV/SWO trace data.
  • Additional JTAG links, e.g. to a CPLD or * FPGA.

FT2232 based JTAG adapters are "dumb" not "smart", because most JTAG request/response interactions involve round trips over the USB link. A "smart" JTAG adapter has intelligence close to the scan chain, so it can for example poll quickly for a status change (usually taking on the order of microseconds not milliseconds) before beginning a queued transaction which require the previous one to have completed.

There are dozens of adapters of this type, differing in details which this driver needs to understand. Those "layout" details are required as part of FT2232 driver configuration.

This code uses information contained in the MPSSE specification which was found here: https://www.ftdichip.com/Support/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf Hereafter this is called the "MPSSE Spec".

The datasheet for the ftdichip.com's FT2232H part is here: https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf

Also note the issue with code 0x4b (clock data to TMS) noted in http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html which can affect longer JTAG state paths.

Definition in file ftdi.c.

Macro Definition Documentation

◆ JTAG_MODE

#define JTAG_MODE   (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)

Definition at line 77 of file ftdi.c.

◆ JTAG_MODE_ALT

#define JTAG_MODE_ALT   (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)

Definition at line 78 of file ftdi.c.

◆ MAX_USB_IDS

#define MAX_USB_IDS   8

Definition at line 87 of file ftdi.c.

◆ SWD_MODE

#define SWD_MODE   (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)

Definition at line 79 of file ftdi.c.

Function Documentation

◆ COMMAND_HANDLER() [1/8]

COMMAND_HANDLER ( ftdi_handle_channel_command  )

◆ COMMAND_HANDLER() [2/8]

COMMAND_HANDLER ( ftdi_handle_device_desc_command  )

Definition at line 714 of file ftdi.c.

References CMD_ARGC, CMD_ARGV, ERROR_OK, ftdi_device_desc, and LOG_ERROR.

◆ COMMAND_HANDLER() [3/8]

COMMAND_HANDLER ( ftdi_handle_get_signal_command  )

◆ COMMAND_HANDLER() [4/8]

COMMAND_HANDLER ( ftdi_handle_layout_init_command  )

◆ COMMAND_HANDLER() [5/8]

◆ COMMAND_HANDLER() [6/8]

COMMAND_HANDLER ( ftdi_handle_set_signal_command  )

◆ COMMAND_HANDLER() [7/8]

COMMAND_HANDLER ( ftdi_handle_tdo_sample_edge_command  )

◆ COMMAND_HANDLER() [8/8]

COMMAND_HANDLER ( ftdi_handle_vid_pid_command  )

◆ create_default_signal()

static int create_default_signal ( const char *  name,
uint16_t  data_mask 
)
static

◆ create_signal()

static struct signal* create_signal ( const char *  name)
static

Definition at line 134 of file ftdi.c.

References name, signal::next, NULL, and signals.

Referenced by COMMAND_HANDLER(), and create_default_signal().

◆ create_signals()

static int create_signals ( void  )
static

Definition at line 1015 of file ftdi.c.

References create_default_signal(), ERROR_FAIL, and ERROR_OK.

Referenced by ftdi_swd_init().

◆ find_signal_by_name()

static struct signal* find_signal_by_name ( const char *  name)
static

◆ ftdi_end_state()

static void ftdi_end_state ( tap_state_t  state)
static

◆ ftdi_execute_command()

◆ ftdi_execute_pathmove()

static void ftdi_execute_pathmove ( struct jtag_command cmd)
static

◆ ftdi_execute_queue()

static int ftdi_execute_queue ( void  )
static

◆ ftdi_execute_runtest()

static void ftdi_execute_runtest ( struct jtag_command cmd)
static

◆ ftdi_execute_scan()

◆ ftdi_execute_sleep()

static void ftdi_execute_sleep ( struct jtag_command cmd)
static

Definition at line 562 of file ftdi.c.

References cmd, jtag_sleep(), LOG_DEBUG_IO, mpsse_flush(), tap_get_state(), and tap_state_name().

Referenced by ftdi_execute_command().

◆ ftdi_execute_stableclocks()

static void ftdi_execute_stableclocks ( struct jtag_command cmd)
static

◆ ftdi_execute_statemove()

static void ftdi_execute_statemove ( struct jtag_command cmd)
static

◆ ftdi_execute_tms()

static void ftdi_execute_tms ( struct jtag_command cmd)
static

Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG (or SWD) state machine.

REVISIT: Not the best method, perhaps.

Definition at line 358 of file ftdi.c.

References cmd, ftdi_jtag_mode, LOG_DEBUG_IO, and mpsse_clock_tms_cs_out().

Referenced by ftdi_execute_command().

◆ ftdi_get_signal()

static int ftdi_get_signal ( const struct signal s,
uint16_t *  value_out 
)
static

◆ ftdi_initialize()

◆ ftdi_khz()

static int ftdi_khz ( int  khz,
int *  jtag_speed 
)
static

Definition at line 290 of file ftdi.c.

References ERROR_FAIL, ERROR_OK, LOG_DEBUG, and mpsse_is_high_speed().

◆ ftdi_quit()

static int ftdi_quit ( void  )
static

Definition at line 695 of file ftdi.c.

References ERROR_OK, ftdi_device_desc, mpsse_close(), signal::name, signal::next, signals, and swd_cmd_queue.

◆ ftdi_reset()

static int ftdi_reset ( int  trst,
int  srst 
)
static

◆ ftdi_set_signal()

◆ ftdi_speed()

static int ftdi_speed ( int  speed)
static

Definition at line 268 of file ftdi.c.

References ERROR_OK, ftdi_jtag_mode, JTAG_MODE_ALT, LOG_ERROR, LOG_INFO, mpsse_set_frequency(), and swd_mode.

◆ ftdi_speed_div()

static int ftdi_speed_div ( int  speed,
int *  khz 
)
static

Definition at line 284 of file ftdi.c.

References ERROR_OK.

◆ ftdi_swd_init()

static int ftdi_swd_init ( void  )
static

◆ ftdi_swd_queue_cmd()

◆ ftdi_swd_read_reg()

static void ftdi_swd_read_reg ( uint8_t  cmd,
uint32_t *  value,
uint32_t  ap_delay_clk 
)
static

Definition at line 1188 of file ftdi.c.

References cmd, ftdi_swd_queue_cmd(), and SWD_CMD_RNW.

◆ ftdi_swd_run_queue()

◆ ftdi_swd_swdio_en()

static void ftdi_swd_swdio_en ( bool  enable)
static

◆ ftdi_swd_switch_seq()

static int ftdi_swd_switch_seq ( enum swd_special_seq  seq)
static

Definition at line 1200 of file ftdi.c.

◆ ftdi_swd_write_reg()

static void ftdi_swd_write_reg ( uint8_t  cmd,
uint32_t  value,
uint32_t  ap_delay_clk 
)
static

Definition at line 1194 of file ftdi.c.

References cmd, ftdi_swd_queue_cmd(), NULL, and SWD_CMD_RNW.

◆ move_to_state()

static void move_to_state ( tap_state_t  goal_state)
static

Function move_to_state moves the TAP controller from the current state to a goal_state through a path given by tap_get_tms_path().

State transition logging is performed by delegation to clock_tms().

Parameters
goal_stateis the destination state for the move.

Definition at line 240 of file ftdi.c.

References ftdi_jtag_mode, LOG_DEBUG_IO, mpsse_clock_tms_cs_out(), tap_get_state(), tap_get_tms_path(), tap_get_tms_path_len(), tap_set_state, tap_state_name(), and tap_state_transition().

Referenced by ftdi_execute_runtest(), ftdi_execute_scan(), and ftdi_execute_statemove().

Variable Documentation

◆ direction

◆ freq

int freq
static

Definition at line 116 of file ftdi.c.

Referenced by FLASH_BANK_COMMAND_HANDLER(), and ftdi_initialize().

◆ ftdi_adapter_driver

struct adapter_driver ftdi_adapter_driver
Initial value:
= {
.name = "ftdi",
.transports = ftdi_transports,
.commands = ftdi_command_handlers,
.init = ftdi_initialize,
.quit = ftdi_quit,
.reset = ftdi_reset,
.speed = ftdi_speed,
.khz = ftdi_khz,
.speed_div = ftdi_speed_div,
.jtag_ops = &ftdi_interface,
.swd_ops = &ftdi_swd,
}
static const struct command_registration ftdi_command_handlers[]
Definition: ftdi.c:989
static struct jtag_interface ftdi_interface
Definition: ftdi.c:1256
static int ftdi_speed(int speed)
Definition: ftdi.c:268
static const struct swd_driver ftdi_swd
Definition: ftdi.c:1246
static const char *const ftdi_transports[]
Definition: ftdi.c:1254
static int ftdi_reset(int trst, int srst)
Definition: ftdi.c:524
static int ftdi_khz(int khz, int *jtag_speed)
Definition: ftdi.c:290
static int ftdi_speed_div(int speed, int *khz)
Definition: ftdi.c:284
static int ftdi_initialize(void)
Definition: ftdi.c:649
static int ftdi_quit(void)
Definition: ftdi.c:695

Definition at line 1254 of file ftdi.c.

◆ ftdi_channel

uint8_t ftdi_channel
static

Definition at line 82 of file ftdi.c.

Referenced by COMMAND_HANDLER(), and ftdi_initialize().

◆ ftdi_command_handlers

const struct command_registration ftdi_command_handlers[]
static
Initial value:
= {
{
.name = "ftdi",
.mode = COMMAND_ANY,
.help = "perform ftdi management",
.usage = "",
},
}
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
@ COMMAND_ANY
Definition: command.h:42
static const struct command_registration ftdi_subcommand_handlers[]
Definition: ftdi.c:925
const char * usage
a string listing the options and arguments, required or optional
Definition: command.h:235

Definition at line 902 of file ftdi.c.

◆ ftdi_device_desc

char* ftdi_device_desc
static

Definition at line 81 of file ftdi.c.

Referenced by COMMAND_HANDLER(), ftdi_initialize(), and ftdi_quit().

◆ ftdi_interface

struct jtag_interface ftdi_interface
static
Initial value:
= {
.supported = DEBUG_CAP_TMS_SEQ,
.execute_queue = ftdi_execute_queue,
}
static int ftdi_execute_queue(void)
Definition: ftdi.c:627
#define DEBUG_CAP_TMS_SEQ
Definition: interface.h:189

Definition at line 1254 of file ftdi.c.

◆ ftdi_jtag_mode

◆ ftdi_pid

uint16_t ftdi_pid[MAX_USB_IDS+1] = { 0 }
static

Definition at line 90 of file ftdi.c.

Referenced by COMMAND_HANDLER(), and ftdi_initialize().

◆ ftdi_subcommand_handlers

const struct command_registration ftdi_subcommand_handlers[]
static

Definition at line 902 of file ftdi.c.

◆ ftdi_swd

const struct swd_driver ftdi_swd
static
Initial value:
= {
.init = ftdi_swd_init,
.switch_seq = ftdi_swd_switch_seq,
.read_reg = ftdi_swd_read_reg,
.write_reg = ftdi_swd_write_reg,
}
static int ftdi_swd_init(void)
Definition: ftdi.c:1028
static void ftdi_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
Definition: ftdi.c:1188
static int ftdi_swd_run_queue(void)
Flush the MPSSE queue and process the SWD transaction queue.
Definition: ftdi.c:1064
static void ftdi_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
Definition: ftdi.c:1194
static int ftdi_swd_switch_seq(enum swd_special_seq seq)
Definition: ftdi.c:1200

Definition at line 1200 of file ftdi.c.

◆ ftdi_transports

const char* const ftdi_transports[] = { "jtag", "swd", NULL }
static

Definition at line 1254 of file ftdi.c.

◆ ftdi_vid

uint16_t ftdi_vid[MAX_USB_IDS+1] = { 0 }
static

Definition at line 89 of file ftdi.c.

Referenced by COMMAND_HANDLER(), and ftdi_initialize().

◆ jtag_direction_init

uint16_t jtag_direction_init
static

Definition at line 121 of file ftdi.c.

Referenced by COMMAND_HANDLER(), ftdi_initialize(), and ftdi_swd_swdio_en().

◆ jtag_output_init

uint16_t jtag_output_init
static

Definition at line 120 of file ftdi.c.

Referenced by COMMAND_HANDLER(), and ftdi_initialize().

◆ mpsse_ctx

struct mpsse_ctx* mpsse_ctx
static

Definition at line 92 of file ftdi.c.

◆ output

◆ queued_retval

int queued_retval
static

Definition at line 115 of file ftdi.c.

Referenced by ftdi_swd_queue_cmd(), and ftdi_swd_run_queue().

◆ signals

struct signal* signals
static

Definition at line 105 of file ftdi.c.

Referenced by create_signal(), find_signal_by_name(), and ftdi_quit().

◆ swd_cmd_queue

struct swd_cmd_queue_entry * swd_cmd_queue
static

◆ swd_cmd_queue_alloced

size_t swd_cmd_queue_alloced
static

Definition at line 114 of file ftdi.c.

Referenced by ftdi_swd_init(), and ftdi_swd_queue_cmd().

◆ swd_cmd_queue_length

size_t swd_cmd_queue_length
static

Definition at line 113 of file ftdi.c.

Referenced by ftdi_swd_queue_cmd(), and ftdi_swd_run_queue().

◆ swd_mode

bool swd_mode
static

Definition at line 85 of file ftdi.c.

Referenced by ftdi_initialize(), ftdi_reset(), ftdi_speed(), and ftdi_swd_init().