Compare commits

..

24 Commits

Author SHA1 Message Date
Philip Howard
7319462023
Merge pull request #43 from pimoroni/patch-pimoroni-pico
CI: Bump pimoroni-pico.
2025-09-22 11:17:57 +01:00
Phil Howard
ae71a1b52f CI: Bump pimoroni-pico. 2025-09-22 10:51:42 +01:00
Philip Howard
5403f151a0
Merge pull request #18 from pimoroni/feature/wireless
Wireless & Bluetooth Support
2025-09-22 10:14:58 +01:00
Phil Howard
c809cf37e2 CI: Bump to rebase on MicroPython 1.26. 2025-09-19 10:39:32 +01:00
Phil Howard
3419f0ba07 CI: Fix ci_cmake_build when CI_RELEASE_FILENAME is unset. 2025-09-10 15:21:50 +01:00
Hel Gibbons
e5d04a5c63
Merge pull request #42 from pimoroni/helgibbons-patch-1
Update README.md
2025-08-08 09:29:43 +01:00
Hel Gibbons
25c6e0d9d2
Update README.md 2025-08-07 10:21:23 +01:00
Hel Gibbons
9a213f226c
Merge pull request #39 from pimoroni/helgibbons-patch-1
Readme: Link to new Plasma repo
2025-04-16 11:43:58 +01:00
Phil Howard
d7a50b9916 CI: Bump to MicroPython branch with sleep fix. 2025-04-14 17:07:49 +01:00
Phil Howard
554817d5fc CI: Bump to latest rebase.
Should include refined PSRAM changes, a version bump to LwIP and other
MicroPython tweaks.
2025-04-14 17:07:49 +01:00
Phil Howard
4dbd106611 CI: Fix board manifest PORT_DIR var. 2025-04-14 17:07:49 +01:00
Phil Howard
5ff24aabe7 CI: Bump to latest rebase.
Should include changes to PSRAM, including a 4K flash saving on non-PSRAM builds.
2025-04-14 17:07:49 +01:00
Phil Howard
c6602aafa2 CI: Enable py_decl filesystem overlap check. 2025-04-14 17:07:47 +01:00
Phil Howard
7a087a8567 CI: Ignore non-existent with-filesystem builds.
Move file rename busywork into micropython.sh.
2025-04-14 17:06:58 +01:00
Phil Howard
af670449c0 CI: Refactor to match our other tooling.
Retarget pimoroni-pico to feature/picovector2-and-layers.
2025-04-14 17:06:58 +01:00
Phil Howard
d4205caedc Remove duplicate MICROPY_PY_NETWORK. 2025-04-14 17:06:58 +01:00
Phil Howard
4d4853e9e2 Remove duplicate lte.py. 2025-04-14 17:06:58 +01:00
Phil Howard
4a24f87253 Add lte.py to common manifest. 2025-04-14 17:06:58 +01:00
Phil Howard
02d9e0fdf4 Enable LTE & PPP for Pico2/Pico2W. 2025-04-14 17:06:58 +01:00
Phil Howard
776f21ea27 Pico2: Remove spurious pico2_w.h. 2025-04-14 17:06:58 +01:00
Hel Gibbons
7d4f727162
Readme: Link to new Plasma repo 2025-04-11 15:52:17 +01:00
Phil Howard
0527852dbd CI: Switch to pico2_w_2025 MicroPython branch. 2025-02-28 13:46:51 +00:00
Hel Gibbons
cf22206e62
Update README.md 2025-02-28 13:42:30 +00:00
Hel Gibbons
f44e12e7ab
Update README.md 2025-02-28 13:39:45 +00:00
81 changed files with 321 additions and 485 deletions

View File

