From 2dcf57363a5c1c55940e5701e5ec047c37c54560 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Wed, 22 Feb 2012 00:06:18 +0100 Subject: A working version for my EFM board. --- src/jtag/drivers/ft2232.c | 109 ++++++++++++++++++++++++++------- src/transport/swd_libswd_drv_openocd.c | 6 +- 2 files changed, 90 insertions(+), 25 deletions(-) (limited to 'src') 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; diff --git a/src/transport/swd_libswd_drv_openocd.c b/src/transport/swd_libswd_drv_openocd.c index 2066d5b3..76fbc4d3 100644 --- a/src/transport/swd_libswd_drv_openocd.c +++ b/src/transport/swd_libswd_drv_openocd.c @@ -171,7 +171,8 @@ int swd_drv_mosi_trn(swd_ctx_t *swdctx, int bits){ int res, val=0; static char buf[SWD_TURNROUND_MAX_VAL]; /* Use driver method to set low (write) signal named RnW. */ - res=jtag_interface->bitbang(NULL, "RnW", 0, &val); +// res=jtag_interface->bitbang(NULL, "RnW", 0, &val); + res=jtag_interface->bitbang(NULL, "RnW", 0xFFFFFFFF, &val); if (res<0) return SWD_ERROR_DRIVER; /* Clock specified number of bits for proper TRN transaction. */ @@ -199,7 +200,8 @@ int swd_drv_miso_trn(swd_ctx_t *swdctx, int bits){ static char buf[SWD_TURNROUND_MAX_VAL]; /* Use driver method to set high (read) signal named RnW. */ - res=jtag_interface->bitbang(NULL, "RnW", 0xFFFFFFFF, &val); +// res=jtag_interface->bitbang(NULL, "RnW", 0xFFFFFFFF, &val); + res=jtag_interface->bitbang(NULL, "RnW", 0, &val); if (res<0) return SWD_ERROR_DRIVER; /* Clock specified number of bits for proper TRN transaction. */ -- cgit v1.2.3