Fix GPIO16 Board Reset; Updated Usage#780
Conversation
|
FYI - tested with OLED Featherwing on Feather Huzzah ESP8266 and button B works! |
tannewt
left a comment
There was a problem hiding this comment.
Awesome work on this! Just a few sanity checks
| 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; |
There was a problem hiding this comment.
Mind factoring gpio16_in_use related code into claim_pin and reset_pin like the SAMD port does? https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/common-hal/microcontroller/Pin.c#L99
There was a problem hiding this comment.
Should I also roll adc_in_use into this? Hardly takes any additional effort.
| void common_hal_digitalio_digitalinout_set_value( | ||
| digitalio_digitalinout_obj_t* self, bool value) { | ||
| if (self->pin->gpio_number == 16) { | ||
| if (self->open_drain) { |
There was a problem hiding this comment.
I think this should be self->open_drain && value since you want to be outputting a zero in open drain.
There was a problem hiding this comment.
I originally had it that way, but I wasn't sure how/if open_drain && !value would get handled. My theoretical line of thinking was related to set_drive_mode using set_value. Does it need to throw an exception in that case?
There was a problem hiding this comment.
So, belay that. I must have confused myself on that. set_drive_mode will only call set_value if the current value is true. I'll update the condition.
| 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; |
There was a problem hiding this comment.
Does this handle open drain 1 correctly?
There was a problem hiding this comment.
With fixing open_drain above, I see why you're asking. And no, it won't, since RTC_GPIO_OUT will return 0.
| "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). |
There was a problem hiding this comment.
I can add if (pull != PULL_NONE) and throw the exception. I just wanted to remove the confusion when swith_to_input called this, and tossed the exception out even though the pin has been switched to input by the time this is called.
|
Open drain update: I think I have the |
|
@sommersoft I tried this on GPIO16 but I don't get any response from the LED if I use OPEN_DRAIN. with PUSH_PULL True is ON , False is OFF. DO I need to do something differently? Here is the completes setup |
|
Doh! Nevermind -- connencting 220 ohm resistor to +3 and cathode to GPIO16 works as you described. led.value=True LED OFF for both PUSH_PULL and OPEN DRAIN |
| 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_OUT) | READ_PERI_REG(RTC_GPIO_ENABLE)) == 0) { |
There was a problem hiding this comment.
Mind removing the bitwise OR in favor of boolean logic? That'll make it easier to read.
| 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 |
There was a problem hiding this comment.
Can OUT be 1? It'd simplify reading the value.
This block can be indented one less too.
There was a problem hiding this comment.
How did that extra indenture sneak in there?... 🤷♂️ 😄
Can OUT be 1? It'd simplify reading the value.
I'm not sure, but I can try it. I want to check if it's used to set the pull mode for input, though. Could easily assume that it is config'd in RTC_GPIO_CONF, but assumptions ya know. I'm rolling through the Arduino esp8266 repo to see how they implemented pull down.
There was a problem hiding this comment.
After reading through Arduino's handling of GPIO16, I'm confident they use one of the CONF registers. Couldn't find where the calls go from pinMode, but they are definitely shifting values in a full byte. I just tested this with setting OUT & 1 and the same LED test, and didn't get any different results. Also tested switching to 'PUSH_PULL'; 5x5. Will update get_value accordingly.
|
I also tested at 3.0.0-alpha.6-5-g396e4ffc3 and "GPIO16" now works for me as an input. Thanks @sommersoft ! Besides testing as an input, I also tested this: This is clearly what the code intends but I have to admit that I'm not sure why. |
See Issue #753.
No longer causes a reset when creating the
digitalioobject. Also updated some of the usage, since a few functions only included normal gpio functions (gpio16 is controlled through RTC register, not GPIO register). Tested both simple output and input usage; both work as expected.Note to Reviewer(s): PLEASE pay extra attention to
common_hal_digitalio_digitalinout_set_value. I'm not totally sure I implemented the conditionals correct with respect toopen_drainandelse.