Sunday, February 19, 2023

STM32-USBFloppyTracer - Successor to the SlamySTM32Floppy

The Learning of Rust

During the last months I was rather busy with another project. On 21.08.2022 I've decided to finally start learning Rust, as I wanted to learn more about the powers it possesses. As a professional C++ developer I've noticed certain flaws of the way C handles concurrency. It doesn't matter if it is a Linux daemon with threads or an embedded project with interrupts. Concurrency can lead to stochastic bugs difficult to pin down. Rust doesn't have this issue as the compiler itself makes use of formal verification to ensure that no data structures are shared globally without mutual exclusive protection.

tl;dr Rust is very safe.

I wanted to learn that language and needed a project to do so.

The Project

My SlamySTM32Floppy project was now finished for a long time. But I wasn't happy anymore with its state. The code is messy and copy protected images were never fully verified after being written. Also new projects have entered the game by now. There is the Greaseweazle and also the KryoFlux. If it wasn't for my desire to cleanup my old project and my love for old technology I would have just bought a Greaseweazle. It is open source and prebuilt hardware is not very expensive.

As I had the old hardware lying around I decided to just go with it and start the firmware and the host tools from scratch. Also my solution never had any housing. A fine remainder:


This was the state during 2016 and it was still like this in my closet by now. That was about to change.

The goal

  • Yet another USB floppy flux thing project because there wasn't one before. lol.
  • Writing of copy protected images as correct as possible
    • Make use of write precompensation this time 
  • Verification of all written data to the level of a single flux reversal
  • Writing of images as fast as possible. No rotation of the disk shall be wasted. 
  • Have some integration tests to check for regressions during development
    • Adding features can break previous accomplishments easily
  • Have a proper documentation about its usage
  • Utilize DMA this time for better performance
  • USB communication is not stalled during flux operations

A different approach to write flux data

The way the Greaseweazle approaches its task is vastly superior to my old technique. The SlamySTM32Floppy used code in its firmware for very specific tasks. GCR and MFM are handled by different functions. DMA was not used to write and collect pulses. Verification of written data was performed by parsing known track formats. There was a verify function for Amiga sectors and for ISO sectors. The code is open source and can be used to learn from my old mistakes.

The Greaseweazle on the other hand has a very basic firmware with only one task to solve: The correct writing of raw fluxes and reading of those. This keeps the firmware simple as all intelligence is on the host side. This however means that more data needs to be transferred between STM32 and PC. But I've decided to go with this approach as well as it seems to be very flexible.

A different approach to verify written flux data

However I was not happy with the way, the Greaseweazle verifies the written tracks. A whole track is read back to the PC and then cross correlation is performed to check the equality of any possible flux stream. I like this idea but I wanted to do the verification on the firmware itself. My goal here is different. As before, this project is targeted to be optimized for writing speed, so this simply won't do. Instead I needed an algorithm for cross correlation which is performed on the device while the just written track is read back from disk. 

The idea of the Greaseweazle with cross correlation was good, but it needed to be scaled down. By the time of writing I went with reading the first 200 flux pulses after the index signal and cross correlating them against the first 20 pulses of the groundtruth data. As soon as both match up both flux streams are considered in sync and are compared until no groundtruth data is left to compare against.

200 flux pulses might sound like a lot, but it had to be as this floppy writer is capable of working without the index pulse to support flipped 5.25" disks. The larger amount of data allows more room for fluctuation in the rotation of the disk.

Usage of write precompensation

Early on, I've never thought about write precompensation but it really improves the quality of the written data. For more information, I've written a markdown file about this topic in the github repo. This must be performed for every drive and can be essential for games like the Amiga version of Turrican II.

A smaller board

Originally this project was started using the STM32F4DISCOVERY. This eval board still performs well today but it's size makes it difficult to fit into a case. I've decided use a smaller one this time: A board without microphone, a headphone amplifier, an acceleration sensor and an integrated stlink.

The Diymore STM32F4 seemed to be the right choice. It is exactly the same microcontroller - the STM32F407 - but reduced to the essentials. All this project needs, is I/O and a USB port.

In the end, I've wasted space nonetheless as the used perfboard could've been smaller.

But still look for yourself:

A much smaller board with only the relevant components

A case made from wood to properly store the electronics 

This time I wanted to have a small case to store everything. It is much easier for transportation that way and the especially naked 5.25" drive is protected.
At first I thought about 3D printing (thx to Chris for support) but wasn't satisfied with the result. It seems that 3D printed models are difficult to rework in case the designed 3D model was not thoughtfully planned to the end. (Yes, cables take up space. Especially thick cables like the one used for floppy drives...)
So I've decided to go for wood instead. It makes reproduction for others more difficult but in the end it would be possible to make a 3D model from it as soon as I was satisfied with how the case was built. A wooden model can be reworked very easily.
Early state of the case viewed from the top. Some rails added for the drives to sit on

Viewed from the front

And the back.

Small piece of wood to keep the PicoPSU in place

Connected the PicoPSU to the small piece of wood

The case and the top piece

The whole case fitted together. A view inside.


A 3.5" drive and the Diymore board

The PicoPSU added

The floppy cable added.

The finished product.

The Result

The project goal was achieved. I did learn a lot about the Rust programming language through practical usage and learning from problems during development. I've learned about development of linux system software as well as embedded development using that language.
 
In the end, the resulting device is very similar to the old SlamySTM32Floppy but surely more advanced. Especially the verification of every written track, even copy protected ones, makes the resulting disk more trustworthy.
 
The knowledge about more sophisticated things like write precompensation was also expanded. 

This project is open source from the start and can be inspected on github.

I've also decided to maintain a list of correctly written images so compatibility is properly documented.