Compare commits

..

23 Commits

Author SHA1 Message Date
Phil Howard
aa51d9edd4 CI: MicroPython target experimental experimental WiFi branch. 2024-11-15 19:24:16 +00:00
Phil Howard
db7bdf5d77 PPP/Plasma: Simplify config.
Since both PPP2 or Plasma2350 have a SP/CE connector, enable WiFi in all cases.

Additionally enable PPP in all cases.

Finally, drop the non-PSRAM build. (TBC if it returns, since it's less RAM but faster.)
2024-11-06 16:45:45 +00:00
Phil Howard
edccf66ec4 plasma2350(w): Fix flash size to be 4MB instead of 8MB.
Should prevent builds from self destructing when a user saves a file.
2024-11-04 17:17:00 +00:00
Phil Howard
5ca62f6cc4 CI: Retarget MicroPython to feature/psram-and-wifi. 2024-11-04 16:29:11 +00:00
Phil Howard
1d4ffe1374 CI: Retarget pimoroni-pico to main. 2024-11-04 12:16:00 +00:00
Phil Howard
bfcb181cdf PPP: Add send_text_message for #14.
Also a quick cleanup of the lte module code.
2024-10-04 15:41:02 +01:00
Phil Howard
6c6a839903 Plasma3350: Add WL ext GPIOs and fallback. 2024-09-30 14:08:14 +01:00
Phil Howard
bddaf2af3b PPP: Shim EXT GPIO on non W builds. 2024-09-30 11:45:28 +01:00
Phil Howard
07b896d425 PPP2W: Add LEDW mapping and WL_GPIO pins. 2024-09-30 11:09:39 +01:00
Phil Howard
667af8be45 CI: Bump GCC to 13.3.Rel1. 2024-09-27 16:31:53 +01:00
Phil Howard
4ad2b20fd0 Plasma2350: Add WiFi + LTE variant. 2024-09-27 13:13:24 +01:00
Phil Howard
7b2f6e92ad Pico2: Add WIRELESS variant for LTE + WiFi modules. 2024-09-26 17:48:45 +01:00
Phil Howard
77a97cf590 PPP: Add ipconfig pass-through. 2024-09-25 15:27:41 +01:00
nkotilainen
a5abc5bbfe PPP: LTE IMSI printout changed to ICCID. 2024-09-25 14:28:47 +01:00
Phil Howard
4c2416715b PPP2: Add wireless. 2024-09-25 14:28:46 +01:00
nkotilainen
af97500976 PPP: LTE IMEI renamed to IMSI. 2024-09-25 14:28:29 +01:00
Phil Howard
e0d5daee47 PPP: Simplify config.
PPP does not use socket extended state, and should be
added automatically in the networking module.
2024-09-19 10:11:03 +01:00
Phil Howard
a9107a5ca8 PPP: Enable PPP. 2024-09-17 15:37:19 +01:00
Phil Howard
c29c98b2b1 PPP: Add CYW43 wireless pins. 2024-09-17 13:58:23 +01:00
Phil Howard
544f1cae8c PPP: Add CYW43 wireless.
If we're bringing in lwip and networking, this variant might as well
support CYW43.
2024-09-17 13:26:41 +01:00
Phil Howard
fd7621fdcb PPP: Fix board name. 2024-09-11 11:22:02 +01:00
Phil Howard
e5515981ea PPP: Add LTE module. 2024-09-02 19:53:16 +01:00
Phil Howard
ac34474435 Pico Plus 2: Add a PPP variant. 2024-08-30 07:44:31 +01:00
84 changed files with 596 additions and 872 deletions

View File

@ -6,34 +6,47 @@ on:
release: release:
types: [created] types: [created]
env:
MICROPYTHON_VERSION: feature/psram-wifi-n-bt
MICROPYTHON_FLAVOUR: pimoroni
PIMORONI_PICO_VERSION: main
jobs: jobs:
build: build:
name: MicroPython ${{ matrix.name }} name: ${{ matrix.name }} (${{ matrix.board }})
runs-on: ubuntu-24.04 runs-on: ubuntu-20.04
continue-on-error: true continue-on-error: true
strategy: strategy:
matrix: matrix:
include: include:
- name: rpi_pico2 - name: pico2_rp2350
- name: rpi_pico2_w board: RPI_PICO2
- name: rpi_pico2b - name: pico2_rp2350_wireless
- name: pimoroni_plasma2350 board: RPI_PICO2
- name: pimoroni_tiny2350 variant: WIRELESS
- name: pimoroni_pico_plus2 - name: pico2b_rp2350
board: RPI_PICO2B
- 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
CI_RELEASE_FILENAME: ${{ matrix.name }}-${{ github.event.release.tag_name || github.sha }}-micropython RELEASE_FILE: ${{ matrix.name }}-${{ github.event.release.tag_name || github.sha }}-pimoroni-micropython
CI_PROJECT_ROOT: ${{ github.workspace }}/src-${{ github.sha }} PIMORONI_PICO_DIR: "${{ github.workspace }}/pimoroni-pico"
CI_BUILD_ROOT: ${{ github.workspace }} MICROPY_BOARD_DIR: "${{ github.workspace }}/pimoroni-pico-rp2350-${{ github.sha }}/micropython/board/${{ matrix.BOARD }}"
CI_USE_ENV: 1 USER_C_MODULES: "${{ github.workspace }}/pimoroni-pico-rp2350-${{ github.sha }}/micropython/micropython-pico2.cmake"
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 Fixup - name: Compiler Cache
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
@ -42,61 +55,76 @@ jobs:
ccache-micropython-${{ matrix.name }}-${{ github.ref }} ccache-micropython-${{ matrix.name }}-${{ github.ref }}
ccache-micropython-${{ matrix.name }}- ccache-micropython-${{ matrix.name }}-
- name: "Checkout Project" - uses: actions/checkout@v4
uses: actions/checkout@v4
with: with:
submodules: true submodules: true
path: ${{ env.CI_PROJECT_ROOT }} path: pimoroni-pico-rp2350-${{ github.sha }}
- name: "Install Arm GNU Toolchain (arm-none-eabi-gcc)" - uses: actions/checkout@v4
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: "Prepare tools & dependencies" - name: Install CCache
shell: bash
run: | run: |
source $CI_PROJECT_ROOT/ci/micropython.sh && ci_debug source $BUILD_TOOLS
mkdir -p $CI_BUILD_ROOT apt_install_build_deps
ci_apt_install_build_deps
ci_prepare_all - name: Checkout MicroPython & Submodules
run: |
source $BUILD_TOOLS
micropython_clone
- name: "MicroPython: Configure" - 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 $CI_PROJECT_ROOT/ci/micropython.sh && ci_debug source $BUILD_TOOLS
micropython_version micropython_version
ci_cmake_configure ${{ matrix.name }} cmake_configure
- name: "MicroPython: Build" - name: Build MicroPython
shell: bash shell: bash
run: | run: |
source $CI_PROJECT_ROOT/ci/micropython.sh && ci_debug source $BUILD_TOOLS
python3 -m venv "$CI_BUILD_ROOT/.dir2uf2" cmake_build
source "$CI_BUILD_ROOT/.dir2uf2/bin/activate"
ci_cmake_build ${{ matrix.name }}
- name: "Artifacts: Upload .uf2" - name: "Py_Decl: Verify 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.CI_RELEASE_FILENAME }}.uf2 name: ${{ env.RELEASE_FILE }}.uf2
path: ${{ env.CI_BUILD_ROOT }}/${{ env.CI_RELEASE_FILENAME }}.uf2 path: build-${{ matrix.name }}/${{ env.RELEASE_FILE }}.uf2
- name: "Release: Upload .uf2" - name: Upload .uf2
if: github.event_name == 'release' if: github.event_name == 'release'
uses: softprops/action-gh-release@v2 uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
files: ${{ env.CI_BUILD_ROOT }}/${{ env.CI_RELEASE_FILENAME }}.uf2 asset_path: build-${{ matrix.name }}/firmware.uf2
upload_url: ${{ github.event.release.upload_url }}
- name: "Artifacts: Upload .uf2 (With Filesystem)" asset_name: ${{ env.RELEASE_FILE }}.uf2
uses: actions/upload-artifact@v4 asset_content_type: application/octet-stream
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
View File

@ -1,39 +0,0 @@
# 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,17 +7,11 @@ 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 | pimoroni_pico_plus2-vx.x.x | [Download from Releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/latest) | :warning: Experimental: Enables PSRAM | Pico Plus 2 | pico_plus2_rp2350 | [pico_plus2_rp2350-v0.0.5-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.5/pico_plus2_rp2350-v0.0.5-pimoroni-micropython.uf2) | Does not enable PSRAM
| Tiny 2350 | pimoroni_tiny2350-vx.x.x | [Download from Releases](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/latest) | | Pico Plus 2 PSRAM | pico_plus2_rp2350_psram | [pico_plus2_rp2350_psram-v0.0.5-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.5/pico_plus2_rp2350_psram-v0.0.5-pimoroni-micropython.uf2) | :warning: Experimental: Enables PSRAM
| 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 | Plasma 2350 | plasma2350 | [plasma2350-v0.0.5-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.5/plasma2350-v0.0.5-pimoroni-micropython.uf2) |
| 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 | Tiny 2350 | tiny2350 | [tiny2350-v0.0.5-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.5/tiny2350-v0.0.5-pimoroni-micropython.uf2) |
| PGA2350 | ~ | [https://github.com/pimoroni/pga/](https://github.com/pimoroni/pga/) | See the PGA repo for builds and boilerplate | PGA2350 | pico2b_rp2350 | [pico2b_rp2350-v0.0.5-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.5/pico2b_rp2350-v0.0.5-pimoroni-micropython.uf2) | Requires the "B" variant for extra pins
| Pimoroni Explorer | ~ | [https://github.com/pimoroni/explorer](https://github.com/pimoroni/explorer) | See the Explorer repo for builds and examples | Pi Pico 2 | pico2_rp2350 | [pico2_rp2350-v0.0.5-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.5/pico2_rp2350-v0.0.5-pimoroni-micropython.uf2) | This gives you the Pimoroni Pico libs on a vanilla Pico 2
| 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
| 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).

View File

@ -1,41 +0,0 @@
# 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()

View File

@ -1,12 +0,0 @@
# 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

@ -1,8 +0,0 @@
require("bundle-networking")
# Bluetooth
require("aioble")
include("$(PORT_DIR)/boards/manifest.py")
include("../manifest_pico2.py")

View File

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

View File

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

View File

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

View File

@ -1,18 +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)
# 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

@ -1,28 +0,0 @@
// Board and hardware specific configuration
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico2"
#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
#include "enable_cyw43.h"
// Enable the ability to pass cyw43 pins into WiFi, Bluetooth and Pin constructors
#define CYW43_PIN_WL_DYNAMIC 1
#define CYW43_PIO_CLOCK_DIV_DYNAMIC 1
// Set the default pins to gpios 2-5
#define CYW43_DEFAULT_PIN_WL_REG_ON 2
#define CYW43_DEFAULT_PIN_WL_CS 3
#define CYW43_DEFAULT_PIN_WL_DATA_OUT 4
#define CYW43_DEFAULT_PIN_WL_DATA_IN 4
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 4
#define CYW43_DEFAULT_PIN_WL_CLOCK 5
// Default pio clock
#define CYW43_PIO_CLOCK_DIV_INT 3
#endif

View File

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

View File

@ -1,16 +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)
# 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

