frequency: Implement for ftdi.

For all 2232H types, use undivided 60 Mhz.
FIXME: Check FT2322C/D for unsymetric clock at 6 MHz!
This commit is contained in:
Uwe Bonnes 2020-11-20 14:07:48 +01:00
parent 13e8a262e4
commit 28a966a3e6
3 changed files with 52 additions and 0 deletions

View File

@ -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));
}

View File

@ -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

View File

@ -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;