Skip to content

Update Floppsy board definition for RP2350B hardware - #11555

Draft
ladyada-eagleclaw wants to merge 5 commits into
adafruit:mainfrom
ladyada-eagleclaw:floppsy-rp2350
Draft

ladyada-eagleclaw wants to merge 5 commits into
adafruit:mainfrom
ladyada-eagleclaw:floppsy-rp2350

Conversation

@ladyada-eagleclaw

@ladyada-eagleclaw ladyada-eagleclaw commented Oct 11, 2026 •

Copy link
Copy Markdown

AI assistance: Codex prepared this board update and ran the build and hardware checks at Limor's request. The board definition and shared PSRAM timing are separate PRs.

What

Replace the obsolete RP2040 Floppsy definition with RP2350B hardware, retaining Floppsy's assigned 0x239A:0x8152 CircuitPython USB identity at the board owner's request. Update the 16 MB flash/8 MB PSRAM configuration, 320x240 ILI9341 TFT, I2C, navigation/BOOT, analog inputs, floppy signals and DS0/DS1, SDIO/card detect, and USB host pins. Reset isolates cable drivers and leaves write/motor/select inactive and USB host power off.

Dependency: merge #11565 first. This PR contains only board files, including its 80 MHz maximum PSRAM clock selection. The shared implementation is in #11565.

TFT and SD startup

Automatic SPI SD mounting claimed SPI0 on GPIO34-39 before the TFT claimed SPI0 on GPIO6/7, causing ValueError: SPI peripheral in use before USB startup. Remove the automatic SPI SD configuration and expose the SD pins for sdioio.SDCard instead.

The normal build now enumerates with TFT and PSRAM enabled. After disconnecting both USB-C and barrel power for five seconds, SDIO initializes successfully with the card inserted. The earlier SDIO error after a SPI diagnostic was not reproduced on this cold start. SDIO-backed USB export as a second MSC LUN is a separate follow-up, #11564.

Validation

Latest setting: raised the ceiling to 80 MHz after a full Arduino DMA capture (160 sides, 480 revolutions) passed SD readback and independent Greaseweazle v1.23 decoding at the same 2,861/2,880-sector count as 40 MHz. Combined CircuitPython build and affected pre-commit hooks pass with the 80 MHz selection. This exact capped CircuitPython build has not yet been flashed; the CircuitPython hardware results below are from the earlier 40 MHz build, with the additional uncapped sweep documented in #11565.

Board files: 2281541735. Shared timing/current-main integration: #11565 at 06ad112da6, based on main 36a5653882.

make -C ports/raspberrypi BOARD=adafruit_floppsy_rp2350 -j4
make -C ports/raspberrypi BOARD=adafruit_fruit_jam -j4

Both builds pass, including the core1 flash-residency check. Combined Floppsy firmware uses 809,212 bytes flash and 40,692 bytes static RAM. The board-only branch also compiled before adding the timing dependency. Repository pre-commit and whitespace checks passed; no submodule or translation changes are included.

Hardware: Floppsy RP2350B Rev D, Windows USB host, 12 V barrel supply, existing microSD and Sony 3.5-inch drive. CircuitPython USB enumeration and REPL pass following both upload and a complete power cycle. The tested UF2 was built just before the merge commit, so its banner is 10.3.0-alpha.4-263-g16753f39f5-dirty; its resolved timing source matches 06ad112da6.

  • PSRAM: three rounds of 150 -> 240 -> 120 -> 150 MHz CPU changes; all 12 steps passed full 1 MiB forward/reverse CRC checks and retention across clock changes. Program and output are in Allow boards to limit RP2350 PSRAM clock frequency #11565.
  • I2C: devices at 0x08, 0x40 and 0x48.
  • SDIO: 25 MHz, four bits, 15,523,840 blocks; sector-zero signature passed. Read the existing FX006.SCP file twice, 1 MiB each time, with matching contents and CRC32 0x4575c34f. Mounted read-only; no SD files changed.
  • TFT: initialized at 320x240 with auto-refresh enabled during SDIO reads. Limor confirmed visible REPL output on the TFT afterward; the four-color-bar image itself was not visually confirmed.
Actual cold-start SDIO/display test and serial output
import binascii
import board
import displayio
import gc
import os
import sdioio
import storage

print("BOARD", board.board_id, "HEAP", gc.mem_free())
print("DISPLAY", board.DISPLAY.width, board.DISPLAY.height)
bitmap = displayio.Bitmap(4, 4, 4)
palette = displayio.Palette(4)
for x, color in enumerate((0xFF0000, 0x00FF00, 0x0000FF, 0xFFFFFF)):
    palette[x] = color
    for y in range(4):
        bitmap[x, y] = x
group = displayio.Group(scale=60, x=40)
group.append(displayio.TileGrid(bitmap, pixel_shader=palette))
board.DISPLAY.root_group = group
board.DISPLAY.auto_refresh = True

i2c = board.I2C()
while not i2c.try_lock():
    pass
try:
    print("I2C", [hex(address) for address in i2c.scan()])
finally:
    i2c.unlock()