@ -6,46 +6,34 @@ on:
release: release:
types: [created] types: [created]
env:
MICROPYTHON_VERSION: feature/psram-and-wifi
MICROPYTHON_FLAVOUR: pimoroni
PIMORONI_PICO_VERSION: main
jobs: jobs:
build: build:
name: ${{ matrix.name }} (${{ matrix.board }}) name: MicroPython ${{ matrix.name }}
runs-on: ubuntu-20.04 runs-on: ubuntu-24.04
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:
include: include:
- name: pico2 - name: rpi_pico2
board: RPI_PICO2 - name: rpi_pico2_w
- name: pico2_w - name: rpi_pico2b
board: RPI_PICO2_W - name: pimoroni_plasma2350
- name: pico2b_rp2350 - name: pimoroni_tiny2350
board: RPI_PICO2B - name: pimoroni_pico_plus2
- name: plasma2350
board: PIMORONI_PLASMA2350
- name: tiny2350
board: PIMORONI_TINY2350
- name: pico_plus2_rp2350
board: PIMORONI_PICO_PLUS2
env: env:
# MicroPython version will be contained in github.event.release.tag_name for releases # MicroPython version will be contained in github.event.release.tag_name for releases
RELEASE_FILE: ${{ matrix.name }}-${{ github.event.release.tag_name || github.sha }}-pimoroni-micropython CI_RELEASE_FILENAME: ${{ matrix.name }}-${{ github.event.release.tag_name || github.sha }}-micropython
PIMORONI_PICO_DIR: "${{ github.workspace }}/pimoroni-pico" CI_PROJECT_ROOT: ${{ github.workspace }}/src-${{ github.sha }}
MICROPY_BOARD_DIR: "${{ github.workspace }}/pimoroni-pico-rp2350-${{ github.sha }}/micropython/board/${{ matrix.BOARD }}" CI_BUILD_ROOT: ${{ github.workspace }}
USER_C_MODULES: "${{ github.workspace }}/pimoroni-pico-rp2350-${{ github.sha }}/micropython/micropython-pico2.cmake" CI_USE_ENV: 1
TAG_OR_SHA: ${{ github.event.release.tag_name || github.sha }}
MICROPY_BOARD: ${{ matrix.board }}
MICROPY_BOARD_VARIANT: ${{ matrix.variant }}
BOARD_NAME: ${{ matrix.name }}
BUILD_TOOLS: pimoroni-pico-rp2350-${{ github.sha }}/ci/micropython.sh
steps: steps:
- name: Compiler Cache - name: Compiler Cache Fixup
run: |
mkdir -p /home/runner/.ccache
- name: "CCache: Restore saved cache"
uses: actions/cache@v4 uses: actions/cache@v4
with: with:
path: /home/runner/.ccache path: /home/runner/.ccache
@ -54,76 +42,61 @@ jobs:
ccache-micropython-${{ matrix.name }}-${{ github.ref }} ccache-micropython-${{ matrix.name }}-${{ github.ref }}
ccache-micropython-${{ matrix.name }}- ccache-micropython-${{ matrix.name }}-
- uses: actions/checkout@v4 - name: "Checkout Project"
uses: actions/checkout@v4
with: with:
submodules: true submodules: true
path: pimoroni-pico-rp2350-${{ github.sha }} path: ${{ env.CI_PROJECT_ROOT }}
- uses: actions/checkout@v4 - name: "Install Arm GNU Toolchain (arm-none-eabi-gcc)"
with:
repository: pimoroni/pimoroni-pico
ref: ${{env.PIMORONI_PICO_VERSION}}
submodules: true
path: pimoroni-pico
- name: Install Arm GNU Toolchain (arm-none-eabi-gcc)
uses: carlosperate/arm-none-eabi-gcc-action@v1 uses: carlosperate/arm-none-eabi-gcc-action@v1
with: with:
release: '13.3.Rel1' release: '13.3.Rel1'
- name: Install CCache - name: "Prepare tools & dependencies"
run: |
source $BUILD_TOOLS
apt_install_build_deps
- name: Checkout MicroPython & Submodules
run: |
source $BUILD_TOOLS
micropython_clone
- name: "Py_Decl: Checkout py_decl"
uses: actions/checkout@v4
with:
repository: gadgetoid/py_decl
ref: v0.0.2
path: py_decl
- name: Build MPY Cross
run: |
source $BUILD_TOOLS
micropython_build_mpy_cross
- name: Configure MicroPython
shell: bash shell: bash
run: | run: |
source $BUILD_TOOLS source $CI_PROJECT_ROOT/ci/micropython.sh && ci_debug
mkdir -p $CI_BUILD_ROOT
ci_apt_install_build_deps
ci_prepare_all
- name: "MicroPython: Configure"
shell: bash
run: |
source $CI_PROJECT_ROOT/ci/micropython.sh && ci_debug
micropython_version micropython_version
cmake_configure ci_cmake_configure ${{ matrix.name }}
- name: Build MicroPython - name: "MicroPython: Build"
shell: bash shell: bash
run: | run: |
source $BUILD_TOOLS source $CI_PROJECT_ROOT/ci/micropython.sh && ci_debug
cmake_build python3 -m venv "$CI_BUILD_ROOT/.dir2uf2"
source "$CI_BUILD_ROOT/.dir2uf2/bin/activate"
ci_cmake_build ${{ matrix.name }}
- name: "Py_Decl: Verify UF2" - name: "Artifacts: Upload .uf2"
shell: bash
run: |
python3 py_decl/py_decl.py --to-json --verify build-${{ matrix.name }}/${{ env.RELEASE_FILE }}.uf2
- name: Store .uf2 as artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_FILE }}.uf2 name: ${{ env.CI_RELEASE_FILENAME }}.uf2
path: build-${{ matrix.name }}/${{ env.RELEASE_FILE }}.uf2 path: ${{ env.CI_BUILD_ROOT }}/${{ env.CI_RELEASE_FILENAME }}.uf2
- name: Upload .uf2 - name: "Release: Upload .uf2"
if: github.event_name == 'release' if: github.event_name == 'release'
uses: actions/upload-release-asset@v1 uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
asset_path: build-${{ matrix.name }}/firmware.uf2 files: ${{ env.CI_BUILD_ROOT }}/${{ env.CI_RELEASE_FILENAME }}.uf2
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ env.RELEASE_FILE }}.uf2 - name: "Artifacts: Upload .uf2 (With Filesystem)"
asset_content_type: application/octet-stream uses: actions/upload-artifact@v4
with:
if-no-files-found: ignore
name: ${{ env.CI_RELEASE_FILENAME }}-with-filesystem.uf2
path: ${{ env.CI_BUILD_ROOT }}/${{ env.CI_RELEASE_FILENAME }}-with-filesystem.uf2
- name: "Release: Upload .uf2 (With Filesystem)"
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: ${{ env.CI_BUILD_ROOT }}/${{ env.CI_RELEASE_FILENAME }}-with-filesystem.uf2