@ -1,10 +0,0 @@
// Board and hardware specific configuration
#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_PY_NETWORK_HOSTNAME_DEFAULT "Pico2W"
// Enable PPP
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
#include "enable_cyw43.h"

View File

@ -1,30 +0,0 @@
GP0,GPIO0
GP1,GPIO1
GP2,GPIO2
GP3,GPIO3
GP4,GPIO4
GP5,GPIO5
GP6,GPIO6
GP7,GPIO7
GP8,GPIO8
GP9,GPIO9
GP10,GPIO10
GP11,GPIO11
GP12,GPIO12
GP13,GPIO13
GP14,GPIO14
GP15,GPIO15
GP16,GPIO16
GP17,GPIO17
GP18,GPIO18
GP19,GPIO19
GP20,GPIO20
GP21,GPIO21
GP22,GPIO22
GP26,GPIO26
GP27,GPIO27
GP28,GPIO28
WL_GPIO0,EXT_GPIO0
WL_GPIO1,EXT_GPIO1
WL_GPIO2,EXT_GPIO2
LED,EXT_GPIO0
1 GP0 GPIO0
2 GP1 GPIO1
3 GP2 GPIO2
4 GP3 GPIO3
5 GP4 GPIO4
6 GP5 GPIO5
7 GP6 GPIO6
8 GP7 GPIO7
9 GP8 GPIO8
10 GP9 GPIO9
11 GP10 GPIO10
12 GP11 GPIO11
13 GP12 GPIO12
14 GP13 GPIO13
15 GP14 GPIO14
16 GP15 GPIO15
17 GP16 GPIO16
18 GP17 GPIO17
19 GP18 GPIO18
20 GP19 GPIO19
21 GP20 GPIO20
22 GP21 GPIO21
23 GP22 GPIO22
24 GP26 GPIO26
25 GP27 GPIO27
26 GP28 GPIO28
27 WL_GPIO0 EXT_GPIO0
28 WL_GPIO1 EXT_GPIO1
29 WL_GPIO2 EXT_GPIO2
30 LED EXT_GPIO0

