Skip to content

Commit 5f3ad45

Browse files
committed
Fix enable_internal_pullup to always use pull-ups
Previously, the pull direction was based on btn_pressed_level, which caused pull-downs to be applied to encoder pins when btn_pressed_level was 1. Encoder pins always need pull-ups since they are wired with common to ground. Now always uses pull-ups and documents that the button pin may need a separate pull-down when btn_pressed_level is 1. Fixes #12
1 parent 10a01cd commit 5f3ad45

File tree

4 files changed

+31
-32
lines changed

4 files changed

+31
-32
lines changed

.eil.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: encoder
33
description: HW timer-based driver for incremental rotary encoders
4-
version: 3.0.0
4+
version: 3.0.1
55
groups:
66
- input
77
code_owners:

encoder.c

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -224,40 +224,29 @@ esp_err_t rotary_encoder_create(const rotary_encoder_config_t *config, rotary_en
224224
}
225225
#endif
226226

227-
// setup GPIO
228-
gpio_config_t io_conf;
229-
memset(&io_conf, 0, sizeof(gpio_config_t));
230-
io_conf.mode = GPIO_MODE_INPUT;
231-
if (config->enable_internal_pullup)
227+
// setup GPIO pins as inputs
228+
gpio_num_t pins[] = { re->pin_a, re->pin_b, re->pin_btn };
229+
int num_pins = PIN_VALID(re->pin_btn) ? 3 : 2;
230+
for (int i = 0; i < num_pins; i++)
232231
{
233-
if (re->btn_pressed_level == 0)
232+
esp_err_t err = gpio_set_direction(pins[i], GPIO_MODE_INPUT);
233+
if (err != ESP_OK)
234234
{
235-
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
236-
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
235+
vSemaphoreDelete(re->lock);
236+
free(re);
237+
return err;
237238
}
238-
else
239+
if (config->enable_internal_pullup)
239240
{
240-
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
241-
io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
241+
err = gpio_set_pull_mode(pins[i], GPIO_PULLUP_ONLY);
242+
if (err != ESP_OK)
243+
{
244+
vSemaphoreDelete(re->lock);
245+
free(re);
246+
return err;
247+
}
242248
}
243249
}
244-
else
245-
{
246-
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
247-
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
248-
}
249-
io_conf.intr_type = GPIO_INTR_DISABLE;
250-
io_conf.pin_bit_mask = GPIO_BIT(re->pin_a) | GPIO_BIT(re->pin_b);
251-
if (PIN_VALID(re->pin_btn))
252-
io_conf.pin_bit_mask |= GPIO_BIT(re->pin_btn);
253-
254-
esp_err_t err = gpio_config(&io_conf);
255-
if (err != ESP_OK)
256-
{
257-
vSemaphoreDelete(re->lock);
258-
free(re);
259-
return err;
260-
}
261250

262251
// Create and start per-encoder timer
263252
const esp_timer_create_args_t timer_args =

encoder.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,18 @@ typedef struct
9696
gpio_num_t pin_a; //!< Encoder pin A
9797
gpio_num_t pin_b; //!< Encoder pin B
9898
gpio_num_t pin_btn; //!< Button pin, or GPIO_NUM_NC if unused
99-
uint8_t btn_pressed_level; //!< GPIO level when button is pressed (0 or 1)
100-
bool enable_internal_pullup; //!< Enable internal pull-up/pull-down resistors on GPIO pins
99+
uint8_t btn_pressed_level; //!< GPIO level when button is pressed (0 or 1).
100+
//!< When set to 1, the button pin may need a pull-down
101+
//!< resistor, either external or set via \c gpio_set_pull_mode()
102+
//!< before creating the encoder, as \c enable_internal_pullup
103+
//!< only enables pull-ups.
104+
bool enable_internal_pullup; //!< Enable internal pull-up resistors on all encoder and
105+
//!< button GPIO pins. Pull-ups are always used, which is
106+
//!< correct for encoders wired with common to ground. When
107+
//!< \c btn_pressed_level is 1, the button pin may need a
108+
//!< pull-down instead — use an external resistor or call
109+
//!< \c gpio_set_pull_mode() before creating the encoder.
110+
//!< When false, pull resistors are left unchanged.
101111
uint32_t btn_dead_time_us; //!< Button dead time in microseconds
102112
uint32_t btn_long_press_time_us; //!< Long press threshold in microseconds
103113
uint32_t acceleration_threshold_ms; //!< Acceleration threshold in milliseconds (acceleration starts below this interval)

idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
version: 3.0.0
2+
version: 3.0.1
33
description: HW timer-based driver for incremental rotary encoders
44
license: BSD-3
55
targets:

0 commit comments

Comments
 (0)