39
.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
**/build
.vscode
# Apple filesystem cruft
.DS_Store
venv

View File

@ -7,15 +7,17 @@ batteries-included flavour of MicroPython for RP2350 / Pico2 boards.
| Board | MicroPython Flavour | Download Link | Notes | | Board | MicroPython Flavour | Download Link | Notes |
|-------|---------------------|---------------|-------| |-------|---------------------|---------------|-------|
| Pimoroni Pico Plus 2 & 2 W | pico_plus2_rp2350 | [pico_plus2_rp2350-v0.0.11-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.11/pico_plus2_rp2350-v0.0.11-pimoroni-micropython.uf2) | :warning: Experimental: Enables PSRAM | Pimoroni Pico Plus 2 & 2 W | pimoroni_pico_plus2-vx.x.x | [Download from Releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/latest) | :warning: Experimental: Enables PSRAM
| Plasma 2350 & Plasma 2350 W | plasma2350 | [plasma2350-v0.0.11-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.11/plasma2350-v0.0.11-pimoroni-micropython.uf2) | | Tiny 2350 | pimoroni_tiny2350-vx.x.x | [Download from Releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/latest) |
| Tiny 2350 | tiny2350 | [tiny2350-v0.0.11-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.11/tiny2350-v0.0.11-pimoroni-micropython.uf2) | | Raspberry Pi Pico 2 | rpi-pico2-vx.x.x | [Download from Releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/latest) | This gives you the Pimoroni Pico libs on a vanilla Pico 2
| Raspberry Pi Pico 2 | pico2 | [pico2-v0.0.11-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.11/pico2-v0.0.11-pimoroni-micropython.uf2) | This gives you the Pimoroni Pico libs on a vanilla Pico 2 | Raspberry Pi Pico 2 W | rpi-pico2_w-vx.x.x | [Download from Releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/latest) | This gives you the Pimoroni Pico libs on a vanilla Pico 2 W
| Raspberry Pi Pico 2 W | pico2_w | [pico2_w-v0.0.11-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.11/pico2_w-v0.0.11-pimoroni-micropython.uf2) | This gives you the Pimoroni Pico libs on a vanilla Pico 2 W
| PGA2350 | ~ | [https://github.com/pimoroni/pga/](https://github.com/pimoroni/pga/) | See the PGA repo for builds and boilerplate | PGA2350 | ~ | [https://github.com/pimoroni/pga/](https://github.com/pimoroni/pga/) | See the PGA repo for builds and boilerplate
| Pimoroni Explorer | ~ | [https://github.com/pimoroni/explorer](https://github.com/pimoroni/explorer) | See the Explorer repo for builds and examples | Pimoroni Explorer | ~ | [https://github.com/pimoroni/explorer](https://github.com/pimoroni/explorer) | See the Explorer repo for builds and examples
| Inky Frame (Pico 2 W Aboard) | ~ | [https://github.com/pimoroni/inky-frame](https://github.com/pimoroni/inky-frame) | See the Inky Frame repo for builds and examples | Inky Frame (Pico 2 W Aboard) | ~ | [https://github.com/pimoroni/inky-frame](https://github.com/pimoroni/inky-frame) | See the Inky Frame repo for builds and examples
| Pico 2 W Unicorn | ~ | [https://github.com/pimoroni/unicorn](https://github.com/pimoroni/unicorn) | See the Unicorn repo for builds and examples | Pico 2 W Unicorn | ~ | [https://github.com/pimoroni/unicorn](https://github.com/pimoroni/unicorn) | See the Unicorn repo for builds and examples
| Pimoroni Presto | ~ | [https://github.com/pimoroni/presto](https://github.com/pimoroni/presto) | See the Presto repo for builds and examples | Pimoroni Presto | ~ | [https://github.com/pimoroni/presto](https://github.com/pimoroni/presto) | See the Presto repo for builds and examples
| Interstate 75 W (RP2350) | ~ | [https://github.com/pimoroni/interstate75](https://github.com/pimoroni/interstate75) | See the Interstate 75 repo for builds and examples
| Plasma 2350 & Plasma 2350 W | ~ | [https://github.com/pimoroni/plasma](https://github.com/pimoroni/plasma) | See the Plasma repo for builds and examples
| Pimoroni Pico LiPo 2 & 2 XL W | ~ | [https://github.com/pimoroni/pico-lipo](https://github.com/pimoroni/pico-lipo) | See the Pico-LiPo repo for builds and examples
For a list of all releases see [https://github.com/pimoroni/pimoroni-pico-rp2350/releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases). For a list of all releases see [https://github.com/pimoroni/pimoroni-pico-rp2350/releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases).

41
boards/common.cmake Normal file
View File

@ -0,0 +1,41 @@
# Make sure we get our VirtualEnv Python
set(Python_FIND_VIRTUALENV "FIRST")
set(Python_FIND_UNVERSIONED_NAMES "FIRST")
set(Python_FIND_STRATEGY "LOCATION")
find_package (Python COMPONENTS Interpreter Development)
message("dir2uf2/py_decl: Using Python ${Python_EXECUTABLE}")
MESSAGE("dir2uf2/py_decl: Using pimoroni tools dir ${PIMORONI_TOOLS_DIR}")
if (EXISTS "${PIMORONI_TOOLS_DIR}/py_decl/py_decl.py")
MESSAGE("py_decl: py_decl.py found, will verify uf2.")
add_custom_target("${MICROPY_TARGET}-verify" ALL
COMMAND ${Python_EXECUTABLE} "${PIMORONI_TOOLS_DIR}/py_decl/py_decl.py" --to-json --verify "${CMAKE_CURRENT_BINARY_DIR}/${MICROPY_TARGET}.uf2"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "pydecl: Verifying ${MICROPY_TARGET}.uf2"
DEPENDS ${MICROPY_TARGET}
)
endif()
if(DEFINED PIMORONI_UF2_MANIFEST AND DEFINED PIMORONI_UF2_DIR)
# Convert supplies paths to absolute, for a quieter life
get_filename_component(PIMORONI_UF2_MANIFEST ${PIMORONI_UF2_MANIFEST} REALPATH)
get_filename_component(PIMORONI_UF2_DIR ${PIMORONI_UF2_DIR} REALPATH)
if (EXISTS "${PIMORONI_TOOLS_DIR}/dir2uf2/dir2uf2" AND EXISTS "${PIMORONI_UF2_MANIFEST}" AND EXISTS "${PIMORONI_UF2_DIR}")
MESSAGE("dir2uf2: Using manifest ${PIMORONI_UF2_MANIFEST}.")
MESSAGE("dir2uf2: Using root ${PIMORONI_UF2_DIR}.")
add_custom_target("${MICROPY_TARGET}-with-filesystem.uf2" ALL
COMMAND ${Python_EXECUTABLE} "${PIMORONI_TOOLS_DIR}/dir2uf2/dir2uf2" --fs-compact --sparse --append-to "${MICROPY_TARGET}.uf2" --manifest "${PIMORONI_UF2_MANIFEST}" --filename with-filesystem.uf2 "${PIMORONI_UF2_DIR}"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "dir2uf2: Appending filesystem to ${MICROPY_TARGET}.uf2."
DEPENDS ${MICROPY_TARGET}
DEPENDS "${MICROPY_TARGET}-verify"
)
else()
MESSAGE("dir2uf2: Could not find manifest ${PIMORONI_UF2_MANIFEST}")
MESSAGE(" and/or root ${PIMORONI_UF2_DIR}.")
endif()
endif()

12
boards/manifest_pico2.py Normal file
View File

@ -0,0 +1,12 @@
# micropython/ports/rp2/../../../
MODULES_PY = "$(PORT_DIR)/../../../pimoroni-pico/micropython/modules_py"
# SD Card
require("sdcard")
freeze(MODULES_PY, "gfx_pack.py")
freeze(MODULES_PY, "pimoroni.py")
freeze(MODULES_PY, "boot.py")
freeze(MODULES_PY, "lte.py")

View File

@ -6,5 +6,3 @@ require("aioble")
include("$(PORT_DIR)/boards/manifest.py") include("$(PORT_DIR)/boards/manifest.py")
include("../manifest_pico2.py") include("../manifest_pico2.py")
freeze("$(BOARD_DIR)/../../modules_py", "lte.py")

View File

@ -36,4 +36,4 @@ set(MICROPY_BLUETOOTH_BTSTACK ON)
# MICROPY_PY_BLUETOOTH_CYW43 = 1 # MICROPY_PY_BLUETOOTH_CYW43 = 1
set(MICROPY_PY_BLUETOOTH_CYW43 ON) set(MICROPY_PY_BLUETOOTH_CYW43 ON)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -0,0 +1,3 @@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
include(usermod-common)

View File

@ -6,5 +6,3 @@ require("aioble")
include("$(PORT_DIR)/boards/manifest.py") include("$(PORT_DIR)/boards/manifest.py")
include("../manifest_pico2.py") include("../manifest_pico2.py")
freeze("$(BOARD_DIR)/../../modules_py", "lte.py")

View File

@ -35,3 +35,4 @@ set(MICROPY_BLUETOOTH_BTSTACK ON)
# MICROPY_PY_BLUETOOTH_CYW43 = 1 # MICROPY_PY_BLUETOOTH_CYW43 = 1
set(MICROPY_PY_BLUETOOTH_CYW43 ON) set(MICROPY_PY_BLUETOOTH_CYW43 ON)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -0,0 +1,3 @@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
include(usermod-common)

View File

@ -6,3 +6,5 @@ set(PICO_PLATFORM "rp2350")
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
set(MICROPY_C_HEAP_SIZE 4096) set(MICROPY_C_HEAP_SIZE 4096)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -0,0 +1,3 @@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
include(usermod-common)

View File

@ -0,0 +1,18 @@
# cmake file for Raspberry Pi Pico2
set(PICO_BOARD "pico2")
# To change the gpio count for QFN-80
# set(PICO_NUM_GPIOS 48)
# Links micropy_lib_lwip and sets MICROPY_PY_LWIP = 1
# Picked up and expanded upon in mpconfigboard.h
set(MICROPY_PY_LWIP ON)
if (PICO_CYW43_SUPPORTED)
include(enable_cyw43.cmake)
set(PICO_PINS_CSV_NAME pins_cyw43.csv)
endif()
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -2,6 +2,12 @@
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico2" #define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico2"
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024 * 2) #define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024 * 2)
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico2"
// Enable WiFi & PPP
#define MICROPY_PY_NETWORK (1)
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
#if MICROPY_PY_NETWORK_CYW43 #if MICROPY_PY_NETWORK_CYW43
#include "enable_cyw43.h" #include "enable_cyw43.h"

View File

@ -0,0 +1,3 @@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
include(usermod-common)

View File

@ -0,0 +1,16 @@
# cmake file for Raspberry Pi Pico 2 W
set(PICO_BOARD "pico2_w")
# To change the gpio count for QFN-80
# set(PICO_NUM_GPIOS 48)
# Links micropy_lib_lwip and sets MICROPY_PY_LWIP = 1
# Picked up and expanded upon in mpconfigboard.h
set(MICROPY_PY_LWIP ON)
include(enable_cyw43.cmake)
# Board specific version of the frozen manifest
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -2,6 +2,9 @@
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico 2 W" #define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico 2 W"
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024 * 2) #define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024 * 2)
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico2W" #define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico2W"
// Enable PPP
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
#include "enable_cyw43.h" #include "enable_cyw43.h"

View File

@ -0,0 +1,3 @@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
include(usermod-common)

View File

@ -10,3 +10,5 @@ set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
set(MICROPY_C_HEAP_SIZE 4096) set(MICROPY_C_HEAP_SIZE 4096)
set(PICO_NUM_GPIOS 48) set(PICO_NUM_GPIOS 48)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -0,0 +1,3 @@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../")
include(usermod-common)

View File

@ -1,5 +1,15 @@
export TERM=${TERM:="xterm-256color"} export TERM=${TERM:="xterm-256color"}
MICROPYTHON_FLAVOUR="pimoroni"
MICROPYTHON_VERSION="pico2_w_2025_09_19"
PIMORONI_PICO_FLAVOUR="pimoroni"
PIMORONI_PICO_VERSION="431d8ad455371075ed247b10ded769d12136c7aa"
PY_DECL_VERSION="v0.0.3"
DIR2UF2_VERSION="v0.0.9"
function log_success { function log_success {
echo -e "$(tput setaf 2)$1$(tput sgr0)" echo -e "$(tput setaf 2)$1$(tput sgr0)"
} }
@ -12,10 +22,19 @@ function log_warning {
echo -e "$(tput setaf 1)$1$(tput sgr0)" echo -e "$(tput setaf 1)$1$(tput sgr0)"
} }
function micropython_clone { function ci_pimoroni_pico_clone {
log_inform "Using MicroPython $MICROPYTHON_VERSION" log_inform "Using Pimoroni Pico $PIMORONI_PICO_FLAVOUR/$PIMORONI_PICO_VERSION"
git clone https://github.com/$MICROPYTHON_FLAVOUR/micropython git clone https://github.com/$PIMORONI_PICO_FLAVOUR/pimoroni-pico "$CI_BUILD_ROOT/pimoroni-pico"
cd micropython cd "$CI_BUILD_ROOT/pimoroni-pico" || return 1
git checkout $PIMORONI_PICO_VERSION
git submodule update --init
cd "$CI_BUILD_ROOT"
}
function ci_micropython_clone {
log_inform "Using MicroPython $MICROPYTHON_FLAVOUR/$MICROPYTHON_VERSION"
git clone https://github.com/$MICROPYTHON_FLAVOUR/micropython "$CI_BUILD_ROOT/micropython"
cd "$CI_BUILD_ROOT/micropython" || return 1
git checkout $MICROPYTHON_VERSION git checkout $MICROPYTHON_VERSION
git submodule update --init lib/pico-sdk git submodule update --init lib/pico-sdk
git submodule update --init lib/cyw43-driver git submodule update --init lib/cyw43-driver
@ -24,42 +43,98 @@ function micropython_clone {
git submodule update --init lib/micropython-lib git submodule update --init lib/micropython-lib
git submodule update --init lib/tinyusb git submodule update --init lib/tinyusb
git submodule update --init lib/btstack git submodule update --init lib/btstack
cd ../ cd "$CI_BUILD_ROOT"
} }
function micropython_build_mpy_cross { function ci_tools_clone {
cd micropython/mpy-cross mkdir -p "$CI_BUILD_ROOT/tools"
git clone https://github.com/gadgetoid/py_decl -b "$PY_DECL_VERSION" "$CI_BUILD_ROOT/tools/py_decl"
git clone https://github.com/gadgetoid/dir2uf2 -b "$DIR2UF2_VERSION" "$CI_BUILD_ROOT/tools/dir2uf2"
python3 -m pip install littlefs-python==0.12.0
}
function ci_micropython_build_mpy_cross {
cd "$CI_BUILD_ROOT/micropython/mpy-cross" || return 1
ccache --zero-stats || true ccache --zero-stats || true
CROSS_COMPILE="ccache " USER_C_MODULES= make CROSS_COMPILE="ccache " make
ccache --show-stats || true ccache --show-stats || true
cd ../../ cd "$CI_BUILD_ROOT"
} }
function apt_install_build_deps { function ci_apt_install_build_deps {
sudo apt update && sudo apt install ccache sudo apt update && sudo apt install ccache
} }
function ci_prepare_all {
ci_tools_clone
ci_micropython_clone
ci_pimoroni_pico_clone
ci_micropython_build_mpy_cross
}
function ci_debug {
log_inform "Project root: $CI_PROJECT_ROOT"
log_inform "Build root: $CI_BUILD_ROOT"
}
function micropython_version { function micropython_version {
echo "MICROPY_GIT_TAG=$MICROPYTHON_VERSION, $BOARD_NAME $TAG_OR_SHA" >> $GITHUB_ENV BOARD=$1
echo "MICROPY_GIT_TAG=$MICROPYTHON_VERSION, $BOARD $TAG_OR_SHA" >> $GITHUB_ENV
echo "MICROPY_GIT_HASH=$MICROPYTHON_VERSION-$TAG_OR_SHA" >> $GITHUB_ENV echo "MICROPY_GIT_HASH=$MICROPYTHON_VERSION-$TAG_OR_SHA" >> $GITHUB_ENV
} }
function cmake_configure { function ci_cmake_configure {
cmake -S micropython/ports/rp2 -B build-$BOARD_NAME \ BOARD=$1
TOOLS_DIR="$CI_BUILD_ROOT/tools"
MICROPY_BOARD_DIR=$CI_PROJECT_ROOT/boards/$BOARD
if [ ! -f "$MICROPY_BOARD_DIR/mpconfigboard.cmake" ]; then
log_warning "Invalid board: \"$BOARD\". Run with ci_cmake_configure <board_name>."
return 1
fi
BUILD_DIR="$CI_BUILD_ROOT/build-$BOARD"
cmake -S $CI_BUILD_ROOT/micropython/ports/rp2 -B "$BUILD_DIR" \
-DPICOTOOL_FORCE_FETCH_FROM_GIT=1 \
-DPICO_BUILD_DOCS=0 \ -DPICO_BUILD_DOCS=0 \
-DPICO_NO_COPRO_DIS=1 \ -DPICO_NO_COPRO_DIS=1 \
-DUSER_C_MODULES=$USER_C_MODULES \ -DPICOTOOL_FETCH_FROM_GIT_PATH="$TOOLS_DIR/picotool" \
-DMICROPY_BOARD_DIR=$MICROPY_BOARD_DIR \ -DPIMORONI_PICO_PATH="$CI_BUILD_ROOT/pimoroni-pico" \
-DMICROPY_BOARD=$MICROPY_BOARD \ -DPIMORONI_TOOLS_DIR="$TOOLS_DIR" \
-DMICROPY_BOARD_VARIANT=$MICROPY_BOARD_VARIANT \ -DUSER_C_MODULES="$MICROPY_BOARD_DIR/usermodules.cmake" \
-DMICROPY_BOARD_DIR="$MICROPY_BOARD_DIR" \
-DMICROPY_BOARD="$BOARD" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
} }
function cmake_build { function ci_cmake_build {
BOARD=$1
MICROPY_BOARD_DIR=$CI_PROJECT_ROOT/boards/$BOARD
if [ ! -f "$MICROPY_BOARD_DIR/mpconfigboard.cmake" ]; then
log_warning "Invalid board: \"$BOARD\". Run with ci_cmake_build <board_name>."
return 1
fi
BUILD_DIR="$CI_BUILD_ROOT/build-$BOARD"
ccache --zero-stats || true ccache --zero-stats || true
cmake --build build-$BOARD_NAME -j 2 cmake --build $BUILD_DIR -j 2
ccache --show-stats || true ccache --show-stats || true
cd build-$BOARD_NAME
cp firmware.uf2 $RELEASE_FILE.uf2 if [ -z ${CI_RELEASE_FILENAME+x} ]; then
CI_RELEASE_FILENAME="$BOARD"
fi
log_inform "Copying .uf2 to $(pwd)/$CI_RELEASE_FILENAME.uf2"
cp "$BUILD_DIR/firmware.uf2" $CI_RELEASE_FILENAME.uf2
if [ -f "$BUILD_DIR/firmware-with-filesystem.uf2" ]; then
log_inform "Copying -with-filesystem .uf2 to $(pwd)/$CI_RELEASE_FILENAME-with-filesystem.uf2"
cp "$BUILD_DIR/firmware-with-filesystem.uf2" $CI_RELEASE_FILENAME-with-filesystem.uf2
fi
} }
if [ -z ${CI_USE_ENV+x} ] || [ -z ${CI_PROJECT_ROOT+x} ] || [ -z ${CI_BUILD_ROOT+x} ]; then
SCRIPT_PATH="$(dirname $0)"
CI_PROJECT_ROOT=$(realpath "$SCRIPT_PATH/..")
CI_BUILD_ROOT=$(pwd)
fi
ci_debug

View File

@ -1,12 +0,0 @@
# cmake file for Raspberry Pi Pico2
set(PICO_BOARD "pico2")
# To change the gpio count for QFN-80
# set(PICO_NUM_GPIOS 48)
if (PICO_CYW43_SUPPORTED)
include(enable_cyw43.cmake)
set(PICO_PINS_CSV_NAME pins_cyw43.csv)
endif()
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)

View File

@ -1,116 +0,0 @@
/*
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// -----------------------------------------------------
// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO
// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES
// -----------------------------------------------------
// This header may be included by other board headers as "boards/pico2_w.h"
// pico_cmake_set PICO_PLATFORM=rp2350
// pico_cmake_set PICO_CYW43_SUPPORTED = 1
#ifndef _BOARDS_PICO2_W_H
#define _BOARDS_PICO2_W_H
// For board detection
#define RASPBERRYPI_PICO2_W
// --- RP2350 VARIANT ---
#define PICO_RP2350A 1
// --- UART ---
#ifndef PICO_DEFAULT_UART
#define PICO_DEFAULT_UART 0
#endif
#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 0
#endif
#ifndef PICO_DEFAULT_UART_RX_PIN
#define PICO_DEFAULT_UART_RX_PIN 1
#endif
// --- LED ---
// no PICO_DEFAULT_LED_PIN - LED is on Wireless chip
// no PICO_DEFAULT_WS2812_PIN
// --- I2C ---
#ifndef PICO_DEFAULT_I2C
#define PICO_DEFAULT_I2C 0
#endif
#ifndef PICO_DEFAULT_I2C_SDA_PIN
#define PICO_DEFAULT_I2C_SDA_PIN 4
#endif
#ifndef PICO_DEFAULT_I2C_SCL_PIN
#define PICO_DEFAULT_I2C_SCL_PIN 5
#endif
// --- SPI ---
#ifndef PICO_DEFAULT_SPI
#define PICO_DEFAULT_SPI 0
#endif
#ifndef PICO_DEFAULT_SPI_SCK_PIN
#define PICO_DEFAULT_SPI_SCK_PIN 18
#endif
#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN 19
#endif
#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN 16
#endif
#ifndef PICO_DEFAULT_SPI_CSN_PIN
#define PICO_DEFAULT_SPI_CSN_PIN 17
#endif
// --- FLASH ---
#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1
#ifndef PICO_FLASH_SPI_CLKDIV
#define PICO_FLASH_SPI_CLKDIV 2
#endif
// pico_cmake_set_default PICO_FLASH_SIZE_BYTES = (4 * 1024 * 1024)
#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024)
#endif
// Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads)
// note the SMSP mode pin is on WL_GPIO1
#ifndef CYW43_WL_GPIO_COUNT
#define CYW43_WL_GPIO_COUNT 3
#endif
#ifndef CYW43_WL_GPIO_LED_PIN
#define CYW43_WL_GPIO_LED_PIN 0
#endif
// If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS.
// This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered.
// PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined.
#ifndef CYW43_WL_GPIO_VBUS_PIN
#define CYW43_WL_GPIO_VBUS_PIN 2
#endif
// If CYW43_USES_VSYS_PIN is defined then CYW43 uses the VSYS GPIO (defined by PICO_VSYS_PIN) for other purposes.
// If this is the case, to use the VSYS GPIO it's necessary to ensure CYW43 is not using it.
// This can be achieved by wrapping the use of the VSYS GPIO in cyw43_thread_enter / cyw43_thread_exit.
#ifndef CYW43_USES_VSYS_PIN
#define CYW43_USES_VSYS_PIN 1
#endif
// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC.
// There is an example in adc/read_vsys in pico-examples.
#ifndef PICO_VSYS_PIN
#define PICO_VSYS_PIN 29
#endif
#ifndef PICO_RP2350_A2_SUPPORTED
#define PICO_RP2350_A2_SUPPORTED 1
#endif
#endif

View File

@ -1,11 +0,0 @@
# cmake file for Raspberry Pi Pico 2 W
set(PICO_BOARD "pico2_w")
# To change the gpio count for QFN-80
# set(PICO_NUM_GPIOS 48)
include(enable_cyw43.cmake)
# Board specific version of the frozen manifest
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)

View File

@ -1,9 +0,0 @@
MODULES_PY = "../../../pimoroni-pico/micropython/modules_py"
# SD Card
require("sdcard")
freeze(MODULES_PY, "gfx_pack.py")
freeze(MODULES_PY, "pimoroni.py")
freeze(MODULES_PY, "boot.py")

View File

@ -1,220 +0,0 @@
from machine import UART, Pin
from network import PPP
from micropython import const
import time
DEFAULT_PIN_RST = 35
DEFAULT_PIN_NETLIGHT = 34
DEFAULT_PIN_RX = 33
DEFAULT_PIN_TX = 32
DEFAULT_UART_ID = 0
DEFAULT_UART_TIMEOUT = const(1)
DEFAULT_UART_TIMEOUT_CHAR = const(1)
DEFAULT_UART_RXBUF = const(1024)
DEFAULT_UART_STARTUP_BAUD = const(115200)
DEFAULT_UART_BAUD = const(460800)
class CellularError(Exception):
def __init__(self, message=None):
self.message = f"CellularError: {message}"
class LTE():
def __init__(self, apn, uart=None, reset_pin=None, netlight_pin=None, netlight_led=None, skip_reset=False):
self._apn = apn
self._reset = reset_pin or Pin(DEFAULT_PIN_RST, Pin.OUT)
self._uart = uart or UART(
DEFAULT_UART_ID,
tx=Pin(DEFAULT_PIN_TX, Pin.OUT),
rx=Pin(DEFAULT_PIN_RX, Pin.OUT))
# Set PPP timeouts and rxbuf
self._uart.init(
timeout=DEFAULT_UART_TIMEOUT,
timeout_char=DEFAULT_UART_TIMEOUT_CHAR,
rxbuf=DEFAULT_UART_RXBUF)
if not skip_reset:
self._reset.value(0)
time.sleep(1.0)
self._reset.value(1)
if netlight_led:
self._led = netlight_led
self._netlight = netlight_pin or Pin(DEFAULT_PIN_NETLIGHT, Pin.IN)
self._netlight.irq(self._netlight_irq)
def _netlight_irq(self, pin):
self._led.value(pin.value())
def ipconfig(self, *args, **kwargs):
if len(args):
return self._ppp.ipconfig(*args)
else:
return self._ppp.ipconfig(**kwargs)
def iccid(self):
try:
return self._send_at_command("AT+CICCID", 1)
except CellularError:
return None
def status(self):
lte_status = self._send_at_command("AT+CEREG?", 1)
gsm_status = self._send_at_command("AT+CGREG?", 1)
return lte_status, gsm_status
def signal_quality(self):
try:
response = self._send_at_command("AT+CSQ", 1)
quality = int(response.split(":")[1].split(",")[0])
db = -113 + (2 * quality) # conversion as per AT command set datasheet
return db
except CellularError:
pass
return None
def stop_ppp(self):
self._ppp.disconnect()
self._send_at_command(f"AT+IPR={DEFAULT_UART_STARTUP_BAUD}")
self._flush_uart()
def start_ppp(self, baudrate=DEFAULT_UART_BAUD, connect=True):
self._wait_ready(poll_time=1.0, timeout=30)
# Switch to a faster baudrate
self._send_at_command(f"AT+IPR={baudrate}")
self._flush_uart()
self._uart.init(
baudrate=baudrate,
timeout=DEFAULT_UART_TIMEOUT,
timeout_char=DEFAULT_UART_TIMEOUT_CHAR,
rxbuf=DEFAULT_UART_RXBUF)
self._wait_ready(poll_time=1.0)
# Connect!
if connect:
self.connect()
# This will just always time out!?
# try:
# self._send_at_command("ATD*99#", timeout=300)
# except CellularError as e:
# print(e)
# Force PPP to use modem's default settings...
self._flush_uart()
self._uart.write("ATD*99#\r")
self._uart.flush()
self._ppp = PPP(self._uart)
self._ppp.connect()
while self._ppp.status() != 4:
time.sleep(1.0)
return self._ppp.ifconfig()
def connect(self, timeout=60):
print(" - setting up cellular uart")
# connect to and flush the uart
# consume any unsolicited messages first, we don't need those
self._flush_uart()
print(" - waiting for cellular module to be ready")
# wait for the cellular module to respond to AT commands
self._wait_ready()
self._send_at_command("ATE0") # disable local echo
self._send_at_command(f"AT+CGDCONT=1,\"IP\",\"{self._apn}\"") # set apn and activate pdp context
# wait for roaming lte connection to be established
giveup = time.time() + timeout
status = None
while status != "+CEREG: 0,5" and status != "+CEREG: 0,1":
status = self._send_at_command("AT+CEREG?", 1)
time.sleep(0.25)
if time.time() > giveup:
raise CellularError("timed out getting network registration")
# disable server and client certification validation
self._send_at_command("AT+CSSLCFG=\"authmode\",0,0")
self._send_at_command("AT+CSSLCFG=\"enableSNI\",0,1")
print(f" - SIM ICCID is {self.iccid()}")
def _wait_ready(self, poll_time=0.25, timeout=10):
giveup = time.time() + timeout
while time.time() <= giveup:
try:
# if __send_at_command doesn't throw an exception then we're good!
self._send_at_command("AT")
return
except CellularError as e:
print(e)
time.sleep(poll_time)
raise CellularError("timed out waiting for AT response")
def _flush_uart(self):
self._uart.flush()
time.sleep(0.25)
while self._uart.any():
self._uart.read(self._uart.any())
time.sleep(0.25)
def _send_at_command(self, command, result_lines=0, timeout=5.0):
# consume any unsolicited messages first, we don't need those
self._flush_uart()
self._uart.write(command + "\r")
self._uart.flush()
status, data = self._read_result(result_lines, timeout=timeout)
print(" -", command, status, data)
if status not in ["OK", "DOWNLOAD"]:
raise CellularError(f"non 'OK' or 'DOWNLOAD' result for command {command}")
if result_lines == 1:
return data[0]
if result_lines > 1:
return data
return None
def _read_result(self, result_lines, timeout=1.0):
status = None
result = []
start = time.ticks_ms()
timeout *= 1000
while len(result) < result_lines or status is None:
if (time.ticks_ms() - start) > timeout:
raise CellularError("cellular module timed out")
line = self._uart.readline()
if line:
line = line.strip()
if line in [b"OK", b"ERROR", b"DOWNLOAD"]:
status = line.decode("ascii")
elif line != b"":
result.append(str(line, "ascii"))
start = time.ticks_ms()
return status, result
def send_text_message(self, recipient, body, timeout=5.0):
self._uart.write("AT+CMGS=\"")
self._uart.write(recipient.encode("ascii"))
self._uart.write(b"\"\r")
time.sleep(0.5)
self._uart.write(body.encode("ascii"))
self._uart.write(b"\x1a\r")
self._uart.flush()
status, _ = self._read_result(1, timeout=timeout)
return status == "OK"