View File

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

View File

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

View File

@ -1,15 +1,5 @@
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)"
} }
@ -22,19 +12,10 @@ function log_warning {
echo -e "$(tput setaf 1)$1$(tput sgr0)" echo -e "$(tput setaf 1)$1$(tput sgr0)"
} }
function ci_pimoroni_pico_clone { function micropython_clone {
log_inform "Using Pimoroni Pico $PIMORONI_PICO_FLAVOUR/$PIMORONI_PICO_VERSION" log_inform "Using MicroPython $MICROPYTHON_VERSION"
git clone https://github.com/$PIMORONI_PICO_FLAVOUR/pimoroni-pico "$CI_BUILD_ROOT/pimoroni-pico" git clone https://github.com/$MICROPYTHON_FLAVOUR/micropython
cd "$CI_BUILD_ROOT/pimoroni-pico" || return 1 cd micropython
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
@ -43,98 +24,42 @@ function ci_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 "$CI_BUILD_ROOT" cd ../
} }
function ci_tools_clone { function micropython_build_mpy_cross {
mkdir -p "$CI_BUILD_ROOT/tools" cd micropython/mpy-cross
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 " make CROSS_COMPILE="ccache " make
ccache --show-stats || true ccache --show-stats || true
cd "$CI_BUILD_ROOT" cd ../../
} }
function ci_apt_install_build_deps { function 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 {
BOARD=$1 echo "MICROPY_GIT_TAG=$MICROPYTHON_VERSION, $BOARD_NAME $TAG_OR_SHA" >> $GITHUB_ENV
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 ci_cmake_configure { function cmake_configure {
BOARD=$1 cmake -S micropython/ports/rp2 -B build-$BOARD_NAME \
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 \
-DPICOTOOL_FETCH_FROM_GIT_PATH="$TOOLS_DIR/picotool" \ -DUSER_C_MODULES=$USER_C_MODULES \
-DPIMORONI_PICO_PATH="$CI_BUILD_ROOT/pimoroni-pico" \ -DMICROPY_BOARD_DIR=$MICROPY_BOARD_DIR \
-DPIMORONI_TOOLS_DIR="$TOOLS_DIR" \ -DMICROPY_BOARD=$MICROPY_BOARD \
-DUSER_C_MODULES="$MICROPY_BOARD_DIR/usermodules.cmake" \ -DMICROPY_BOARD_VARIANT=$MICROPY_BOARD_VARIANT \
-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 ci_cmake_build { function 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_DIR -j 2 cmake --build build-$BOARD_NAME -j 2
ccache --show-stats || true ccache --show-stats || true
cd build-$BOARD_NAME
if [ -z ${CI_RELEASE_FILENAME+x} ]; then cp firmware.uf2 $RELEASE_FILE.uf2
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 @@
"""
Wire up a big LED to GP15 (with a resistor) and ground and make it blink!
"""
import machine
import time
led_external = machine.Pin(15, machine.Pin.OUT)
while True:
led_external.toggle()
time.sleep(1)

View File

@ -1,23 +0,0 @@
"""
Wire a big arcade button up to GP16 and ground and read the state.
If you have an LED connected to GP15 (with a resistor) and ground the button will turn it on and off.
"""
import machine
import time
button = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_UP)
led_external = machine.Pin(15, machine.Pin.OUT)
while True:
# as we're using a pull up, the logic state is reversed
if button.value() == 0:
print("Button pushed!")
led_external.on()
time.sleep(0.5)
else:
led_external.off()
print("Button not pushed!")
led_external.off()
time.sleep(0.5)

View File

@ -1,22 +0,0 @@
"""
Wire a big toggle switch up to GP16 and ground and read the on/off state.
If you have an LED connected to GP15 (with a resistor) and ground the button will turn it on and off.
"""
import machine
import time
button = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_UP)
led_external = machine.Pin(15, machine.Pin.OUT)
while True:
# as we're using a pull up, the logic state is reversed
if button.value() == 0:
print("Toggle on!")
led_external.on()
time.sleep(0.5)
else:
print("Toggle off!")
led_external.off()
time.sleep(0.5)

View File

@ -1,32 +0,0 @@
"""
List all the humans who are currently in space!
This example was adapted from one written by Les Pounder for Tom's Hardware: https://www.tomshardware.com/how-to/connect-raspberry-pi-pico-w-to-the-internet
"""
import lte
import time
import requests
MOBILE_APN = "iot.1nce.net"
con = lte.LTE(MOBILE_APN)
con.start_ppp()
try:
t_start = time.time()
astronauts = requests.get("http://api.open-notify.org/astros.json").json()
number = astronauts['number']
print(f'There are currently {number} humans in space:')
for i in range(number):
print(astronauts['people'][i]['name'])
finally:
t_end = time.time()
print(f"Took: {t_end - t_start} seconds")
print("Disconnecting...")
con.stop_ppp()
print("Done!")

View File

@ -1,28 +0,0 @@
"""
Get yourself a cat fact over 4G!
"""
import lte
import time
import requests
MOBILE_APN = "iot.1nce.net"
con = lte.LTE(MOBILE_APN)
con.start_ppp()
try:
t_start = time.time()
request = requests.get('http://catfact.ninja/fact').json()
fact = request['fact']
print('Cat fact!')
print(fact)
finally:
t_end = time.time()
print(f"Took: {t_end - t_start} seconds")
print("Disconnecting...")
con.stop_ppp()
print("Done!")

View File

@ -1,25 +0,0 @@
"""
Get a cat fact from t'internet!
You will need to add your wireless SSID and password to secrets.py (and save this file to your Pico)
"""
import network
import requests
from secrets import WIFI_SSID, WIFI_PASSWORD
from time import sleep
# Specify the pins that that wireless module is connected to
# The pins below are for a Pimoroni Pico Plus 2 with a RM2 breakout connected via SP/CE
wlan = network.WLAN(network.STA_IF, pin_on=32, pin_out=35, pin_in=35, pin_wake=35, pin_clock=34, pin_cs=33)
# connect to wifi
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while wlan.isconnected() is False:
print('Waiting for connection...')
sleep(1)
request = requests.get('http://catfact.ninja/fact').json()
fact = request['fact']
print('Cat fact!')
print(fact)

View File

@ -1,2 +0,0 @@
WIFI_SSID = 'ssid_goes_here'
WIFI_PASSWORD = 'password_goes_here'

View File

@ -1,25 +0,0 @@
"""
List all the humans who are currently in space!
You will need to add your wireless SSID and password to secrets.py (and save this file to your Pico)
This example was adapted from one written by Les Pounder for Tom's Hardware: https://www.tomshardware.com/how-to/connect-raspberry-pi-pico-w-to-the-internet
"""
import network
import requests
from secrets import WIFI_SSID, WIFI_PASSWORD
from time import sleep
# connect to wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while wlan.isconnected() is False:
print('Waiting for connection...')
sleep(1)
astronauts = requests.get("http://api.open-notify.org/astros.json").json()
number = astronauts['number']
print(f'There are currently {number} humans in space:')
for i in range(number):
print(astronauts['people'][i]['name'])

View File

@ -1,13 +0,0 @@
from machine import Pin
# Setup the LED and Button pin.
led = Pin('LEDW', Pin.OUT)
button = Pin(45, Pin.IN)
# Light the LED when the button is pressed!
while True:
if button.value() == 0:
led.value(1)
else:
led.value(0)

View File

@ -1,22 +0,0 @@
"""
Get a cat fact from t'internet!
You will need to add your wireless SSID and password to secrets.py (and save this file to your Pico)
"""
import network
import requests
from secrets import WIFI_SSID, WIFI_PASSWORD
from time import sleep
# connect to wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while wlan.isconnected() is False:
print('Waiting for connection...')
sleep(1)
request = requests.get('http://catfact.ninja/fact').json()
fact = request['fact']
print('Cat fact!')
print(fact)

View File

@ -1,14 +0,0 @@
import time
from machine import Pin
# Setup the LED pin.
led = Pin('LEDW', Pin.OUT)
# Blink the LED!
while True:
led.value(1)
time.sleep(1)
led.value(0)
time.sleep(1)

View File

@ -1,2 +0,0 @@
WIFI_SSID = 'ssid_goes_here'
WIFI_PASSWORD = 'password_goes_here'

View File

@ -1,25 +0,0 @@
"""
Get a cat fact from t'internet!
You will need to add your wireless SSID and password to secrets.py (and save this file to your Plasma)
"""
import network
import requests
from secrets import WIFI_SSID, WIFI_PASSWORD
from time import sleep
# Specify the pins that that wireless module is connected to
# The pins below are for a Plasma 2350 with a RM2 breakout connected via SP/CE
wlan = network.WLAN(network.STA_IF, pin_on=8, pin_out=11, pin_in=11, pin_wake=11, pin_clock=10, pin_cs=9)
# connect to wifi
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while wlan.isconnected() is False:
print('Waiting for connection...')
sleep(1)
request = requests.get('http://catfact.ninja/fact').json()
fact = request['fact']
print('Cat fact!')
print(fact)

View File

@ -1,2 +0,0 @@
WIFI_SSID = 'ssid_goes_here'
WIFI_PASSWORD = 'password_goes_here'

View File

@ -1,48 +0,0 @@
'''
An example that uses the buttons to control the colour and brightness of the attached LED strip.
Button A - Change the hue
BOOT/User button - Cycle through brightness. 10 levels of brightness available.
'''
import time
import machine
import plasma
from plasma import plasma2040
# Set how many LEDs you have
NUM_LEDS = 66
# Setup for the button pins
user_button = machine.Pin(22, machine.Pin.IN)
a_button = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_UP)
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, color_order=plasma.COLOR_ORDER_BGR)
# Start updating the LED strip
led_strip.start()
hue = 0.0
brightness = 1.0
while True:
if a_button.value() == 0:
hue += float(10) / 2000.0
time.sleep(0.02)
if user_button.value() == 0:
if brightness >= 0.0 and brightness < 1.0:
brightness += 0.1
else:
brightness = 0.0
# Wait until the user releases the button
while user_button.value() == 0:
pass
# Set each LED in the strip to the colour we want
for i in range(NUM_LEDS):
led_strip.set_hsv(i, hue, 1.0, brightness)

View File

@ -1,74 +0,0 @@
import plasma
from plasma import plasma2040
import network
import time
import requests
# Total number of LEDs on our LED strip
NUM_LEDS = 66
# How long between cheerslight updates in seconds
INTERVAL = 60
# Check and import the SSID and Password from secrets.py
try:
from secrets import WIFI_SSID, WIFI_PASSWORD
if WIFI_SSID == "":
raise ValueError("WIFI_SSID in 'secrets.py' is empty!")
if WIFI_PASSWORD == "":
raise ValueError("WIFI_PASSWORD in 'secrets.py' is empty!")
except ImportError:
raise ImportError("'secrets.py' is missing from your Plasma 2350 W!")
except ValueError as e:
print(e)
wlan = network.WLAN(network.STA_IF)
def connect():
# Connect to the network specified in secrets.py
wlan.active(True)
wlan.connect(WIFI_SSID, WIFI_PASSWORD)
while wlan.isconnected() is False:
print("Attempting connection to {}".format(WIFI_SSID))
time.sleep(1)
# APA102 / DotStar™ LEDs
# led_strip = plasma.APA102(NUM_LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK)
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, color_order=plasma.COLOR_ORDER_BGR)
# Start connection to the network
connect()
# Store the local IP address
ip_addr = wlan.ipconfig('addr4')[0]
# Let the user know the connection has been successful
# and display the current IP address of the Plasma 2350 W
print("Successfully connected to {}. Your Plasma 2350 W's IP is: {}".format(WIFI_SSID, ip_addr))
# Start updating the LED strip
led_strip.start()
while True:
if wlan.isconnected():
try:
print("Getting new colour...")
req = requests.get("http://api.thingspeak.com/channels/1417/field/2/last.json", timeout=None)
json = req.json()
req.close()
print("Success!")
colour = tuple(int(json['field2'][i:i + 2], 16) for i in (1, 3, 5))
for i in range(NUM_LEDS):
led_strip.set_rgb(i, *colour)
except OSError:
print("Error: Failed to get new colour")
else:
print("Lost connection to network {}".format(WIFI_SSID))
time.sleep(INTERVAL)

