BMOW title
Floppy Emu banner

First Look at the RP2040 – Raspberry Pi Microcontroller

In response to my last post, a few readers suggested looking at the Raspberry Pi Foundation’s RP2040 microcontroller for possible use in a future Floppy Emu hardware refresh. The RP2040 was announced in January 2021, first as part of the Raspberry Pi Pico development board, and later as a stand-alone chip. While Raspberry Pi’s other offerings are essentially full-fledged computers, the RP2040 is a traditional microcontroller that will compete directly with familiar products from Microchip, ST, Espressif, and NXP. So what does it offer that might set it apart from the competition? Is it worth a look? Here’s my take.

 
Strong Points

RP2040 is a 133 MHz dual-core ARM Cortex M0+ microcontroller, with 264 KB of RAM, and a unit price of $1 USD. Right off the bat, that looks appealing. I don’t know of any other microcontroller from a major vendor that offer a better ratio of hardware specs per dollar. 133 MHz is quite zippy, and 264 KB of RAM is substantially more than any of the alternative parts I’ve been considering. Dual core is just icing on the cake.

The hardware also includes two programmable I/O (PIO) blocks with interesting potential. These are hard to describe in a single paragraph, but they’re like high-speed specialized coprocessors that could replace much of the software-based bit-banging that’s often needed in microcontroller applications. They’re a good fit for high-speed bit twiddling, independent of the main cores. For the Floppy Emu, PIO blocks could probably be used to replace some of the specialized logic that’s currently handled by a CPLD programmable logic chip.

The documentation looks well-written. So far I’ve reviewed the chip datasheet, hardware design guide, the C/C++ SDK documentation, and the Getting Started Guide.

The RP2040 is available and shipping in large quantities right now, which is quite an accomplishment given the current shortages everywhere else in the industry. DigiKey has over 50000 in stock. You can also order the chips directly from Raspberry Pi.

 
Weak Points

There’s zero flash or non-volatile memory for program storage on the RP2040. All the application code and data must be stored in an external flash chip. Six dedicated pins are used to communicate with a separate QSPI flash, using execute-in-place (XIP) technology to run code directly from flash without needing to copy it to RAM first. A 16 KB XIP cache helps speed up this process. Relying entirely on external flash helps keep the RP2040 price down, and lets the user choose a flash chip whose storage size matches their needs, but it also has some serious drawbacks for my purposes.

The biggest worry is code execution speed. If most of the code fits into the 16 KB cache, then the code should run as fast as any other CM0+ microcontroller with similar specs. But for uncached code, and especially for application startup code when nothing is yet cached, I fear it will be slooooow, slower even than 8-bit AVRs with much lower system clock speeds. I used section 2.3 of this Atmel document to understand what XIP traffic looks like for a QSPI interface. Fetching a 32-bit value requires 20 SPI clocks, which is 80 system clocks using the RP2040’s default settings. A 32-bit value can hold two 16-bit Thumb instructions, so it looks like 40 system clocks per instruction, or 3.3 MIPS at 133 MHz. Slow.

For many time-critical routines, code can be pre-loaded into RAM with some extra effort, where it will run much faster. But for application startup code there’s really no way around this bottleneck. I’m not sure if this would be a serious problem, or if I’m worrying over nothing.

There’s no easy place to store settings information, like the EEPROM on an AVR. Presumably settings would need to be stored in the same external flash as the program code. This would require copying some section of code to RAM and executing it, which would deactivate the XIP interface and use standard SPI flash commands to update a few bytes, before re-enabling XIP and resuming the program.

The RP2040 bootloader could be considered both a strong point and a weak one. There’s a built-in USB bootloader in mask ROM, which is activated if the external flash is missing or deactivated. To the computer it appears as a USB mass storage device, so you can update the firmware with a simple drag-and-drop. This is great if your product already has a USB device (USB-B) connector on it, but the Floppy Emu doesn’t and doesn’t need one. I could roll my own pseudo-bootloader as part of the main application code, to load firmware updates from the SD card, but it wouldn’t be in protected memory like a real bootloader. If something went wrong during the update, it might corrupt the pseudo-bootloader and effectively brick the device.

