NuttX RTOS on PicoCalc

Hi, this is my initial work on getting NuttX to run on PicoCalc with Pico 2 on board

Currently: SD Card, SPI, I2C, PWM, Speakers, Serial connection are working.
Next: Display and builtin PicoCalc keyboard.

There is also firmware uf2 file in pre-release on github for pico 2 based PicoCalc

More info about NuttX https://nuttx.apache.org/

PS
Also year ago NuttX landed on the moon Apache NuttX Powers World's Smallest Lunar Robot in Japan's Historic Autonomous Lunar Exploration Mission | Developer World

17 Likes

Update:
Currently I am working at porting NuttX to RISC-V cores on rp2350

At current state It’s usable right now and will be ready soon to merge, after the platform docs, cleanup etc.

  • Screen is working
  • Keyboard is working
  • SD card working, FAT fs working fine
  • PWM is working (test sounds from speakers), no audio driver yet for NuttX
  • WAMR WASM runtime (WAMR - WebAssembly Micro Runtime) included

I will update GitHub - shtirlic/picocalc-nx: NuttX for PicoCalc main branch with configs and other stuff after PR merge in upstream.

Also I am writing the UI shell for NuttX(LVGL), where you can run normal apps and WASM apps.
Source also will be available as custom app for NuttX and will be used as init/startup app in picocalc-nx board.

5 Likes

Update: my RISC-V port merged to NuttX, so I continue to expand picocalc-nx to new features and update custom UI shell.

4 Likes

Knock, knock,
Wake up NEO2350!

I am very interested in this project.

Unfortunately, it obliterates uf2loader by @pelrun.

Since I switch between uf2’s on the fly (on the PicoCalc) using uf2loader, I really cannot get into this project. :frowning: I would really love to, though.

NuttX mess up with the bootloader loaded in RAM?
That’s good to know indeed.

I am not sure what is happening. The Nuttx uf2 may be over writing the flash partition table?

Honestly, I am not an expert on the flash stuff and the RP2350. @pelrun might have an idea?

I’ll add this to the list of apps to investigate - it’ll be using the old flash API, most likely.

I think I can make a build with modified linker script to be compatible with SD boot
as I can see the difference only on flash position leaving it to bootloader

FLASH(rx) : ORIGIN = 0x10000000 + 256k, LENGTH = 4096k - 256k

this is original

FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 4096k

No! :smiley:

Changing the linker script was required for SD Boot, not UF2 Loader.

Don’t worry about trying to figure this out yourself - I’m doing a bunch of sneaky things under the hood and it’s my job to figure out how to get everything to play nice.

(also, this is the first thing that seems to be built for RISC-V and I really want to see that working!)

WHOA this is WEIRD.

The bootloader isn’t actually overwritten at all, but for some reason it can no longer read the sd card!

NuttX, what did you do!??! :sweat_smile:

(edit: even weirder, if I get picotool to erase the partition, it starts working again! Nothing in the partition should be affecting this stage of a cold boot!)

1 Like

There is some complicated process of choosing what arch should be run from the start, risc-v or arm. Maybe if they mixed arch arm and risc-v there is some issue.

Made 0.4.0 RISC-V Pico 2 pre-release uf2

1 Like

I don’t remember if you can “switch” the rp2350 arch on the fly (without through a power reset).
Technically, I would say no, since it is possible to load RISC code on the second core when the first is running in ARM mode…

Yes, reset is needed but you can use 2 different cores in the same time.

3.9.2. Mixed Architecture Combinations
The ARCHSEL register has one bit for each processor socket, so it is possible to request mixed combinations of Arm
and RISC-V processors: either Arm core 0 and RISC-V core 1, or RISC-V core 0 and Arm core 1.

So it’s possible to have ARM image and second RISC-V image, for example run the ARM image then boot to second RISC-V image.

1 Like

The problem is happening long before the system is asked to start executing the application, so what arch it’s using shouldn’t really matter (and for the record I was using the ARM uf2 anyway.)

I suspect a bug in my implementation is spuriously looking deep into the application partition, and just happens to work by coincidence when that location is empty.

Yeah, this is still being weird. I’ve replaced my low-level sd driver with ChaN’s, and my Sandisk cards work, but the Lexar still fails (and in a weird way - it claims everything is fine but gives back all zeros when asked to read a sector.)

This’ll probably be where I have to leave it for v2.1 - I need to hook up the logic analyzer to dig into it further, but that’ll take some time.

Until I worked on my own FAT32 code, I never truly appreciated that SD Cards are not media, but a hardware device with which one communicates and every manufacturer or card has its own quirks.

