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 +- tcl/board/olimex_efm32g880f128.cfg | 6 ++ tcl/chip/energymicro/efm32.tcl | 3 + tcl/interface/olimex-arm-usb-tiny-h+swd.cfg | 31 ++++++++ tcl/target/efm32.cfg | 77 ++++++++++++++++++++ 6 files changed, 207 insertions(+), 25 deletions(-) create mode 100644 tcl/board/olimex_efm32g880f128.cfg create mode 100644 tcl/chip/energymicro/efm32.tcl create mode 100644 tcl/interface/olimex-arm-usb-tiny-h+swd.cfg create mode 100644 tcl/target/efm32.cfg 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. */ diff --git a/tcl/board/olimex_efm32g880f128.cfg b/tcl/board/olimex_efm32g880f128.cfg new file mode 100644 index 00000000..ffa26d59 --- /dev/null +++ b/tcl/board/olimex_efm32g880f128.cfg @@ -0,0 +1,6 @@ +# # Work-area size (RAM size) = 20kB for STM32F103RB device +# set WORKAREASIZE 0x5000 + +# CPUIDTAP 0x2BA01477 + +source [find target/efm32.cfg] diff --git a/tcl/chip/energymicro/efm32.tcl b/tcl/chip/energymicro/efm32.tcl new file mode 100644 index 00000000..1dc9bd7f --- /dev/null +++ b/tcl/chip/energymicro/efm32.tcl @@ -0,0 +1,3 @@ +source [find cpu/arm/cortex_m3.tcl] + +# 0x2BA01477 diff --git a/tcl/interface/olimex-arm-usb-tiny-h+swd.cfg b/tcl/interface/olimex-arm-usb-tiny-h+swd.cfg new file mode 100644 index 00000000..3c4eb990 --- /dev/null +++ b/tcl/interface/olimex-arm-usb-tiny-h+swd.cfg @@ -0,0 +1,31 @@ +# +# Olimex ARM-USB-TINY-H with ARM-JTAG-SWD adapter. +# +# http://www.olimex.com/dev/arm-usb-tiny-h.html +# http://www.olimex.com/dev/arm-jtag-swd.html +# + +interface ft2232_swd +# ALl other examples have "Olimex OpenOCD JTAG ARM-USB-TINY-H", but my +# adaptor doesn't. +# ft2232_device_desc "Olimed Ltd." + +#ft2232_layout olimex-jtag +ft2232_layout olimex-swd + +ft2232_vid_pid 0x15ba 0x002a + +# TRST is used as RnW +# interface_signal add RnW 0x0100 + +# TMS is used as RnW +interface_signal add RnW 0x0008 + +# TRST + TMS is used as RnW +# interface_signal add RnW 0x0108 + +interface_signal add LED 0x0800 + +# interface_signal add SRST 0x0a00 + +adapter_khz 10 diff --git a/tcl/target/efm32.cfg b/tcl/target/efm32.cfg new file mode 100644 index 00000000..de5384cb --- /dev/null +++ b/tcl/target/efm32.cfg @@ -0,0 +1,77 @@ +# script for Energy Micro's efm32 + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME efm32 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# Work-area is a space in RAM used for flash programming +# By default use 16kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x4000 +} + +# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz +adapter_khz 1000 + +adapter_nsrst_delay 100 +# jtag_ntrst_delay 100 + +#jtag scan chain +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0008 + # Section 26.6.3 + set _CPUTAPID 0x3ba00477 +} +# jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +swd newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID ] } { + # FIXME this never gets used to override defaults... + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0008 + # Section 29.6.2 + # Low density devices, Rev A + set _BSTAPID1 0x06412041 + # Medium density devices, Rev A + set _BSTAPID2 0x06410041 + # Medium density devices, Rev B and Rev Z + set _BSTAPID3 0x16410041 + set _BSTAPID4 0x06420041 + # High density devices, Rev A + set _BSTAPID5 0x06414041 + # Connectivity line devices, Rev A and Rev Z + set _BSTAPID6 0x06418041 + # XL line devices, Rev A + set _BSTAPID7 0x06430041 +} +# jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ +swd newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \ + -expected-id $_BSTAPID2 -expected-id $_BSTAPID3 \ + -expected-id $_BSTAPID4 -expected-id $_BSTAPID5 \ + -expected-id $_BSTAPID6 -expected-id $_BSTAPID7 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +# flash size will be probed +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32x 0x08000000 0 0 0 $_TARGETNAME + +# if srst is not fitted use SYSRESETREQ to +# perform a soft reset +cortex_m3 reset_config sysresetreq -- cgit v1.2.3