|
From 348917565bd17f2941e3626cd944ff6e55d053cc Mon Sep 17 00:00:00 2001 |
|
From: Jeff Epler <[email protected]> |
|
Date: Fri, 12 Feb 2021 12:07:47 -0600 |
|
Subject: [PATCH] WIP allow reading bootsel |
|
|
|
!!! it's probably broekn !!! |
|
--- |
|
.../common-hal/digitalio/DigitalInOut.c | 52 ++++++++++++++++++- |
|
.../common-hal/microcontroller/Pin.c | 16 +++++- |
|
.../common-hal/microcontroller/__init__.c | 1 + |
|
.../common-hal/microcontroller/__init__.h | 2 +- |
|
ports/raspberrypi/peripherals/pins.c | 1 + |
|
ports/raspberrypi/peripherals/pins.h | 1 + |
|
6 files changed, 70 insertions(+), 3 deletions(-) |
|
|
|
diff --git a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c |
|
index b0bc1b96e..07d49083c 100644 |
|
--- a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c |
|
+++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c |
|
@@ -32,9 +32,12 @@ |
|
|
|
#include "common-hal/microcontroller/Pin.h" |
|
#include "shared-bindings/digitalio/DigitalInOut.h" |
|
+#include "shared-bindings/microcontroller/__init__.h" |
|
#include "supervisor/shared/translate.h" |
|
|
|
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" |
|
+#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" |
|
+#include "hardware/regs/io_qspi.h" |
|
|
|
digitalinout_result_t common_hal_digitalio_digitalinout_construct( |
|
digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { |
|
@@ -66,6 +69,13 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self |
|
|
|
void common_hal_digitalio_digitalinout_switch_to_input( |
|
digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) { |
|
+ const uint8_t pin = self->pin->number; |
|
+ if(pin == 33) { |
|
+ if (pull != PULL_UP) { |
|
+ mp_raise_RuntimeError(translate("Pin only usable in input mode with pull up")); |
|
+ } |
|
+ return; |
|
+ } |
|
self->output = false; |
|
// This also sets direction to input. |
|
common_hal_digitalio_digitalinout_set_pull(self, pull); |
|
@@ -75,6 +85,9 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( |
|
digitalio_digitalinout_obj_t* self, bool value, |
|
digitalio_drive_mode_t drive_mode) { |
|
const uint8_t pin = self->pin->number; |
|
+ if(pin == 33) { |
|
+ mp_raise_RuntimeError(translate("Pin only usable in input mode")); |
|
+ } |
|
gpio_set_dir(pin, GPIO_OUT); |
|
// TODO: Turn on "strong" pin driving (more current available). |
|
|
|
@@ -92,6 +105,9 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( |
|
void common_hal_digitalio_digitalinout_set_value( |
|
digitalio_digitalinout_obj_t* self, bool value) { |
|
const uint8_t pin = self->pin->number; |
|
+ if(pin == 33) { |
|
+ mp_raise_RuntimeError(translate("Pin only usable in input mode")); |
|
+ } |
|
if (self->open_drain) { |
|
gpio_set_dir(pin, value ? GPIO_IN : GPIO_OUT); |
|
} else { |
|
@@ -99,9 +115,43 @@ void common_hal_digitalio_digitalinout_set_value( |
|
} |
|
} |
|
|
|
+static inline void inline_delay_loop(uint32_t count) { |
|
+ asm volatile ( |
|
+ "1: \n\t" |
|
+ "sub %0, %0, #1 \n\t" |
|
+ "bne 1b" |
|
+ : "+r" (count) |
|
+ ); |
|
+} |
|
+ |
|
+static bool __attribute__((noinline)) __not_in_flash_func(read_bootsel)(int clock_mhz) { |
|
+ // Check CSn strap: delay for pullups to charge trace, then take a majority vote. |
|
+ |
|
+ io_rw_32 *reg = (io_rw_32 *) (IO_QSPI_BASE + IO_QSPI_GPIO_QSPI_SS_CTRL_OFFSET); |
|
+ io_rw_32 oreg = *reg; |
|
+ *reg = (*reg & ~0x1f) | 5; // return pin to sio |
|
+ sio_hw->gpio_hi_oe_clr = 1u << 1; // Output disable |
|
+ inline_delay_loop(200 * clock_mhz / 3); |
|
+ uint32_t sum = 0; |
|
+ for (int i = 0; i < 9; ++i) { |
|
+ inline_delay_loop(5 * clock_mhz / 3); |
|
+ sum += (sio_hw->gpio_hi_in >> 1) & 1u; |
|
+ } |
|
+ sio_hw->gpio_hi_oe_set = 1u << 1; // Output enable |
|
+ *reg = oreg; |
|
+ return (sum >= 8); |
|
+} |
|
+ |
|
bool common_hal_digitalio_digitalinout_get_value( |
|
digitalio_digitalinout_obj_t* self) { |
|
- return gpio_get(self->pin->number); |
|
+ const uint8_t pin = self->pin->number; |
|
+ if(pin == 33) { |
|
+ common_hal_mcu_disable_interrupts(); |
|
+ bool result = read_bootsel((clock_get_hz(clk_sys) + 999999) / 1000000); |
|
+ common_hal_mcu_enable_interrupts(); |
|
+ return result; |
|
+ } |
|
+ return gpio_get(pin); |
|
} |
|
|
|
digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( |
|
diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.c b/ports/raspberrypi/common-hal/microcontroller/Pin.c |
|
index ca5cf5a04..1dbff37a3 100644 |
|
--- a/ports/raspberrypi/common-hal/microcontroller/Pin.c |
|
+++ b/ports/raspberrypi/common-hal/microcontroller/Pin.c |
|
@@ -33,6 +33,7 @@ |
|
|
|
#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" |
|
|
|
+bool bootsel_in_use; |
|
#ifdef MICROPY_HW_NEOPIXEL |
|
bool neopixel_in_use; |
|
#endif |
|
@@ -47,8 +48,9 @@ bool speaker_enable_in_use; |
|
STATIC uint32_t never_reset_pins; |
|
|
|
void reset_all_pins(void) { |
|
+ bootsel_in_use = false; |
|
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) { |
|
- if ((never_reset_pins & (1 << i)) != 0) { |
|
+ if (i < TOTAL_GPIO_COUNT && (never_reset_pins & (1 << i)) != 0) { |
|
continue; |
|
} |
|
reset_pin_number(i); |
|
@@ -64,6 +66,11 @@ void never_reset_pin_number(uint8_t pin_number) { |
|
} |
|
|
|
void reset_pin_number(uint8_t pin_number) { |
|
+ if (pin_number == 33) { |
|
+ bootsel_in_use = false; |
|
+ return; |
|
+ } |
|
+ |
|
if (pin_number >= TOTAL_GPIO_COUNT) { |
|
return; |
|
} |
|
@@ -113,6 +120,9 @@ void common_hal_reset_pin(const mcu_pin_obj_t* pin) { |
|
} |
|
|
|
void claim_pin(const mcu_pin_obj_t* pin) { |
|
+ if (pin == &pin_GPIO33) { |
|
+ bootsel_in_use = true; |
|
+ } |
|
#ifdef MICROPY_HW_NEOPIXEL |
|
if (pin == MICROPY_HW_NEOPIXEL) { |
|
neopixel_in_use = true; |
|
@@ -135,6 +145,7 @@ void claim_pin(const mcu_pin_obj_t* pin) { |
|
} |
|
|
|
bool pin_number_is_free(uint8_t pin_number) { |
|
+ |
|
if (pin_number >= TOTAL_GPIO_COUNT) { |
|
return false; |
|
} |
|
@@ -145,6 +156,9 @@ bool pin_number_is_free(uint8_t pin_number) { |
|
} |
|
|
|
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { |
|
+ if (pin == &pin_GPIO33) { |
|
+ return !bootsel_in_use; |
|
+ } |
|
#ifdef MICROPY_HW_NEOPIXEL |
|
if (pin == MICROPY_HW_NEOPIXEL) { |
|
return !neopixel_in_use; |
|
diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.c b/ports/raspberrypi/common-hal/microcontroller/__init__.c |
|
index bfea8b2d9..440d8111e 100644 |
|
--- a/ports/raspberrypi/common-hal/microcontroller/__init__.c |
|
+++ b/ports/raspberrypi/common-hal/microcontroller/__init__.c |
|
@@ -176,5 +176,6 @@ const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = { |
|
{ MP_ROM_QSTR(MP_QSTR_GPIO27), MP_ROM_PTR(&pin_GPIO27) }, |
|
{ MP_ROM_QSTR(MP_QSTR_GPIO28), MP_ROM_PTR(&pin_GPIO28) }, |
|
{ MP_ROM_QSTR(MP_QSTR_GPIO29), MP_ROM_PTR(&pin_GPIO29) }, |
|
+ { MP_ROM_QSTR(MP_QSTR_GPIO33), MP_ROM_PTR(&pin_GPIO33) }, |
|
}; |
|
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); |
|
diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.h b/ports/raspberrypi/common-hal/microcontroller/__init__.h |
|
index cc509b6b1..6bcf9bd4f 100644 |
|
--- a/ports/raspberrypi/common-hal/microcontroller/__init__.h |
|
+++ b/ports/raspberrypi/common-hal/microcontroller/__init__.h |
|
@@ -29,7 +29,7 @@ |
|
|
|
#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h" |
|
|
|
-#define TOTAL_GPIO_COUNT NUM_BANK0_GPIOS |
|
+#define TOTAL_GPIO_COUNT (1+NUM_BANK0_GPIOS) |
|
|
|
extern const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT]; |
|
|
|
diff --git a/ports/raspberrypi/peripherals/pins.c b/ports/raspberrypi/peripherals/pins.c |
|
index a2a7b85bd..be23e6013 100644 |
|
--- a/ports/raspberrypi/peripherals/pins.c |
|
+++ b/ports/raspberrypi/peripherals/pins.c |
|
@@ -65,3 +65,4 @@ PIN(26); |
|
PIN(27); |
|
PIN(28); |
|
PIN(29); |
|
+PIN(33); |
|
diff --git a/ports/raspberrypi/peripherals/pins.h b/ports/raspberrypi/peripherals/pins.h |
|
index 99ab9cfe4..0db9b79c3 100644 |
|
--- a/ports/raspberrypi/peripherals/pins.h |
|
+++ b/ports/raspberrypi/peripherals/pins.h |
|
@@ -67,5 +67,6 @@ extern const mcu_pin_obj_t pin_GPIO26; |
|
extern const mcu_pin_obj_t pin_GPIO27; |
|
extern const mcu_pin_obj_t pin_GPIO28; |
|
extern const mcu_pin_obj_t pin_GPIO29; |
|
+extern const mcu_pin_obj_t pin_GPIO33; |
|
|
|
#endif // MICROPY_INCLUDED_RASPBERRYPI_PERIPHERALS_PINS_H |
|
-- |
|
2.20.1 |
|
|
Hi Jeff,
I'd like to port my "old" Yubikey simulator from Arduino to CircuitPython on RasPi-Pico.
The HID features of CircuitPython should make this easy. But I would need to solder a button to the RasPi-Pico.
This could be avoided, if the BOOTSEL button of the RasPi-Pico could be used easily in CircuitPython.
So my question is: Has your demo code for MicroPython already been ported to CircuitPython?
Anf if yes, in which version?
Thanks, Mike