Skip to content

pinMode is much slower in 2.0.3 (and 2.0.4) #7049

Closed as not planned
Closed as not planned
@jenscski

Description

@jenscski

Board

All boards

Device Description

Tested with featheresp32

Hardware Configuration

DS18B20 connected to A0

Version

v2.0.3

IDE Name

not applicable

Operating System

not applicable

Flash frequency

not applicable

PSRAM enabled

no

Upload speed

not applicable

Description

In version 2.0.3 the GPIO handing was rewritten using IDF instead of the old implementation.

This caused the time pinMode takes to finish from ~4us to ~16us.

In ESPHome the one wire implementation uses the normal Arduino calls to manipulate GPIO, and this change is probably the cause of One Wire not working in ESPHome when using Arduino 2.0.3.

esphome/issues#3401

Is it possible to speed up pinMode?

After studying the ESPHome and Arduino code, I see that when ESPHome is compiled using ESP-IDF, it uses a different approach than Arduino for setting pin mode.

ESPHome https://github.com/esphome/esphome/blob/ed26c57d990c77cf9eed9bd54da2681f8f7881c9/esphome/components/esp32/gpio_idf.cpp#L83-L106

Arduino

extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
{
#ifdef RGB_BUILTIN
if (pin == RGB_BUILTIN){
__pinMode(RGB_BUILTIN-SOC_GPIO_PIN_COUNT, mode);
return;
}
#endif
if (!GPIO_IS_VALID_GPIO(pin)) {
log_e("Invalid pin selected");
return;
}
gpio_hal_context_t gpiohal;
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
gpio_config_t conf = {
.pin_bit_mask = (1ULL<<pin), /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
.mode = GPIO_MODE_DISABLE, /*!< GPIO mode: set input/output mode */
.pull_up_en = GPIO_PULLUP_DISABLE, /*!< GPIO pull-up */
.pull_down_en = GPIO_PULLDOWN_DISABLE, /*!< GPIO pull-down */
.intr_type = gpiohal.dev->pin[pin].int_type /*!< GPIO interrupt type - previously set */
};
if (mode < 0x20) {//io
conf.mode = mode & (INPUT | OUTPUT);
if (mode & OPEN_DRAIN) {
conf.mode |= GPIO_MODE_DEF_OD;
}
if (mode & PULLUP) {
conf.pull_up_en = GPIO_PULLUP_ENABLE;
}
if (mode & PULLDOWN) {
conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
}
}
if(gpio_config(&conf) != ESP_OK)
{
log_e("GPIO config failed");
return;
}
}

Sketch

This is the sketch I ran using 2.0.2 and 2.0.3. pinMode was the only one with different timing


#include <Arduino.h>

void test()
{
  auto d1 = micros();
  pinMode(A0, OUTPUT);
  auto d2 = micros();
  digitalWrite(A0, LOW);
  auto d3 = micros();
  pinMode(A0, INPUT_PULLUP);
  auto d4 = micros();
  digitalRead(A0);
  auto d5 = micros();

  Serial.println(d2 - d1);
  Serial.println(d3 - d2);
  Serial.println(d4 - d3);
  Serial.println(d5 - d4);
  Serial.println();
}

void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.println("Hello");

  test();
  test();
  test();
  test();
}

void loop()
{
  // put your main code here, to run repeatedly:
}

Debug Message

not applicable

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Labels

Area: PerformanceIssue related to performance problems and improvementsArea: Peripherals APIRelates to peripheral's APIs.Resolution: WontfixArduino ESP32 team will not fix the issue

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions