From 28a966a3e66665eaea34b8fc8217a05cfbfcecce Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 20 Nov 2020 14:07:48 +0100 Subject: [PATCH] frequency: Implement for ftdi. For all 2232H types, use undivided 60 Mhz. FIXME: Check FT2322C/D for unsymetric clock at 6 MHz! --- src/platforms/hosted/ftdi_bmp.c | 43 +++++++++++++++++++++++++++++++++ src/platforms/hosted/ftdi_bmp.h | 4 +++ src/platforms/hosted/platform.c | 5 ++++ 3 files changed, 52 insertions(+) diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c index d7ea3d7b..0d15113b 100644 --- a/src/platforms/hosted/ftdi_bmp.c +++ b/src/platforms/hosted/ftdi_bmp.c @@ -376,6 +376,18 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) } int index = 0; ftdi_init[index++]= LOOPBACK_END; /* FT2232D gets upset otherwise*/ + switch(ftdic->type) { + case TYPE_2232H: + case TYPE_4232H: + case TYPE_232H: + ftdi_init[index++] = EN_DIV_5; + break; + case TYPE_2232C: + break; + default: + DEBUG_WARN("FTDI Chip has no MPSSE\n"); + goto error_2; + } ftdi_init[index++]= TCK_DIVISOR; /* Use CLK/2 for about 50 % SWDCLK duty cycle on FT2232c.*/ ftdi_init[index++]= 1; @@ -618,3 +630,34 @@ const char *libftdi_target_voltage(void) } return NULL; } + +static uint16_t divisor; +void libftdi_max_frequency_set(uint32_t freq) +{ + uint32_t clock; + if (ftdic->type == TYPE_2232C) + clock = 12 * 1000 * 1000; + else + /* Undivided clock set during startup*/ + clock = 60 * 1000 * 1000; + uint32_t div = (clock + 2 * freq - 1)/ freq; + if ((div < 4) && (ftdic->type = TYPE_2232C)) + div = 4; /* Avoid bad unsymetrict FT2232C clock at 6 MHz*/ + divisor = div / 2 - 1; + uint8_t buf[3]; + buf[0] = TCK_DIVISOR; + buf[1] = divisor & 0xff; + buf[2] = (divisor >> 8) & 0xff; + libftdi_buffer_write(buf, 3); +} + +uint32_t libftdi_max_frequency_get(void) +{ + uint32_t clock; + if (ftdic->type == TYPE_2232C) + clock = 12 * 1000 * 1000; + else + /* Undivided clock set during startup*/ + clock = 60 * 1000 * 1000; + return clock/ ( 2 *(divisor + 1)); +} diff --git a/src/platforms/hosted/ftdi_bmp.h b/src/platforms/hosted/ftdi_bmp.h index 12c90223..ffb9e866 100644 --- a/src/platforms/hosted/ftdi_bmp.h +++ b/src/platforms/hosted/ftdi_bmp.h @@ -119,6 +119,8 @@ const char *libftdi_target_voltage(void) {return "ERROR";}; void libftdi_jtagtap_tdi_tdo_seq( uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) {}; bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;}; +void libftdi_max_frequency_set(uint32_t freq) {}; +uint32_t libftdi_max_frequency_get(void) {return 0;}; # pragma GCC diagnostic pop #else int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info); @@ -131,6 +133,8 @@ const char *libftdi_target_voltage(void); void libftdi_jtagtap_tdi_tdo_seq( uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks); bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd); +void libftdi_max_frequency_set(uint32_t freq); +uint32_t libftdi_max_frequency_get(void); #endif #define MPSSE_SK 1 diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c index 07aab72d..6578327f 100644 --- a/src/platforms/hosted/platform.c +++ b/src/platforms/hosted/platform.c @@ -331,6 +331,9 @@ void platform_max_frequency_set(uint32_t freq) case BMP_TYPE_CMSIS_DAP: dap_swj_clock(freq); break; + case BMP_TYPE_LIBFTDI: + libftdi_max_frequency_set(freq); + break; default: DEBUG_WARN("Setting max SWJ frequency not yet implemented\n"); break; @@ -345,6 +348,8 @@ uint32_t platform_max_frequency_get(void) case BMP_TYPE_CMSIS_DAP: return dap_swj_clock(0); break; + case BMP_TYPE_LIBFTDI: + return libftdi_max_frequency_get(); default: DEBUG_WARN("Reading max SWJ frequency not yet implemented\n"); break;