View File

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Plasma 2350 W</title>
</head>
<body>
<h1>Plasma 2350 W</h1>
<h3>You can use this webpage to change the colour of your attached LED strip! &#127752</h3>
<form action="/", method="post">
<input type="color" id="rgbled" name="rgbled" value={{last_hex}}>
<br>
<br>
<input type="submit" value="Apply">
</form>
</body>
</html>

View File

@ -1,2 +0,0 @@
WIFI_SSID = ""
WIFI_PASSWORD = ""

View File

@ -1,84 +0,0 @@
'''
A simple web example that allows you to set the LED Strip colour using a colour picker.
You will need to install Phew for this example to work
In Thonny select Tools > Manage Packages and search for "micropython-phew"
'''
import network
from pimoroni import RGBLED
from phew import server, connect_to_wifi, is_connected_to_wifi
from phew.template import render_template
import plasma
# Check and import the SSID and Password from secrets.py
try:
from secrets import WIFI_SSID, WIFI_PASSWORD
if WIFI_SSID == "":
raise ValueError("WIFI_SSID in 'secrets.py' is empty!")
if WIFI_PASSWORD == "":
raise ValueError("WIFI_PASSWORD in 'secrets.py' is empty!")
except ImportError:
raise ImportError("'secrets.py' is missing from your Plasma 2350 W!")
except ValueError as e:
print(e)
# Total number of LEDs on our LED strip
NUM_LEDS = 66
# APA102 / DotStar™ LEDs
# led_strip = plasma.APA102(NUM_LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK)
# WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma.plasma2040.DAT, color_order=plasma.COLOR_ORDER_BGR)
# Setup the RGB Led
led = RGBLED(16, 17, 18)
last_hex = 0
# Connect our Tiny FX W to the network
connect_to_wifi(WIFI_SSID, WIFI_PASSWORD)
# If we're connected to the network, print out the IP address in the terminal
if is_connected_to_wifi():
print("Connected")
print(network.WLAN(network.STA_IF).ifconfig()[0])
# Start updating the LED strip
led_strip.start()
# Convert our hex value to RGB
# https://www.30secondsofcode.org/python/s/hex-to-rgb/
def hex_to_rgb(hex):
return tuple(int(hex[i:i + 2], 16) for i in (0, 2, 4))
# We've only got one page in the root so we setup the routing for that request
# and return the index.html
@server.route("/", methods=["GET", "POST"])
def index(request):
global last_hex
# If a GET request is made, return the page
if request.method == 'GET':
return render_template("html/index.html")
# If a POST request is made we need to process the information
# and use that to update the LED colour
if request.method == 'POST':
last_hex = request.form["rgbled"]
value = hex_to_rgb(last_hex[1:])
led.set_rgb(value[0], value[1], value[2])
for i in range(NUM_LEDS):
led_strip.set_rgb(i, value[0], value[1], value[2])
return render_template("html/index.html")
# catchall
@server.catchall()
def catchall(request):
return "Not found", 404
# Run the server!
server.run()