print("SDIO INIT")
sd = sdioio.SDCard(
    clock=board.SD_CLK,
    command=board.SD_COMMAND,
    data=board.SDIO_DATA,
    frequency=25000000,
)
mounted = False
try:
    print("SDIO", sd.frequency, "Hz", sd.width, "bits", sd.count(), "blocks")
    sector = bytearray(512)
    sd.readblocks(0, sector)
    assert sector[510:] == b"\x55\xaa", "Missing boot-sector signature"
    print("SECTOR 0 PASS")
    storage.mount(storage.VfsFat(sd), "/sd", readonly=True)
    mounted = True
    names = os.listdir("/sd")
    print("FILES", names)
    filename = next(name for name in names if name.upper().endswith(".SCP"))
    with open("/sd/" + filename, "rb") as source:
        first = source.read(1048576)
        assert len(first) == 1048576
        assert first[:3] == b"SCP"
        crc = binascii.crc32(first)
        source.seek(0)
        second = source.read(1048576)
        assert second == first, "Repeated SD read mismatch"
    print("SDIO FILE PASS", filename, len(first), "bytes CRC32", hex(crc))
    print("SDIO + TFT PASS (read-only)")
finally:
    if mounted:
        storage.umount("/sd")
    sd.deinit()
BOARD adafruit_floppsy_rp2350 HEAP 8271312
DISPLAY 320 240
I2C ['0x8', '0x40', '0x48']
SDIO INIT
SDIO 25000000 Hz 4 bits 15523840 blocks
SECTOR 0 PASS
FILES ['System Volume Information', 'FX000.PART', 'FX001.PART', 'FX002.PART', 'FX003.PART', 'FX004.PART', 'FX005.PART', 'FD000.PART', 'FX006.SCP', 'FD000.MAP', 'FX007.PART', 'FD001.MAP', 'FD001.BAD.IMG', 'FD002.MAP', 'FD002.BAD.IMG']
SDIO FILE PASS FX006.SCP 1048576 bytes CRC32 0x4575c34f
SDIO + TFT PASS (read-only)

Scope and limitations

USB host/camera, Python floppy operations, and electrical pin-reset behavior were not tested in this pass. The PSRAM frequency sweep is a memory-integrity test, not an instrument measurement of the PSRAM clock. CPU frequencies above 240 MHz were not tested.

The working Arduino dumper was restored and its USB command interface verified after testing. Floppy IMG/SCP dumping and Greaseweazle support live in Adafruit_Floppy #57. This PR adds no camera application, floppy Python API, emulation firmware or SDIO-backed USB MSC implementation.

Keep the assigned USB identity, update board pins and display, and allow a conservative per-board PSRAM clock limit.

Co-authored-by: Limor Fried <ladyada@users.noreply.github.com>
Expose the card pins for sdioio instead; the socket and TFT use different GPIOs on the same SPI0 peripheral.

Co-authored-by: Limor Fried <ladyada@users.noreply.github.com>
ladyada-eagleclaw and others added 2 commits October 12, 2026 10:19
The timing implementation is now reviewed in adafruit#11565. Keep the board clock selection here and merge the timing support first.

Co-authored-by: Limor Fried <ladyada@users.noreply.github.com>
@ladyada

ladyada commented Oct 12, 2026

Copy link
Copy Markdown
Member

This may have more tweaks as we continue testing so leaving as draft for now

Co-authored-by: Limor Fried <ladyada@users.noreply.github.com>
@dhalbert dhalbert self-assigned this Oct 12, 2026
@dhalbert

Copy link
Copy Markdown
Collaborator

Looking fine so far. We will need to update https://circuitpython.org/board/adafruit_floppsy_rp2040/ when this gets merged.

@dhalbert dhalbert removed their assignment Oct 12, 2026
@dhalbert
dhalbert self-requested a review October 12, 2026 15:29

@dhalbert dhalbert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude wrote this:

USB host pin names

Other Adafruit boards with a PIO USB host port (Fruit Jam, Metro RP2350, Feather RP2040 USB Host) name the pins USB_HOST_DATA_PLUS, USB_HOST_DATA_MINUS, and USB_HOST_5V_POWER. Please use the same names here (aliases are fine if the short names are wanted too), since board pin names are hard to change after release.

Those boards also define DEFAULT_USB_HOST_DATA_PLUS/_MINUS/_5V_POWER so the host port starts at boot. If leaving host power off by default is intentional on Floppsy, a comment in mpconfigboard.h would help.

Merge order

If this merges before #11565, CIRCUITPY_PSRAM_MAX_SCK_HZ is silently ignored and PSRAM runs at up to 133 MHz. Please merge #11565 first, and flash the 80 MHz-capped CircuitPython build before merging this one.

circuitpython.org

_board/adafruit_floppsy_rp2040.md in adafruit/circuitpython-org needs a companion PR replacing it with adafruit_floppsy_rp2350.

Minor

  • board.c: the safe-pin GPIO numbers appear twice as bare literals. Named constants (or pin_GPIOnn.number) would make the mapping to pins.c checkable.
  • The new files' copyright headers say 2021 Scott Shawcroft.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants