From 1029501b7edd6a3ec27459a27f79ba06567d6769 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 10 Oct 2024 19:26:21 +0100 Subject: [PATCH 1/5] rp2: Allow extra arguments in Makefile. When building allow the port to be configured on the command line by passing a value for CMAKE_ARGS. Signed-off-by: Peter Harper --- ports/rp2/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ports/rp2/Makefile b/ports/rp2/Makefile index afa21cc7a4383..0b3a00c8e572f 100644 --- a/ports/rp2/Makefile +++ b/ports/rp2/Makefile @@ -34,26 +34,26 @@ ifeq ($(BUILD_VERBOSE),1) MAKE_ARGS += VERBOSE=1 # Picked up in Makefile generated by CMake endif -CMAKE_ARGS += -DMICROPY_BOARD=$(BOARD) -DMICROPY_BOARD_DIR="$(abspath $(BOARD_DIR))" +override CMAKE_ARGS += -DMICROPY_BOARD=$(BOARD) -DMICROPY_BOARD_DIR="$(abspath $(BOARD_DIR))" ifdef USER_C_MODULES -CMAKE_ARGS += -DUSER_C_MODULES=${USER_C_MODULES} +override CMAKE_ARGS += -DUSER_C_MODULES=${USER_C_MODULES} endif ifneq ($(FROZEN_MANIFEST),) -CMAKE_ARGS += -DMICROPY_FROZEN_MANIFEST=${FROZEN_MANIFEST} +override CMAKE_ARGS += -DMICROPY_FROZEN_MANIFEST=${FROZEN_MANIFEST} endif ifeq ($(DEBUG),1) -CMAKE_ARGS += -DCMAKE_BUILD_TYPE=Debug +override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=Debug endif ifdef BOARD_VARIANT -CMAKE_ARGS += -DMICROPY_BOARD_VARIANT=$(BOARD_VARIANT) +override CMAKE_ARGS += -DMICROPY_BOARD_VARIANT=$(BOARD_VARIANT) endif ifdef MICROPY_PREVIEW_VERSION_2 -CMAKE_ARGS += -DMICROPY_PREVIEW_VERSION_2=1 +override CMAKE_ARGS += -DMICROPY_PREVIEW_VERSION_2=1 endif HELP_BUILD_ERROR ?= "See \033[1;31mhttps://github.com/micropython/micropython/wiki/Build-Troubleshooting\033[0m" From d6cfdcaf4e53e4b99e154aa8a629cebc4a525a3d Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 10 Oct 2024 19:30:32 +0100 Subject: [PATCH 2/5] rp2: Put cyw43 config in separate files. Signed-off-by: Peter Harper --- .../boards/RPI_PICO2_W/mpconfigboard.cmake | 8 +----- ports/rp2/boards/RPI_PICO2_W/mpconfigboard.h | 19 ++------------ .../rp2/boards/RPI_PICO_W/mpconfigboard.cmake | 8 +----- ports/rp2/boards/RPI_PICO_W/mpconfigboard.h | 20 ++------------- ports/rp2/enable_cyw43.cmake | 7 ++++++ ports/rp2/enable_cyw43.h | 25 +++++++++++++++++++ 6 files changed, 38 insertions(+), 49 deletions(-) create mode 100644 ports/rp2/enable_cyw43.cmake create mode 100644 ports/rp2/enable_cyw43.h diff --git a/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.cmake b/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.cmake index 1d9b7fc448a0c..b77ff7d979c3c 100644 --- a/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.cmake +++ b/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.cmake @@ -5,13 +5,7 @@ set(PICO_BOARD "pico2_w") # To change the gpio count for QFN-80 # set(PICO_NUM_GPIOS 48) -set(MICROPY_PY_LWIP ON) -set(MICROPY_PY_NETWORK_CYW43 ON) - -# Bluetooth -set(MICROPY_PY_BLUETOOTH ON) -set(MICROPY_BLUETOOTH_BTSTACK ON) -set(MICROPY_PY_BLUETOOTH_CYW43 ON) +include(enable_cyw43.cmake) # Board specific version of the frozen manifest set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) diff --git a/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.h b/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.h index fe688c2803192..46aa4e0a7c908 100644 --- a/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.h +++ b/ports/rp2/boards/RPI_PICO2_W/mpconfigboard.h @@ -2,21 +2,6 @@ #define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico 2 W" #define MICROPY_HW_FLASH_STORAGE_BYTES (PICO_FLASH_SIZE_BYTES - 1536 * 1024) -// Enable networking. -#define MICROPY_PY_NETWORK 1 -#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico2W" +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico2W" -// CYW43 driver configuration. -#define CYW43_USE_SPI (1) -#define CYW43_LWIP (1) -#define CYW43_GPIO (1) -#define CYW43_SPI_PIO (1) - -// For debugging mbedtls - also set -// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose -// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 1 - -#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) +#include "enable_cyw43.h" diff --git a/ports/rp2/boards/RPI_PICO_W/mpconfigboard.cmake b/ports/rp2/boards/RPI_PICO_W/mpconfigboard.cmake index cea6c38d73b4e..6cee0a0799669 100644 --- a/ports/rp2/boards/RPI_PICO_W/mpconfigboard.cmake +++ b/ports/rp2/boards/RPI_PICO_W/mpconfigboard.cmake @@ -2,13 +2,7 @@ set(PICO_BOARD "pico_w") -set(MICROPY_PY_LWIP ON) -set(MICROPY_PY_NETWORK_CYW43 ON) - -# Bluetooth -set(MICROPY_PY_BLUETOOTH ON) -set(MICROPY_BLUETOOTH_BTSTACK ON) -set(MICROPY_PY_BLUETOOTH_CYW43 ON) +include(enable_cyw43.cmake) # Board specific version of the frozen manifest set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) diff --git a/ports/rp2/boards/RPI_PICO_W/mpconfigboard.h b/ports/rp2/boards/RPI_PICO_W/mpconfigboard.h index 45ad6107ba14e..5b4530a01f67e 100644 --- a/ports/rp2/boards/RPI_PICO_W/mpconfigboard.h +++ b/ports/rp2/boards/RPI_PICO_W/mpconfigboard.h @@ -4,22 +4,6 @@ // todo: We need something to check our binary size #define MICROPY_HW_FLASH_STORAGE_BYTES (848 * 1024) -// Enable networking. -#define MICROPY_PY_NETWORK 1 -#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "PicoW" +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "PicoW" -// CYW43 driver configuration. -#define CYW43_USE_SPI (1) -#define CYW43_LWIP (1) -#define CYW43_GPIO (1) -#define CYW43_SPI_PIO (1) - -// For debugging mbedtls - also set -// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose -// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 1 - -#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT - -// If this returns true for a pin then its irq will not be disabled on a soft reboot -int mp_hal_is_pin_reserved(int n); -#define MICROPY_HW_PIN_RESERVED(i) mp_hal_is_pin_reserved(i) +#include "enable_cyw43.h" diff --git a/ports/rp2/enable_cyw43.cmake b/ports/rp2/enable_cyw43.cmake new file mode 100644 index 0000000000000..5b12e86fb20d4 --- /dev/null +++ b/ports/rp2/enable_cyw43.cmake @@ -0,0 +1,7 @@ +set(MICROPY_PY_LWIP ON) +set(MICROPY_PY_NETWORK_CYW43 ON) + +# Bluetooth +set(MICROPY_PY_BLUETOOTH ON) +set(MICROPY_BLUETOOTH_BTSTACK ON) +set(MICROPY_PY_BLUETOOTH_CYW43 ON) diff --git a/ports/rp2/enable_cyw43.h b/ports/rp2/enable_cyw43.h new file mode 100644 index 0000000000000..ab38d62e5aa47 --- /dev/null +++ b/ports/rp2/enable_cyw43.h @@ -0,0 +1,25 @@ +// Enable networking. +#define MICROPY_PY_NETWORK 1 + +#ifndef MICROPY_PY_NETWORK_HOSTNAME_DEFAULT +#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "Pico" +#endif + +// CYW43 driver configuration. +#define CYW43_USE_SPI (1) +#define CYW43_LWIP (1) +#define CYW43_GPIO (1) +#define CYW43_SPI_PIO (1) + +// For debugging mbedtls - also set +// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose +// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 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) From ba8f1bd89c693db95cc53306819afc9ce20f4e7a Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 10 Oct 2024 19:31:42 +0100 Subject: [PATCH 3/5] rp2: Allow pins.csv filename to be configured. Signed-off-by: Peter Harper --- ports/rp2/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 8a4092529b1f2..7390430591c84 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -632,8 +632,12 @@ if(NOT PICO_NUM_EXT_GPIOS) set(PICO_NUM_EXT_GPIOS 10) endif() -if(EXISTS "${MICROPY_BOARD_DIR}/pins.csv") - set(GEN_PINS_BOARD_CSV "${MICROPY_BOARD_DIR}/pins.csv") +if (NOT PICO_PINS_CSV_NAME) + set(PICO_PINS_CSV_NAME pins.csv) +endif() + +if(EXISTS "${MICROPY_BOARD_DIR}/${PICO_PINS_CSV_NAME}") + set(GEN_PINS_BOARD_CSV "${MICROPY_BOARD_DIR}/${PICO_PINS_CSV_NAME}") set(GEN_PINS_CSV_ARG --board-csv "${GEN_PINS_BOARD_CSV}") endif() From 7c6a51da3f81c0984fa577ac7b456b00c9d27df7 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Thu, 10 Oct 2024 19:35:57 +0100 Subject: [PATCH 4/5] rp2: Allow pico and pico2 to use cyw43. Signed-off-by: Peter Harper --- ports/rp2/boards/RPI_PICO/manifest.py | 7 +++++ ports/rp2/boards/RPI_PICO/mpconfigboard.cmake | 6 ++++ ports/rp2/boards/RPI_PICO/mpconfigboard.h | 23 ++++++++++++++ ports/rp2/boards/RPI_PICO/pins_cyw43.csv | 31 +++++++++++++++++++ ports/rp2/boards/RPI_PICO2/manifest.py | 7 +++++ .../rp2/boards/RPI_PICO2/mpconfigboard.cmake | 6 ++++ ports/rp2/boards/RPI_PICO2/mpconfigboard.h | 19 ++++++++++++ ports/rp2/boards/RPI_PICO2/pins_cyw43.csv | 31 +++++++++++++++++++ 8 files changed, 130 insertions(+) create mode 100644 ports/rp2/boards/RPI_PICO/manifest.py create mode 100644 ports/rp2/boards/RPI_PICO/pins_cyw43.csv create mode 100644 ports/rp2/boards/RPI_PICO2/manifest.py create mode 100644 ports/rp2/boards/RPI_PICO2/pins_cyw43.csv diff --git a/ports/rp2/boards/RPI_PICO/manifest.py b/ports/rp2/boards/RPI_PICO/manifest.py new file mode 100644 index 0000000000000..fdae49fbf4be2 --- /dev/null +++ b/ports/rp2/boards/RPI_PICO/manifest.py @@ -0,0 +1,7 @@ +# This file is only used if cyw43 is enabled +include("$(PORT_DIR)/boards/manifest.py") + +require("bundle-networking") + +# Bluetooth +require("aioble") diff --git a/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake b/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake index 386bd33285890..352132a5066dd 100644 --- a/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake +++ b/ports/rp2/boards/RPI_PICO/mpconfigboard.cmake @@ -1,3 +1,9 @@ # cmake file for Raspberry Pi Pico set(PICO_BOARD "pico") set(PICO_PLATFORM "rp2040") + +if (PICO_CYW43_SUPPORTED) + include(enable_cyw43.cmake) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) + set(PICO_PINS_CSV_NAME pins_cyw43.csv) +endif() diff --git a/ports/rp2/boards/RPI_PICO/mpconfigboard.h b/ports/rp2/boards/RPI_PICO/mpconfigboard.h index c39bc4d489bb6..4f904cd4d32d4 100644 --- a/ports/rp2/boards/RPI_PICO/mpconfigboard.h +++ b/ports/rp2/boards/RPI_PICO/mpconfigboard.h @@ -1,3 +1,26 @@ // Board and hardware specific configuration #define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico" + +#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 + +// we have to reduce the flash storage if cyw43 is enabled or else the firmware gets overwritten +#define MICROPY_HW_FLASH_STORAGE_BYTES (848 * 1024) +#else #define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024) +#endif diff --git a/ports/rp2/boards/RPI_PICO/pins_cyw43.csv b/ports/rp2/boards/RPI_PICO/pins_cyw43.csv new file mode 100644 index 0000000000000..6459a8d4bfa20 --- /dev/null +++ b/ports/rp2/boards/RPI_PICO/pins_cyw43.csv @@ -0,0 +1,31 @@ +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 +GP25,GPIO25 +GP26,GPIO26 +GP27,GPIO27 +GP28,GPIO28 +LED,GPIO25 +WL_GPIO0,EXT_GPIO0 +WL_GPIO1,EXT_GPIO1 +WL_GPIO2,EXT_GPIO2 diff --git a/ports/rp2/boards/RPI_PICO2/manifest.py b/ports/rp2/boards/RPI_PICO2/manifest.py new file mode 100644 index 0000000000000..fdae49fbf4be2 --- /dev/null +++ b/ports/rp2/boards/RPI_PICO2/manifest.py @@ -0,0 +1,7 @@ +# This file is only used if cyw43 is enabled +include("$(PORT_DIR)/boards/manifest.py") + +require("bundle-networking") + +# Bluetooth +require("aioble") diff --git a/ports/rp2/boards/RPI_PICO2/mpconfigboard.cmake b/ports/rp2/boards/RPI_PICO2/mpconfigboard.cmake index 48b6545aa3428..73dbc16d055bb 100644 --- a/ports/rp2/boards/RPI_PICO2/mpconfigboard.cmake +++ b/ports/rp2/boards/RPI_PICO2/mpconfigboard.cmake @@ -3,3 +3,9 @@ set(PICO_BOARD "pico2") # To change the gpio count for QFN-80 # set(PICO_NUM_GPIOS 48) + +if (PICO_CYW43_SUPPORTED) + include(enable_cyw43.cmake) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) + set(PICO_PINS_CSV_NAME pins_cyw43.csv) +endif() diff --git a/ports/rp2/boards/RPI_PICO2/mpconfigboard.h b/ports/rp2/boards/RPI_PICO2/mpconfigboard.h index 4b5eac6eb3ae3..927ea9619cdd3 100644 --- a/ports/rp2/boards/RPI_PICO2/mpconfigboard.h +++ b/ports/rp2/boards/RPI_PICO2/mpconfigboard.h @@ -1,3 +1,22 @@ // 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) + +#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 diff --git a/ports/rp2/boards/RPI_PICO2/pins_cyw43.csv b/ports/rp2/boards/RPI_PICO2/pins_cyw43.csv new file mode 100644 index 0000000000000..6459a8d4bfa20 --- /dev/null +++ b/ports/rp2/boards/RPI_PICO2/pins_cyw43.csv @@ -0,0 +1,31 @@ +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 +GP25,GPIO25 +GP26,GPIO26 +GP27,GPIO27 +GP28,GPIO28 +LED,GPIO25 +WL_GPIO0,EXT_GPIO0 +WL_GPIO1,EXT_GPIO1 +WL_GPIO2,EXT_GPIO2 From c3570b2f23578a6b86dcb3a4abb822c34ca4f302 Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Tue, 22 Oct 2024 18:01:34 +0100 Subject: [PATCH 5/5] rp2: Dynamic cyw43 config. Allow cyw43 pins and clock to be configured at runtime. Move cyw43 init code from main. e.g. wlan = network.WLAN(network.STA_IF, pin_on=2, pin_cs=3, pin_dat=4, pin_clock=5, div_int=3) ble = bluetooth.BLE(pin_on=2, pin_cs=3, pin_dat=4, pin_clock=5, div_int=3) ext_led = Pin('WL_GPIO0', Pin.OUT, pin_on=2, pin_cs=3, pin_dat=4, pin_clock=5, div_int=3) Signed-off-by: Peter Harper --- extmod/modbluetooth.c | 21 +++++-- extmod/network_cyw43.c | 27 +++++++- ports/rp2/CMakeLists.txt | 7 +++ ports/rp2/machine_pin.c | 31 +++++++--- ports/rp2/main.c | 26 -------- ports/rp2/mpconfigport.h | 37 +++++++++++ ports/rp2/mpnetworkport.c | 4 ++ ports/rp2/rp2_init_cyw43.c | 122 +++++++++++++++++++++++++++++++++++++ 8 files changed, 233 insertions(+), 42 deletions(-) create mode 100644 ports/rp2/rp2_init_cyw43.c diff --git a/extmod/modbluetooth.c b/extmod/modbluetooth.c index 7049c35dfdf56..5bcbc40ab76ab 100644 --- a/extmod/modbluetooth.c +++ b/extmod/modbluetooth.c @@ -257,11 +257,24 @@ MP_DEFINE_CONST_OBJ_TYPE( // Bluetooth object: General // ---------------------------------------------------------------------------- +// Allow the port to add extra parameters +#ifdef MICROPY_PY_BLUETOOTH_OBJ_INIT_ARGS +#define EXTRA_ARGS MICROPY_PY_BLUETOOTH_OBJ_INIT_ARGS +#else +#define EXTRA_ARGS +#endif + +MP_WEAK void bluetooth_ble_obj_init(mp_arg_val_t *args) { +} + static mp_obj_t bluetooth_ble_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - (void)type; - (void)n_args; - (void)n_kw; - (void)all_args; + const mp_arg_t allowed_args[] = { + EXTRA_ARGS + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + bluetooth_ble_obj_init(args); + if (MP_STATE_VM(bluetooth) == MP_OBJ_NULL) { mp_obj_bluetooth_ble_t *o = m_new0(mp_obj_bluetooth_ble_t, 1); o->base.type = &mp_type_bluetooth_ble; diff --git a/extmod/network_cyw43.c b/extmod/network_cyw43.c index 02b022cb81327..27cdf6be51e45 100644 --- a/extmod/network_cyw43.c +++ b/extmod/network_cyw43.c @@ -93,14 +93,35 @@ static void network_cyw43_print(const mp_print_t *print, mp_obj_t self_in, mp_pr ); } -static mp_obj_t network_cyw43_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, false); - if (n_args == 0 || mp_obj_get_int(args[0]) == MOD_NETWORK_STA_IF) { +// Allow the port to add extra parameters +#ifdef MICROPY_PY_NETWORK_CYW43_OBJ_INIT_ARGS +#define EXTRA_ARGS MICROPY_PY_NETWORK_CYW43_OBJ_INIT_ARGS +#else +#define EXTRA_ARGS +#endif + +MP_WEAK void network_cyw43_obj_init(mp_arg_val_t *args) { +} + +static mp_obj_t network_cyw43_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_interface, ARG_last }; + const mp_arg_t allowed_args[] = { + { MP_QSTR_interface, MP_ARG_INT, {.u_int = MOD_NETWORK_STA_IF} }, + EXTRA_ARGS + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args); + mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + network_cyw43_obj_init(args + ARG_last); + if (args[ARG_interface].u_int == MOD_NETWORK_STA_IF) { return MP_OBJ_FROM_PTR(&network_cyw43_wl_sta); } else { return MP_OBJ_FROM_PTR(&network_cyw43_wl_ap); } } +#undef EXTRA_ARGS static mp_obj_t network_cyw43_send_ethernet(mp_obj_t self_in, mp_obj_t buf_in) { network_cyw43_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 7390430591c84..63e7c943e5328 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -195,6 +195,12 @@ set(MICROPY_SOURCE_QSTR ${CMAKE_BINARY_DIR}/pins_${MICROPY_BOARD}.c ) +if (MICROPY_PY_NETWORK_CYW43) + list(APPEND MICROPY_SOURCE_QSTR + ${MICROPY_PORT_DIR}/rp2_init_cyw43.c + ) +endif() + set(PICO_SDK_COMPONENTS boot_bootrom_headers hardware_adc @@ -403,6 +409,7 @@ if (MICROPY_PY_NETWORK_CYW43) list(APPEND MICROPY_SOURCE_PORT machine_pin_cyw43.c + rp2_init_cyw43.c ) target_link_libraries(${MICROPY_TARGET} diff --git a/ports/rp2/machine_pin.c b/ports/rp2/machine_pin.c index 8ba0b44a684f7..1a12a21a8e7a2 100644 --- a/ports/rp2/machine_pin.c +++ b/ports/rp2/machine_pin.c @@ -242,17 +242,25 @@ static void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin mp_printf(print, ")"); } -enum { - ARG_mode, ARG_pull, ARG_value, ARG_alt -}; -static const mp_arg_t allowed_args[] = { - {MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, - {MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, - {MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, - {MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = GPIO_FUNC_SIO}}, -}; +// Allow the port to add extra parameters +#ifdef MICROPY_HW_PIN_EXT_OBJ_INIT_ARGS +#define EXTRA_ARGS MICROPY_HW_PIN_EXT_OBJ_INIT_ARGS +#else +#define EXTRA_ARGS +#endif + +MP_WEAK void machine_pin_ext_obj_init(mp_arg_val_t *args) { +} static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_mode, ARG_pull, ARG_value, ARG_alt, ARG_last }; + const mp_arg_t allowed_args[] = { + {MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + {MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + {MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, + {MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = GPIO_FUNC_SIO}}, + EXTRA_ARGS + }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -277,6 +285,10 @@ static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj); if (is_ext_pin(self)) { #if MICROPY_HW_PIN_EXT_COUNT + + // called in case the port needs some initialisation before using an external pin + machine_pin_ext_obj_init(args + ARG_last); + // The regular Pins are const, but the external pins are mutable. machine_pin_obj_t *mutable_self = (machine_pin_obj_t *)self; machine_pin_ext_config(mutable_self, mode, value); @@ -312,6 +324,7 @@ static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_ } return mp_const_none; } +#undef EXTRA_ARGS // constructor(id, ...) mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { diff --git a/ports/rp2/main.c b/ports/rp2/main.c index d6bf448267152..0180af04afc23 100644 --- a/ports/rp2/main.c +++ b/ports/rp2/main.c @@ -49,15 +49,11 @@ #include "pico/stdlib.h" #include "pico/binary_info.h" -#include "pico/unique_id.h" #include "hardware/structs/rosc.h" #if MICROPY_PY_LWIP #include "lwip/init.h" #include "lwip/apps/mdns.h" #endif -#if MICROPY_PY_NETWORK_CYW43 -#include "lib/cyw43-driver/src/cyw43.h" -#endif #if PICO_RP2040 #include "RP2040.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk #elif PICO_RP2350 && PICO_ARM @@ -132,28 +128,6 @@ int main(int argc, char **argv) { #endif #endif - #if MICROPY_PY_NETWORK_CYW43 || MICROPY_PY_BLUETOOTH_CYW43 - { - cyw43_init(&cyw43_state); - cyw43_irq_init(); - cyw43_post_poll_hook(); // enable the irq - uint8_t buf[8]; - memcpy(&buf[0], "PICO", 4); - - // MAC isn't loaded from OTP yet, so use unique id to generate the default AP ssid. - const char hexchr[16] = "0123456789ABCDEF"; - pico_unique_board_id_t pid; - pico_get_unique_board_id(&pid); - buf[4] = hexchr[pid.id[7] >> 4]; - buf[5] = hexchr[pid.id[6] & 0xf]; - buf[6] = hexchr[pid.id[5] >> 4]; - buf[7] = hexchr[pid.id[4] & 0xf]; - cyw43_wifi_ap_set_ssid(&cyw43_state, 8, buf); - cyw43_wifi_ap_set_auth(&cyw43_state, CYW43_AUTH_WPA2_AES_PSK); - cyw43_wifi_ap_set_password(&cyw43_state, 8, (const uint8_t *)"picoW123"); - } - #endif - // Hook for setting up anything that can wait until after other hardware features are initialised. MICROPY_BOARD_EARLY_INIT(); diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 8f4e846ba13bb..c74e45b583fd2 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -316,3 +316,40 @@ extern void lwip_lock_release(void); #ifndef MICROPY_BOARD_END_SOFT_RESET #define MICROPY_BOARD_END_SOFT_RESET() #endif + +#if MICROPY_PY_NETWORK_CYW43 +// Array of allowed arguments needed to initialise cyw43 pins +#if CYW43_PIN_WL_DYNAMIC +#define CYW43_INIT_PINS_ALLOWED_ARGS \ + { MP_QSTR_pin_on, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, \ + { MP_QSTR_pin_out, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, \ + { MP_QSTR_pin_in, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, \ + { MP_QSTR_pin_wake, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, \ + { MP_QSTR_pin_clock, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, \ + { MP_QSTR_pin_cs, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, \ + { MP_QSTR_pin_dat, MP_ARG_KW_ONLY | MP_ARG_OBJ, { .u_obj = MP_OBJ_NULL } }, +#else +#define CYW43_INIT_PINS_ALLOWED_ARGS +#endif // CYW43_PIN_WL_DYNAMIC + +// Array of allowed arguments needed to initialise cyw43 pio clock +#if CYW43_PIO_CLOCK_DIV_DYNAMIC +#define CYW43_INIT_CLOCK_ALLOWED_ARGS \ + { MP_QSTR_div_int, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = 0 } }, \ + { MP_QSTR_div_frac, MP_ARG_KW_ONLY | MP_ARG_INT, { .u_int = 0 } }, +#else +#define CYW43_INIT_CLOCK_ALLOWED_ARGS +#endif // CYW43_PIO_CLOCK_DIV_DYNAMIC + +// Array of allowed arguments needed to initialise cyw43 +#define MICROPY_HW_PIN_EXT_OBJ_INIT_ARGS \ + CYW43_INIT_PINS_ALLOWED_ARGS \ + CYW43_INIT_CLOCK_ALLOWED_ARGS +#define MICROPY_PY_NETWORK_CYW43_OBJ_INIT_ARGS \ + CYW43_INIT_PINS_ALLOWED_ARGS \ + CYW43_INIT_CLOCK_ALLOWED_ARGS +#define MICROPY_PY_BLUETOOTH_OBJ_INIT_ARGS \ + CYW43_INIT_PINS_ALLOWED_ARGS \ + CYW43_INIT_CLOCK_ALLOWED_ARGS + +#endif // MICROPY_PY_NETWORK_CYW43 diff --git a/ports/rp2/mpnetworkport.c b/ports/rp2/mpnetworkport.c index af2cabb3bff0f..8c919480347fb 100644 --- a/ports/rp2/mpnetworkport.c +++ b/ports/rp2/mpnetworkport.c @@ -81,6 +81,10 @@ void cyw43_irq_init(void) { #endif } +void cyw43_irq_deinit(void) { + gpio_remove_raw_irq_handler(CYW43_PIN_WL_HOST_WAKE, gpio_irq_handler); +} + void cyw43_post_poll_hook(void) { cyw43_has_pending = 0; gpio_set_irq_enabled(CYW43_PIN_WL_HOST_WAKE, CYW43_IRQ_LEVEL, true); diff --git a/ports/rp2/rp2_init_cyw43.c b/ports/rp2/rp2_init_cyw43.c new file mode 100644 index 0000000000000..27254de87e67a --- /dev/null +++ b/ports/rp2/rp2_init_cyw43.c @@ -0,0 +1,122 @@ +#include "py/runtime.h" +#include "extmod/network_cyw43.h" +#include "extmod/modnetwork.h" +#include "lib/cyw43-driver/src/cyw43.h" +#include "pico/unique_id.h" + +void cyw43_irq_deinit(void); +void cyw43_irq_init(void); + +#if CYW43_PIN_WL_DYNAMIC +// Defined in cyw43_bus_pio_spi.c +int cyw43_set_pins_wl(uint pins[CYW43_PIN_INDEX_WL_COUNT]); +#endif + +#if CYW43_PIO_CLOCK_DIV_DYNAMIC +// Defined in cyw43_bus_pio_spi.c +void cyw43_set_pio_clkdiv_int_frac8(uint32_t clock_div_int, uint8_t clock_div_frac8); +#endif + +// enums for the arguments needed to initialise cyw43 +#define CYW43_INIT_ARG_ENUM \ + ARG_pin_on, ARG_pin_out, ARG_pin_in, ARG_pin_wake, ARG_pin_clock, ARG_pin_cs, ARG_pin_dat, ARG_div_int, ARG_div_frac + +// Builds an array of pins needed by cyw43_set_pins_wl from function arguments +// order defined by cyw43_pin_index_t +#if CYW43_PIN_WL_DYNAMIC +#define SET_CYW43_PIN_ARG(ARG_ENUM, DEFAULT) args[ARG_ENUM].u_obj != MP_OBJ_NULL ? mp_hal_get_pin_obj(args[ARG_ENUM].u_obj) : (DEFAULT) +#define CYW43_PIN_ARRAY \ + SET_CYW43_PIN_ARG(ARG_pin_on, NUM_BANK0_GPIOS), \ + SET_CYW43_PIN_ARG(ARG_pin_out, SET_CYW43_PIN_ARG(ARG_pin_dat, NUM_BANK0_GPIOS)), \ + SET_CYW43_PIN_ARG(ARG_pin_in, SET_CYW43_PIN_ARG(ARG_pin_dat, NUM_BANK0_GPIOS)), \ + SET_CYW43_PIN_ARG(ARG_pin_wake, SET_CYW43_PIN_ARG(ARG_pin_dat, NUM_BANK0_GPIOS)), \ + SET_CYW43_PIN_ARG(ARG_pin_clock, NUM_BANK0_GPIOS), \ + SET_CYW43_PIN_ARG(ARG_pin_cs, NUM_BANK0_GPIOS), +#else +#define CYW43_PIN_ARRAY 0 +#endif + +static void rp2_cyw43_init(uint *pins, uint32_t clock_div_int, uint8_t clock_div_frac8) { + static bool cyw43_init_done; + if (!cyw43_init_done) { + cyw43_init(&cyw43_state); + cyw43_irq_init(); + cyw43_post_poll_hook(); // enable the irq + cyw43_init_done = true; + uint8_t buf[8]; + memcpy(&buf[0], "PICO", 4); + + // Use unique id to generate the default AP ssid. + const char hexchr[16] = "0123456789ABCDEF"; + pico_unique_board_id_t pid; + pico_get_unique_board_id(&pid); + buf[4] = hexchr[pid.id[7] >> 4]; + buf[5] = hexchr[pid.id[6] & 0xf]; + buf[6] = hexchr[pid.id[5] >> 4]; + buf[7] = hexchr[pid.id[4] & 0xf]; + cyw43_wifi_ap_set_ssid(&cyw43_state, 8, buf); + cyw43_wifi_ap_set_auth(&cyw43_state, CYW43_AUTH_WPA2_AES_PSK); + cyw43_wifi_ap_set_password(&cyw43_state, 8, (const uint8_t *)"picoW123"); + } + + #if CYW43_PIN_WL_DYNAMIC + assert(pins); + // Set unspecified pins + for (int i = 0; i < CYW43_PIN_INDEX_WL_COUNT; i++) { + if (pins[i] == NUM_BANK0_GPIOS) { + pins[i] = cyw43_get_pin_wl(i); + } + } + // check if the pins have actually changed + for (int i = 0; i < CYW43_PIN_INDEX_WL_COUNT; i++) { + if (pins[i] != cyw43_get_pin_wl(i)) { + // re-initialise cyw43. This can fail if the pins are invalid (gpio base is incompatible) or the pio is in use + int error = cyw43_set_pins_wl(pins); + if (error == PICO_ERROR_RESOURCE_IN_USE) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("wifi in use")); + } else if (error != PICO_OK) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("wifi pins invalid")); + } + cyw43_irq_deinit(); + cyw43_irq_init(); + break; + } + } + #endif // CYW43_PIN_WL_DYNAMIC + #if CYW43_PIO_CLOCK_DIV_DYNAMIC + // set the pio clock divisor - has no effect if the pio is in use + if (clock_div_int > 0) { + cyw43_set_pio_clkdiv_int_frac8(clock_div_int, clock_div_frac8); + } + #endif // CYW43_PIO_CLOCK_DIV_DYNAMIC +} + +static void cyw43_obj_init(mp_arg_val_t *args) { + assert(args); + enum { CYW43_INIT_ARG_ENUM }; + uint pins[] = { + CYW43_PIN_ARRAY + }; + + uint32_t clock_div_int = 0; + uint8_t clock_div_frac8 = 0; + #if CYW43_PIO_CLOCK_DIV_DYNAMIC + clock_div_int = args[ARG_div_int].u_int; + clock_div_frac8 = (uint8_t)args[ARG_div_frac].u_int; + #endif + + rp2_cyw43_init(pins, clock_div_int, clock_div_frac8); +} + +void network_cyw43_obj_init(mp_arg_val_t *args) { + cyw43_obj_init(args); +} + +void bluetooth_ble_obj_init(mp_arg_val_t *args) { + cyw43_obj_init(args); +} + +// perform extra initialisation in machine_pin_obj_init_helper +void machine_pin_ext_obj_init(mp_arg_val_t *args) { + cyw43_obj_init(args); +}