View File

@ -1,8 +1,10 @@
include("$(PORT_DIR)/boards/manifest.py")
require("bundle-networking") require("bundle-networking")
# Bluetooth # Bluetooth
require("aioble") require("aioble")
include("../manifest_pico2.py") include("$(PORT_DIR)/boards/manifest.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

@ -5,4 +5,6 @@ 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,4 +35,3 @@ 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

@ -6,5 +6,3 @@ 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,8 @@
require("bundle-networking")
# Bluetooth
require("aioble")
include("manifest.py")
freeze("$(BOARD_DIR)/../../modules_py", "lte.py")

View File

@ -0,0 +1,8 @@
# cmake file for Raspberry Pi Pico
set(PICO_BOARD "pico2")
set(PICO_PLATFORM "rp2350")
# Board specific version of the frozen manifest
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
set(MICROPY_C_HEAP_SIZE 4096)

View File

@ -0,0 +1,52 @@
// Board and hardware specific configuration
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (2 * 1024 * 1024))
// Set up networking.
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico2"
#if defined(MICROPY_PY_NETWORK_CYW43)
// CYW43 driver configuration.
#define CYW43_USE_SPI (1)
#define CYW43_LWIP (1)
#define CYW43_GPIO (1)
#define CYW43_SPI_PIO (1)
#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT
#if defined(CYW43_PIN_WL_DYNAMIC)
#define CYW43_PIO_CLOCK_DIV_DYNAMIC (1)
// CYW43 default pin configuration
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 24u
#define CYW43_DEFAULT_PIN_WL_REG_ON 23u
#define CYW43_DEFAULT_PIN_WL_DATA_OUT CYW43_DEFAULT_PIN_WL_HOST_WAKE
#define CYW43_DEFAULT_PIN_WL_DATA_IN CYW43_DEFAULT_PIN_WL_HOST_WAKE
#define CYW43_DEFAULT_PIN_WL_CLOCK 29u
#define CYW43_DEFAULT_PIN_WL_CS 25u
// Slow down the wireless clock, since we'll be running
// comms through wiring spaghetti!
#define CYW43_PIO_CLOCK_DIV_INT 50
#define CYW43_PIO_CLOCK_DIV_FRAC 0
#define CYW43_SPI_PROGRAM_NAME spi_gap0_sample1
#endif
#endif
// Might be defined in mpconfigvariant_PPP.cmake
// This is not checked by mpconfigport.h so we must set up networking below
#if defined(MICROPY_PY_NETWORK_PPP_LWIP)
// Nothing to do here?
#endif
// If a variant is not used, define a fallback board name
#ifndef MICROPY_HW_BOARD_NAME
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico 2"
#endif

