1
\$\begingroup\$

So. I've been trying for several days to get parallel data transfer from a Raspberry Pico through a FT232H to a host computer. I'd like ~25MB/s, which is why I'm trying this route in the first place.

I have a Raspberry Pico W, and two FT232H breakout boards ( https://www.amazon.com/dp/B09KGT5TGJ and https://www.adafruit.com/product/2264 , tested in that order ). I plug the Pico and breakout into breadboards, and then wire the two together. (After a full day of that not fully working, I have switched to ~3 inch breadboard wires directly between the breakout boards, which seems to have reduced the noise I was getting at the time, but the bad data remains.) I have a logic analyzer, and an oscilloscope, but the oscilloscope isn't fast enough to really keep up - it just turns into smooth sinewaves at the time scales involved.

I've several times gotten SOME data fast, but I keep running into these periodic segments of bad data. Like so: good data, then a streak of bad data, then more good data I've set the Pico to count up and output the 7 lowest bits. (Plus or minus some structure to help debugging, and slight variations tried over time.) I tried for hours to get synchronous FIFO to work, but the 60 MHz clock of the FT232H was a little too fast to respond to in time, even with the Pico overclocked to 280 MHz, especially once I figured out the Pico adds a ~3.5 cycle lag on GPIO inputs (by default). And my attempt to structure the output in a way that would work around the failure to synchronize with the clock still left these weird runs of bad data. Last night I switched to trying CPU FIFO mode, wherein basically I pull down two lines for 30 nanoseconds to write data, which I think may be a slower ultimate speed, but maybe still faster than the other options. On the first breakout I got some data, but also still the runs of bad data. On the second breakout it's just giving an I/O error. For the second board, I've tried simplifying down to the baremost possible, just 0s on all data lines, 0 on A0, pull down CS# for 5 ns, pull down RD# for 30 ns, pull up RD# for 5 ns, pull CS# up and wait for a while. Unless the chip secretly REQUIRES you to e.g. read status or check for incoming data or something, I think the datasheet indicates this should be how you write data. Have some pictures of the output of the logic analyzer. In these pictures (slightly mix-and-matched) I've only actually attached WR#, CS#, and D7 (which should and does stay 0).

logic analyzer, wide shot

4ns

29ns

And 4ns for that second ledge there, too. That seems to me probably close enough to the specs that it ought to work. (I also tried slightly longer times.) BUT I'm still just getting an I/O error. (If I disconnect the control lines I just get "failed to fill whole buffer".)

The oscilloscope says there's still some noise on the lines, that happens when the Pico is running, but I'm not sure what's exactly causing it, nor how to stop it, nor whether it's the cause of the problem, nor whether my oscilloscope is accurately reporting the noise.

I don't know if the problem is noise, or some kind of timing inaccuracy I've failed to account for, or if the FT232H doesn't like e.g. that I'm only writing and never reading (though the host never writes, so, it SHOULDN'T.). I don't know why one of the breakouts read bad data and the other gave an IO error; I thought they were the same chip. Can anybody shed any light on this? My top remaining option is to design and order a PCB with an RP2040 and an FT232H in close proximity with ground planes and all to try really hard to eliminate noise, but that's not really a great option, since that's a number of hours of design work, ordering a thing that may not actually fix the problem, waiting a week for it to arrive, and the traces will be too small to check with an analyzer or oscilloscope at that point so if there are still problems I won't really be able to debug further. :| Anybody see any clear mistake?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

That data you posted seems to show inserted data, but no lost data, so WR# is held low for longer than it should be. There's also some cases of the same data twice (e.g. -091 and nearby), so you're not updating the data fast enough, and it's being held for two of the clock cycles.

Have you had a look at the PIO state machines? One of those should be fine for sending data. If you want to receive as well, you'd use another SM.

If you could use the same clock source for both the RP2040 and the FT232H, you'd make all timing easier for yourself too. I think they both use 12MHz oscillators, so it should be straight-forward to share the oscillator clock.

I played with the FT2232H >10 years ago connected to an FPGA, and it was straight-forward because I sync'd everything to the 60MHz clock, and checked/updated all signals on the particular clock edge that meant I didn't have to worry about setup/hold times etc. I can't remember which edge it was, but there's only two to try :)

\$\endgroup\$
7
  • \$\begingroup\$ For synchronous FIFO, that would and probably sometimes was true (which is why I abandoned it for CPU FIFO), but CPU FIFO isn't synced to a clock, as far as the datasheet indicates - the pico pulls CS# low for 5ns, then pulls WR# low for 30ns to write data, then pulls WR# high again for 5ns and then CS# high, to finish the write. I don't remember if CS# needs to be brought high between writes, but it shouldn't break anything. The datasheet doesn't mention having to synchronize these changes with any other clock, so I don't know why I still got missed or duplicated or corrupted writes. \$\endgroup\$
    – Erhannis
    Commented Aug 19, 2023 at 18:07
  • \$\begingroup\$ I am indeed using the PIOs - it's how I got anywhere near as close as I have, haha. The idea to share an oscillator has potential. I'm currently waiting for those foretold PCBs to arrive, haha, so I guess around Tuesday we'll see if tightening up the connections and adding a ground plane fixed the problem. Otherwise maybe I'll redo the design to share an oscillator and reorder them, haha. :P Would I be able to just, drive the crystal from one chip, and connect the crystal to both chips' XINs? Or does it need extra circuitry to compensate for the presence of two chips or something? \$\endgroup\$
    – Erhannis
    Commented Aug 19, 2023 at 18:11
  • 1
    \$\begingroup\$ Re the shared clock, I'd assume you can connect from xout of one IC to Xin of the other IC via a wire, a resistor, or a capacitor. You can try it out on your existing PCB before ordering another \$\endgroup\$ Commented Aug 24, 2023 at 22:03
  • \$\begingroup\$ I've soldered the outputs of the two crystals together with a magnet wire, which feels bad, but does appear to synchronize the chips, and remove the runs of bad data. I'm not yet convinced I won't by chance start in a state out of phase with the clock etc., and there are still periodic skips, which I suspect are related to buffering issues - ironically, I suspect I may need the SIWU# pin, which is one of the few I DIDN'T connect on the pcb. So, progress is happening, but still trying to hammer out some problems. The dedicated "canWrite" transistor has merit - though input latency may nix it. \$\endgroup\$
    – Erhannis
    Commented Aug 25, 2023 at 3:12
  • \$\begingroup\$ I wouldn't think connecting the outputs together would be a good idea... \$\endgroup\$ Commented Aug 25, 2023 at 22:26
1
\$\begingroup\$

So, I think I figured it out. Apparently I wasn't actually in CPU FIFO mode? (Though I set the EEPROM as such, and I remember checking that the 60MHz clock had gone away.) See, FT_SetBitmode doesn't HAVE a mode for CPU FIFO. So I'd left it at Synchronous 245 FIFO, since that seemed the closest one. Removing that, and leaving FT_SetBitmode(Reset) alone, fixed the problem with runs of bad data. (I also needed to check the "can write" status on the PIO side, to fix the final remaining transfer errors.)

I don't understand how it worked AT ALL, given that CPU FIFO mode is wildly different from any other mode AFAICT. As I said, I think I checked that the clock signal had gone away, so I wasn't in sync FIFO mode anymore, so I don't know what mode I WAS in. Well, anyway.

The PCBs did work, btw, though they didn't fix the problem. At least they're tidier than this skywired mess. My code and PCBs are here and here, if you want them. Kindof a mess.

\$\endgroup\$
2
  • \$\begingroup\$ It should perhaps be noted I'm only getting like 8.5MB/s, sadly. \$\endgroup\$
    – Erhannis
    Commented Aug 24, 2023 at 2:54
  • \$\begingroup\$ Another note: writing data as fast as possible with no checks for whether it's received, CPU FIFO mode gets 17.7 MB/s, while SYNC FIFO mode gets 38.6 MB/s. \$\endgroup\$
    – Erhannis
    Commented Aug 25, 2023 at 3:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.