Compare commits

...

23 Commits

Author SHA1 Message Date
Phil Howard
ba2cf6549e CI: 2MB/2MB split for Pico 2 and Pico 2 W builds. 2024-11-26 22:48:31 +00:00
Phil Howard
deefd4d016 CI: Sync RPi stock boards with upstream.
Replace our experimental configs with the board config(s) from the
(as yet unmerged) Pico 2 W changes branch.
2024-11-26 22:42:02 +00:00
Phil Howard
9dfb5c0429 CI: Workaround silly mpy-cross build wart. 2024-11-26 22:00:41 +00:00
Phil Howard
222331ef44 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-21 17:45:45 +00:00
Phil Howard
f194af476f 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-21 17:45:45 +00:00
Phil Howard
0080f2f00f CI: Retarget MicroPython to feature/psram-and-wifi. 2024-11-21 17:45:45 +00:00
Phil Howard
7b6b1934f8 PPP: Add send_text_message for #14.
Also a quick cleanup of the lte module code.
2024-11-21 17:45:45 +00:00
Phil Howard
a8a28576dc Plasma3350: Add WL ext GPIOs and fallback. 2024-11-21 17:45:45 +00:00
Phil Howard
5ce3c2b33d PPP: Shim EXT GPIO on non W builds. 2024-11-21 17:45:45 +00:00
Phil Howard
53c8357f42 PPP2W: Add LEDW mapping and WL_GPIO pins. 2024-11-21 17:45:45 +00:00
Phil Howard
792ceda06b Plasma2350: Add WiFi + LTE variant. 2024-11-21 17:45:45 +00:00
Phil Howard
cb541d5284 Pico2: Add WIRELESS variant for LTE + WiFi modules. 2024-11-21 17:45:45 +00:00
Phil Howard
a2530f9b3b PPP: Add ipconfig pass-through. 2024-11-21 17:45:45 +00:00
nkotilainen
152e214b9b PPP: LTE IMSI printout changed to ICCID. 2024-11-21 17:45:45 +00:00
Phil Howard
d02408c5ae PPP2: Add wireless. 2024-11-21 17:45:45 +00:00
nkotilainen
6141244e97 PPP: LTE IMEI renamed to IMSI. 2024-11-21 17:45:45 +00:00
Phil Howard
aa3bf94f66 PPP: Simplify config.
PPP does not use socket extended state, and should be
added automatically in the networking module.
2024-11-21 17:45:45 +00:00
Phil Howard
23b3541990 PPP: Enable PPP. 2024-11-21 17:45:45 +00:00
Phil Howard
7d13e47ebb PPP: Add CYW43 wireless pins. 2024-11-21 17:45:45 +00:00
Phil Howard
b48e6a7e77 PPP: Add CYW43 wireless.
If we're bringing in lwip and networking, this variant might as well
support CYW43.
2024-11-21 17:45:45 +00:00
Phil Howard
ba38f25eaa PPP: Fix board name. 2024-11-21 17:45:45 +00:00
Phil Howard
675f9e3df0 PPP: Add LTE module. 2024-11-21 17:45:45 +00:00
Phil Howard
f06b6b153d Pico Plus 2: Add a PPP variant. 2024-11-21 17:45:45 +00:00
24 changed files with 954 additions and 50 deletions

View File

@ -7,7 +7,7 @@ on:
types: [created] types: [created]
env: env:
MICROPYTHON_VERSION: feature/psram MICROPYTHON_VERSION: feature/psram-and-wifi
MICROPYTHON_FLAVOUR: pimoroni MICROPYTHON_FLAVOUR: pimoroni
PIMORONI_PICO_VERSION: main PIMORONI_PICO_VERSION: main
@ -19,17 +19,16 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- name: pico2_rp2350 - name: pico2
board: RPI_PICO2 board: RPI_PICO2
- name: pico2_w
board: RPI_PICO2_W
- name: pico2b_rp2350 - name: pico2b_rp2350
board: RPI_PICO2B board: RPI_PICO2B
- name: plasma2350 - name: plasma2350
board: PIMORONI_PLASMA2350 board: PIMORONI_PLASMA2350
- name: tiny2350 - name: tiny2350
board: PIMORONI_TINY2350 board: PIMORONI_TINY2350
- name: pico_plus2_rp2350_psram
board: PIMORONI_PICO_PLUS2
variant: PSRAM
- name: pico_plus2_rp2350 - name: pico_plus2_rp2350
board: PIMORONI_PICO_PLUS2 board: PIMORONI_PICO_PLUS2