While I admit I haven’t tried it, the C/C++ development toolchain doesn’t look great. Ideally I’d hope to see an IDE like Atmel Studio or STM32 Cube, with hardware-specific tools to help configure the peripherals, GUI settings for all the build options, an integrated simulator and debugger, and so on. But the reality is more like a pile of libraries, header files, and build scripts. Changing any kind of build settings relies heavily on editing CMake files and adding new defines whose existence you may not have known about. Sure you can use the VSCode IDE, but it doesn’t seem to do much more than function as a text editor, and you’ll still be tearing your hair out struggling with CMake. The build environment is also clearly geared towards Linux, and while setup is possible under Windows, it appears to be cumbersome.

My last worry is over the RP2040 development community, or really the lack of a community. If you’re developing for an AVR, or Atmel SAM, or STM32, you’ll find thousands of helpful resources on the web with example code, discussion forums, and sample projects. There’s very little of this for RP2040, and most of what does exist is geared towards Micro Python and Circuit Python, rather than bare metal C/C++ development. The only discussion forum I’ve found is a small subsection of the main Rasperry Pi forums. This doesn’t make it impossible to develop – the documentation seems thorough and there is some help on the web. But it’s a far cry from working “in the herd” and developing for a more popular microcontroller family.

 
Conclusions

So is the RP2040 the future of the Floppy Emu? It’s hard to say, but I think probably not. It may help to compare it against some other possibilities, like the Atmel SAMD21 (48 MHz CM0+ with 32 KB RAM) or SAMD51 (120 MHz CM4 with 128 KB RAM), which cost around $4 each in large quantities. Compare these to an RP2040 plus an external flash chip, with a combined cost of about $2. The RP2040 solution is half the price, but both alternatives are cheap enough, and I would choose whatever solution will make development easiest.

The extra RAM of the RP2040 is welcome, but I’m unsure what I’d do with it. 32 KB is more than enough to buffer a disk track plus other application data, and unless I had 1MB or more to buffer a whole disk, additional RAM might not be immediately useful.

133 MHz is greater than 48 MHz, so maybe the RP2040 is much faster than the SAMD21? Or maybe not, given the overhead of XIP code execution?

All these differences in favor of the RP2040 look interesting, but if they aren’t critical for my specific application, then are they worth the trade-offs of the build environment, development community, and concerns about external flash?

For the specific case of the Floppy Emu, I think the best argument in favor of the RP2040 is the PIO blocks. If those could replace all of the logic that’s currently handled by a CPLD programmable logic chip, then I could eliminate the CPLD entirely, and greatly simplify the whole design. But if the PIO blocks can only replace some of the logic, then I still need a CPLD or something similar, and the advantage of the RP2040 is much less. But that’s a difficult question to answer by just reading the docs, and I’d need to really dig in and try building it.

Read 16 comments and join the conversation 

