aboutsummaryrefslogtreecommitdiff
path: root/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino
diff options
context:
space:
mode:
Diffstat (limited to 'circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino')
-rw-r--r--circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino163
1 files changed, 163 insertions, 0 deletions
diff --git a/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino b/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino
new file mode 100644
index 0000000..ab407cd
--- /dev/null
+++ b/circuitpython/lib/adafruit_floppy/examples/msd_test/msd_test.ino
@@ -0,0 +1,163 @@
+// this example makes a lot of assumptions: MFM floppy which is already inserted
+// and only reading is supported - no write yet!
+
+#include <Adafruit_Floppy.h>
+#include "Adafruit_TinyUSB.h"
+
+Adafruit_USBD_MSC usb_msc;
+
+// If using SAMD51, turn on TINYUSB USB stack
+#if defined(ADAFRUIT_FEATHER_M4_EXPRESS)
+ #define DENSITY_PIN A0 // IDC 2
+ #define INDEX_PIN A1 // IDC 8
+ #define SELECT_PIN A2 // IDC 12
+ #define MOTOR_PIN A3 // IDC 16
+ #define DIR_PIN A4 // IDC 18
+ #define STEP_PIN A5 // IDC 20
+ #define WRDATA_PIN 13 // IDC 22 (not used during read)
+ #define WRGATE_PIN 12 // IDC 24 (not used during read)
+ #define TRK0_PIN 11 // IDC 26
+ #define PROT_PIN 10 // IDC 28
+ #define READ_PIN 9 // IDC 30
+ #define SIDE_PIN 6 // IDC 32
+ #define READY_PIN 5 // IDC 34
+#if F_CPU != 180000000L
+ #warning "please set CPU speed to 180MHz overclock"
+#endif
+#elif defined (ARDUINO_ADAFRUIT_FEATHER_RP2040)
+ #define DENSITY_PIN A0 // IDC 2
+ #define INDEX_PIN A1 // IDC 8
+ #define SELECT_PIN A2 // IDC 12
+ #define MOTOR_PIN A3 // IDC 16
+ #define DIR_PIN 24 // IDC 18
+ #define STEP_PIN 25 // IDC 20
+ #define WRDATA_PIN 13 // IDC 22 (not used during read)
+ #define WRGATE_PIN 12 // IDC 24 (not used during read)
+ #define TRK0_PIN 11 // IDC 26
+ #define PROT_PIN 10 // IDC 28
+ #define READ_PIN 9 // IDC 30
+ #define SIDE_PIN 8 // IDC 32
+ #define READY_PIN 7 // IDC 34
+#if F_CPU != 200000000L
+ #warning "please set CPU speed to 200MHz overclock"
+#endif
+#elif defined (ARDUINO_RASPBERRY_PI_PICO)
+ #define DENSITY_PIN 2 // IDC 2
+ #define INDEX_PIN 3 // IDC 8
+ #define SELECT_PIN 4 // IDC 12
+ #define MOTOR_PIN 5 // IDC 16
+ #define DIR_PIN 6 // IDC 18
+ #define STEP_PIN 7 // IDC 20
+ #define WRDATA_PIN 8 // IDC 22 (not used during read)
+ #define WRGATE_PIN 9 // IDC 24 (not used during read)
+ #define TRK0_PIN 10 // IDC 26
+ #define PROT_PIN 11 // IDC 28
+ #define READ_PIN 12 // IDC 30
+ #define SIDE_PIN 13 // IDC 32
+ #define READY_PIN 14 // IDC 34
+#if F_CPU != 200000000L
+ #warning "please set CPU speed to 200MHz overclock"
+#endif
+#else
+#error "Please set up pin definitions!"
+#endif
+
+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, IBMPC1440K);
+
+
+constexpr size_t SECTOR_SIZE = 512UL;
+int8_t last_track_read = -1; // last cached track
+
+void setup() {
+ pinMode(LED_BUILTIN, OUTPUT);
+ Serial.begin(115200);
+
+#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
+ // Manual begin() is required on core without built-in support for TinyUSB such as
+ // - mbed rp2040
+ TinyUSB_Device_Init(0);
+#endif
+
+ // Set disk vendor id, product id and revision with string up to 8, 16, 4 characters respectively
+ usb_msc.setID("Adafruit", "Floppy Mass Storage", "1.0");
+
+ // Set disk size
+ usb_msc.setCapacity(mfm_floppy.sectors_per_track() * mfm_floppy.tracks_per_side() * FLOPPY_HEADS, SECTOR_SIZE);
+
+ // Set callback
+ usb_msc.setReadWriteCallback(msc_read_callback, msc_write_callback, msc_flush_callback);
+
+ floppy.debug_serial = &Serial;
+ floppy.begin();
+ // Set Lun ready
+ usb_msc.setUnitReady(true);
+ Serial.println("Ready!");
+
+ usb_msc.begin();
+
+ if (! mfm_floppy.begin()) {
+ Serial.println("Failed to spin up motor & find index pulse");
+ while (1) yield();
+ }
+}
+
+void loop() {
+ delay(1000);
+}
+
+// Callback invoked when received READ10 command.
+// Copy disk's data to buffer (up to bufsize) and
+// return number of copied bytes (must be multiple of block size)
+int32_t msc_read_callback (uint32_t lba, void* buffer, uint32_t bufsize)
+{
+ Serial.printf("read call back block %d size %d\n", lba, bufsize);
+
+ uint8_t track = lba / (2 * mfm_floppy.sectors_per_track());
+ uint8_t head = (lba / mfm_floppy.sectors_per_track()) % 2;
+ uint8_t subsector = lba % mfm_floppy.sectors_per_track();
+
+ uint8_t retries = 5;
+
+ for (int retry=0; retry<retries; retry++) {
+ if (((track * 2 + head) == last_track_read) && mfm_floppy.track_validity[subsector]) {
+ // aah we've got it and its valid!
+ Serial.println("OK!");
+ memcpy(buffer, mfm_floppy.track_data+(subsector * SECTOR_SIZE), SECTOR_SIZE);
+ return SECTOR_SIZE;
+ }
+ // ok so either its not valid, or we didn't read this track yet...
+ int32_t tracks_read = mfm_floppy.readTrack(track, head);
+ if (tracks_read < 0) {
+ Serial.println("Failed to seek to track");
+ return 0;
+ }
+ last_track_read = track * 2 + head;
+ // we'll go again on the next round
+ }
+ Serial.println("subsector invalid CRC :(");
+ return 0;
+}
+
+// Callback invoked when received WRITE10 command.
+// Process data in buffer to disk's storage and
+// return number of written bytes (must be multiple of block size)
+int32_t msc_write_callback (uint32_t lba, uint8_t* buffer, uint32_t bufsize)
+{
+ Serial.printf("write call back block %d size %d\n", lba, bufsize);
+ // we dont actually write yet
+ return bufsize;
+}
+
+// Callback invoked when WRITE10 command is completed (status received and accepted by host).
+// used to flush any pending cache.
+void msc_flush_callback (void)
+{
+ Serial.println("flush\n");
+ // nothing to do
+} \ No newline at end of file