Add BOOTSEL, allowing BOOTSEL use as a button
Since every board has a bootsel button, allow end users to read its state with a simple `if (BOOTSEL)`. Uses code from the pico-examples.
This commit is contained in:
parent
481ee1c9cf
commit
1124455627
5 changed files with 106 additions and 1 deletions
|
|
@ -59,7 +59,6 @@ void delay(unsigned long);
|
|||
void delayMicroseconds(unsigned int us);
|
||||
unsigned long millis();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
@ -68,6 +67,7 @@ unsigned long millis();
|
|||
#include "SerialUSB.h"
|
||||
#include "SerialUART.h"
|
||||
#include "RP2040.h"
|
||||
#include "Bootsel.h"
|
||||
|
||||
// Template which will evaluate at *compile time* to a single 32b number
|
||||
// with the specified bits set.
|
||||
|
|
|
|||
58
cores/rp2040/Bootsel.cpp
Normal file
58
cores/rp2040/Bootsel.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "hardware/structs/ioqspi.h"
|
||||
#include "hardware/structs/sio.h"
|
||||
|
||||
// This example blinks the Pico LED when the BOOTSEL button is pressed.
|
||||
//
|
||||
// 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.
|
||||
|
||||
static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
|
||||
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();
|
||||
|
||||
// Set chip select to Hi-Z
|
||||
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);
|
||||
|
||||
// Note we can't call into any sleep functions in flash right now
|
||||
for (volatile int i = 0; i < 1000; ++i);
|
||||
|
||||
// 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));
|
||||
|
||||
// Need to restore the state of chip select, else we are going to have a
|
||||
// bad time when we return to code in flash!
|
||||
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);
|
||||
|
||||
restore_interrupts(flags);
|
||||
|
||||
return button_state;
|
||||
}
|
||||
|
||||
__Bootsel::operator bool() {
|
||||
return get_bootsel_button();
|
||||
}
|
||||
|
||||
__Bootsel BOOTSEL;
|
||||
29
cores/rp2040/Bootsel.h
Normal file
29
cores/rp2040/Bootsel.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Simple BOOTSEL reader object
|
||||
*
|
||||
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class __Bootsel {
|
||||
public:
|
||||
__Bootsel() { }
|
||||
operator bool();
|
||||
};
|
||||
|
||||
extern __Bootsel BOOTSEL;
|
||||
17
libraries/rp2040/examples/Bootsel/Bootsel.ino
Normal file
17
libraries/rp2040/examples/Bootsel/Bootsel.ino
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* Simple sketch to do something on a BOOTSEL press */
|
||||
/* Releaed into the public domain */
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(5000);
|
||||
Serial.println("I dare you to hit the BOOTSEL button...");
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
void loop() {
|
||||
if (BOOTSEL) {
|
||||
Serial.printf("\a\aYou pressed BOOTSEL %d times!\n", ++c);
|
||||
// Wait for BOOTSEL to be released
|
||||
while (BOOTSEL) { delay(1); }
|
||||
}
|
||||
}
|
||||
1
libraries/rp2040/keywords.txt
Normal file
1
libraries/rp2040/keywords.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
BOOTSEL KEYWORD1
|
||||
Loading…
Reference in a new issue