From e70ece4c413b8fa5dce99240bff04e4641edf3a8 Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 25 Apr 2018 03:57:09 +0000 Subject: [PATCH 1/5] now checks for proper pin in is_pin_free; initialize GPIO16 as input in reset_pins --- ports/esp8266/common-hal/microcontroller/Pin.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ports/esp8266/common-hal/microcontroller/Pin.c b/ports/esp8266/common-hal/microcontroller/Pin.c index 5c90f4f1a0..4b6efb428d 100644 --- a/ports/esp8266/common-hal/microcontroller/Pin.c +++ b/ports/esp8266/common-hal/microcontroller/Pin.c @@ -33,14 +33,18 @@ #include "eagle_soc.h" extern volatile bool adc_in_use; +volatile bool gpio16_in_use __attribute__((aligned(4))) = false; bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { if (pin == &pin_TOUT) { return !adc_in_use; } - if (pin->gpio_number == NO_GPIO || pin->gpio_number == SPECIAL_CASE) { + if (pin->gpio_number == NO_GPIO) { return false; } + if (pin->gpio_number == 16) { + return !gpio16_in_use; + } return (READ_PERI_REG(pin->peripheral) & (PERIPHS_IO_MUX_FUNC<gpio_number)) == 0 && @@ -48,7 +52,7 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { } void reset_pins(void) { - for (int i = 0; i < 17; i++) { + for (int i = 0; i < 16; i++) { // 5 is RXD, 6 is TXD if ((i > 4 && i < 13) || i == 12) { continue; @@ -59,4 +63,9 @@ void reset_pins(void) { // Disable the pin. gpio_output_set(0x0, 0x0, 0x0, 1 << i); } + // Set GPIO16 as input + 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 = false; } From bd5a5daaaebbdb36d4ad81541b452e9b485e8b3a Mon Sep 17 00:00:00 2001 From: sommersoft Date: Wed, 25 Apr 2018 03:59:36 +0000 Subject: [PATCH 2/5] updated GPIO16 construct and handling --- .../common-hal/digitalio/DigitalInOut.c | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) 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) { From 441ce2a78ff1c3d5a09a317b34795460038aeaee Mon Sep 17 00:00:00 2001 From: sommersoft Date: Thu, 26 Apr 2018 01:35:58 +0000 Subject: [PATCH 3/5] reset GPIO16 to input on deinit --- ports/esp8266/common-hal/digitalio/DigitalInOut.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.c b/ports/esp8266/common-hal/digitalio/DigitalInOut.c index 660fcf1dad..6fc875547a 100644 --- a/ports/esp8266/common-hal/digitalio/DigitalInOut.c +++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.c @@ -65,6 +65,9 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self PIN_FUNC_SELECT(self->pin->peripheral, 0); PIN_PULLUP_DIS(self->pin->peripheral); } else { + 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 = false; } self->pin = mp_const_none; From 4e1f7d43ebc5a897302e5964189251c9f97a0fcf Mon Sep 17 00:00:00 2001 From: sommersoft Date: Fri, 27 Apr 2018 02:51:07 +0000 Subject: [PATCH 4/5] added exception for PULL_UP; corrected open_drain handling --- .../common-hal/digitalio/DigitalInOut.c | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.c b/ports/esp8266/common-hal/digitalio/DigitalInOut.c index 6fc875547a..bc1ae990f5 100644 --- a/ports/esp8266/common-hal/digitalio/DigitalInOut.c +++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.c @@ -45,9 +45,9 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( 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 { + } else { PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); - } + } return DIGITALINOUT_OK; } @@ -112,7 +112,7 @@ 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) { + if (self->open_drain && value) { // 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); @@ -158,7 +158,11 @@ bool common_hal_digitalio_digitalinout_get_value( return GPIO_INPUT_GET(self->pin->gpio_number); } else { if (self->pin->gpio_number == 16) { - return READ_PERI_REG(RTC_GPIO_OUT) & 1; + if (self->open_drain && (READ_PERI_REG(RTC_GPIO_OUT) | READ_PERI_REG(RTC_GPIO_ENABLE)) == 0) { + return true; + } else { + return READ_PERI_REG(RTC_GPIO_OUT) & 1; + } } else { uint32_t pin_mask = 1 << self->pin->gpio_number; if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) { @@ -199,9 +203,14 @@ void common_hal_digitalio_digitalinout_set_pull( return; } if (self->pin->gpio_number == 16) { - // PULL_DOWN is the only hardware pull direction available on GPIO16 + // 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). + // to set pull (which won't work anyway). If PULL_UP is requested, + // raise the exception so the user knows PULL_UP is not available + if (pull != PULL_NONE){ + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "GPIO16 does not support pull up.")); + } return; } if (pull == PULL_NONE) { From 396e4ffc34d2b68a9d1e506c301da16d96ab9a4c Mon Sep 17 00:00:00 2001 From: sommersoft Date: Sat, 28 Apr 2018 17:27:23 +0000 Subject: [PATCH 5/5] implemented 'claim_pin' methodology; updated 'open_drain' handling --- ports/esp8266/common-hal/analogio/AnalogIn.c | 6 +-- .../common-hal/digitalio/DigitalInOut.c | 21 +++++----- .../esp8266/common-hal/microcontroller/Pin.c | 38 +++++++++++++++---- .../esp8266/common-hal/microcontroller/Pin.h | 2 + 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/ports/esp8266/common-hal/analogio/AnalogIn.c b/ports/esp8266/common-hal/analogio/AnalogIn.c index d3a81272ee..e01eceabd7 100644 --- a/ports/esp8266/common-hal/analogio/AnalogIn.c +++ b/ports/esp8266/common-hal/analogio/AnalogIn.c @@ -36,14 +36,12 @@ #include "user_interface.h" -volatile bool adc_in_use __attribute__((aligned(4))) = false; - void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, const mcu_pin_obj_t *pin) { if (pin != &pin_TOUT) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin %q does not have ADC capabilities", pin->name)); } - adc_in_use = true; + claim_pin(pin); } bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t* self) { @@ -54,7 +52,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self) { if (common_hal_analogio_analogin_deinited(self)) { return; } - adc_in_use = false; + reset_pin(&pin_TOUT); self->deinited = true; } diff --git a/ports/esp8266/common-hal/digitalio/DigitalInOut.c b/ports/esp8266/common-hal/digitalio/DigitalInOut.c index bc1ae990f5..96945737b3 100644 --- a/ports/esp8266/common-hal/digitalio/DigitalInOut.c +++ b/ports/esp8266/common-hal/digitalio/DigitalInOut.c @@ -44,7 +44,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( 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; + claim_pin(pin); } else { PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); } @@ -65,10 +65,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self PIN_FUNC_SELECT(self->pin->peripheral, 0); PIN_PULLUP_DIS(self->pin->peripheral); } else { - 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 = false; + reset_pin(self->pin); } self->pin = mp_const_none; } @@ -113,12 +110,12 @@ void common_hal_digitalio_digitalinout_set_value( digitalio_digitalinout_obj_t* self, bool value) { if (self->pin->gpio_number == 16) { if (self->open_drain && value) { - // 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; + // 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=1 + return; } else { int out_en = self->output; WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); @@ -158,7 +155,7 @@ bool common_hal_digitalio_digitalinout_get_value( return GPIO_INPUT_GET(self->pin->gpio_number); } else { if (self->pin->gpio_number == 16) { - if (self->open_drain && (READ_PERI_REG(RTC_GPIO_OUT) | READ_PERI_REG(RTC_GPIO_ENABLE)) == 0) { + if (self->open_drain && READ_PERI_REG(RTC_GPIO_ENABLE) == 0) { return true; } else { return READ_PERI_REG(RTC_GPIO_OUT) & 1; diff --git a/ports/esp8266/common-hal/microcontroller/Pin.c b/ports/esp8266/common-hal/microcontroller/Pin.c index 4b6efb428d..6d2af2d2e8 100644 --- a/ports/esp8266/common-hal/microcontroller/Pin.c +++ b/ports/esp8266/common-hal/microcontroller/Pin.c @@ -32,23 +32,45 @@ #include "eagle_soc.h" -extern volatile bool adc_in_use; -volatile bool gpio16_in_use __attribute__((aligned(4))) = false; +bool adc_in_use; +bool gpio16_in_use; bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { if (pin == &pin_TOUT) { return !adc_in_use; } + if (pin == &pin_XPD_DCDC) { + return !gpio16_in_use; + } if (pin->gpio_number == NO_GPIO) { return false; } - if (pin->gpio_number == 16) { - return !gpio16_in_use; - } return (READ_PERI_REG(pin->peripheral) & (PERIPHS_IO_MUX_FUNC<gpio_number)) == 0 && - (READ_PERI_REG(pin->peripheral) & PERIPHS_IO_MUX_PULLUP) == 0; + (READ_PERI_REG(pin->peripheral) & PERIPHS_IO_MUX_PULLUP) == 0; +} + +void claim_pin(const mcu_pin_obj_t* pin) { + if (pin == &pin_XPD_DCDC) { + gpio16_in_use = true; + } + if (pin == &pin_TOUT) { + adc_in_use = true; + } +} + +void reset_pin(const mcu_pin_obj_t* pin) { + if (pin == &pin_XPD_DCDC) { + // Set GPIO16 as input + 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 = false; + } + if (pin == &pin_TOUT) { + adc_in_use = false; + } } void reset_pins(void) { @@ -67,5 +89,7 @@ void reset_pins(void) { 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 + + adc_in_use = false; gpio16_in_use = false; -} +} \ No newline at end of file diff --git a/ports/esp8266/common-hal/microcontroller/Pin.h b/ports/esp8266/common-hal/microcontroller/Pin.h index 405557ddc9..3aa290bbd3 100644 --- a/ports/esp8266/common-hal/microcontroller/Pin.h +++ b/ports/esp8266/common-hal/microcontroller/Pin.h @@ -41,6 +41,8 @@ typedef struct { #define NO_GPIO 0xff #define SPECIAL_CASE 0xfe +void claim_pin(const mcu_pin_obj_t* pin); +void reset_pin(const mcu_pin_obj_t* pin); void reset_pins(void); #endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H