From 42a29dbe7b35801e4125a56c48644a6988e1d147 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Mon, 8 Aug 2022 11:21:59 +0100 Subject: [PATCH] Wakeup: Port to Badger 2040. --- .github/workflows/micropython-badger2040.yml | 2 +- micropython/_board/badger2040/fixup.sh | 6 + .../_board/badger2040/wakeup_gpio.patch | 143 ++++++++++++++++++ micropython/modules/badger2040/badger2040.cpp | 11 +- micropython/modules/badger2040/badgerinit.S | 38 ----- .../modules/badger2040/micropython.cmake | 1 - 6 files changed, 156 insertions(+), 45 deletions(-) create mode 100644 micropython/_board/badger2040/fixup.sh create mode 100644 micropython/_board/badger2040/wakeup_gpio.patch delete mode 100644 micropython/modules/badger2040/badgerinit.S diff --git a/.github/workflows/micropython-badger2040.yml b/.github/workflows/micropython-badger2040.yml index 2144cc4a..cdd8bfe2 100644 --- a/.github/workflows/micropython-badger2040.yml +++ b/.github/workflows/micropython-badger2040.yml @@ -7,7 +7,7 @@ on: types: [created] env: - MICROPYTHON_VERSION: v1.19 + MICROPYTHON_VERSION: 9dfabcd6d3d080aced888e8474e921f11dc979bb BOARD_TYPE: PIMORONI_BADGER2040 # MicroPython version will be contained in github.event.release.tag_name for releases RELEASE_FILE: pimoroni-badger2040-${{github.event.release.tag_name || github.sha}}-micropython diff --git a/micropython/_board/badger2040/fixup.sh b/micropython/_board/badger2040/fixup.sh new file mode 100644 index 00000000..6acb551d --- /dev/null +++ b/micropython/_board/badger2040/fixup.sh @@ -0,0 +1,6 @@ +SRC_DIR=$1 +DST_DIR=$2 + +echo "Applying wakeup_gpio.patch" +cd "$DST_DIR/../../lib/pico-sdk" +git apply "$SRC_DIR/wakeup_gpio.patch" \ No newline at end of file diff --git a/micropython/_board/badger2040/wakeup_gpio.patch b/micropython/_board/badger2040/wakeup_gpio.patch new file mode 100644 index 00000000..abaef7f0 --- /dev/null +++ b/micropython/_board/badger2040/wakeup_gpio.patch @@ -0,0 +1,143 @@ +diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c +index 70dd3bb..b8c1ed0 100644 +--- a/src/rp2_common/pico_runtime/runtime.c ++++ b/src/rp2_common/pico_runtime/runtime.c +@@ -17,6 +17,7 @@ + #include "hardware/clocks.h" + #include "hardware/irq.h" + #include "hardware/resets.h" ++#include "hardware/gpio.h" + + #include "pico/mutex.h" + #include "pico/time.h" +@@ -32,6 +33,21 @@ + #include "pico/bootrom.h" + #endif + ++// Pins to toggle on wakeup ++#ifndef PICO_WAKEUP_PIN_MASK ++#define PICO_WAKEUP_PIN_MASK ((0b1 << 10) | (0b1 << 25)) ++#endif ++ ++// Direction ++#ifndef PICO_WAKEUP_PIN_DIR ++#define PICO_WAKEUP_PIN_DIR ((0b1 << 10) | (0b1 << 25)) ++#endif ++ ++// Value ++#ifndef PICO_WAKEUP_PIN_VALUE ++#define PICO_WAKEUP_PIN_VALUE ((0b1 << 10) | (0b1 << 25)) ++#endif ++ + extern char __StackLimit; /* Set by linker. */ + + uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[48]; +@@ -61,11 +77,18 @@ void runtime_install_stack_guard(void *stack_bottom) { + | 0x10000000; // XN = disable instruction fetch; no other bits means no permissions + } + +-void runtime_init(void) { ++void runtime_user_init(void) { ++ gpio_init_mask(PICO_WAKEUP_PIN_MASK); ++ gpio_set_dir_masked(PICO_WAKEUP_PIN_MASK, PICO_WAKEUP_PIN_DIR); ++ gpio_put_masked(PICO_WAKEUP_PIN_MASK, PICO_WAKEUP_PIN_VALUE); ++} ++ ++void runtime_reset_peripherals(void) { + // Reset all peripherals to put system into a known state, + // - except for QSPI pads and the XIP IO bank, as this is fatal if running from flash + // - and the PLLs, as this is fatal if clock muxing has not been reset on this boot + // - and USB, syscfg, as this disturbs USB-to-SWD on core 1 ++ + reset_block(~( + RESETS_RESET_IO_QSPI_BITS | + RESETS_RESET_PADS_QSPI_BITS | +@@ -86,7 +109,9 @@ void runtime_init(void) { + RESETS_RESET_UART1_BITS | + RESETS_RESET_USBCTRL_BITS + )); ++} + ++void runtime_init(void) { + // pre-init runs really early since we need it even for memcpy and divide! + // (basically anything in aeabi that uses bootrom) + +diff --git a/src/rp2_common/pico_standard_link/crt0.S b/src/rp2_common/pico_standard_link/crt0.S +index b2992f6..6091e70 100644 +--- a/src/rp2_common/pico_standard_link/crt0.S ++++ b/src/rp2_common/pico_standard_link/crt0.S +@@ -9,6 +9,8 @@ + #include "hardware/regs/addressmap.h" + #include "hardware/regs/sio.h" + #include "pico/binary_info/defs.h" ++#include "hardware/regs/resets.h" ++#include "hardware/regs/rosc.h" + + #ifdef NDEBUG + #ifndef COLLAPSE_IRQS +@@ -225,6 +227,23 @@ _reset_handler: + cmp r0, #0 + bne hold_non_core0_in_bootrom + ++ // Increase ROSC frequency to ~48MHz (range 14.4 - 96) ++ // Startup drops from ~160ms to ~32ms on Pico W MicroPython ++ ldr r0, =(ROSC_BASE + ROSC_DIV_OFFSET) ++ ldr r1, =0xaa2 ++ str r1, [r0] ++ ++ ldr r1, =runtime_reset_peripherals ++ blx r1 ++ ++ ldr r1, =runtime_user_init ++ blx r1 ++ ++ // Read GPIO state for front buttons and store ++ movs r3, 0xd0 // Load 0xd0 into r3 ++ lsls r3, r3, 24 // Shift left 24 to get 0xd0000000 ++ ldr r6, [r3, 4] // Load GPIO state (0xd0000004) into r6 ++ + // In a NO_FLASH binary, don't perform .data copy, since it's loaded + // in-place by the SRAM load. Still need to clear .bss + #if !PICO_NO_FLASH +@@ -251,6 +270,10 @@ bss_fill_test: + cmp r1, r2 + bne bss_fill_loop + ++ // runtime_wakeup_gpio_state gets zero init above ++ ldr r2, =runtime_wakeup_gpio_state // Load output var addr into r2 ++ str r6, [r2] // Store r6 to r2 ++ + platform_entry: // symbol for stack traces + // Use 32-bit jumps, in case these symbols are moved out of branch range + // (e.g. if main is in SRAM and crt0 in flash) +@@ -314,6 +337,19 @@ data_cpy_table: + runtime_init: + bx lr + ++.weak runtime_user_init ++.type runtime_user_init,%function ++.thumb_func ++runtime_user_init: ++ bx lr ++ ++.weak runtime_reset_peripherals ++.type runtime_reset_peripherals,%function ++.thumb_func ++runtime_reset_peripherals: ++ bx lr ++ ++ + // ---------------------------------------------------------------------------- + // If core 1 somehow gets into crt0 due to a spectacular VTOR mishap, we need to + // catch it and send back to the sleep-and-launch code in the bootrom. Shouldn't +@@ -345,3 +381,9 @@ __get_current_exception: + .align 2 + .equ HeapSize, PICO_HEAP_SIZE + .space HeapSize ++ ++.section .data._reset_handler ++.global runtime_wakeup_gpio_state ++.align 4 ++runtime_wakeup_gpio_state: ++.word 0x00000000 +\ No newline at end of file diff --git a/micropython/modules/badger2040/badger2040.cpp b/micropython/modules/badger2040/badger2040.cpp index 55acd0a9..b6577e45 100644 --- a/micropython/modules/badger2040/badger2040.cpp +++ b/micropython/modules/badger2040/badger2040.cpp @@ -9,20 +9,21 @@ extern "C" { #include "py/builtin.h" #include "py/mpthread.h" -extern uint32_t badger_buttons_on_wake; +extern uint32_t runtime_wakeup_gpio_state; +const uint32_t BUTTON_MASK = 0b11111 << 11; static bool _Badger2040_wake_state_any() { - return badger_buttons_on_wake > 0; + return (runtime_wakeup_gpio_state & BUTTON_MASK) > 0; } static bool _Badger2040_wake_state_get(uint32_t pin) { - return badger_buttons_on_wake & (0b1 << pin); + return runtime_wakeup_gpio_state & BUTTON_MASK & (0b1 << pin); } static bool _Badger2040_wake_state_get_once(uint32_t pin) { uint32_t mask = 0b1 << pin; - bool value = badger_buttons_on_wake & mask; - badger_buttons_on_wake &= ~mask; + bool value = runtime_wakeup_gpio_state & BUTTON_MASK & mask; + runtime_wakeup_gpio_state &= ~mask; return value; } diff --git a/micropython/modules/badger2040/badgerinit.S b/micropython/modules/badger2040/badgerinit.S deleted file mode 100644 index 82142929..00000000 --- a/micropython/modules/badger2040/badgerinit.S +++ /dev/null @@ -1,38 +0,0 @@ - -.syntax unified -.cpu cortex-m0plus -.thumb - -#include "pico/asm_helper.S" - -// This macro tells the pico runtime to call __badger_init very early in boot -__pre_init __badger_init, 00003 - -.section .data.badger_init -.global badger_buttons_on_wake -.align 4 -badger_buttons_on_wake: -.word 0x00000000 - -.section .text -.thumb_func -__badger_init: - // Read GPIO state for front buttons and store - movs r3, 0xd0 - lsls r3, r3, 24 - ldr r1, [r3, 4] // Read all GPIOs - movs r2, 0b11111 // Mask the front buttons (pins 15-11) - lsls r2, 11 - ands r1, r1, r2 - ldr r2, =badger_buttons_on_wake - str r1, [r2] - - // Enable 3v3 pin on the badger - ldr r1, =0x40014054 // GPIO control register 10 - movs r2, 5 // SIO function - str r2, [r1] // Set Enable 3v3 to SIO - str r2, [r1, 120] // Also set LED (25) to SIO - ldr r2, =0x02000400 // Pins 25 and 10 - str r2, [r3, 36] // Enable pins out - str r2, [r3, 20] // Set pins high - bx lr diff --git a/micropython/modules/badger2040/micropython.cmake b/micropython/modules/badger2040/micropython.cmake index 2bbe2bf4..ded85199 100644 --- a/micropython/modules/badger2040/micropython.cmake +++ b/micropython/modules/badger2040/micropython.cmake @@ -5,7 +5,6 @@ add_library(usermod_${MOD_NAME} INTERFACE) target_sources(usermod_${MOD_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.cpp - ${CMAKE_CURRENT_LIST_DIR}/badgerinit.S ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/badger2040/badger2040.cpp ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/uc8151_legacy/uc8151_legacy.cpp )