diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.c b/ports/esp8266/common-hal/digitalio/DigitalInOut.c index 7101e64145..660fcf1dad 100644 --- a/ports/esp8266/common-hal/digitalio/DigitalInOut.c +++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.c @@ -33,11 +33,21 @@ #include "py/mphal.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "common-hal/microcontroller/Pin.h" + +extern volatile bool gpio16_in_use; digitalinout_result_t common_hal_digitalio_digitalinout_construct( digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { self->pin = pin; - PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); + if (self->pin->gpio_number == 16) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable + WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable + gpio16_in_use = true; + } else { + PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); + } return DIGITALINOUT_OK; } @@ -54,6 +64,8 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self gpio_output_set(0x0, 0x0, 0x0, pin_mask); PIN_FUNC_SELECT(self->pin->peripheral, 0); PIN_PULLUP_DIS(self->pin->peripheral); + } else { + gpio16_in_use = false; } self->pin = mp_const_none; } @@ -96,6 +108,23 @@ digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( void common_hal_digitalio_digitalinout_set_value( digitalio_digitalinout_obj_t* self, bool value) { + if (self->pin->gpio_number == 16) { + if (self->open_drain) { + // configure GPIO16 as input with output register holding 0 + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input + WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1)); // out=0 + return; + } else { + int out_en = self->output; + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | out_en); + WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1) | value); + return; + } + } if (value) { if (self->open_drain) { // Disable output. @@ -125,11 +154,15 @@ bool common_hal_digitalio_digitalinout_get_value( } return GPIO_INPUT_GET(self->pin->gpio_number); } else { - uint32_t pin_mask = 1 << self->pin->gpio_number; - if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) { - return true; + if (self->pin->gpio_number == 16) { + return READ_PERI_REG(RTC_GPIO_OUT) & 1; } else { - return ((*PIN_OUT) & pin_mask) != 0; + uint32_t pin_mask = 1 << self->pin->gpio_number; + if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) { + return true; + } else { + return ((*PIN_OUT) & pin_mask) != 0; + } } } } @@ -163,8 +196,9 @@ void common_hal_digitalio_digitalinout_set_pull( return; } if (self->pin->gpio_number == 16) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "Pin does not support pull.")); + // PULL_DOWN is the only hardware pull direction available on GPIO16 + // since we don't support pull down, just return without attempting + // to set pull (which won't work anyway). return; } if (pull == PULL_NONE) {