summaryrefslogtreecommitdiff
path: root/src/jtag/drivers/ft2232.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jtag/drivers/ft2232.c')
-rw-r--r--src/jtag/drivers/ft2232.c109
1 files changed, 86 insertions, 23 deletions
diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c
index 4d417899..56ef54bf 100644
--- a/src/jtag/drivers/ft2232.c
+++ b/src/jtag/drivers/ft2232.c
@@ -71,7 +71,9 @@
* Hereafter this is called the "MPSSE Spec".
*
* The datasheet for the ftdichip.com's FT2232D part is here:
- * http://www.ftdichip.com/Documents/DataSheets/DS_FT2232D.pdf
+ * http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232D.pdf
+ * and for the FT2232H part it is here:
+ * http://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
@@ -168,17 +170,17 @@ static uint16_t ft2232_pid[MAX_USB_IDS + 1] = { 0x6010, 0 };
/** This structure describes different layout of FT2232 based devices. */
struct ft2232_layout {
- /// Layout name
+ // Layout name
char* name;
- /// Lyout specific initialization routine
+ // Layout specific initialization routine
int (*init)(void);
- /// Layout specific reset routine
+ // Layout specific reset routine
void (*reset)(int trst, int srst);
- /// Layout specific LED blink routine
+ // Layout specific LED blink routine
void (*blink)(void);
- /// Which FTDI channel does this layout use
+ // Which FTDI channel does this layout use
int channel;
- /// This will forbid bitbanging selected port pins
+ // This will forbid bitbanging selected port pins
int bitbang_deny;
};
@@ -188,6 +190,7 @@ static int jtagkey_init(void);
static int lm3s811_jtag_init(void);
static int icdi_jtag_init(void);
static int olimex_jtag_init(void);
+static int olimex_swd_init(void);
static int flyswatter_init(void);
static int minimodule_init(void);
static int turtle_init(void);
@@ -271,6 +274,11 @@ static const struct ft2232_layout ft2232_layouts[] =
.reset = olimex_jtag_reset,
.blink = olimex_jtag_blink
},
+ { .name = "olimex-swd",
+ .init = olimex_swd_init,
+ .reset = olimex_jtag_reset,
+ .blink = olimex_jtag_blink
+ },
{ .name = "flyswatter",
.init = flyswatter_init,
.reset = flyswatter_reset,
@@ -2245,16 +2253,14 @@ static int ft2232_execute_command(struct jtag_command *cmd)
switch (cmd->type)
{
- case JTAG_RESET: retval = ft2232_execute_reset(cmd); break;
- case JTAG_RUNTEST: retval = ft2232_execute_runtest(cmd); break;
- case JTAG_TLR_RESET: retval = ft2232_execute_statemove(cmd); break;
- case JTAG_PATHMOVE: retval = ft2232_execute_pathmove(cmd); break;
- case JTAG_SCAN: retval = ft2232_execute_scan(cmd); break;
- case JTAG_SLEEP: retval = ft2232_execute_sleep(cmd); break;
+ case JTAG_RESET: retval = ft2232_execute_reset(cmd); break;
+ case JTAG_RUNTEST: retval = ft2232_execute_runtest(cmd); break;
+ case JTAG_TLR_RESET: retval = ft2232_execute_statemove(cmd); break;
+ case JTAG_PATHMOVE: retval = ft2232_execute_pathmove(cmd); break;
+ case JTAG_SCAN: retval = ft2232_execute_scan(cmd); break;
+ case JTAG_SLEEP: retval = ft2232_execute_sleep(cmd); break;
case JTAG_STABLECLOCKS: retval = ft2232_execute_stableclocks(cmd); break;
- case JTAG_TMS:
- retval = ft2232_execute_tms(cmd);
- break;
+ case JTAG_TMS: retval = ft2232_execute_tms(cmd); break;
default:
LOG_ERROR("BUG: unknown JTAG command type encountered");
retval = ERROR_JTAG_QUEUE_FAILED;
@@ -3019,12 +3025,67 @@ static int olimex_jtag_init(void)
/* initialize low byte for jtag */
if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK)
{
- LOG_ERROR("couldn't initialize FT2232 with 'Olimex' layout");
+ LOG_ERROR("couldn't initialize FT2232 with 'olimex-jtag' layout");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ nTRST = 0x01;
+ nTRSTnOE = 0x04;
+ nSRST = 0x02;
+ nSRSTnOE = 0x00; /* no output enable for nSRST */
+
+ high_output = 0x0;
+ high_direction = 0x0f;
+
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
+ if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+ {
+ high_output |= nTRSTnOE;
+ high_output &= ~nTRST;
+ }
+ else
+ {
+ high_output &= ~nTRSTnOE;
+ high_output |= nTRST;
+ }
+
+ if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+ {
+ LOG_ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");
+ }
+ else
+ {
+ high_output &= ~nSRST;
+ }
+
+ /* turn red LED on */
+ high_output |= 0x08;
+
+ /* initialize high byte for jtag */
+ if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK)
+ {
+ LOG_ERROR("couldn't initialize FT2232 with 'olimex-jtag' layout");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ return ERROR_OK;
+}
+
+static int olimex_swd_init(void)
+{
+ low_output = 0x08;
+ low_direction = 0x1b;
+
+ /* initialize low byte for jtag */
+ if (ft2232_set_data_bits_low_byte(low_output,low_direction) != ERROR_OK)
+ {
+ LOG_ERROR("couldn't initialize FT2232 with 'olimex-swd' layout");
return ERROR_JTAG_INIT_FAILED;
}
nTRST = 0x01;
- nTRSTnOE = 0x4;
+ nTRST = 0x00; // We want TMS to be low at all time
+ nTRSTnOE = 0x04;
nSRST = 0x02;
nSRSTnOE = 0x00; /* no output enable for nSRST */
@@ -3032,6 +3093,8 @@ static int olimex_jtag_init(void)
high_direction = 0x0f;
enum reset_types jtag_reset_config = jtag_get_reset_config();
+ LOG_WARNING("jtag_reset_config & RESET_TRST_OPEN_DRAIN=%d", jtag_reset_config & RESET_TRST_OPEN_DRAIN);
+ printf("jtag_reset_config & RESET_TRST_OPEN_DRAIN=%d\n", jtag_reset_config & RESET_TRST_OPEN_DRAIN);
if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
{
high_output |= nTRSTnOE;
@@ -3058,7 +3121,7 @@ static int olimex_jtag_init(void)
/* initialize high byte for jtag */
if (ft2232_set_data_bits_high_byte(high_output,high_direction) != ERROR_OK)
{
- LOG_ERROR("couldn't initialize FT2232 with 'Olimex' layout");
+ LOG_ERROR("couldn't initialize FT2232 with 'olimex-swd' layout");
return ERROR_JTAG_INIT_FAILED;
}
@@ -4573,10 +4636,10 @@ static int ktlink_init_swd(void)
/* Low Byte (ADBUS) members. */
static uint8_t SWCLK=0x01, TDI=0x02, TDO=0x04, nSWDIOsel=0x20;
- nTRST = TRST;
- nSRST = SRST;
- nTRSTnOE = nTRSTen;
- nSRSTnOE = nSRSTen;
+ nTRST = TRST; // 0x01
+ nSRST = SRST; // 0x02
+ nTRSTnOE = nTRSTen; // 0x04
+ nSRSTnOE = nSRSTen; // 0x08
/* Set ADBUS Port Data: SWCLK=0, TDI=0,TDO=1, nSWDIOsel=0 */
low_output = 0 | TDO;