2323
2424#include "pico/stdlib.h"
2525#include "pico_servo.h"
26+ #include "hardware/gpio.h"
27+ #include "hardware/sync.h"
28+ #include "hardware/structs/ioqspi.h"
29+ #include "hardware/structs/sio.h"
2630#include <stdio.h>
2731
2832#define A 2
2933#define B 12
3034
35+ bool __no_inline_not_in_flash_func (get_bootsel_button )() {
36+ const uint CS_PIN_INDEX = 1 ;
37+
38+ // Must disable interrupts, as interrupt handlers may be in flash, and we
39+ // are about to temporarily disable flash access!
40+ uint32_t flags = save_and_disable_interrupts ();
41+
42+ // Set chip select to Hi-Z
43+ hw_write_masked (& ioqspi_hw -> io [CS_PIN_INDEX ].ctrl ,
44+ GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB ,
45+ IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS );
46+
47+ // Note we can't call into any sleep functions in flash right now
48+ for (volatile int i = 0 ; i < 1000 ; ++ i );
49+
50+ // The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
51+ // Note the button pulls the pin *low* when pressed.
52+ bool button_state = !(sio_hw -> gpio_hi_in & (1u << CS_PIN_INDEX ));
53+
54+ // Need to restore the state of chip select, else we are going to have a
55+ // bad time when we return to code in flash!
56+ hw_write_masked (& ioqspi_hw -> io [CS_PIN_INDEX ].ctrl ,
57+ GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB ,
58+ IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS );
59+
60+ restore_interrupts (flags );
61+
62+ return button_state ;
63+ }
64+
3165int main ()
3266{
3367 stdio_init_all ();
@@ -40,6 +74,10 @@ int main()
4074
4175 while (1 )
4276 {
77+ if (!get_bootsel_button ())
78+ {
79+ continue ;
80+ }
4381 servo_move_to (A , 0 );
4482 servo_move_to (B , 0 );
4583 sleep_ms (500 );
@@ -48,4 +86,4 @@ int main()
4886 sleep_ms (500 );
4987 }
5088 return 0 ;
51- }
89+ }
0 commit comments