Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for RP2350 #16

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: prawnblaster-firmware-${{ github.sha }}
path: build/prawn_do/prawn_do.uf2
path: build_*/prawn_do/*.uf2

- name: Create release
if: (github.event_name == 'push' && contains(github.ref, '/tags'))
Expand All @@ -35,4 +35,5 @@ jobs:
prerelease: false
files: |
LICENSE.txt
build/prawn_do/prawn_do.uf2
build_rp2040/prawn_do/prawn_do_rp2040.uf2
build_rp2350/prawn_do/prawn_do_rp2350.uf2
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
build/*
!build/*.uf2
build*/*
.vscode
.DS_Store
cmake-*
cmake-*
pico_sdk_import.cmake
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.17)

include(pico_sdk_import.cmake)

Expand Down
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ This firmware turns pins 0-15 into programmable digital outputs. Their states ar

Pin 20 is reserved for optional external clock input.

## Supported boards

We support either the official [Raspberry Pi Pico (RP2040 chip)](https://www.raspberrypi.com/products/raspberry-pi-pico/) board or the official [Raspberry Pi Pico 2 (RP2350 chip)](https://www.raspberrypi.com/products/raspberry-pi-pico-2/) board.
We recommend the Pico 2 (RP2350) board due to its faster clock and larger RAM.

## Specs

All timings are given relative to the default system clock of 100 MHz.
Expand All @@ -14,12 +19,21 @@ All timings are given relative to the default system clock of 100 MHz.
* **Minimum Pulse Width**: 5 clock cycles (50 ns)
* **Max Pulse Rate**: 1/10 system clock frequency (10 MHz)
* **Maximum Pulse Width**: 2^32 - 1 clock cycles (42.94967295 s)
* **Max Instructions**: 30,000
* **Max Instructions**: 60,000 (Pico 2 - RP2350) or 30,000 (Pico - RP2040)
* Supports Indefinite Waits and Full Stops
* Max system clock frequency of 133 MHz
* Max system clock frequency of 150 MHz (Pico 2 - RP2350) or 133 MHz (Pico - RP2040)
* Support for referencing the system clock to an external clock source to synchronise with other devices (officially limited to 50MHz on the Pico and Pico 2, but testing has shown it works up to 133MHz).

## Installing the .uf2 file
Before plugging in usb, hold down the bootsel button, which should pop-up a window to drag/drop the .uf2 file into, and when that .uf2 file is added, the window should disappear.
Download the latest prawn_do.uf2 file:
- [Pico 2 - RP2350](https://github.com/labscript-suite/prawn_digital_out/releases/latest/download/prawn_do_rp2350.uf2)
- [Pico - RP2040](https://github.com/labscript-suite/prawn_digital_out/releases/latest/download/prawn_do_rp2040.uf2)

On your Raspberry Pi Pico, hold down the "bootsel" button while plugging the Pico into USB port on a PC (that must already be turned on).
The Pico should mount as a mass storage device (if it doesn't, try again or consult the Pico documentation).
Drag and drop the `.uf2` file into the mounted mass storage device.
The mass storage device should unmount after the copy completes.
Your Pico is now running the Prawn Digital Output firmware!

## Serial Communication
Commands must end with a newline character: `'\n'`.
Expand All @@ -43,6 +57,7 @@ These commands can be run at any time (ie during sequence execution).
* `deb` - Turns on debugging mode which adds printed output when adding instructions. By default, debugging is off.
* `ndb` - Turns off debugging mode.
* `ver` - Displays the version of the PrawnDO code.
* `brd` - Responds with a string containing the board version (`pico1` or `pico2`).
* `abt` - Abort execution of a running sequence.

These commands must be run when the running status is `STOPPED`.
Expand Down Expand Up @@ -79,7 +94,7 @@ These commands must be run when the running status is `STOPPED`.
* `len` - Print total number of instructions in the programmed sequence.
* `cls` - Clear the current sequence of programmed outputs.

* `clk <src (0: internal, 1: external)> <freq (in decimal Hz)>` - Sets the system clock and frequency. Maximum frequency allowed is 133 MHz. Default is 100 MHz internal clock. External clock frequency input is GPIO pin 20.
* `clk <src (0: internal, 1: external)> <freq (in decimal Hz)>` - Sets the system clock and frequency. Maximum frequency allowed is 150 MHz (Pico 2 - RP2350) or 133 MHz (Pico - RP2040). Default is 100 MHz internal clock. External clock frequency input is GPIO pin 20.
* `frq` - Measure and print system frequencies.
* `prg` - Equivalent to disconnecting the Pico, holding down the "bootsel" button, and reconnecting the Pico. Places the Pico into firmware flashing mode; the PrawnDO serial port should disappear and the Pico should mount as a mass storage device.

Expand Down Expand Up @@ -140,7 +155,7 @@ If you want to make changes to the firmware, or want to compile it yourself (bec
2. Clone this repository
3. Open a terminal with the current working directory set to the repository root (the `docker-compose.yaml`` file should be there)
4. Run `docker compose build --pull` to build the docker container
5. Run `docker compose up` to build the PrawnBlaster firmware.
5. Run `docker compose up` to build the PrawnDO firmware.

Step 4 will take a while as it has to build the docker container.
If it is slow to download packages from the Ubuntu package repositories, consider providing an explicit apt mirror that is fast for you: `docker compose build --pull --build-arg APT_MIRROR="http://azure.archive.ubuntu.com/ubuntu/"`.
Expand All @@ -151,3 +166,8 @@ Just change the git tag of the pico SDK that gets cloned out by git, then rebuil
Note once the docker container is built, you can run step 5 as many times as you like.
You do not need to rebuild the container, even if you make changes to the source code.
You only need to rebuild the docker container if you modify the `build/docker/Dockerfile` file.

By default, running `docker compose up` builds the all variations of the firmware.
If you only want to build for a specific board, run either `docker compose up build_rp2040_firmware` or `docker compose up build_rp2350_firmware`.

The firmware will be located in `build_rp2xxx/prawn_do/prawn_do_rp2xxx.uf2` where `rp2xxx` will be either `rp2040` or `rp2350`.
27 changes: 23 additions & 4 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
name: prawn_do

services:
buildfirmware:
prawn_do_firmware_base:
build:
dockerfile: docker/Dockerfile
command: /bin/bash -c 'cmake .. && make'
image: prawn_digital_output/build-firmware
volumes:
- .:/prawn_digital_output
working_dir: /prawn_digital_output/build
init: true
command: /bin/bash -c 'cp /pico/pico-sdk/external/pico_sdk_import.cmake /prawn_digital_output/'
container_name: prawn_do_firmware_base

build_rp2040_firmware:
image: prawn_digital_output/build-firmware
command: /bin/bash -c 'cmake .. -D PICO_PLATFORM=rp2040 && make'
volumes:
- .:/prawn_digital_output
working_dir: /prawn_digital_output/build_rp2040
init: true
depends_on:
- prawn_do_firmware_base
build_rp2350_firmware:
image: prawn_digital_output/build-firmware
command: /bin/bash -c 'cmake .. -D PICO_PLATFORM=rp2350 && make'
volumes:
- .:/prawn_digital_output
working_dir: /prawn_digital_output/build_rp2350
init: true
depends_on:
- prawn_do_firmware_base
10 changes: 6 additions & 4 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@ ARG APT_MIRROR="mirror://mirrors.ubuntu.com/mirrors.txt"
# ARG APT_MIRROR="http://mirror.aarnet.edu.au/pub/ubuntu/archive/"

# Configure mirror. Pass --build-arg APT_MIRROR=<mirror URL> to set a mirror if this is slow
RUN sed -i "s#htt[p|ps]://archive.ubuntu.com/ubuntu/#$APT_MIRROR#g" /etc/apt/sources.list
RUN sed -i "s#htt[p|ps]://archive.ubuntu.com/ubuntu/#$APT_MIRROR#g" /etc/apt/sources.list.d/ubuntu.sources

# Install packages
RUN \
apt update && \
apt install -y git python3 && \
apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
# For Pico SDK
apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib build-essential

# Install Pico SDK into a new stage
FROM base as buildtools

# Install Pico SDK
RUN \
mkdir -p /pico/ && \
cd /pico/ && \
git clone https://github.com/raspberrypi/pico-sdk.git --branch 1.5.1 && \
git clone https://github.com/raspberrypi/pico-sdk.git --branch 2.0.0 && \
cd pico-sdk/ && \
git submodule update --init && \
cd /

# Set the Pico SDK environment variable
ENV PICO_SDK_PATH=/pico/pico-sdk/
ENV PICO_SDK_PATH=/pico/pico-sdk/
73 changes: 0 additions & 73 deletions pico_sdk_import.cmake

This file was deleted.

74 changes: 49 additions & 25 deletions prawn_do/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
add_executable(prawn_do
prawn_do.c
fast_serial.c
)

pico_generate_pio_header(prawn_do
${CMAKE_CURRENT_LIST_DIR}/prawn_do.pio
)

# add local includes for fast_serial
target_include_directories(prawn_do PRIVATE ${CMAKE_CURRENT_LIST_DIR})

# pull in pico stdlib
target_link_libraries(prawn_do
pico_multicore
pico_stdlib
pico_unique_id
hardware_dma
hardware_pio
tinyusb_device
tinyusb_board
)

# create map/bin/hex/uf2 files
pico_add_extra_outputs(prawn_do)
set(overclocks 0;)

foreach (overclock IN LISTS overclocks)
# Compute firmware name
set(firmware_name prawn_do)
if(PICO_PLATFORM MATCHES "^rp2350")
set(firmware_name "${firmware_name}_rp2350")
else()
set(firmware_name "${firmware_name}_${PICO_PLATFORM}")
endif()
if(overclock)
set(firmware_name "${firmware_name}_overclock")
endif()

add_executable(${firmware_name} prawn_do.c fast_serial.c)

pico_generate_pio_header(${firmware_name} ${CMAKE_CURRENT_LIST_DIR}/prawn_do.pio)

# Pass in number of instructions to firmware as a compiler definition
set(num_instructions 30000)
if(PICO_PLATFORM MATCHES "^rp2350")
set(num_instructions 60000)
endif()
target_compile_definitions(${firmware_name} PUBLIC "PRAWNDO_NUM_INSTRUCTIONS=${num_instructions}")

# Pass in board type to firmware as a compiler definition. Note that PICO_BOARD is passed in by the SDK, but it's passed in a string which isn't valid and so I can't use it...
# This is also, to some extent, a duplicate of the above PRAWNDO_NUM_INSTRUCTIONS but I think it makes sense to keep these seperate.
if (PICO_BOARD STREQUAL "pico")
target_compile_definitions(${firmware_name} PUBLIC "PRAWNDO_PICO_BOARD=1")
elseif (PICO_BOARD STREQUAL "pico2")
target_compile_definitions(${firmware_name} PUBLIC "PRAWNDO_PICO_BOARD=2")
else ()
message(FATAL_ERROR "Unsupported PICO_BOARD")
endif()


# Pass in overclock state to firmware as a compiler definition
if(overclock)
target_compile_definitions(${firmware_name} PUBLIC "PRAWNDO_OVERCLOCK=1")
endif()

# Pull in our pico_stdlib which aggregates commonly used features
target_link_libraries(${firmware_name} pico_stdlib hardware_pio pico_multicore pico_unique_id hardware_clocks hardware_dma tinyusb_device tinyusb_board)
target_include_directories(${firmware_name} PRIVATE ${CMAKE_CURRENT_LIST_DIR})

# create map/bin/hex/uf2 file etc.
pico_add_extra_outputs(${firmware_name})

endforeach()
Loading