kopia lustrzana https://github.com/pimoroni/pimoroni-pico
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
rodzic
898e2a1b32
commit
f7781e2696
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Ładowanie…
Reference in New Issue