ftdi: drop divide_by_5 param, now it's automatically set/unset according to the frequency. Better freq display

This commit is contained in:
Gwenhael Goavec-Merou 2021-02-19 07:07:10 +01:00
parent 5f9a8835da
commit 7cc5676e8e
10 changed files with 41 additions and 31 deletions

View File

@ -35,8 +35,6 @@ class AnlogicCable : public JtagInterface {
virtual ~AnlogicCable();
int setClkFreq(uint32_t clkHZ) override;
int setClkFreq(uint32_t clkHZ, char use_divide_by_5) override {
(void)use_divide_by_5; return setClkFreq(clkHZ);}
/* TMS */
int writeTMS(uint8_t *tms, int len, bool flush_buffer) override;

View File

@ -35,8 +35,6 @@ class DirtyJtag : public JtagInterface {
virtual ~DirtyJtag();
int setClkFreq(uint32_t clkHZ) override;
int setClkFreq(uint32_t clkHZ, char use_divide_by_5) override {
(void)use_divide_by_5; return setClkFreq(clkHZ);}
/* TMS */
int writeTMS(uint8_t *tms, int len, bool flush_buffer) override;

View File

@ -41,8 +41,6 @@ class FtdiJtagBitBang : public JtagInterface, private FTDIpp_MPSSE {
virtual ~FtdiJtagBitBang();
int setClkFreq(uint32_t clkHZ) override;
int setClkFreq(uint32_t clkHZ, char use_divide_by_5) override {
return FTDIpp_MPSSE::setClkFreq(clkHZ, use_divide_by_5);}
/* TMS */
int writeTMS(uint8_t *tms, int len, bool flush_buffer) override;

View File

@ -41,8 +41,6 @@ class FtdiJtagMPSSE : public JtagInterface, private FTDIpp_MPSSE {
int setClkFreq(uint32_t clkHZ) override {
return FTDIpp_MPSSE::setClkFreq(clkHZ);
}
int setClkFreq(uint32_t clkHZ, char use_divide_by_5) override {
return FTDIpp_MPSSE::setClkFreq(clkHZ, use_divide_by_5);}
/* TMS */
int writeTMS(uint8_t *tms, int len, bool flush_buffer) override;

View File

@ -169,7 +169,7 @@ int FTDIpp_MPSSE::init(unsigned char latency, unsigned char bitmask_mode,
unsigned char buf1[5];
ftdi_read_data(_ftdi, buf1, 5);
if (setClkFreq(_clkHZ, 0) < 0)
if (setClkFreq(_clkHZ) < 0)
return -1;
int to_wr = 3;
@ -194,29 +194,31 @@ int FTDIpp_MPSSE::init(unsigned char latency, unsigned char bitmask_mode,
int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ)
{
return setClkFreq(clkHZ, 0);
}
int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ, char use_divide_by_5)
{
_clkHZ = clkHZ;
int ret;
bool use_divide_by_5;
uint8_t buffer[4] = { TCK_DIVISOR, 0x00, 0x00};
uint32_t base_freq;
uint32_t real_freq = 0;
float real_freq = 0;
uint16_t presc;
_clkHZ = clkHZ;
/* FT2232C has no divide by 5 instruction
* and default freq is 12MHz
*/
if (_ftdi->type != TYPE_2232C) {
base_freq = 60000000;
if (use_divide_by_5) {
/* use full speed only when freq > 6MHz
* => more freq resolution using
* 2^16 to describe 0 -> 6MHz
*/
if (clkHZ > 6000000) {
use_divide_by_5 = false;
mpsse_store(DIS_DIV_5);
} else {
use_divide_by_5 = true;
base_freq /= 5;
mpsse_store(EN_DIV_5);
} else {
mpsse_store(DIS_DIV_5);
}
} else {
base_freq = 12000000;
@ -240,10 +242,33 @@ int FTDIpp_MPSSE::setClkFreq(uint32_t clkHZ, char use_divide_by_5)
if (real_freq > _clkHZ)
presc ++;
real_freq = base_freq / ((1+presc)*2);
printInfo("Jtag frequency : requested " + std::to_string(clkHZ) +
"Hz -> real " + std::to_string(real_freq) + "Hz");
display("presc : %d input freq : %d requested freq : %d real freq : %d\n",
/* just to have a better display */
string clkHZ_str(10, ' ');
string real_freq_str(10, ' ');
if (clkHZ >= 1e6)
snprintf(&clkHZ_str[0], 9, "%2.2fMHz", clkHZ / 1e6);
else if (clkHZ >= 1e3)
snprintf(&clkHZ_str[0], 10, "%3.2fKHz", clkHZ / 1e3);
else
snprintf(&clkHZ_str[0], 10, "%3d.00Hz", clkHZ);
if (real_freq >= 1e6)
snprintf(&real_freq_str[0], 9, "%2.2fMHz", real_freq / 1e6);
else if (real_freq >= 1e3)
snprintf(&real_freq_str[0], 10, "%3.2fKHz", real_freq / 1e3);
else
snprintf(&real_freq_str[0], 10, "%3.2fHz", real_freq);
printInfo("Jtag frequency : requested " + clkHZ_str +
" -> real " + real_freq_str);
display("presc : %d input freq : %d requested freq : %d real freq : %f\n",
presc, base_freq, _clkHZ, real_freq);
/*printf("base freq %d div by 5 %c presc %d\n", base_freq, (use_divide_by_5)?'1':'0',
presc); */
buffer[1] = presc & 0xff;
buffer[2] = (presc >> 8) & 0xff;

View File

@ -22,7 +22,6 @@ class FTDIpp_MPSSE {
int init(unsigned char latency, unsigned char bitmask_mode,
unsigned char mode);
int setClkFreq(uint32_t clkHZ);
int setClkFreq(uint32_t clkHZ, char use_divide_by_5);
int vid() {return _vid;}
int pid() {return _pid;}

View File

@ -87,7 +87,7 @@ Gowin::Gowin(Jtag *jtag, const string filename, Device::prog_type_t prg_type,
throw std::runtime_error("incompatible file format");
}
}
_jtag->setClkFreq(2500000, 0);
_jtag->setClkFreq(2500000);
/* erase and program flash differ for GW1N1 */
if (idCode() == 0x0900281B)

View File

@ -35,8 +35,6 @@ class Jtag {
/* maybe to update */
int setClkFreq(uint32_t clkHZ) { return _jtag->setClkFreq(clkHZ);}
int setClkFreq(uint32_t clkHZ, char use_divide_by_5) {
return _jtag->setClkFreq(clkHZ, use_divide_by_5);}
int detectChain(std::vector<int> &devices, int max_dev);

View File

@ -33,7 +33,6 @@ class JtagInterface {
virtual ~JtagInterface() {}
virtual int setClkFreq(uint32_t clkHZ) = 0;
virtual int setClkFreq(uint32_t clkHZ, char use_divide_by_5) = 0;
/*!
* \brief flush TMS internal buffer (ie. transmit to converter)

View File

@ -39,9 +39,6 @@ class UsbBlaster : public JtagInterface {
virtual ~UsbBlaster();
int setClkFreq(uint32_t clkHZ) override;
int setClkFreq(uint32_t clkHZ, char use_divide_by_5) override {
(void)clkHZ; (void) use_divide_by_5;
return 1;}
/*!
* \brief drive TMS to move in JTAG state machine