Wakeup: Fixup crt0.S and runtime.c.

Assert the VSYS_EN pin before copying SRAM and zeroing BSS.

Saves ~142ms of startup time before GPIO input is latched and pin is asserted.
feature/wakeup
Phil Howard 2022-08-04 12:16:08 +01:00
rodzic 898e2a1b32
commit f7781e2696
6 zmienionych plików z 164 dodań i 7 usunięć

Wyświetl plik

@ -13,4 +13,9 @@ fi
if [[ ! -d "$MPY_DIR/boards/$BOARD" ]] && [[ -d "$FIXUP_DIR/$NAME/$BOARD/" ]]; then
echo "Missing board dir. Copying: $FIXUP_DIR/$NAME/$BOARD/ to $MPY_DIR/boards/"
cp -r "$FIXUP_DIR/$NAME/$BOARD/" "$MPY_DIR/boards/"
fi
if [[ -f "$FIXUP_DIR/$NAME/fixup.sh" ]]; then
echo "Running custom fixup[.sh"
bash "$FIXUP_DIR/$NAME/fixup.sh" "$FIXUP_DIR/$NAME" "$MPY_DIR"
fi

Wyświetl plik

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

Wyświetl plik

@ -0,0 +1,136 @@
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 << 2) | (0b1 << 6))
+#endif
+
+// Direction
+#ifndef PICO_WAKEUP_PIN_DIR
+#define PICO_WAKEUP_PIN_DIR ((0b1 << 2) | (0b1 << 6))
+#endif
+
+// Value
+#ifndef PICO_WAKEUP_PIN_VALUE
+#define PICO_WAKEUP_PIN_VALUE ((0b1 << 2) | (0b1 << 6))
+#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..80367da 100644
--- a/src/rp2_common/pico_standard_link/crt0.S
+++ b/src/rp2_common/pico_standard_link/crt0.S
@@ -9,6 +9,7 @@
#include "hardware/regs/addressmap.h"
#include "hardware/regs/sio.h"
#include "pico/binary_info/defs.h"
+#include "hardware/regs/resets.h"
#ifdef NDEBUG
#ifndef COLLAPSE_IRQS
@@ -225,6 +226,17 @@ _reset_handler:
cmp r0, #0
bne hold_non_core0_in_bootrom
+ 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 +263,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 +330,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 +374,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

Wyświetl plik

@ -5,7 +5,7 @@ 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}/${MOD_NAME}.S
#${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.S
)
target_include_directories(usermod_${MOD_NAME} INTERFACE

Wyświetl plik

@ -6,7 +6,7 @@
#include "pico/asm_helper.S"
// This macro tells the pico runtime to call __wakeup_gpio_latch very early in boot
__pre_init __wakeup_gpio_latch, 00001
__pre_init __wakeup_gpio_latch, 00000
.section .data.wakeup_gpio_latch
.global wakeup_gpio_state
@ -23,4 +23,14 @@ __wakeup_gpio_latch:
ldr r1, [r3, 4] // Load GPIO state (0xd0000004) into r1
ldr r2, =wakeup_gpio_state // Load output var addr into r2
str r1, [r2] // Store r1 to 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 // https://github.com/raspberrypi/pico-sdk/blob/2e6142b15b8a75c1227dd3edbe839193b2bf9041/src/rp2_common/hardware_gpio/include/hardware/gpio.h#L96
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 // Return

Wyświetl plik

@ -1,16 +1,16 @@
#include "hardware/gpio.h"
#include "wakeup.config.hpp"
extern uint32_t wakeup_gpio_state;
extern uint32_t runtime_wakeup_gpio_state;
namespace {
struct Wakeup {
public:
Wakeup() {
// Assert wakeup pins (indicator LEDs, VSYS hold etc)
gpio_init_mask(WAKEUP_PIN_MASK);
gpio_set_dir_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_DIR);
gpio_put_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_VALUE);
//gpio_init_mask(WAKEUP_PIN_MASK);
//gpio_set_dir_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_DIR);
//gpio_put_masked(WAKEUP_PIN_MASK, WAKEUP_PIN_VALUE);
#if WAKEUP_HAS_RTC==1
// Set up RTC I2C pins and send reset command
@ -40,7 +40,7 @@ extern "C" {
#include "wakeup.h"
mp_obj_t Wakeup_get_gpio_state() {
return mp_obj_new_int(wakeup_gpio_state);
return mp_obj_new_int(runtime_wakeup_gpio_state);
}
}