Steve Tell
2017-06-30 04:10:08 UTC
Here's another patch I've had kicking around for a while, now cleaned up a
bit.
I was having a problem using an ARM-OCD-USB-H cable where after using the
interactive "frequency" command, the TCK frequency was 5 times what I
wanted.
The ARM-OCD-USB vs ARM-OCD-USB-H cables are wired pretty much the same,
but for the "H" chip on the latter.
The only distinction made in the tap/cable/ft2232.c between the H and
non-H versions is in
calling of ft2232_set_frequency() vs ft2232h_set_frequency() for
ARM-USB-OCD-H. ft2232h_set_frequency() is only called in intitial
setup, and ft2232_set_frequency is called afterwards. The result is
that user-requested TCK frequencies are 5x what the user asked for.
It looks like the driver tables were assuming they could call
ft2232_set_frequency() as a generic thing for either chip. But that's
not correct: the calculation for FT2232H is different once the divider
is disabled to take it out of FT2232 compatibility mode.
This was most clear in the ARM-OCD-USB vs ARM-OCD-USB-H cable drivers,
whose short init routines both call ft2232_armusbocd_init_common
with an is_ft2232h argument of 0 and 1, respectively.
The fix in this patch:
- store the value of is_ft2232h from init time in the params struct
- make a single compatible ft2232_set_frequency() function, which uses
the is_ft2232h flag to determine the base (maximum) rate for the divider
calculation.
another change I considered but decided not to make:
- if the requested frequency is less than the maximum for non-H
parts, we could change back to non-H compatibility mode, 6 MHz base frequency.
- but except for not being able to hit very low frequencies,
this actually is less flexible, as the frequencies available are very coarse
near the 6 MHz limit.
So instead, I left things as they were before; FT2232H chips always use
the 30 MHz base frequency, which results in a minimum frequency of 457
Hz - which should be slow enough for everyone.
Another issue that we don't address: some cables have comments about
maximum frequencies that are lower than the chip's maximum TCK rate
for other hardware reasons. This suggested-maximum is still set in
the init routines, and is still not rememembered. So users invoking
the "frequency" command or python set_frequency() method still need to
be aware of their hardware's limitations when overriding the default TCK
frequency.
One last cleanup included: rather than calling ft2232_set_frequency
(cable, FT2232_MAX_TCK_FREQ); or ft2232_set_frequency (cable,
FT2232H_MAX_TCK_FREQ); in all of the init routines, we can simply call:
ft2232_set_frequency (cable, 0) in all of the init routines, because
ft2232_set_frequency() defaults to setting the maximum frequency. This
makes the code clear that most cables set the default, and makes the few
non-default cases stand out.
Note that when using FT2232H/FT4232H cables, the default of 30 MHz
requires careful attention to the electrical environment of the JTAG
signals. long ribbon cables are likely to be problematic - or at least
seldom work for me.
So users may need to set a lower frequency, and its nice when the
frequency requested is actually what gets set.
bit.
I was having a problem using an ARM-OCD-USB-H cable where after using the
interactive "frequency" command, the TCK frequency was 5 times what I
wanted.
The ARM-OCD-USB vs ARM-OCD-USB-H cables are wired pretty much the same,
but for the "H" chip on the latter.
The only distinction made in the tap/cable/ft2232.c between the H and
non-H versions is in
calling of ft2232_set_frequency() vs ft2232h_set_frequency() for
ARM-USB-OCD-H. ft2232h_set_frequency() is only called in intitial
setup, and ft2232_set_frequency is called afterwards. The result is
that user-requested TCK frequencies are 5x what the user asked for.
It looks like the driver tables were assuming they could call
ft2232_set_frequency() as a generic thing for either chip. But that's
not correct: the calculation for FT2232H is different once the divider
is disabled to take it out of FT2232 compatibility mode.
This was most clear in the ARM-OCD-USB vs ARM-OCD-USB-H cable drivers,
whose short init routines both call ft2232_armusbocd_init_common
with an is_ft2232h argument of 0 and 1, respectively.
The fix in this patch:
- store the value of is_ft2232h from init time in the params struct
- make a single compatible ft2232_set_frequency() function, which uses
the is_ft2232h flag to determine the base (maximum) rate for the divider
calculation.
another change I considered but decided not to make:
- if the requested frequency is less than the maximum for non-H
parts, we could change back to non-H compatibility mode, 6 MHz base frequency.
- but except for not being able to hit very low frequencies,
this actually is less flexible, as the frequencies available are very coarse
near the 6 MHz limit.
So instead, I left things as they were before; FT2232H chips always use
the 30 MHz base frequency, which results in a minimum frequency of 457
Hz - which should be slow enough for everyone.
Another issue that we don't address: some cables have comments about
maximum frequencies that are lower than the chip's maximum TCK rate
for other hardware reasons. This suggested-maximum is still set in
the init routines, and is still not rememembered. So users invoking
the "frequency" command or python set_frequency() method still need to
be aware of their hardware's limitations when overriding the default TCK
frequency.
One last cleanup included: rather than calling ft2232_set_frequency
(cable, FT2232_MAX_TCK_FREQ); or ft2232_set_frequency (cable,
FT2232H_MAX_TCK_FREQ); in all of the init routines, we can simply call:
ft2232_set_frequency (cable, 0) in all of the init routines, because
ft2232_set_frequency() defaults to setting the maximum frequency. This
makes the code clear that most cables set the default, and makes the few
non-default cases stand out.
Note that when using FT2232H/FT4232H cables, the default of 30 MHz
requires careful attention to the electrical environment of the JTAG
signals. long ribbon cables are likely to be problematic - or at least
seldom work for me.
So users may need to set a lower frequency, and its nice when the
frequency requested is actually what gets set.