There's a requirement for Project Egbert (graven in stone by one of the customers, but it's been on the highly-desirable list for in-house use all along) that the firmware, including the FPGA configuration, be field-upgradeable via the RS-232 debug port.
Well, what with the nuisance factor of reprogramming the FPGA's configuration PROM using iMPACT version 11, I thought I'd go ahead and implement FPGA upgrade this weekend.
The obvious approach is to shove the hex file (Intel MCS format) down the wire, using XON/XOFF flow control ('cause there's no hardware flow control on that port), convert to binary, and write the pages out to the serial flash as they fill up.
Well.
Being in a bit of a rush, I decided not to take the time to implement proper soft flow control in the AGROS serial-port handler, but instead threw together a test routine that (given that the serial port is configured with a suitably large ring buffer) does flow control at the application level, converts hex to binary, and goes to sleep for 20 ms every 512 bytes to simulate flash-writing activity.
The hex file is 780476 bytes long, containing 283776 bytes of configuration data, or 555 flash blocks. At 115200 bits/sec and 10 bits/character, the transfer time ought, theoretically, to be 67.75 seconds, and the simulated flash writes should eat up 11.1 seconds, for a total time of about 1 minute 20 seconds.
In reality? About 7 minutes.
I'm reasonably sure the problem isn't on my side, as I instrumented my code and determined that the time spent paused (i.e., between sending a ^S and sending a ^Q) adds up to 11.7 seconds.
(Having a serial protocol analyzer would be helpful right about now. I used to have one, but (a) it broke, (b) the remains long since vanished along with a defunct company, and (c) it didn't go anywhere near 115200 Baud. I think the function might be approximated using a Linux box with two serial ports.)
This kinda suggests that Teraterm is being sluggish when sending with XON/XOFF flow control enabled.
And what about other programs?
Well, Hyperterminal doesn't appear to handle XON/XOFF flow control at all, or at least not usefully. When I tried it, I got horrible overruns right away. Likewise gtkterm. Minicom sends plain-text files using ascii-xfr, which appears to turn off Linux's built-in flow-control capability, so, again, overruns.
So, with Teraterm I get all the bytes there, eventually; it just takes five times as long as it should. With the alternatives I've tried, bytes get dropped on the floor.
Maybe it's time for stty and two instances of cat....
(Oh, and this is complicated, once again, by the LPC2xxx ISP circuitry, which requires that either (a) the terminal program drive DTR and RTS in nonstandard ways or (b) I disconnect the RESET signal from the processor when switching between an LPC-aware program (such as the one used to install the latest test firmware) and some other program (such as Teraterm or cat).)
Update: Teraterm is slow. Routing the traffic through snooper on the Linux box was somewhat informative, and revealed a burst of un-flow-controlled transmission taking roughly three times as long as it ought; then I reconnected directly, and... with flow control turned entirely off, a transfer (with no errors recorded) takes... sometimes about 7 minutes, and sometimes about 3:40. And, yes, transmit delay is set to 0 msec/char and 0 msec/line.
Teraterm is running on a somewhat old, bargain-basement machine... but, really now: it may have a pathetic old 2.08 GHz Athlon XP to run on, but the other end of the connection is a 72 MHz ARM7 toaster controller, which seems to keep up just fine, and should only need the flow control because of the flash-writing breaks.
I suppose the technician might want a coffee break....
Update 2: Results above were based on a recently-downloaded copy of the open-source version of Teraterm. Switching back to Tera Term Web 3.1 (aka Tera Term Pro, I think), which, if memory serves, hadn't been cooperating yesterday, and enabling XON/XOFF flow control, I get a time of just over 2 minutes, with no overruns. Hooray!
I guess my side of the flow control wasn't working right when I tried it with TTPro yesterday. Now it's working all the way through*, and we have, apparently, a solution to the problem at hand, and I don't need to cobble together an XMODEM line discipline or any such foolishness.
* Well, most of the way. It's not actually writing to the flash yet, just sleeping for about the right amount of time.
Update 3: With the flash-writing code in place, the transfer takes just about 2 minutes, and results in an image that the FPGA will load, and that appears to work properly.
Loading a bogus image (a couple of dozen kbytes of ARM code,as it happens) makes the FPGA not load, which shows that the flash is in fact getting written.
Subsequently loading a proper image requires holding the FPGA reset for the duration, 'cause otherwise it's driving the SPI bus, and the processor can't commandeer the bus for the write operations, duh!
Still needs to be tested loading a different FPGA image... just to make sure the whole thing's getting through. That can happen after I add a new feature, the need for which cropped up on Thursday.
Also still need to implement processor-firmware updates, but that shares a fair bit of the code that's now working.
Update 4: I was thinking gtkterm looked kinda rough around the edges. Seems it's been at 0.99.5 for over 4 years now. But, being as how it's open source, I can have a look at the code, and see if I can figure out how to add the features I want, maybe in a way others might find useful. Features: (1) allow enabling XON/XOFF control on the port so that it works properly with send-raw-file (this may run into issues with the Linux device drivers; I'll see how that turns out); (2) have all the configuration data stay saved, including the flow control and RTS/DTR settings; (3) allow specifying RTS/DTR settings from the command line. And, maybe, (4) add a special feature to invoke lpc21isp from within the terminal, though this is kinda specialized. Maybe a more general form to allow temporarily closing the port, running a user-specified command, and displaying the output.
When I find the time....
Update 5: <daffy>Pipeline trouble.</daffy>
Duuuh... thing about soft flow control is, it only holds off characters that have not yet been sent to the hardware.
The Windows machine in the lab has a gen-u-wine built-in serial port, which is what Teraterm is using to talk to the gadget.
When I hook it up to the Linux machine, a serial-port-less laptop, the connection goes via USB.
So, when the Windows system sees a ^S, there might be 16 characters in the UART's transmit FIFO.
When the Linux system sees a ^S, there might be a full FIFO plus a buncha bytes propagating through the USB stack and out the wire.
Not having time to dig through the Linux USB stack, I'll just try bumping the ring buffer size on the toaster. Still got 50K of free RAM (out of 64K), so a bigger buffer isn't a problem on this particular gadget.
Update 5a: I'd already boosted the ring buffer from the default 40 to 240; setting it to 512 solved the problem, and sending the hex file over the Linux→USB→toaster→flash path now takes about 1:15, including the time it takes me to start the transmission.
At some point, though, I should write an XMODEM line discipline for AGROS, in support of little gadgets that don't have RAM to burn, but that might need to burn flash based on data sent via a serial connection.
Recent Comments