View File

@ -30,7 +30,7 @@ function micropython_clone {
function micropython_build_mpy_cross { function micropython_build_mpy_cross {
cd micropython/mpy-cross cd micropython/mpy-cross
ccache --zero-stats || true ccache --zero-stats || true
CROSS_COMPILE="ccache " make CROSS_COMPILE="ccache " USER_C_MODULES= make
ccache --show-stats || true ccache --show-stats || true
cd ../../ cd ../../
} }

View File

@ -1,3 +1,10 @@
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")
freeze("$(BOARD_DIR)/../../modules_py", "lte.py")

View File

@ -1,5 +1,6 @@
# cmake file for Raspberry Pi Pico # cmake file for Raspberry Pi Pico
set(PICO_BOARD "pimoroni_pico_plus2_rp2350") set(PICO_BOARD "pimoroni_pico_plus2w_rp2350")
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
set(PICO_PLATFORM "rp2350") set(PICO_PLATFORM "rp2350")
set(PICO_NUM_GPIOS 48) set(PICO_NUM_GPIOS 48)
@ -7,3 +8,32 @@ set(PICO_NUM_GPIOS 48)
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)
# 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)

View File

@ -1,8 +1,31 @@
// Board and hardware specific configuration // 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_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_HW_PSRAM_CS_PIN PIMORONI_PICO_PLUS2_PSRAM_CS_PIN
#define MICROPY_GC_SPLIT_HEAP (1)

View File

@ -1,6 +0,0 @@
# 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,162 @@
/*
* 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

@ -45,3 +45,12 @@ 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
45 GP46 GPIO46
46 GP47 GPIO47
47 LED GPIO25
48 LEDW EXT_GPIO0
49 WL_GPIO0 EXT_GPIO0
50 WL_GPIO1 EXT_GPIO1
51 WL_GPIO2 EXT_GPIO2
52 SPICE_TX GPIO32
53 SPICE_RX GPIO33
54 SPICE_NETLIGHT GPIO34
55 SPICE_RESET GPIO35
56 SPICE_PWRKEY GPIO36

View File

@ -1,3 +1,10 @@
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")
freeze("$(BOARD_DIR)/../../modules_py", "lte.py")

View File

@ -1,8 +1,37 @@
# cmake file for Raspberry Pi Pico # cmake file for Pimoroni Plasma 2350
set(PICO_BOARD "pimoroni_plasma2350") set(PICO_BOARD "pimoroni_plasma2350w")
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
set(PICO_PLATFORM "rp2350") set(PICO_PLATFORM "rp2350")
# Board specific version of the frozen manifest # Board specific version of the frozen manifest
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)
# 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)

View File

@ -1,7 +1,31 @@
// Board and hardware specific configuration // 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)) #define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - (2 * 1024 * 1024))
// I2C0 (non-default) // I2C0 (non-default)
#define MICROPY_HW_I2C0_SCL (PLASMA2350_SDA_PIN) #define MICROPY_HW_I2C0_SCL (PLASMA2350_SDA_PIN)
#define MICROPY_HW_I2C0_SDA (PLASMA2350_SCL_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

@ -0,0 +1,184 @@
/*
* 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,19 +0,0 @@
{
"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,11 @@
# cmake file for Raspberry Pi Pico # cmake file for Raspberry Pi Pico2
set(PICO_BOARD "pico2") set(PICO_BOARD "pico2")
set(PICO_PLATFORM "rp2350")
# Board specific version of the frozen manifest # To change the gpio count for QFN-80
# set(PICO_NUM_GPIOS 48)
if (PICO_CYW43_SUPPORTED)
include(enable_cyw43.cmake)
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)
set(PICO_PINS_CSV_NAME pins_cyw43.csv)
set(MICROPY_C_HEAP_SIZE 4096) endif()

View File

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

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

View File

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

View File

@ -0,0 +1,7 @@
// 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"
#include "enable_cyw43.h"

View File

@ -0,0 +1,30 @@
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,5 +1,8 @@
MODULES_PY = "../../../pimoroni-pico/micropython/modules_py" MODULES_PY = "../../../pimoroni-pico/micropython/modules_py"
# SD Card
require("sdcard")
freeze(MODULES_PY, "gfx_pack.py") freeze(MODULES_PY, "gfx_pack.py")
freeze(MODULES_PY, "pimoroni.py") freeze(MODULES_PY, "pimoroni.py")

View File

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

@ -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"