The current initialisation code I now have works with the smattering of SD Cards I own, but it didn’t start that way.

JFYI, I managed to get QSPI working on PSRAM by modified version of rp2040-psram project, so we will get the speed bump for PSRAM.

The only thing that not working right now is variable bytes write/reads, reads/writes up to 128bits is working now.

Update: Initially wrote about SD card, but then remembered it’s for PSRAM :wink:

Here is the stats:

All tests done on on RISC-V core

Full chart without 8bit test for 150mhz sysclock

Testing PSRAM(SPI)...
16 bit: PSRAM write 8MB in 3299527 us, 2542366 B/s
16 bit: PSRAM read 8MB in 6263501 us, 1339284 B/s
32 bit: PSRAM write 8MB in 2306877 us, 3636348 B/s
32 bit: PSRAM read 8MB in 3704978 us, 2264145 B/s
128 bit: PSRAM write 8MB in 1250219 us, 6709711 B/s
128 bit: PSRAM read 8MB in 1613943 us, 5197586 B/s
Testing PSRAM(QSPI)...
16 bit: PSRAM write 8MB in 2963981 us, 2830182 B/s
16 bit: PSRAM read 8MB in 4026536 us, 2083331 B/s
32 bit: PSRAM write 8MB in 1761612 us, 4761893 B/s
32 bit: PSRAM read 8MB in 2278914 us, 3680967 B/s
128 bit: PSRAM write 8MB in 774859 us, 10825980 B/s
128 bit: PSRAM read 8MB in 768089 us, 10921401 B/s

Key Gains:

  • Write speeds: 11% to 61% improvement

  • Read speeds: 55% to 110% improvement

This is with sysclock 200mhz

Testing PSRAM(SPI)...
16 bit: PSRAM write 8MB in 2474646 us, 3389821 B/s
16 bit: PSRAM read 8MB in 4697627 us, 1785711 B/s
32 bit: PSRAM write 8MB in 1730158 us, 4848463 B/s
32 bit: PSRAM read 8MB in 2778734 us, 3018859 B/s
128 bit: PSRAM write 8MB in 937664 us, 8946284 B/s
128 bit: PSRAM read 8MB in 1210457 us, 6930116 B/s
Testing PSRAM(QSPI)...
16 bit: PSRAM write 8MB in 2222985 us, 3773578 B/s
16 bit: PSRAM read 8MB in 3019904 us, 2777773 B/s
32 bit: PSRAM write 8MB in 1321209 us, 6349191 B/s
32 bit: PSRAM read 8MB in 1709185 us, 4907958 B/s
128 bit: PSRAM write 8MB in 581143 us, 14434671 B/s
128 bit: PSRAM read 8MB in 576068 us, 14561836 B/s

sysclock 230mhz

Testing PSRAM(SPI)...
16 bit: PSRAM write 8MB in 2151866 us, 3898294 B/s
16 bit: PSRAM read 8MB in 4084893 us, 2053568 B/s
32 bit: PSRAM write 8MB in 1504485 us, 5575734 B/s
32 bit: PSRAM read 8MB in 2416290 us, 3471689 B/s
128 bit: PSRAM write 8MB in 815360 us, 10288226 B/s
128 bit: PSRAM read 8MB in 1052571 us, 7969636 B/s
Testing PSRAM(QSPI)...
16 bit: PSRAM write 8MB in 1933030 us, 4339616 B/s
16 bit: PSRAM read 8MB in 2626002 us, 3194440 B/s
32 bit: PSRAM write 8MB in 1148877 us, 7301572 B/s
32 bit: PSRAM read 8MB in 1486247 us, 5644154 B/s
128 bit: PSRAM write 8MB in 505343 us, 16599830 B/s
128 bit: PSRAM read 8MB in 500928 us, 16746135 B/s

If I set higher sysclock I got some failures and bitflips while reading

PS I guess we can use PSRAM as framebuffer?

320 × 320 × 2 bytes × 30 fps = 6.14 MB/s
320 × 320 × 2 bytes × 45 fps = 9.22 MB/s
320 × 320 × 2 bytes × 60 fps = 12.29 MB/s

Here is the draft pull to upstream Initial QSPI(QPI) support by shtirlic · Pull Request #15 · polpo/rp2040-psram · GitHub

3 Likes

We’ve talked a little about this possibility here and here.

The main issue is the maximum LCD SPI speed, which seem to be 62.5 MHz (the maximum for the RP2350, 75 MHz in overclock, can’t say the screen don’t have some artefacts).
So the maximum bitrate shoul be around 7.8 MB/s. 30 or 45 FPS seem feasable, but the 60 is far away unfortunatly. :confused:

1 Like