16 Comments so far

  1. Tux2000 - February 19th, 2022 3:53 am

    Coincidentally, I’ve discussed using the RP2040 as a replacement for the SAM D21 or D51 in a current project with one of my fellows. In that project, the current hardware uses a D21, but it severely lacks both RAM and clock speed for the project requirements. We would like to use the D51, but the client does not like its higher price.

    The current chip shortage made us think about switching to a completely different controller. The RP2040 is definitively interesting. Compared to the D21 and D51, the second ARM core is a clear win. We also like the amount of RAM available. The PIO blocks are very interesting.

    The ROM bootloader needs some considerations. It delays the startup, so peripheral hardware needs to be secure by default (as it is already in most of our projects). It offers an easy way for firmware updates via USB, so we don’t need our own bootloader. But because the update is so easy and especially not specific for the project, it would be easy to load a wrong firmware. (Our update software checks both the project identification from the existing firmware and a signature for the new firmware.)

    In general, our SAM-based projects have at least one external I²C EEPROM for configuration, some also log to a second EEPROM. We do not write to program flash, except for firmware updates. Simply because EEPROMs have about 10^5 to 10^6 erase cycles, but flash has only about 10^3 to 10^4. Also, erasing the program flash would also erase all configuration (and log) data. The RP2040 is no different in this respect, it simply needs an external EEPROM (or battery-backed RAM) for configuration, just like the SAMs do.

    We have used an external QSPI flash only for static resources (fonts and bitmaps) in a single project with the SAM D51, so our experience is limited. But: The D51 internal flash also can not be read at full CPU core speed: At 120 MHz core speed, it needs five wait states (see datasheet, 54 Electrical Characteristics, 54.12 NVM Characteristics).

    “Fetching a 32-bit value requires 20 SPI clocks” – The D51 can setup the QSPI interface for sequential read (“continuous read mode”), so once it has transfered the read command and the start address, it just needs to generate 8 clock cycles to read the next 32 bits, 4 clock cycles in DDR mode. From a quick look at the RP2040 datasheet, the RP2040 also seems to support both continuous read mode and DDR mode.

    Short jumps in the code (e.g. local loops) should be buffered by the cache, so the controller should be able to keep the QSPI interface in continuous read mode for quite a while. Also, you don’t run all of your code all the time. Quite a lot of the code is just executed once to init the system, or will not run at all (error handling), or only once in a while (long-running timers, handlers for user input). So if the cache controller is not completely stupid, it will keep the “hot” code doing the main business in the cache. Also note that you can directly control how the cache is used by the address you use. See chaper 2.6.3.1. XIP Cache: Addresses 0x10xxxxxx are normal operation, 0x13xxxxxx bypass the XIP cache completely, 0x11xxxxxx read, but do not update the cache. So you can device if code from QSPI will be cached or not. Hot, timing-critical code goes into 0x10xxxxxx, cold code into 0x11xxxxxx or 0x13xxxxxx.

    Tux2000

  2. Tux2000 - February 19th, 2022 3:57 am

    Oh, and of course, you could copy really critical code into RAM during init. That frees up the QSPI interface and cache for code that is not that critical.

    Tux2000

  3. Steve - February 19th, 2022 8:15 am

    Thanks! This is some great commentary on the RP2040.

    > It delays the startup, so peripheral hardware needs to be secure by default

    I’m not sure what this means. The initial pin states after hardware reset need to be safe for the application, until the application code is loaded from flash?

    > But because the update is so easy and especially not specific for the project, it would be easy to load a wrong firmware.

    That’s a very good point. I have such mixed feelings about the built-in USB bootloader. It’s super convenient, but it’s not customizable. Any device built on the RP2040 will appear as a mass storage drive named RPI-RP2 with two files named INFO_UF2.TXT and INDEX.HTM. The HTML file points to a page on the Raspberry Pi website which will be useless and confusing for my customers. Many Floppy Emu customers would surely assume this mass storage device was a place to store their disk images, and would try to copy them there. If the USB bootloader were customizable, or if there were support for creating a non-USB bootloader in protected memory, I’d feel much better about it.

    > We do not write to program flash, except for firmware updates. Simply because EEPROMs have about 10^5 to 10^6 erase cycles, but flash has only about 10^3 to 10^4.

    Interesting. The SAMD21 datasheet says program flash has minimum 25K erase cycles, and EEPROM emulation (not sure what that is) has 100K minimum. For logging I can see how this might not be enough, but for configuration settings it seems fine.

    > But: The D51 internal flash also can not be read at full CPU core speed: At 120 MHz core speed, it needs five wait states

    Yes 5 wait states for D51 internal flash. And the RP2040 is essentially 80 wait states (20 QSPI cycles). In practice it won’t be quite so bad for either chip, because a single miss in the program cache will fetch multiple instructions’ worth of data from flash. And there may also be some prefetching. It’s unclear exactly how the RP2040 XIP cache works. There’s some discussion and speculation here: https://forums.raspberrypi.com/viewtopic.php?t=329944

    > The D51 can setup the QSPI interface for sequential read (“continuous read mode”), so once it has transfered the read command and the start address, it just needs to generate 8 clock cycles to read the next 32 bits, 4 clock cycles in DDR mode. From a quick look at the RP2040 datasheet, the RP2040 also seems to support both continuous read mode and DDR mode.

    RP2040 does have that ability, but from my understanding of the datasheet and the discussion I linked to above, XIP code execution doesn’t do this. There was a comment somewhere from one of the chip developers saying this would be a good idea. For normal XIP code execution, I think it sends 24 bits of address plus some extra stuff for every 32 bit fetch from flash, even if it’s the next sequential address. I could be wrong though.

    My guess is this all works well enough for typical code, since as you say, hot code doing the main business will be in the cache. And you can explicitly put some code in RAM if you really need to. I’m more worried about the performance at startup, and all the initialization code, since there’s not really any way to speed it up. It doesn’t make sense to copy initialization code to RAM, because you’ll waste time doing the RAM copy before even running the code, so there’s no overall speed-up. I’m finding it hard to quantify just how slow initialization code could be for a real world example, and whether it’s something I need to be concerned about. I think it’s probably OK, but it worries me.

    Are there other microcontrollers you’re considering, as you migrate away from the SAMD21?

  4. Tux2000 - February 19th, 2022 12:30 pm

    > > It delays the startup, so peripheral hardware needs to be secure by default

    > I’m not sure what this means. The initial pin states after hardware reset need to be safe for the application, until the application code is loaded from flash?

    Right. The SAM D21, L21, D51 all start with pins set to input, but with some leakage current to positive supply. Effectively, there is a very weak pull-up on every pin. So we add a pull-down for an active-high death ray device, or add a pull-up and use an active low death ray device. Optionally, we add some hardware interlocking.

    > The SAMD21 datasheet says program flash has minimum 25K erase cycles, and EEPROM emulation (not sure what that is) has 100K minimum.

    EEPROM emulation is essentially a little bit of hardware support and a library. Hardware adds a second way to access a little part at the top of the internal flash, the library fakes byte-wise write and erase using a part of that memory. The available “EEPROM” is thus slightly smaller. Annoyingly, EE is not available on the D21A, the most common model.

    > RP2040 does have that ability, but from my understanding of the datasheet and the discussion I linked to above, XIP code execution doesn’t do this.

    OK, I did not research that. I simply assumed that the hardware was capable to do that, and some startup code would be needed to fully configure the QSPI interface and flash.

    > I’m more worried about the performance at startup, and all the initialization code, since there’s not really any way to speed it up. It doesn’t make sense to copy initialization code to RAM, because you’ll waste time doing the RAM copy before even running the code, so there’s no overall speed-up. I’m finding it hard to quantify just how slow initialization code could be for a real world example, and whether it’s something I need to be concerned about. I think it’s probably OK, but it worries me.

    Yes, that would also be my worry for a peripheral device like the floppy emu. In some situations, you could slow down the host (e.g. on a Sinclair ZX81, ZX Spectrum, you could effectively slow down or stop the CPU from the expansion port using WAIT or BUSREQ), but a floppy drive is typically “too far away” from the CPU to play such tricks.

    Our projects are usually stand-alone, or are connected using RS232 or RS485 to other microcontrollers or PCs. Boot-up time is usually not an issue, there is no impatient host system.

    About 10 € / 10 US$ will get you an RP2040 on a Pi Pico board to evaluate. Put some code on the Pico doing excessive startup, finish by pulsing a GPIO pin. Drive RUN low, then release it to high. Measure time until the GPIO pin is pulsed. Repeat with switching the supply voltage on instead of driving RUN. Should be trivial using almost any microcontroller, or even using just a bare switch and a two-channel digital oscilloscope or a logic analyser.

    > Are there other microcontrollers you’re considering, as you migrate away from the SAMD21?

    We have a large code base of bare metal, non-blocking driver code for the SAM D21, L21, and D51, because these three are our most commonly used controllers, and their peripherals are relatively similar. We won’t give up them just because they are currently hard to get. They will return, and we will continue to use them.

    We literally just have started thinking about switching the microcontroller for that single project two days ago. Mainly because our customer asked if we could use another microcontroller, how long that would take, and how much that would cost.

    Currently, we are completely open.

    We have no experience with the RP2040, neither in hobby projects nor in professional projects.

    AVRs, our previous standard controllers, are simply too small, too slow, and too expensive for their performance. (We occasionally use an Arduino in engineering tests.)

    A fellow mentioned the ESP32, very specifically for this project. It would allow removing the existing Bluetooth module from the device and thus save some hardware costs / allow a more expensive microcontroller, because the ESP32 already comes with Bluetooth. Also, we might just barely get away without using our non-blocking driver architecture and use Arduino libraries instead.

    I think we would prefer using some ARM Cortex-M based controller, or at least a 32-bit controller that can address all of its memory and peripherals without quirks like bank switching. Basically, we want to write in C89 or C99, compile using GCC, and we don’t want to count every bit of RAM and every clock cycle.

  5. Roy - February 20th, 2022 6:48 am

    264K is odd. I know it’s 256 + 8, but that extra 8 seems a little weird. Anyone have an explanation for that design choice?

  6. Steve - February 20th, 2022 8:21 am

    There are four 64K banks and two 4K banks, each with an independent connection to the bus, so each can be accessed simultaneously without contention by the two M0+ cores, DMA, and peripherals. From the programmer’s viewpoint it’s a single contiguous 264K block, so it doesn’t create any extra programming difficulties. But if you want the super highest possible performance, you can intentionally allocate memory in the address range for a specific bank if you know the memory will be used mainly by DMA or a peripheral.

  7. Steve - February 20th, 2022 8:34 am

    Another microcontroller that’s similar to the RP2040 in many ways is the Espressif ESP32. Like the RP2040, it uses external flash with XIP code execution, and is cheap, fast, has lots of RAM, and has surprisingly good availability during this global chip shortage. The ESP32-S2 is a single core 240 MHz 32-bit CPU with 320K RAM, for $1.35. It’s designed for Wi-Fi applications, but I don’t see any reason you couldn’t ignore the Wi-Fi part and use it as a general-purpose mcu.

  8. Tom G - February 22nd, 2022 12:55 pm

    You could maybe take a look at the Cypress PSoC chips. I’m looking at a PSoC 4L series chip for my design. Some of the nice advantages are that it has a (very) small amount of programmable logic on board. It might maybe be enough to replace your CPLD. It also natively runs at 5V through an on board regulator. All the IOs handle 5V as well. But I’m not sure about availability.

  9. John Payson - February 23rd, 2022 10:07 am

    I like the PSoC chips, though availability is a concern. I think the ability to do 5-volt I/O directly is certainly elegant, though I’m not sure to what extent it really matters since I don’t think the ARM-based versions can combine 3.3-volt I/O and 5-volt I/O.

    For some purposes, having a device run self-contained from an SD card is nice; for other purposes such as software development, using a USB-connected computer to hold the virtual disk may be more convenient. I think it should be practical to implement a very-light-weight “networking DOS” whose functionality would be limited to watching for DOS commands being input or output, relay them to the floppy port, and watch for commands from the floppy port to either read bytes of RAM at a specified address and send them out the floppy port 8:7 coded, or accept a sequence of 8:7 coded bytes from the floppy port and store them to RAM at a specified address, or release control back to whatever code was running on the Apple. With suitable software on the PC, this would allow users on the Apple to treat a specified directory and any subdirectories thereof as though they were a giant file system on the Apple, without having to build disk images, and without any 32MB limitation.

  10. Patrick Kloepfer - March 2nd, 2022 11:25 am

    There is currently a project going on to bring FujiNet to the Apple 2. They are doing this using the ESP32 and bit banging to emulate multiple SmartPort devices connected via a DB-19/20-pin flopping connector. FYI, they are really looking forward to Yellowstone to connect it to. In their design, they use the ESP wifi stuff to connect to Fujinet servers on the backend for storage (disk images). They have got it reading/writing smartport protocol packets to and from the apple to the esp, which suggests that an EMU based on it would be possible. There is a discord forum where all this is being discussed I can point you to if interested.

  11. Tux2000 - March 3rd, 2022 11:33 am

    A note regarding the RP2040 boot ROM:

    It seems you need to press a button on the Pi Pico board. According to the RP2040 datasheet (“2.8.2 Processor Controlled Boot Sequence”), it polls the flash CS line (i.e. QSPI_SS, Pin 56) “multiple times”, that seems to happen about 100 µs after power-up. After that point, either the USB device bootloader starts, or QSPI is configured and reads the first 256 bytes (first stage flash code), varying CPOL and CPHA. Failing to start for more than 0.5 sec also enters the USB device bootloader.

    I don’t know why, but I assumed the boot ROM would do much more USB stuff and only start the application if USB failed. Maybe I got that idea from old SAM boot ROMs.

    Looking at the flow diagram, there is always a 100 µs delay before QSPI_SS is polled, an extra few µs for polling QSPI_SS, for configuring SSI and the PAD connections. With the right QSPI flash, loading the first stage flash code should succeed on the first attempt. The datasheet explains that each attempt takes about 4 ms.

    So, whatever you build using a RP2040, you need to plan for at least 4.1 ms until the first stage loader runs.

    On my first computer, the ZX81, about 13000 clock cycles would have passed during that time, sufficient for about 3000 assembler instructions. That’s pretty much code, given that there were only 8 KByte ROM.

    Using the RP2040 as a bootable peripheral will likely need some mechanism to slow down the host until the RP2040 has finished booting. On a Z80, I would probably delay the Z80 using BUSREQ, controlled by a flip-flop that RP2040 software needs to set (or clear) when it is ready. Slowing down a 6502 seems to be harder, as it has no signal comparable to BUSREQ.

  12. Steve - March 3rd, 2022 3:09 pm

    Unfortunately the Apple standard floppy disk port doesn’t expose any pin that can slow or halt the CPU, but this may not be necessary. All Apple machines that I’ve tested have a fairly long delay (hundreds of milliseconds at least) between when power is turned on and when they begin to search for disks. The current generation Floppy Emu needs at least 50-70 ms to initialize after power on, but is still able to initialize quickly enough to work as a boot disk for the computer. The only possible exception is the Apple IIc Plus. I don’t have one in my collection for testing, but I suspect it may initialize quicker than other Apple II and Mac models.

  13. Tim Buchheim - March 4th, 2022 1:57 pm

    If the //c+ is the only machine likely to have a problem with the Floppy Emu’s startup time then it wouldn’t be a big deal; the //c+ isn’t a very common machine. Users could always hit control-command-reset after the “No startup disk” error or even just hold down control-reset for a few seconds while turning on the machine to delay startup. (Users of certain other modern peripherals are already accustomed to doing this; VidHD for examples takes a few seconds to boot so users who need working HDMI output very early in the boot process have to do this.)

  14. John Payson - March 4th, 2022 2:35 pm

    If the //c+ ROM would give up pretty quickly on trying to boot a smart port device and switch to looking for an ordinary floppy, perhaps those could be accommodated by having the emulator watch the head-position wires for the move-to-track-zero sequence and, if that is seen, repeatedly send data that would appear as a boot sector whose code would let the emulator know that it was running and then restart the system boot process.

  15. Jeff Epler - March 9th, 2022 11:46 am

    For the last couple of months I’ve been working on a flux reading/writing library with Adafruit (called, unimaginatively, Adafruit_Floppy; code is on github) that can work with FluxEngine & GreaseWeazle host software; the first two microcontrollers we’ve been working with are the SAM D51 and the RP2040. We worked with PC drives first, but on my desk here is a board with RP2040 that is reading flux from a Disk ][ and running the stepper.

    The RP2040’s PIO peripheral is great for capturing and generating pulses like floppy drives deal in, as long as you can use DMA or ensure that the peripheral’s FIFO (with a modest 8 32-bit entries) is kept fed.

    However, it’s not so great for combinatorial logic, A = (B & C) | (D & ~E) and the like, or arithmetic.

    It can function as an extended ‘pin change detection’ peripheral, which would be handy for processing the stepper motor signals to an Apple floppy drive. And maybe you can devote the second CPU core to processing table driven logic to do the rest. I’m not familiar with what tasks your CPLD has to do in the floppy emulator so I’m very much in hand-wave mode there.

    I suspect that a very dumb and not full featured disk emulator for RP2040 is well within the realm of possibility (and hope to have time to try my hand at it this spring to find out if I’m right). Taking it to a high level of polish, well, that’d be a whole thing.

    The series of ESP32 microcontrollers is interesting as well. I think they all share an “RMT” peripheral, which is designed to generate & record fairly arbitrary waveforms based on duration & polarity. It may be applicable to work with floppy flux data, but I haven’t tried it yet.

    The main advantage the RP2040 and ESP32-family have right at this very moment is availability; I hear that by comparison that SAM D21, SAM D51 and a bunch of similar 32-bit micros are quite strongly affected by supply chain issues.

  16. Tux2000 - March 17th, 2022 3:52 am

    Some Graham Sanderson has ported DOOM to the RP2040. The interesting part is that the RP2040 not only runs DOOM, but also generates a VGA signal, OPL2 FM music, and eight sound channels for effects. Also, it has networking over I²C.

    This is clearly not a floppy emu, but generating all of those signals while also playing DOOM clearly has some real-time requirements. So it may also serve as a case study.

    https://kilograham.github.io/rp2040-doom/ explains in detail how it is done. https://kilograham.github.io/rp2040-doom/speed_and_ram.html explains the trade-offs beween QSPI XIP flash and RAM.

Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.