Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions ports/esp8266/common-hal/analogio/AnalogIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}

Expand Down
57 changes: 50 additions & 7 deletions ports/esp8266/common-hal/digitalio/DigitalInOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
claim_pin(pin);
} else {
PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function);
}
return DIGITALINOUT_OK;
}

Expand All @@ -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 {
reset_pin(self->pin);
}
self->pin = mp_const_none;
}
Expand Down Expand Up @@ -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 && 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=1
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.
Expand Down Expand Up @@ -125,11 +154,19 @@ 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) {
if (self->open_drain && READ_PERI_REG(RTC_GPIO_ENABLE) == 0) {
return true;
} else {
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;
}
}
}
}
Expand Down Expand Up @@ -163,8 +200,14 @@ 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). 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) {
Expand Down
43 changes: 38 additions & 5 deletions ports/esp8266/common-hal/microcontroller/Pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,49 @@

#include "eagle_soc.h"

extern volatile bool adc_in_use;
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->gpio_number == NO_GPIO || pin->gpio_number == SPECIAL_CASE) {
if (pin == &pin_XPD_DCDC) {
return !gpio16_in_use;
}
if (pin->gpio_number == NO_GPIO) {
return false;
}
return (READ_PERI_REG(pin->peripheral) &
(PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S)) == 0 &&
(GPIO_REG_READ(GPIO_ENABLE_ADDRESS) & (1 << pin->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) {
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;
Expand All @@ -59,4 +85,11 @@ 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

adc_in_use = false;
gpio16_in_use = false;
}
2 changes: 2 additions & 0 deletions ports/esp8266/common-hal/microcontroller/Pin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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