mirror of
https://github.com/micropython/micropython.git
synced 2026-01-05 19:50:30 +01:00
rp2/modrp2: Disable other core, shorten delay to 8us in bootsel_button.
This function seems to work fine in multi-core applications now. The delay is now in units of microseconds instead of depending on the clock speed, and is adjustable by board configuration headers. Also added documentation.
This commit is contained in:
committed by
Damien George
parent
673957b643
commit
f80d040c03
@@ -41,49 +41,43 @@
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mod_network_country_obj);
|
||||
#endif
|
||||
|
||||
// Picoboard has a button attached to the flash CS pin, which the bootrom
|
||||
// checks, and jumps straight to the USB bootcode if the button is pressed
|
||||
// (pulling flash CS low). We can check this pin in by jumping to some code in
|
||||
// SRAM (so that the XIP interface is not required), floating the flash CS
|
||||
// pin, and observing whether it is pulled low.
|
||||
//
|
||||
// This doesn't work if others are trying to access flash at the same time,
|
||||
// e.g. XIP streamer, or the other core.
|
||||
// Improved version of
|
||||
// https://github.com/raspberrypi/pico-examples/blob/master/picoboard/button/button.c
|
||||
|
||||
bool __no_inline_not_in_flash_func(get_bootsel_button)() {
|
||||
STATIC bool __no_inline_not_in_flash_func(bootsel_button)(void) {
|
||||
const uint CS_PIN_INDEX = 1;
|
||||
|
||||
// Must disable interrupts, as interrupt handlers may be in flash, and we
|
||||
// are about to temporarily disable flash access!
|
||||
uint32_t flags = save_and_disable_interrupts();
|
||||
// Disable interrupts and the other core since they might be
|
||||
// executing code from flash and we are about to temporarily
|
||||
// disable flash access.
|
||||
mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||
|
||||
// Set chip select to Hi-Z
|
||||
// Set the CS pin to high impedance.
|
||||
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||
(GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB),
|
||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||
|
||||
// Note we can't call into any sleep functions in flash right now
|
||||
for (volatile int i = 0; i < 1000; ++i) {;
|
||||
// Delay without calling any functions in flash.
|
||||
uint32_t start = timer_hw->timerawl;
|
||||
while ((uint32_t)(timer_hw->timerawl - start) <= MICROPY_HW_BOOTSEL_DELAY_US) {
|
||||
;
|
||||
}
|
||||
|
||||
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
|
||||
// Note the button pulls the pin *low* when pressed.
|
||||
bool button_state = !(sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX));
|
||||
// The button pulls the QSPI_SS pin *low* when pressed.
|
||||
bool button_state = !(sio_hw->gpio_hi_in & (1 << CS_PIN_INDEX));
|
||||
|
||||
// Need to restore the state of chip select, else we are going to have a
|
||||
// bad time when we return to code in flash!
|
||||
// Restore the QSPI_SS pin so we can use flash again.
|
||||
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
|
||||
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
|
||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||
(GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB),
|
||||
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
|
||||
|
||||
restore_interrupts(flags);
|
||||
MICROPY_END_ATOMIC_SECTION(atomic_state);
|
||||
|
||||
return button_state;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t rp2_bootsel_button(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(get_bootsel_button());
|
||||
return MP_OBJ_NEW_SMALL_INT(bootsel_button());
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(rp2_bootsel_button_obj, rp2_bootsel_button);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user