Skip to content

Commit e4fe1fc

Browse files
Merge pull request earlephilhower#56 from earlephilhower/bootsel
Add BOOTSEL, allowing BOOTSEL use as a button
2 parents 481ee1c + 1124455 commit e4fe1fc

File tree

5 files changed

+106
-1
lines changed

5 files changed

+106
-1
lines changed

cores/rp2040/Arduino.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ void delay(unsigned long);
5959
void delayMicroseconds(unsigned int us);
6060
unsigned long millis();
6161

62-
6362
#ifdef __cplusplus
6463
} // extern "C"
6564
#endif
@@ -68,6 +67,7 @@ unsigned long millis();
6867
#include "SerialUSB.h"
6968
#include "SerialUART.h"
7069
#include "RP2040.h"
70+
#include "Bootsel.h"
7171

7272
// Template which will evaluate at *compile time* to a single 32b number
7373
// with the specified bits set.

cores/rp2040/Bootsel.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
#include <Arduino.h>
7+
#include "pico/stdlib.h"
8+
#include "hardware/gpio.h"
9+
#include "hardware/sync.h"
10+
#include "hardware/structs/ioqspi.h"
11+
#include "hardware/structs/sio.h"
12+
13+
// This example blinks the Pico LED when the BOOTSEL button is pressed.
14+
//
15+
// Picoboard has a button attached to the flash CS pin, which the bootrom
16+
// checks, and jumps straight to the USB bootcode if the button is pressed
17+
// (pulling flash CS low). We can check this pin in by jumping to some code in
18+
// SRAM (so that the XIP interface is not required), floating the flash CS
19+
// pin, and observing whether it is pulled low.
20+
//
21+
// This doesn't work if others are trying to access flash at the same time,
22+
// e.g. XIP streamer, or the other core.
23+
24+
static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
25+
const uint CS_PIN_INDEX = 1;
26+
27+
// Must disable interrupts, as interrupt handlers may be in flash, and we
28+
// are about to temporarily disable flash access!
29+
uint32_t flags = save_and_disable_interrupts();
30+
31+
// Set chip select to Hi-Z
32+
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
33+
GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
34+
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
35+
36+
// Note we can't call into any sleep functions in flash right now
37+
for (volatile int i = 0; i < 1000; ++i);
38+
39+
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
40+
// Note the button pulls the pin *low* when pressed.
41+
bool button_state = !(sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX));
42+
43+
// Need to restore the state of chip select, else we are going to have a
44+
// bad time when we return to code in flash!
45+
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
46+
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
47+
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
48+
49+
restore_interrupts(flags);
50+
51+
return button_state;
52+
}
53+
54+
__Bootsel::operator bool() {
55+
return get_bootsel_button();
56+
}
57+
58+
__Bootsel BOOTSEL;

cores/rp2040/Bootsel.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Simple BOOTSEL reader object
3+
*
4+
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#pragma once
22+
23+
class __Bootsel {
24+
public:
25+
__Bootsel() { }
26+
operator bool();
27+
};
28+
29+
extern __Bootsel BOOTSEL;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* Simple sketch to do something on a BOOTSEL press */
2+
/* Releaed into the public domain */
3+
4+
void setup() {
5+
Serial.begin(115200);
6+
delay(5000);
7+
Serial.println("I dare you to hit the BOOTSEL button...");
8+
}
9+
10+
int c = 0;
11+
void loop() {
12+
if (BOOTSEL) {
13+
Serial.printf("\a\aYou pressed BOOTSEL %d times!\n", ++c);
14+
// Wait for BOOTSEL to be released
15+
while (BOOTSEL) { delay(1); }
16+
}
17+
}

libraries/rp2040/keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
BOOTSEL KEYWORD1

0 commit comments

Comments
 (0)