Adafruit has an Arduino library & example code ready to go with this FeatherWing. The library is optimized for the Adafruit Feather RP2040 microcontroller board.
This library needs to be installed using the Arduino Library Manager. From the Arduino “Sketch” menu, select “Include Library” then “Manage Libraries…”.
Type “floppy” in the search field to quickly find the library — Adafruit_Floppy:
If prompted to install additional libraries, say "yes"; Adafruit_Floppy relies on Adafruit BusIO and SdFat - Adafruit Fork.
You have to make specific selections in the Tools menu:
- Board: "Adafruit Feather RP2040"
- CPU Speed: "200 MHz (Overclock)"
- Optimize: "Optimize Even More (-O3)"
- USB Stack: "Adafruit TinyUSB"
After restarting the Arduino software, you should see a new example folder called Adafruit_Floppy, and inside, an example called floppy_capture_track_test. Upload the sketch to your Arduino and open the serial monitor. Place a disk in your floppy drive, and reset the board. Your floppy should "spin up" and you should see information about the flux data on your floppy's "track zero". For a formatted floppy, the "flux bins" (a histogram of times between adacent flux transitions) should cluster preferentially into 3 to 4 different groups of values with large gaps between them. For example, here's the frequency information from an MFM-formatted (DOS) floppy. The peaks correspond to 4, 6, and 8µs, or 96, 144, and 192 counts at 24MHz:
[12:22:39] its time for a nice floppy transfer! [12:22:39] Sample freqency 24.00MHz [12:22:40] Waiting for index pulse...Found! [12:22:40] Seeking track...Going to track 0 [12:22:40] Going to track 0 [12:22:40] done! [12:22:40] Captured 45282 flux transitions [12:22:40] ------- [12:22:40] 93: 130 [12:22:40] 94: 1460 [12:22:40] 95: 6257 [12:22:40] 96: 13469 [12:22:40] 97: 10962 [12:22:40] 98: 3345 [12:22:40] 99: 836 [12:22:40] 100: 302 [12:22:40] ------- [12:22:40] 139: 122 [12:22:40] 140: 273 [12:22:40] 141: 464 [12:22:40] 142: 848 [12:22:40] 143: 1083 [12:22:40] 144: 1258 [12:22:40] 145: 1265 [12:22:40] 146: 1098 [12:22:40] 147: 700 [12:22:40] 148: 296 [12:22:40] ------- [12:22:40] 192: 115 [12:22:40] 193: 122 [12:22:40] 194: 142 [12:22:40] 195: 111 [12:22:40] 196: 111 [12:22:40] Ready? No [12:22:40] Write Protected? Yes [12:22:40] Track 0? Yes
Because the floppy is inherently an analog device, the exact counts in each flux bin will vary slightly from run to run.
MFM (DOS/Windows) Floppy Decoding
There are a lot of floppy formats, but one ubiquitous one at the end of the floppy era was the IBM PC compatible MFM floppy. The example "mfm_test" will decode the content of such a floppy disk and display it on the serial monitor in hex and ASCII.
Seeking track 8 head 1 Going to track 8 Captured 9 sectors Validity: VVVVVVVVV 00000000 65 76 65 72 61 6c 20 6c 6f 77 65 72 20 63 6f 75 | everal lower cou 00000010 72 74 20 6f 70 69 6e 69 6f 6e 73 2c 20 69 6e 63 | rt opinions, inc 00000020 6c 75 64 69 6e 67 20 0d 0a 74 68 65 20 6f 70 69 | luding the opi 00000030 6e 69 6f 6e 73 20 69 6e 20 41 6d 65 72 61 64 61 | nions in Amerada 00000040 20 48 65 73 73 20 61 6e 64 20 4c 54 56 20 53 65 | Hess and LTV Se 00000050 63 75 72 69 74 69 65 73 20 74 68 61 74 20 61 72 | curities that ar 00000060 65 20 73 6f 20 0d 0a 66 72 65 71 75 65 6e 74 6c | e so frequentl 00000070 79 20 63 69 74 65 64 20 69 6e 20 73 75 70 70 6f | y cited in suppo 00000080 72 74 20 6f 66 20 74 68 65 20 62 72 6f 61 64 65 | rt of the broade 00000090 72 20 73 63 6f 70 65 20 66 6f 72 20 74 68 65 20 | r scope for the 000000a0 0d 0a 70 72 69 76 69 6c 65 67 65 2e 18 11 31 31 | privilege. 11 000000b0 32 18 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20 | 2 There is no 000000c0 63 61 75 74 69 6f 6e 20 74 68 61 74 20 74 68 65 | caution that the 000000d0 20 6c 61 6e 67 75 61 67 65 20 71 75 6f 74 65 64 | language quoted 000000e0 20 66 72 6f 6d 20 0d 0a 41 6d 65 72 61 64 61 20 | from Amerada 000000f0 48 65 73 73 20 6d 61 79 20 62 65 20 6e 6f 20 6d | Hess may be no m
For full details of the Adafruit Floppy library, see the API documentation. Here are some key details, though:
Pins & Construction
There are a lot of pins, so we put a standard definition block at the top of the examples for you to cut & paste into your code:
// these are for Adafruit Feather RP2040 #define DENSITY_PIN A1 // IDC 2 #define INDEX_PIN 25 // IDC 8 #define SELECT_PIN A0 // IDC 12 #define MOTOR_PIN A2 // IDC 16 #define DIR_PIN A3 // IDC 18 #define STEP_PIN 24 // IDC 20 #define WRDATA_PIN 13 // IDC 22 #define WRGATE_PIN 12 // IDC 24 #define TRK0_PIN 10 // IDC 26 #define PROT_PIN 11 // IDC 28 #define READ_PIN 9 // IDC 30 #define SIDE_PIN 8 // IDC 32 #define READY_PIN 7 // IDC 34 Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, MOTOR_PIN, DIR_PIN, STEP_PIN, WRDATA_PIN, WRGATE_PIN, TRK0_PIN, PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN);
Usually, you'll start with the sequence: begin
, select
, spin_motor
, and goto_track
:
if (!floppy.begin()) { Serial.println("Failed to initialize floppy interface"); while (1) yield(); } floppy.select(true); if (! floppy.spin_motor(true)) { Serial.println("Failed to spin up motor & find index pulse"); while (1) yield(); } Serial.print("Seeking track..."); if (! floppy.goto_track(0)) { Serial.println("Failed to seek to track"); while (1) yield(); }
// outside any function // WARNING! there are 150K max flux pulses per track! uint8_t flux_transitions[MAX_FLUX_PULSE_PER_TRACK]; // inside loop() or other function int32_t index_pulse_offset; uint32_t captured_flux = floppy.capture_track(flux_transitions, sizeof(flux_transitions), &index_pulse_offset, true);
Decoding MFM flux data
Or use an Adafruit_MFM_Floppy
object to get block-level access to a MFM-formatted floppy disk:
// outside any function, after defining floppy object Adafruit_Floppy floppy(DENSITY_PIN, INDEX_PIN, SELECT_PIN, MOTOR_PIN, DIR_PIN, STEP_PIN, WRDATA_PIN, WRGATE_PIN, TRK0_PIN, PROT_PIN, READ_PIN, SIDE_PIN, READY_PIN); // You can select IBMPC1440K or IBMPC360K (check adafruit_floppy_disk_t options!) Adafruit_MFM_Floppy mfm_floppy(&floppy, IBMPC360K); // in loop() or other function int32_t captured_sectors = mfm_floppy.readTrack(track, head); // then access mfm_floppy.track_validity, mfm_floppy.track_data, and other fields
Page last edited March 08, 2024
Text editor powered by tinymce.