View File

@ -0,0 +1,40 @@
# Override the MicroPython board name
# And set basic options which are expanded upon in mpconfigboard.h
list(APPEND MICROPY_DEF_BOARD
"MICROPY_HW_BOARD_NAME=\"Raspberry Pi Pico 2 (LTE + WiFi)\""
"MICROPY_PY_NETWORK=1"
"CYW43_PIN_WL_DYNAMIC=1"
"MICROPY_PY_NETWORK_PPP_LWIP=1"
)
# Links micropy_lib_lwip and sets MICROPY_PY_LWIP = 1
# Picked up and expanded upon in mpconfigboard.h
set(MICROPY_PY_LWIP ON)
# Links cyw43-driver and sets:
# MICROPY_PY_NETWORK_CYW43 = 1,
# MICROPY_PY_SOCKET_DEFAULT_TIMEOUT_MS = 30000
set(MICROPY_PY_NETWORK_CYW43 ON)
# Adds mpbthciport.c
# And sets:
# MICROPY_PY_BLUETOOTH = 1,
# MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS = 1,
# MICROPY_PY_BLUETOOTH_ENABLE_CENTRAL_MODE = 1
set(MICROPY_PY_BLUETOOTH ON)
# Links pico_btstack_hci_transport_cyw43
# And sets:
# MICROPY_BLUETOOTH_BTSTACK = 1,
# MICROPY_BLUETOOTH_BTSTACK_CONFIG_FILE =
set(MICROPY_BLUETOOTH_BTSTACK ON)
# Sets:
# CYW43_ENABLE_BLUETOOTH = 1,
# MICROPY_PY_BLUETOOTH_CYW43 = 1
set(MICROPY_PY_BLUETOOTH_CYW43 ON)
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest-wireless.py)
set(PICO_BOARD "pico2_w")
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})

