KryoFlux - USB Communication

2009-07-08

The communication must be super reliable during dumping, so the USB communication should be handled properly. It is probably easier to develop it using the original sample code provided by the ATMEL library. The ATMEL libraries have been rewritten since Cyclone20 was built, and their new SDK was made available recently on their website. They no longer support the old stuff Cyclone20 was based on, and those old libraries seemed really buggy.

We need to read the ATMEL manuals, or at least have a look how best setup the hardware for what we want to achieve - timers and interrupts. We are very tight on timing, and we do not intend to do any assembly code. We will have to make sure we have the most efficient setup, but for that we need to know the board hardware well, then make the most efficient code possible in C.

Using assembly would mean learning ARM7 assembly just for this project - pointless and lots of time. Not to mention that the code cannot then be migrated to other boards afterwards, such as the Beagle using a different CPU architecture and so on. Using assembly is a recipe for an abandoned project - these boards come and go, and get updated every year.

(later)

Still currently in research mode... Timing is very sensitive on these boards, it is easy to trigger USB hangs, as well as how the data is generated in the FIFO buffer. Having looked at the data sets produced and observing how USB bombed out under Cyclone20, we are very seriously considering using a more compact transfer format based on differential coding - like say real-time speech compression. After all, what we have here is the same domain - your voice is frequency changes, and reading a disk is also just frequency changes. Speech compression is something we are familiar with professionally.

The board we are working with might have USB communication limitations, or perhaps a mix of undocumented bugs and hardware problems. We should use the new USB sample ATMEL recommends, at least there is a small chance that it has a work around in it that resolves some of the problems seen by Cyclone20. If not we can still implement the streaming in a way that allows re-transmission and error recovery. After all that it is still possible that the CPU power we have (again, we will not go for assembly coding) is simply not enough to handle HD disks.

(later still)

Found a bug in WinUSB yesterday night, it’s nothing serious though.

Apart from one issue, the board startup is instant. There is no waiting for random amount of time that Cyclone20 had to resort to in order to work around SDK/hardware bugs. Cyclone20 ejected and re-inserted the USB hardware by disabling it in Windows. This had to be done as it is the only way to tell the system that a new board with different capabilities is connected. We did make a nicer version, but it was still a bit slow since practically all it did was the same a user would do to start/stop a device in the Windows hardware manager.

Yesterday we got the board to disconnect and reconnect by itself - very cool, and this results in Windows (or whatever that supports Plug&Play) asking the board what it is.

The remaining problem is that the device has to respond in a very short time or the OS would time out. It waits a few seconds, and retries about 3 times. You don’t want that to happen (it can be random seconds of waiting, sometimes it is very long), so the board should be responsive to any host request after “connecting”. It is a bad idea to initialise the drive at this point, so we will allow that to be done through USB communication instead. It works now, but there is a circular dependency in timing USB and system initialisation in firmware that must be resolved. Maybe this can be fixed quickly tonight by delaying the drive initialization and failing all KryoFlux commands until they can be executed - the firmware must obey self-configuration and enumeration requests from the OS first, before doing anything that might delay it answering the host - otherwise the host fails the device.

Also found out that Olimex and the Ukrainian board is different in GPIO while getting this self-reconnection code working.