Compare commits

..

5 Commits

Author SHA1 Message Date
thirdr
3c0b40e220 cover-art.py: removed unused variable 2025-01-23 15:54:31 +00:00
thirdr
228ecb1fc6 adding cover-art.py 2025-01-23 15:52:59 +00:00
thirdr
c0b95c2316 Examples: adding today.py 2024-11-25 10:31:27 +00:00
thirdr
25930b58af Examples: adding cubes.py 2024-11-22 15:56:54 +00:00
thirdr
c51c430cdf Examples: adding random_maze.py 2024-11-22 15:48:32 +00:00
90 changed files with 878 additions and 981 deletions

View File

@ -6,34 +6,47 @@ on:
release: release:
types: [created] types: [created]
env:
MICROPYTHON_VERSION: feature/psram
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: pico2b_rp2350
- name: pimoroni_plasma2350 board: RPI_PICO2B
- name: pimoroni_tiny2350 - name: plasma2350
- name: pimoroni_pico_plus2 board: PIMORONI_PLASMA2350
- name: tiny2350
board: PIMORONI_TINY2350
- name: pico_plus2_rp2350_psram
board: PIMORONI_PICO_PLUS2
variant: PSRAM
- 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.7-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.7/pico_plus2_rp2350-v0.0.7-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.7-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.7/pico_plus2_rp2350_psram-v0.0.7-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.7-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.7/plasma2350-v0.0.7-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.7-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.7/tiny2350-v0.0.7-pimoroni-micropython.uf2) |
| Pi Pico 2 | pico2_rp2350 | [pico2_rp2350-v0.0.7-pimoroni-micropython.uf2](https://github.com/pimoroni/pimoroni-pico-rp2350/releases/download/v0.0.7/pico2_rp2350-v0.0.7-pimoroni-micropython.uf2) | This gives you the Pimoroni Pico libs on a vanilla Pico 2
| 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
| 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,39 +0,0 @@
# cmake file for Raspberry Pi Pico
set(PICO_BOARD "pimoroni_pico_plus2w_rp2350")
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
set(PICO_PLATFORM "rp2350")
set(PICO_NUM_GPIOS 48)
# Board specific version of the frozen manifest
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
set(MICROPY_C_HEAP_SIZE 4096)
# 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)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -1,31 +0,0 @@
// 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 "PPP2"
#define MICROPY_HW_BOARD_NAME "Pimoroni Pico Plus 2 (PSRAM + LTE + WiFi)"
// Enable WiFi & PPP
#define MICROPY_PY_NETWORK (1)
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
// CYW43 driver configuration.
#define CYW43_USE_SPI (1)
#define CYW43_LWIP (1)
#define CYW43_GPIO (1)
#define CYW43_SPI_PIO (1)
#ifndef CYW43_WL_GPIO_COUNT
#define CYW43_WL_GPIO_COUNT 3
#endif
#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT
int mp_hal_is_pin_reserved(int n);
#define MICROPY_HW_PIN_RESERVED(i) mp_hal_is_pin_reserved(i)
// PSRAM Settings
#define MICROPY_HW_ENABLE_PSRAM (1)
#define MICROPY_HW_PSRAM_CS_PIN PIMORONI_PICO_PLUS2_PSRAM_CS_PIN
#define MICROPY_GC_SPLIT_HEAP (1)

View File

@ -1,162 +0,0 @@
/*
* Copyright (c) 2020 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/pimoroni_pico_plus2w_rp2350.h"
// pico_cmake_set PICO_PLATFORM=rp2350
#ifndef _BOARDS_PIMORONI_PICO_PLUS2W_RP2350_H
#define _BOARDS_PIMORONI_PICO_PLUS2W_RP2350_H
// For board detection
#define PIMORONI_PICO_PLUS2_RP2350
#define PIMORONI_PICO_PLUS2W_RP2350
// --- BOARD SPECIFIC ---
#define SPICE_SPI 0
#define SPICE_TX_MISO_PIN 32
#define SPICE_RX_CS_PIN 33
#define SPICE_NETLIGHT_SCK_PIN 34
#define SPICE_RESET_MOSI_PIN 35
#define SPICE_PWRKEY_BL_PIN 36
#define PIMORONI_PICO_PLUS2_USER_SW_PIN 45
#define PIMORONI_PICO_PLUS2_PSRAM_CS_PIN 47
// --- 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 ---
#ifndef PICO_DEFAULT_LED_PIN
#define PICO_DEFAULT_LED_PIN 25
#endif
// 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 SPICE_NETLIGHT_SCK_PIN
#endif
#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN SPICE_RESET_MOSI_PIN
#endif
#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN SPICE_TX_MISO_PIN
#endif
#ifndef PICO_DEFAULT_SPI_CSN_PIN
#define PICO_DEFAULT_SPI_CSN_PIN SPICE_RX_CS_PIN
#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 = (16 * 1024 * 1024)
#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
#endif
#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.
// no CYW43_WL_GPIO_VBUS_PIN
// 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.
// no CYW43_USES_VSYS_PIN
// The GPIO Pin used to read VBUS to determine if the device is battery powered.
#ifndef PICO_VBUS_PIN
#define PICO_VBUS_PIN 24
#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 43
#endif
#ifndef PICO_RP2350_A2_SUPPORTED
#define PICO_RP2350_A2_SUPPORTED 1
#endif
// PICO_CONFIG: CYW43_PIN_WL_DYNAMIC, flag to indicate if cyw43 SPI pins can be changed at runtime, type=bool, default=false, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_PIN_WL_DYNAMIC
#define CYW43_PIN_WL_DYNAMIC 1
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_REG_ON, gpio pin to power up the cyw43 chip, type=int, default=23, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_REG_ON
#define CYW43_DEFAULT_PIN_WL_REG_ON 23u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_OUT, gpio pin for spi data out to the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT
#define CYW43_DEFAULT_PIN_WL_DATA_OUT 24u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_IN, gpio pin for spi data in from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN
#define CYW43_DEFAULT_PIN_WL_DATA_IN 24u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_HOST_WAKE, gpio (irq) pin for the irq line from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 24u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CLOCK, gpio pin for the spi clock line to the cyw43 chip, type=int, default=29, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_CLOCK
#define CYW43_DEFAULT_PIN_WL_CLOCK 29u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CS, gpio pin for the spi chip select to the cyw43 chip, type=int, default=25, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_CS
#define CYW43_DEFAULT_PIN_WL_CS 25u
#endif
#endif

View File

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

View File

@ -1,38 +0,0 @@
# cmake file for Pimoroni Plasma 2350
set(PICO_BOARD "pimoroni_plasma2350w")
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
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)
# 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)
include(${CMAKE_CURRENT_LIST_DIR}/../common.cmake)

View File

@ -1,31 +0,0 @@
// Board and hardware specific configuration
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (2 * 1024 * 1024))
// I2C0 (non-default)
#define MICROPY_HW_I2C0_SCL (PLASMA2350_SDA_PIN)
#define MICROPY_HW_I2C0_SDA (PLASMA2350_SCL_PIN)
// Set up networking.
#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "PLASMA2350"
#define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2350 (LTE + WiFi)"
// Enable WiFi & PPP
#define MICROPY_PY_NETWORK (1)
#define MICROPY_PY_NETWORK_PPP_LWIP (1)
// CYW43 driver configuration.
#define CYW43_USE_SPI (1)
#define CYW43_LWIP (1)
#define CYW43_GPIO (1)
#define CYW43_SPI_PIO (1)
#ifndef CYW43_WL_GPIO_COUNT
#define CYW43_WL_GPIO_COUNT 3
#endif
#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT
int mp_hal_is_pin_reserved(int n);
#define MICROPY_HW_PIN_RESERVED(i) mp_hal_is_pin_reserved(i)

View File

@ -1,184 +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 PIMORONI_PLASMA2350
#define PIMORONI_PLASMA2350W
// --- BOARD SPECIFIC ---
#define SPICE_SPI 0
#define SPICE_TX_MISO_PIN 8
#define SPICE_RX_CS_PIN 9
#define SPICE_NETLIGHT_SCK_PIN 10
#define SPICE_RESET_MOSI_PIN 11
#define SPICE_PWRKEY_BL_PIN 7
#define PLASMA2350_SW_A_PIN 12
#define PLASMA2350_CLK_PIN 14
#define PLASMA2350_DATA_PIN 15
#define PLASMA2350_LED_R_PIN 16
#define PLASMA2350_LED_G_PIN 17
#define PLASMA2350_LED_B_PIN 18
#define PLASMA2350_I2C 0
#define PLASMA2350_INT_PIN 19
#define PLASMA2350_SDA_PIN 20
#define PLASMA2350_SCL_PIN 21
#define PLASMA2350_USER_SW_PIN 22
#define PLASMA2350_A0_PIN 26
#define PLASMA2350_A1_PIN 27
#define PLASMA2350_A2_PIN 28
#define PLASMA2350_NUM_ADC_PINS 3
#define PLASMA2350_CURRENT_SENSE_PIN 29
// --- RP2350 VARIANT ---
#define PICO_RP2350A 1
// --- UART ---
// no PICO_DEFAULT_UART
// no PICO_DEFAULT_UART_TX_PIN
// no PICO_DEFAULT_UART_RX_PIN
// --- LED ---
#ifndef PICO_DEFAULT_LED_PIN
#define PICO_DEFAULT_LED_PIN TINY2350_LED_G_PIN
#endif
// no PICO_DEFAULT_WS2812_PIN
#ifndef PICO_DEFAULT_LED_PIN_INVERTED
#define PICO_DEFAULT_LED_PIN_INVERTED 1
#endif
// --- I2C ---
// routed to Qw/St connector
#ifndef PICO_DEFAULT_I2C
#define PICO_DEFAULT_I2C PLASMA2350_I2C
#endif
#ifndef PICO_DEFAULT_I2C_SDA_PIN
#define PICO_DEFAULT_I2C_SDA_PIN PLASMA2350_SDA_PIN
#endif
#ifndef PICO_DEFAULT_I2C_SCL_PIN
#define PICO_DEFAULT_I2C_SCL_PIN PLASMA2350_SCL_PIN
#endif
// --- SPI ---
#ifndef PICO_DEFAULT_SPI
#define PICO_DEFAULT_SPI 0
#endif
#ifndef PICO_DEFAULT_SPI_SCK_PIN
#define PICO_DEFAULT_SPI_SCK_PIN SPICE_NETLIGHT_SCK_PIN
#endif
#ifndef PICO_DEFAULT_SPI_TX_PIN
#define PICO_DEFAULT_SPI_TX_PIN SPICE_RESET_MOSI_PIN
#endif
#ifndef PICO_DEFAULT_SPI_RX_PIN
#define PICO_DEFAULT_SPI_RX_PIN SPICE_TX_MISO_PIN
#endif
#ifndef PICO_DEFAULT_SPI_CSN_PIN
#define PICO_DEFAULT_SPI_CSN_PIN SPICE_RX_CS_PIN
#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
// PICO_CONFIG: CYW43_PIN_WL_DYNAMIC, flag to indicate if cyw43 SPI pins can be changed at runtime, type=bool, default=false, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_PIN_WL_DYNAMIC
#define CYW43_PIN_WL_DYNAMIC 1
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_REG_ON, gpio pin to power up the cyw43 chip, type=int, default=23, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_REG_ON
#define CYW43_DEFAULT_PIN_WL_REG_ON 23u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_OUT, gpio pin for spi data out to the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_DATA_OUT
#define CYW43_DEFAULT_PIN_WL_DATA_OUT 24u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_IN, gpio pin for spi data in from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_DATA_IN
#define CYW43_DEFAULT_PIN_WL_DATA_IN 24u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_HOST_WAKE, gpio (irq) pin for the irq line from the cyw43 chip, type=int, default=24, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_HOST_WAKE
#define CYW43_DEFAULT_PIN_WL_HOST_WAKE 24u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CLOCK, gpio pin for the spi clock line to the cyw43 chip, type=int, default=29, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_CLOCK
#define CYW43_DEFAULT_PIN_WL_CLOCK 29u
#endif
// PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CS, gpio pin for the spi chip select to the cyw43 chip, type=int, default=25, advanced=true, group=pico_cyw43_driver
#ifndef CYW43_DEFAULT_PIN_WL_CS
#define CYW43_DEFAULT_PIN_WL_CS 25u
#endif
#endif

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,38 +0,0 @@
import lte
import time
import requests
from machine import Pin, PWM
MOBILE_APN = "Your APN Here"
# Setting this to True will attempt to resume an existing connection
RESUME = False
# Fix the eye-searing brightness of the onboard LED with PWM
class Netlight:
def __init__(self):
self.pin = PWM(Pin("LED", Pin.OUT), freq=1000)
def value(self, value):
self.pin.duty_u16(value * 2000)
con = lte.LTE(MOBILE_APN, netlight_led=Netlight(), skip_reset=RESUME)
con.start_ppp(connect=not RESUME)
# Do some requests! Internet stuff should just work now.
try:
t_start = time.time()
for x in range(2):
req = requests.get("https://shop.pimoroni.com/robots.txt")
print(req)
finally:
t_end = time.time()
print(f"Took: {t_end - t_start} seconds")
print("Disconnecting...")
con.stop_ppp()
print("Done!")

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

@ -0,0 +1,9 @@
# cmake file for Raspberry Pi Pico
set(PICO_BOARD "pimoroni_pico_plus2_rp2350")
set(PICO_PLATFORM "rp2350")
set(PICO_NUM_GPIOS 48)
# 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,8 @@
// Board and hardware specific configuration
#ifndef MICROPY_HW_BOARD_NAME
// Might be defined by mpconfigvariant.cmake
#define MICROPY_HW_BOARD_NAME "Pimoroni Pico Plus 2"
#endif
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (2 * 1024 * 1024))
#define MICROPY_HW_PSRAM_CS_PIN PIMORONI_PICO_PLUS2_PSRAM_CS_PIN

View File

@ -0,0 +1,6 @@
# Override the MicroPython board name
list(APPEND MICROPY_DEF_BOARD
"MICROPY_HW_ENABLE_PSRAM=1"
"MICROPY_GC_SPLIT_HEAP=1"
"MICROPY_HW_BOARD_NAME=\"Pimoroni Pico Plus 2 (PSRAM)\""
)

View File

@ -0,0 +1,8 @@
# cmake file for Raspberry Pi Pico
set(PICO_BOARD "pimoroni_plasma2350")
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,7 @@
// Board and hardware specific configuration
#define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2350"
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (2 * 1024 * 1024))
// I2C0 (non-default)
#define MICROPY_HW_I2C0_SCL (PLASMA2350_SDA_PIN)
#define MICROPY_HW_I2C0_SDA (PLASMA2350_SCL_PIN)

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

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

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

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,3 @@
// Board and hardware specific configuration
#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico"
#define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1024 * 1024)

View File

@ -44,13 +44,4 @@ GP44,GPIO44
GP45,GPIO45 GP45,GPIO45
GP46,GPIO46 GP46,GPIO46
GP47,GPIO47 GP47,GPIO47
LED,GPIO25 LED,GPIO25
LEDW,EXT_GPIO0
WL_GPIO0,EXT_GPIO0
WL_GPIO1,EXT_GPIO1
WL_GPIO2,EXT_GPIO2
SPICE_TX,GPIO32
SPICE_RX,GPIO33
SPICE_NETLIGHT,GPIO34
SPICE_RESET,GPIO35
SPICE_PWRKEY,GPIO36
1 GP0 GPIO0
44 GP45 GPIO45
45 GP46 GPIO46
46 GP47 GPIO47
47 LED GPIO25
LEDW EXT_GPIO0
WL_GPIO0 EXT_GPIO0
WL_GPIO1 EXT_GPIO1
WL_GPIO2 EXT_GPIO2
SPICE_TX GPIO32
SPICE_RX GPIO33
SPICE_NETLIGHT GPIO34
SPICE_RESET GPIO35
SPICE_PWRKEY GPIO36

View File

@ -0,0 +1,6 @@
MODULES_PY = "../../../pimoroni-pico/micropython/modules_py"
freeze(MODULES_PY, "gfx_pack.py")
freeze(MODULES_PY, "pimoroni.py")
freeze(MODULES_PY, "boot.py")

View File

@ -0,0 +1,39 @@
"""
Simple example to display cover art.
Album art should be saved in 128 x 128 resolution PNG format
and placed in a folder called 'covers' in the root.
"""
import time
from interstate75 import Interstate75, DISPLAY_INTERSTATE75_128X128
import pngdec
import os
from random import choice
# Time between covers
INTERVAL = 10
# Setup for the display
i75 = Interstate75(display=DISPLAY_INTERSTATE75_128X128, stb_invert=False, panel_type=Interstate75.PANEL_GENERIC)
display = i75.display
WIDTH, HEIGHT = display.get_bounds()
p = pngdec.PNG(display)
while True:
# Select a PNG image from our 'covers' folder at random
file = choice(os.listdir("covers"))
img = f"covers/{file}"
p.open_file(img)
# Decode our PNG file and set the X and Y
p.decode(0, 0)
i75.update()
time.sleep(INTERVAL)

View File

@ -0,0 +1,156 @@
import time
import math
from random import randint, randrange
from interstate75 import Interstate75, DISPLAY_INTERSTATE75_128X128
# Setup for the display
i75 = Interstate75(
display=DISPLAY_INTERSTATE75_128X128, stb_invert=False, panel_type=Interstate75.PANEL_GENERIC)
display = i75.display
WIDTH, HEIGHT = display.get_bounds()
BLACK = display.create_pen(0, 0, 0)
WHITE = display.create_pen(255, 255, 255)
class Cube(object):
# The corners of the cube
vertices = [[-1, -1, 1],
[1, -1, 1],
[1, -1, -1],
[-1, -1, -1],
[-1, 1, 1],
[1, 1, 1],
[1, 1, -1],
[-1, 1, -1]]
# The corners that will be connected together to make a cube :)
edges = [(0, 1), (1, 2), (2, 3), (3, 0),
(4, 5), (5, 6), (6, 7), (7, 4),
(0, 4), (1, 5), (2, 6), (3, 7)]
def __init__(self, fov, distance, x, y, speed):
self.tick = time.ticks_ms() / 1000.0
self.cos = math.cos(self.tick)
self.sin = math.sin(self.tick)
self.fov = fov
self.distance = distance
self.pos_x = x
self.pos_y = y
self.speed = speed
self.cube_points = []
# Project our points
def to_2d(self, x, y, z, pos_x, pos_y, fov, distance):
factor = fov / (distance + z)
x = x * factor + pos_x
y = -y * factor + pos_y
return int(x), int(y)
def return_tick(self):
return self.tick
# Clear our points and recalculate the sin and cos values
def _update(self):
self.cube_points = []
self.tick = time.ticks_ms() / (self.speed * 1000)
self.cos = math.cos(self.tick)
self.sin = math.sin(self.tick)
def set_fov(self, fov):
self.fov = fov
def set_distance(self, distance):
self.distance = distance
def set_speed(self, speed):
self.speed = speed
def set_x(self, x):
self.pos_x = x
def set_y(self, y):
self.pos_y = y
def get_fov(self):
return self.fov
# Rotate on XYZ and save the new points in our list
def rotate(self):
for v in self.vertices:
start_x, start_y, start_z = v
# X
y = start_y * self.cos - start_z * self.sin
z = start_y * self.sin + start_z * self.cos
# Y
x = start_x * self.cos - z * self.sin
z = start_x * self.sin + z * self.cos
# Z
n_y = x * self.sin + y * self.cos
n_x = x * self.cos - y * self.sin
y = n_y
x = n_x
point = self.to_2d(x, y, z, self.pos_x, self.pos_y, self.fov, self.distance)
self.cube_points.append(point)
# Draw the edges of the cube so we can see it on screen!
def draw(self):
for edge in self.edges:
display.line(self.cube_points[edge[0]][0], self.cube_points[edge[0]][1], self.cube_points[edge[1]][0], self.cube_points[edge[1]][1])
self._update()
# Setup the first 3 cubes.
cubes = [Cube(16, 8, WIDTH / 2, HEIGHT / 2, 1.0), Cube(32, 8, 100, 100, 0.9), Cube(32, 8, 100, 100, 0.5)]
# Set our initial pen colour
pen = display.create_pen_hsv(1.0, 1.0, 1.0)
while 1:
# We'll use this for cycling through the rainbow
t = time.ticks_ms() / 1000
# Set the layer we're going to be drawing to.
display.set_layer(0)
# Clear the screen and set the pen colour for the cubes
display.set_pen(BLACK)
display.clear()
display.set_pen(WHITE)
display.text("Flying Cubes!", 33, 55, WIDTH, 1)
display.reset_pen(pen)
pen = display.create_pen_hsv(t, 1.0, 1.0)
display.set_pen(pen)
# Now we go through each Cube object we have in 'cubes'
# and increase the FOV angle so it appears closer to the screen.
# We'll also rotate the cube during this loop too.
for i, cube in enumerate(cubes):
fov = cube.get_fov()
fov += 3
cube.set_fov(fov)
cube.rotate()
cube.draw()
# We want the cubes to disappear randomly as they appear close to the screen, so we'll decide when this happens based on the current FOV
# We'll replace that cube with a new one and start the process from the beginning!
if fov > randint(250, 600):
cubes[i] = Cube(8, 8, randint(10, WIDTH), randint(10, HEIGHT), randrange(4, 9) / 10)
# Finally we update the display with our changes :)
i75.update()
time.sleep(0.03)

View File

@ -0,0 +1,377 @@
import gc
import random
import time
from collections import namedtuple
from interstate75 import DISPLAY_INTERSTATE75_128X128, Interstate75
from machine import I2C
from qwstpad import ADDRESSES, QwSTPad
"""
A single player game demo. Navigate a set of mazes from the start (red) to the goal (green).
Mazes get bigger / harder with each increase in level.
Makes use of 1 QwSTPad and a 128x128 LED matrix + i75W.
Controls:
* U = Move Forward
* D = Move Backward
* R = Move Right
* L = Move left
* + = Continue (once the current level is complete)
"""
# General Constants
I2C_PINS = {"id": 0, "sda": 20, "scl": 21} # The I2C pins the QwSTPad is connected to
I2C_ADDRESS = ADDRESSES[0] # The I2C address of the connected QwSTPad
BRIGHTNESS = 1.0 # The brightness of the LCD backlight (from 0.0 to 1.0)
# Gameplay Constants
Position = namedtuple("Position", ("x", "y"))
MIN_MAZE_WIDTH = 2
MAX_MAZE_WIDTH = 5
MIN_MAZE_HEIGHT = 2
MAX_MAZE_HEIGHT = 5
WALL_SHADOW = 1
WALL_GAP = 1
TEXT_SHADOW = 1
MOVEMENT_SLEEP = 0.1
DIFFICULT_SCALE = 0.5
# Setup for the display
i75 = Interstate75(
display=DISPLAY_INTERSTATE75_128X128, stb_invert=False, panel_type=Interstate75.PANEL_GENERIC)
display = i75.display
# Colour Constants
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
RED = display.create_pen(255, 0, 0)
GREEN = display.create_pen(0, 255, 0)
PLAYER = display.create_pen(227, 231, 110)
WALL = display.create_pen(127, 125, 244)
BACKGROUND = display.create_pen(60, 57, 169)
PATH = display.create_pen((227 + 60) // 2, (231 + 57) // 2, (110 + 169) // 2)
# Variables
i2c = I2C(**I2C_PINS) # The I2C instance to pass to the QwSTPad
complete = False # Has the game been completed?
level = 0 # The current "level" the player is on (affects difficulty)
# Get the width and height from the display
WIDTH, HEIGHT = display.get_bounds()
# Classes
class Cell:
def __init__(self, x, y):
self.x = x
self.y = y
self.bottom = True
self.right = True
self.visited = False
@staticmethod
def remove_walls(current, next):
dx, dy = current.x - next.x, current.y - next.y
if dx == 1:
next.right = False
if dx == -1:
current.right = False
if dy == 1:
next.bottom = False
if dy == -1:
current.bottom = False
class MazeBuilder:
def __init__(self):
self.width = 0
self.height = 0
self.cell_grid = []
self.maze = []
def build(self, width, height):
if width <= 0:
raise ValueError("width out of range. Expected greater than 0")
if height <= 0:
raise ValueError("height out of range. Expected greater than 0")
self.width = width
self.height = height
# Set the starting cell to the centre
cx = (self.width - 1) // 2
cy = (self.height - 1) // 2
gc.collect()
# Create a grid of cells for building a maze
self.cell_grid = [[Cell(x, y) for y in range(self.height)] for x in range(self.width)]
cell_stack = []
# Retrieve the starting cell and mark it as visited
current = self.cell_grid[cx][cy]
current.visited = True
# Loop until every cell has been visited
while True:
next = self.choose_neighbour(current)
# Was a valid neighbour found?
if next is not None:
# Move to the next cell, removing walls in the process
next.visited = True
cell_stack.append(current)
Cell.remove_walls(current, next)
current = next
# No valid neighbour. Backtrack to a previous cell
elif len(cell_stack) > 0:
current = cell_stack.pop()
# No previous cells, so exit
else:
break
gc.collect()
# Use the cell grid to create a maze grid of 0's and 1s
self.maze = []
row = [1]
for x in range(0, self.width):
row.append(1)
row.append(1)
self.maze.append(row)
for y in range(0, self.height):
row = [1]
for x in range(0, self.width):
row.append(0)
row.append(1 if self.cell_grid[x][y].right else 0)
self.maze.append(row)
row = [1]
for x in range(0, self.width):
row.append(1 if self.cell_grid[x][y].bottom else 0)
row.append(1)
self.maze.append(row)
self.cell_grid.clear()
gc.collect()
self.grid_columns = (self.width * 2 + 1)
self.grid_rows = (self.height * 2 + 1)
def choose_neighbour(self, current):
unvisited = []
for dx in range(-1, 2, 2):
x = current.x + dx
if x >= 0 and x < self.width and not self.cell_grid[x][current.y].visited:
unvisited.append((x, current.y))
for dy in range(-1, 2, 2):
y = current.y + dy
if y >= 0 and y < self.height and not self.cell_grid[current.x][y].visited:
unvisited.append((current.x, y))
if len(unvisited) > 0:
x, y = random.choice(unvisited)
return self.cell_grid[x][y]
return None
def maze_width(self):
return (self.width * 2) + 1
def maze_height(self):
return (self.height * 2) + 1
def draw(self, display):
# Draw the maze we have built. Each '1' in the array represents a wall
for row in range(self.grid_rows):
for col in range(self.grid_columns):
# Calculate the screen coordinates
x = (col * wall_separation) + offset_x
y = (row * wall_separation) + offset_y
if self.maze[row][col] == 1:
# Draw a wall shadow
display.set_pen(BLACK)
display.rectangle(x + WALL_SHADOW, y + WALL_SHADOW, wall_size, wall_size)
# Draw a wall top
display.set_pen(WALL)
display.rectangle(x, y, wall_size, wall_size)
if self.maze[row][col] == 2:
# Draw the player path
display.set_pen(PATH)
display.rectangle(x, y, wall_size, wall_size)
class Player(object):
def __init__(self, x, y, colour, pad):
self.x = x
self.y = y
self.colour = colour
self.pad = pad
def position(self, x, y):
self.x = x
self.y = y
def update(self, maze):
# Read the player's gamepad
button = self.pad.read_buttons()
if button['L'] and maze[self.y][self.x - 1] != 1:
self.x -= 1
time.sleep(MOVEMENT_SLEEP)
elif button['R'] and maze[self.y][self.x + 1] != 1:
self.x += 1
time.sleep(MOVEMENT_SLEEP)
elif button['U'] and maze[self.y - 1][self.x] != 1:
self.y -= 1
time.sleep(MOVEMENT_SLEEP)
elif button['D'] and maze[self.y + 1][self.x] != 1:
self.y += 1
time.sleep(MOVEMENT_SLEEP)
maze[self.y][self.x] = 2
def draw(self, display):
display.set_pen(self.colour)
display.rectangle(self.x * wall_separation + offset_x,
self.y * wall_separation + offset_y,
wall_size, wall_size)
def build_maze():
global wall_separation
global wall_size
global offset_x
global offset_y
global start
global goal
difficulty = int(level * DIFFICULT_SCALE)
width = random.randrange(MIN_MAZE_WIDTH, MAX_MAZE_WIDTH)
height = random.randrange(MIN_MAZE_HEIGHT, MAX_MAZE_HEIGHT)
builder.build(width + difficulty, height + difficulty)
wall_separation = min(HEIGHT // builder.grid_rows,
WIDTH // builder.grid_columns)
wall_size = wall_separation - WALL_GAP
offset_x = (WIDTH - (builder.grid_columns * wall_separation) + WALL_GAP) // 2
offset_y = (HEIGHT - (builder.grid_rows * wall_separation) + WALL_GAP) // 2
start = Position(1, builder.grid_rows - 2)
goal = Position(builder.grid_columns - 2, 1)
# Create the maze builder and build the first maze and put
builder = MazeBuilder()
build_maze()
# Create the player object if a QwSTPad is connected
try:
player = Player(*start, PLAYER, QwSTPad(i2c, I2C_ADDRESS))
except OSError:
print("QwSTPad: Not Connected ... Exiting")
raise SystemExit
print("QwSTPad: Connected ... Starting")
# Store text strings and calculate centre location
text_1_string = "Maze Complete!"
text_1_size = display.measure_text(text_1_string, 1)
text_2_string = "Press + to continue"
text_2_size = display.measure_text(text_2_string, 1)
text_1_location = ((WIDTH // 2) - (text_1_size // 2), 55)
text_2_location = ((WIDTH // 2) - (text_2_size // 2), 65)
# Wrap the code in a try block, to catch any exceptions (including KeyboardInterrupt)
try:
# Loop forever
while True:
if not complete:
# Update the player's position in the maze
player.update(builder.maze)
# Check if any player has reached the goal position
if player.x == goal.x and player.y == goal.y:
complete = True
else:
# Check for the player wanting to continue
if player.pad.read_buttons()['+']:
complete = False
level += 1
build_maze()
player.position(*start)
# Clear the screen to the background colour
display.set_pen(BACKGROUND)
display.clear()
# Draw the maze walls
builder.draw(display)
# Draw the start location square
display.set_pen(RED)
display.rectangle(start.x * wall_separation + offset_x,
start.y * wall_separation + offset_y,
wall_size, wall_size)
# Draw the goal location square
display.set_pen(GREEN)
display.rectangle(goal.x * wall_separation + offset_x,
goal.y * wall_separation + offset_y,
wall_size, wall_size)
# Draw the player
player.draw(display)
# Display the level
display.set_pen(BLACK)
display.text(f"Lvl: {level}", 2 + TEXT_SHADOW, 2 + TEXT_SHADOW, WIDTH, 1)
display.set_pen(WHITE)
display.text(f"Lvl: {level}", 2, 2, WIDTH, 1)
if complete:
# Draw banner shadow
display.set_pen(BLACK)
display.rectangle(4, 44, WIDTH, 50)
# Draw banner
display.set_pen(PLAYER)
display.rectangle(0, 40, WIDTH, 50)
# Draw text shadow
display.set_pen(BLACK)
display.text(f"{text_1_string}", text_1_location[0] + TEXT_SHADOW, text_1_location[1] + TEXT_SHADOW, WIDTH, 1)
display.text(f"{text_2_string}", text_2_location[0] + TEXT_SHADOW, text_2_location[1] + TEXT_SHADOW, WIDTH, 1)
# Draw text
display.set_pen(WHITE)
display.text(f"{text_1_string}", text_1_location[0], text_1_location[1], WIDTH, 1)
display.text(f"{text_2_string}", text_2_location[0], text_2_location[1], WIDTH, 1)
# Finally we update the display with our changes :)
i75.update()
# Handle the QwSTPad being disconnected unexpectedly
except OSError:
print("QwSTPad: Disconnected .. Exiting")
# Turn off the LEDs of the connected QwSTPad
finally:
try:
player.pad.clear_leds()
except OSError:
pass

View File

@ -0,0 +1,118 @@
import time
import machine
import network
import ntptime
from interstate75 import DISPLAY_INTERSTATE75_128X128, Interstate75
SHADOW_OFFSET = 1
# Check and import the Network SSID and Password from secrets.py
try:
from secrets import WIFI_PASSWORD, WIFI_SSID
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)
rtc = machine.RTC()
DAYS = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"]
# Enable the Wireless
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
def network_connect(SSID, PSK):
# Number of attempts to make before timeout
max_wait = 5
# Sets the Wireless LED pulsing and attempts to connect to your local network.
print("connecting...")
wlan.config(pm=0xa11140) # Turn WiFi power saving off for some slow APs
wlan.connect(SSID, PSK)
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
# Handle connection error. Switches the Warn LED on.
if wlan.status() != 3:
print("Unable to connect. Attempting connection again")
# Function to sync the Pico RTC using NTP
def sync_time():
try:
network_connect(WIFI_SSID, WIFI_PASSWORD)
except NameError:
print("Create secrets.py with your WiFi credentials")
if wlan.status() < 0 or wlan.status() >= 3:
try:
ntptime.settime()
except OSError:
print("Unable to sync with NTP server. Check network and try again.")
# Setup for the display
i75 = Interstate75(
display=DISPLAY_INTERSTATE75_128X128, stb_invert=False, panel_type=Interstate75.PANEL_GENERIC)
display = i75.display
WIDTH, HEIGHT = display.get_bounds()
# Pens
RED = display.create_pen(120, 0, 0)
WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
sync_time()
while True:
current_t = rtc.datetime()
# Set the pen to Red and clear the screen.
display.set_pen(WHITE)
display.clear()
# Measures the length of the text to help us with centring later.
day_length = display.measure_text(DAYS[current_t[3]], 4)
date_length = display.measure_text(str(current_t[2]), 7)
# Red banner
display.set_pen(RED)
display.rectangle(0, 0, WIDTH, 30)
# Drop Shadow
display.set_font("bitmap6")
display.set_pen(BLACK)
display.text(DAYS[current_t[3]], (WIDTH // 2) - (day_length // 2) + SHADOW_OFFSET, 2 + SHADOW_OFFSET, WIDTH, 4)
display.set_font("bitmap8")
display.text(str(current_t[2]), (WIDTH // 2) - (date_length // 2) + SHADOW_OFFSET + 4, 55 + SHADOW_OFFSET, WIDTH, 7)
# Main Text
display.set_font("bitmap6")
display.set_pen(WHITE)
display.text(DAYS[current_t[3]], (WIDTH // 2) - (day_length // 2), 2, WIDTH, 4)
display.set_pen(RED)
display.set_font("bitmap8")
display.text(str(current_t[2]), (WIDTH // 2) - (date_length // 2) + 4, 55, WIDTH, 7)
display.set_pen(display.create_pen(0, 0, 0))
i75.update()

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()