rp2040: allow board to customize pin reset state

.. and use it on usb host feather to set the reset state of the USB
power pin to "output high", while leaving it possible to create
a DigitalInOut of this pin from CircuitPython code.
This commit is contained in:
Jeff Epler 2024-02-16 11:09:27 -06:00
parent e06b3da135
commit 6fd89b7b13
3 changed files with 31 additions and 4 deletions

View file

@ -28,15 +28,26 @@
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/usb_host/Port.h"
#include "hardware/gpio.h"
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
digitalio_digitalinout_obj_t _host_power;
void board_init(void) {
common_hal_digitalio_digitalinout_construct(&_host_power, &pin_GPIO18);
common_hal_digitalio_digitalinout_never_reset(&_host_power);
common_hal_digitalio_digitalinout_switch_to_output(&_host_power, true, DRIVE_MODE_PUSH_PULL);
bool board_reset_pin_number(uint8_t pin_number) {
if (pin_number == 18) {
// doing this (rather than gpio_init) in this specific order ensures no
// glitch if pin was already configured as a high output. gpio_init() temporarily
// configures the pin as an input, so the power enable value would potentially
// glitch.
gpio_put(pin_number, 1);
gpio_set_dir(pin_number, GPIO_OUT);
gpio_set_function(pin_number, GPIO_FUNC_SIO);
return true;
}
return false;
}
void board_init(void) {
common_hal_usb_host_port_construct(&pin_GPIO16, &pin_GPIO17);
}

View file

@ -73,6 +73,11 @@ void never_reset_pin_number(uint8_t pin_number) {
never_reset_pins |= 1 << pin_number;
}
// By default, all pins get reset in the same way
MP_WEAK bool board_reset_pin_number(uint8_t pin_number) {
return false;
}
void reset_pin_number(uint8_t pin_number) {
if (pin_number >= NUM_BANK0_GPIOS) {
return;
@ -81,6 +86,11 @@ void reset_pin_number(uint8_t pin_number) {
gpio_bank0_pin_claimed &= ~(1 << pin_number);
never_reset_pins &= ~(1 << pin_number);
// Allow the board to override the reset state of any pin
if (board_reset_pin_number(pin_number)) {
return;
}
// We are very aggressive in shutting down the pad fully. Both pulls are
// disabled and both buffers are as well.
gpio_init(pin_number);

View file

@ -34,6 +34,12 @@
#include "peripherals/pins.h"
// If a board needs a different reset state for one or more pins, implement
// board_reset_pin_number so that it sets this state and returns `true` for those
// pin numbers, `false` for others.
// A default weak implementation always returns `false`.
bool board_reset_pin_number(uint8_t pin_number);
void reset_all_pins(void);
// reset_pin_number takes the pin number instead of the pointer so that objects don't
// need to store a full pointer.