From f293cc4bc19409ac77287f0e7298801d55e42b11 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Thu, 10 Feb 2011 15:24:54 +1300 Subject: [PATCH] Improved Linux/libftdi platform support. Tested with Floss-JTAG. SWD working. --- src/linux/jtagtap.c | 87 ++++--------------------------------------- src/linux/platform.c | 88 +++++++++++++++++++++++++++++++++++++++++++- src/linux/platform.h | 6 ++- src/linux/swdptap.c | 57 ++++------------------------ src/main.c | 4 -- src/stm32/gdb_if.c | 7 ---- src/stm32/platform.c | 4 ++ 7 files changed, 112 insertions(+), 141 deletions(-) diff --git a/src/linux/jtagtap.c b/src/linux/jtagtap.c index fac44bb..ba1ab90 100644 --- a/src/linux/jtagtap.c +++ b/src/linux/jtagtap.c @@ -50,76 +50,11 @@ #define TMS 0x08 #define nSRST 0x20 -struct ftdi_context *ftdic; - -#define BUF_SIZE 4096 -static uint8_t outbuf[BUF_SIZE]; -static uint16_t bufptr = 0; - -static void buffer_flush(void) -{ - assert(ftdi_write_data(ftdic, outbuf, bufptr) == bufptr); -// printf("FT2232 buffer flush: %d bytes\n", bufptr); - bufptr = 0; -} - -static int buffer_write(const uint8_t *data, int size) -{ - if((bufptr + size) / BUF_SIZE > 0) buffer_flush(); - memcpy(outbuf + bufptr, data, size); - bufptr += size; - return size; -} - -static int buffer_read(uint8_t *data, int size) -{ - int index = 0; - buffer_flush(); - while((index += ftdi_read_data(ftdic, data + index, size-index)) != size); - return size; -} - - int jtagtap_init(void) { int err; - if(ftdic) { - ftdi_usb_close(ftdic); - ftdi_free(ftdic); - ftdic = NULL; - } - if((ftdic = ftdi_new()) == NULL) { - fprintf(stderr, "ftdi_new: %s\n", - ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_set_interface(ftdic, INTERFACE_A)) != 0) { - fprintf(stderr, "ftdi_set_interface: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_usb_open(ftdic, FT2232_VID, FT2232_PID)) != 0) { - fprintf(stderr, "unable to open ftdi device: %d (%s)\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - - if((err = ftdi_set_latency_timer(ftdic, 1)) != 0) { - fprintf(stderr, "ftdi_set_latency_timer: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_set_baudrate(ftdic, 1000000)) != 0) { - fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_usb_purge_buffers(ftdic)) != 0) { - fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } + assert(ftdic != NULL); if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_MPSSE)) != 0) { fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", @@ -129,12 +64,6 @@ int jtagtap_init(void) assert(ftdi_write_data(ftdic, "\x86\x00\x00\x80\xA8\xAB", 6) == 6); - if((err = ftdi_write_data_set_chunksize(ftdic, BUF_SIZE)) != 0) { - fprintf(stderr, "ftdi_write_data_set_chunksize: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - /* Go to JTAG mode for SWJ-DP */ for(int i = 0; i <= 50; i++) jtagtap_next(1, 0); /* Reset SW-DP */ jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */ @@ -150,7 +79,7 @@ void jtagtap_reset(void) void jtagtap_srst(void) { - buffer_flush(); + platform_buffer_flush(); //ftdi_write_data(ftdic, "\x80\x88\xAB", 3); //usleep(1000); //ftdi_write_data(ftdic, "\x80\xA8\xAB", 3); @@ -167,7 +96,7 @@ jtagtap_tms_seq(uint32_t MS, int ticks) tmp[2] = 0x80 | (MS & 0x7F); // assert(ftdi_write_data(ftdic, tmp, 3) == 3); - buffer_write(tmp, 3); + platform_buffer_write(tmp, 3); MS >>= 7; ticks -= 7; } } @@ -207,7 +136,7 @@ jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) tmp[index++] = (*DI)>>rticks?0x81:0x01; } // assert(ftdi_write_data(ftdic, tmp, index) == index); - buffer_write(tmp, index); + platform_buffer_write(tmp, index); } #endif @@ -248,10 +177,10 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int tmp[index++] = (*DI)>>rticks?0x81:0x01; } // assert(ftdi_write_data(ftdic, tmp, index) == index); - buffer_write(tmp, index); + platform_buffer_write(tmp, index); // index = 0; // while((index += ftdi_read_data(ftdic, tmp + index, rsize-index)) != rsize); - buffer_read(tmp, rsize); + platform_buffer_read(tmp, rsize); /*for(index = 0; index < rsize; index++) printf("%02X ", tmp[index]); printf("\n");*/ @@ -281,8 +210,8 @@ uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDO) tmp[2] = (dTDO?0x80:0) | (dTMS?0x01:0); // assert(ftdi_write_data(ftdic, tmp, 3) == 3); // while(ftdi_read_data(ftdic, &ret, 1) != 1); - buffer_write(tmp, 3); - buffer_read(&ret, 1); + platform_buffer_write(tmp, 3); + platform_buffer_read(&ret, 1); ret &= 0x80; diff --git a/src/linux/platform.c b/src/linux/platform.c index c18d8a6..e526578 100644 --- a/src/linux/platform.c +++ b/src/linux/platform.c @@ -18,6 +18,92 @@ * along with this program. If not, see . */ #include "platform.h" +#include "gdb_if.h" +#include "jtag_scan.h" -int platform_init(void) { return 0; } +#include +#include +#include + +struct ftdi_context *ftdic; + +#define BUF_SIZE 4096 +static uint8_t outbuf[BUF_SIZE]; +static uint16_t bufptr = 0; + +int platform_init(void) +{ + int err; + + if(ftdic) { + ftdi_usb_close(ftdic); + ftdi_free(ftdic); + ftdic = NULL; + } + if((ftdic = ftdi_new()) == NULL) { + fprintf(stderr, "ftdi_new: %s\n", + ftdi_get_error_string(ftdic)); + abort(); + } + if((err = ftdi_set_interface(ftdic, INTERFACE_A)) != 0) { + fprintf(stderr, "ftdi_set_interface: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + if((err = ftdi_usb_open(ftdic, FT2232_VID, FT2232_PID)) != 0) { + fprintf(stderr, "unable to open ftdi device: %d (%s)\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + + if((err = ftdi_set_latency_timer(ftdic, 1)) != 0) { + fprintf(stderr, "ftdi_set_latency_timer: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + if((err = ftdi_set_baudrate(ftdic, 1000000)) != 0) { + fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + if((err = ftdi_usb_purge_buffers(ftdic)) != 0) { + fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + if((err = ftdi_write_data_set_chunksize(ftdic, BUF_SIZE)) != 0) { + fprintf(stderr, "ftdi_write_data_set_chunksize: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + + assert(gdb_if_init() == 0); + + jtag_scan(); + + return 0; +} + +void platform_buffer_flush(void) +{ + assert(ftdi_write_data(ftdic, outbuf, bufptr) == bufptr); +// printf("FT2232 platform_buffer flush: %d bytes\n", bufptr); + bufptr = 0; +} + +int platform_buffer_write(const uint8_t *data, int size) +{ + if((bufptr + size) / BUF_SIZE > 0) platform_buffer_flush(); + memcpy(outbuf + bufptr, data, size); + bufptr += size; + return size; +} + +int platform_buffer_read(uint8_t *data, int size) +{ + int index = 0; + platform_buffer_flush(); + while((index += ftdi_read_data(ftdic, data + index, size-index)) != size); + return size; +} diff --git a/src/linux/platform.h b/src/linux/platform.h index 6859bac..ffe07a6 100644 --- a/src/linux/platform.h +++ b/src/linux/platform.h @@ -25,7 +25,7 @@ #include #define FT2232_VID 0x0403 -#define FT2232_PID 0xbcd9 +#define FT2232_PID 0x6010 #define SET_RUN_STATE(state) #define SET_IDLE_STATE(state) @@ -41,5 +41,9 @@ extern struct ftdi_context *ftdic; int platform_init(void); +void platform_buffer_flush(void); +int platform_buffer_write(const uint8_t *data, int size); +int platform_buffer_read(uint8_t *data, int size); + #endif diff --git a/src/linux/swdptap.c b/src/linux/swdptap.c index 0958183..ecd5acc 100644 --- a/src/linux/swdptap.c +++ b/src/linux/swdptap.c @@ -29,50 +29,12 @@ #include "platform.h" #include "swdptap.h" -#define BUF_SIZE 4096 - int swdptap_init(void) { int err; - if(ftdic) { - ftdi_usb_close(ftdic); - ftdi_free(ftdic); - ftdic = NULL; - } - if((ftdic = ftdi_new()) == NULL) { - fprintf(stderr, "ftdi_new: %s\n", - ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_set_interface(ftdic, INTERFACE_A)) != 0) { - fprintf(stderr, "ftdi_set_interface: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_usb_open(ftdic, FT2232_VID, FT2232_PID)) != 0) { - fprintf(stderr, "unable to open ftdi device: %d (%s)\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } + assert(ftdic != NULL); - if((err = ftdi_set_latency_timer(ftdic, 1)) != 0) { - fprintf(stderr, "ftdi_set_latency_timer: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_set_baudrate(ftdic, 1000000)) != 0) { - fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - if((err = ftdi_usb_purge_buffers(ftdic)) != 0) { - fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - - printf("enabling bitbang mode(channel 1)\n"); if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_BITBANG)) != 0) { fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", err, ftdi_get_error_string(ftdic)); @@ -81,14 +43,9 @@ int swdptap_init(void) assert(ftdi_write_data(ftdic, "\xAB\xA8", 2) == 2); - if((err = ftdi_write_data_set_chunksize(ftdic, BUF_SIZE)) != 0) { - fprintf(stderr, "ftdi_write_data_set_chunksize: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - /* This must be investigated in more detail. * As described in STM32 Reference Manual... */ + swdptap_seq_out(0xFFFF, 16); swdptap_reset(); swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */ swdptap_reset(); @@ -108,7 +65,8 @@ void swdptap_turnaround(uint8_t dir) { static uint8_t olddir = 0; - DEBUG("%s", dir ? "\n-> ":"\n<- "); + //DEBUG("%s", dir ? "\n-> ":"\n<- "); + platform_buffer_flush(); if(dir == olddir) return; olddir = dir; @@ -132,7 +90,7 @@ uint8_t swdptap_bit_in(void) ret &= 0x08; ftdi_write_data(ftdic, "\xA1\xA0", 2); - DEBUG("%d", ret?1:0); + //DEBUG("%d", ret?1:0); return ret; } @@ -141,13 +99,14 @@ void swdptap_bit_out(uint8_t val) { uint8_t buf[3] = "\xA0\xA1\xA0"; - DEBUG("%d", val); + //DEBUG("%d", val); if(val) { for(int i = 0; i < 3; i++) buf[i] |= 0x08; } - ftdi_write_data(ftdic, buf, 3); + //ftdi_write_data(ftdic, buf, 3); + platform_buffer_write(buf, 3); } uint32_t swdptap_seq_in(int ticks) diff --git a/src/main.c b/src/main.c index 0ca7b94..4b46764 100644 --- a/src/main.c +++ b/src/main.c @@ -37,10 +37,6 @@ int main(void) { assert(platform_init() == 0); - assert(gdb_if_init() == 0); - - jtag_scan(); -// adiv5_swdp_scan(); PLATFORM_SET_FATAL_ERROR_RECOVERY(); diff --git a/src/stm32/gdb_if.c b/src/stm32/gdb_if.c index ca0b520..852b43f 100644 --- a/src/stm32/gdb_if.c +++ b/src/stm32/gdb_if.c @@ -35,13 +35,6 @@ static uint32_t out_ptr; static uint8_t buffer_out[VIRTUAL_COM_PORT_DATA_SIZE]; static uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE]; -int gdb_if_init(void) -{ - cdcacm_init(); - - return 0; -} - void gdb_if_putchar(unsigned char c, int flush) { buffer_in[count_in++] = c; diff --git a/src/stm32/platform.c b/src/stm32/platform.c index 44e0f62..1760595 100644 --- a/src/stm32/platform.c +++ b/src/stm32/platform.c @@ -85,6 +85,10 @@ platform_init(void) /* Enable IRQs */ nvic_enable_irq(NVIC_TIM2_IRQ); + cdcacm_init(); + + jtag_scan(); + return 0; }