View File

@ -0,0 +1,116 @@
/*
* 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

@ -0,0 +1,19 @@
{
"deploy": [
"../deploy.md"
],
"docs": "",
"features": [
"Dual-core",
"External Flash",
"USB"
],
"images": [
"rp2-picos.jpg"
],
"mcu": "rp2350",
"product": "Pico2",
"thumbnail": "",
"url": "https://www.raspberrypi.com/products/raspberry-pi-pico2/",
"vendor": "Raspberry Pi"
}

View File

@ -10,5 +10,3 @@ 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,9 @@
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

@ -3,13 +3,13 @@ from plasma import plasma2040
import time import time
# Set how many LEDs you have # Set how many LEDs you have
NUM_LEDS = 66 NUM_LEDS = 50
# APA102 / DotStar™ LEDs # APA102 / DotStar™ LEDs
# led_strip = plasma.APA102(NUM_LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK) # led_strip = plasma.APA102(NUM_LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK)
# WS2812 / NeoPixel™ LEDs # WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, color_order=plasma.COLOR_ORDER_BGR) led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT)
# Start updating the LED strip # Start updating the LED strip
led_strip.start() led_strip.start()
@ -22,6 +22,6 @@ while True:
for i in range(NUM_LEDS): for i in range(NUM_LEDS):
hue = float(i) / NUM_LEDS hue = float(i) / NUM_LEDS
led_strip.set_hsv(i, hue+offset, 1.0, 1.0) led_strip.set_hsv(i, offset, 1.0, 1.0)
time.sleep(1.0 / 60) time.sleep(1.0 / 60)

View File

@ -2,13 +2,13 @@ import plasma
from plasma import plasma2040 from plasma import plasma2040
# Set how many LEDs you have # Set how many LEDs you have
NUM_LEDS = 66 NUM_LEDS = 50
# APA102 / DotStar™ LEDs # APA102 / DotStar™ LEDs
# led_strip = plasma.APA102(NUM_LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK) # led_strip = plasma.APA102(NUM_LEDS, 0, 0, plasma2040.DAT, plasma2040.CLK)
# WS2812 / NeoPixel™ LEDs # WS2812 / NeoPixel™ LEDs
led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT, color_order=plasma.COLOR_ORDER_BGR) led_strip = plasma.WS2812(NUM_LEDS, 0, 0, plasma2040.DAT)
# Start updating the LED strip # Start updating the LED strip
led_strip.start() led_strip.start()

View File

@ -0,0 +1,220 @@
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"