Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

FloppyController

Dual-core RP2040 firmware that turns a Raspberry Pi Pico into a USB floppy disk controller. Interfaces directly with a 3.5" IBM PC floppy drive over GPIO and presents either a USB Mass Storage device or a GreaseWeasel-compatible raw flux interface.

Hardware

SignalGPIODirection
INDEX0IN
TRACK01IN
WP2IN
RDATA3IN
DSKCHG4IN
DRVSB5OUT
MOTEA6OUT
DIR7OUT
STEP8OUT
WDATA9OUT
WGATE10OUT
SIDE111OUT
DENSITY12OUT
DIP 127IN (debug)
DIP 226IN (write enable)
DIP 315IN (GW mode)
DIP 414IN (track write)
LED16OUT (WS2812)

DIP Switch Configuration

DIPFunctionOFFON
1Debug serialDisabledCDC ACM debug output
2Write enableRead-onlyWrites allowed
3Operation modeMSC (mass storage)GreaseWeasel
4Track writeRead-modify-write entire track

Build

Requires Raspberry Pi Pico SDK 2.2.0 and arm-none-eabi-gcc 14.2.

mkdir build && cd build
cmake ..
make -j4

Flash FloppyController.uf2 to the Pico in BOOTSEL mode.

Architecture

  • Core 0: TinyUSB stack (MSC + CDC ACM), SCSI command handling, LED driver, GreaseWeasel protocol
  • Core 1: Bare-metal floppy I/O — seek, motor control, read/write via PIO state machines, MFM decode/encode

PIO State Machines

PIOSMProgramClockPurpose
pio0flux_smflux_reader.piosysclk/1 (200 MHz)Capture raw flux transition timings from RDATA
pio1write_smflux_writer.piosysclk/10 (20 MHz)Generate WDATA from half-cell MFM bitstream
pio1gw_write_smgw_writer.piosysclk/4 (50 MHz)Raw flux write for GreaseWeasel mode
pio0ws2812.pioWS2812 RGB LED

Write Path

⚠ Currently broken — writing via MSC corrupts the diskette.

The flux_writer PIO output is not producing valid MFM-encoded flux. Track writes result in noise/unreadable data on disk. Root cause under investigation.

Host USB SCSI WRITE(10)
→ tud_msc_write10_cb() [Core 0]
→ shared_sector_buffer [cross-core]
→ core1_floppy_worker() [Core 1]
→ read all 18 sectors of target track into tw_buf[18][512]
→ update target sector in buffer
→ format_track_with_data_encode() → MFM half-cell bitstream
→ write_track_raw()
→ DMA → flux_writer PIO → WDATA pin → drive write head
→ write_track_raw() returns → WGATE off

Writes are committed immediately (no deferred caching). SYNC CACHE and START/STOP UNIT SCSI commands trigger a dirty-track flush.

Read Path

Host USB SCSI READ(10)
→ tud_msc_read10_cb() [Core 0]
→ core1_floppy_worker() [Core 1]
→ flux_reader PIO captures RDATA flux timings
→ Software PLL tracks half-cell period
→ Hunt for 0x4489 sync marks
→ Decode ID and data fields
→ CRC-16/CCITT validation
→ Single-sector read cache

Modes

MSC Mode (DIP3 OFF)

Appears as a 1.44 MB USB mass storage device (2880 blocks × 512 bytes). Supports:

  • Read (10), Write (10)
  • Format Unit (full 80-track format)
  • Mode Sense, Read Format Capacities
  • SYNCHRONIZE CACHE, START/STOP UNIT

GreaseWeasel Mode (DIP3 ON)

CDC ACM virtual serial port implementing the Adafruit GreaseWeasel protocol. 22 commands: seek, read flux (ticks/RPM/revs modes), write flux, erase flux, parameter get/set, pin control. VID 0x1209 PID 0x4d69. Compatible with FluxEngine and HxC.

License

MIT

About

RP2040 Floppy Controller firmware supporting Greaseweazle and USB MSC

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages