Skip to content

Commit d5deddc

Browse files
authored
Merge pull request #6207 from domdfcoding/esp32-rotaryio
Add espressif rotaryio divisor support.
2 parents b0bb5ff + f297e87 commit d5deddc

File tree

6 files changed

+43
-15
lines changed

6 files changed

+43
-15
lines changed

locale/circuitpython.pot

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3126,10 +3126,6 @@ msgstr ""
31263126
msgid "division by zero"
31273127
msgstr ""
31283128

3129-
#: ports/espressif/common-hal/rotaryio/IncrementalEncoder.c
3130-
msgid "divisor must be 4"
3131-
msgstr ""
3132-
31333129
#: extmod/ulab/code/numpy/vector.c
31343130
msgid "dtype must be float, or complex"
31353131
msgstr ""

ports/espressif/common-hal/rotaryio/IncrementalEncoder.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,14 @@
2929
#include "common-hal/microcontroller/Pin.h"
3030

3131
#include "py/runtime.h"
32-
#include "supervisor/shared/translate.h"
3332

3433
void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self,
3534
const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) {
3635
claim_pin(pin_a);
3736
claim_pin(pin_b);
3837

3938
// Prepare configuration for the PCNT unit
40-
const pcnt_config_t pcnt_config = {
39+
pcnt_config_t pcnt_config = {
4140
// Set PCNT input signal and control GPIOs
4241
.pulse_gpio_num = pin_a->number,
4342
.ctrl_gpio_num = pin_b->number,
@@ -51,11 +50,32 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
5150
};
5251

5352
// Initialize PCNT unit
54-
const int8_t unit = peripherals_pcnt_init(pcnt_config);
53+
const int8_t unit = peripherals_pcnt_get_unit(pcnt_config);
5554
if (unit == -1) {
5655
mp_raise_RuntimeError(translate("All PCNT units in use"));
5756
}
5857

58+
pcnt_unit_config(&pcnt_config);
59+
60+
pcnt_config.pulse_gpio_num = pin_b->number; // What was control is now signal
61+
pcnt_config.ctrl_gpio_num = pin_a->number; // What was signal is now control
62+
pcnt_config.channel = PCNT_CHANNEL_1;
63+
// What to do on the positive / negative edge of pulse input?
64+
pcnt_config.pos_mode = PCNT_COUNT_DEC; // Count up on the positive edge
65+
pcnt_config.neg_mode = PCNT_COUNT_INC; // Keep the counter value on the negative edge
66+
// What to do when control input is low or high?
67+
pcnt_config.lctrl_mode = PCNT_MODE_KEEP; // Keep the primary counter mode if low
68+
pcnt_config.hctrl_mode = PCNT_MODE_REVERSE; // Reverse counting direction if high
69+
70+
pcnt_unit_config(&pcnt_config);
71+
72+
// Initialize PCNT's counter
73+
pcnt_counter_pause(pcnt_config.unit);
74+
pcnt_counter_clear(pcnt_config.unit);
75+
76+
// Everything is set up, now go to counting
77+
pcnt_counter_resume(pcnt_config.unit);
78+
5979
self->pin_a = pin_a->number;
6080
self->pin_b = pin_b->number;
6181
self->unit = (pcnt_unit_t)unit;
@@ -77,21 +97,20 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o
7797
mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t *self) {
7898
int16_t count;
7999
pcnt_get_counter_value(self->unit, &count);
80-
return (count / 2) + self->position;
100+
101+
return (count + self->position) / self->divisor;
81102
}
82103

83104
void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t *self,
84105
mp_int_t new_position) {
85-
self->position = new_position;
106+
self->position = new_position * self->divisor;
86107
pcnt_counter_clear(self->unit);
87108
}
88109

89110
mp_int_t common_hal_rotaryio_incrementalencoder_get_divisor(rotaryio_incrementalencoder_obj_t *self) {
90-
return 4;
111+
return self->divisor;
91112
}
92113

93114
void common_hal_rotaryio_incrementalencoder_set_divisor(rotaryio_incrementalencoder_obj_t *self, mp_int_t divisor) {
94-
if (divisor != 4) {
95-
mp_raise_ValueError(translate("divisor must be 4"));
96-
}
115+
self->divisor = divisor;
97116
}

ports/espressif/common-hal/rotaryio/IncrementalEncoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef struct {
3535
uint8_t pin_a, pin_b;
3636
mp_int_t position;
3737
pcnt_unit_t unit;
38+
int8_t divisor; // Number of quadrature edges required per count
3839
} rotaryio_incrementalencoder_obj_t;
3940

4041
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H

ports/espressif/peripherals/pcnt.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void peripherals_pcnt_reset(void) {
3737
}
3838
}
3939

40-
int peripherals_pcnt_init(pcnt_config_t pcnt_config) {
40+
int peripherals_pcnt_get_unit(pcnt_config_t pcnt_config) {
4141
// Look for available pcnt unit
4242
for (uint8_t i = 0; i <= 3; i++) {
4343
if (pcnt_unit_state[i] == PCNT_UNIT_INACTIVE) {
@@ -49,6 +49,17 @@ int peripherals_pcnt_init(pcnt_config_t pcnt_config) {
4949
}
5050
}
5151

52+
return pcnt_config.unit;
53+
}
54+
55+
int peripherals_pcnt_init(pcnt_config_t pcnt_config) {
56+
// Look for available pcnt unit
57+
58+
const int8_t unit = peripherals_pcnt_get_unit(pcnt_config);
59+
if (unit == -1) {
60+
return -1;
61+
}
62+
5263
// Initialize PCNT unit
5364
pcnt_unit_config(&pcnt_config);
5465

ports/espressif/peripherals/pcnt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "soc/pcnt_struct.h"
3232

3333
extern int peripherals_pcnt_init(pcnt_config_t pcnt_config);
34+
extern int peripherals_pcnt_get_unit(pcnt_config_t pcnt_config);
3435
extern void peripherals_pcnt_deinit(pcnt_unit_t *unit);
3536
extern void peripherals_pcnt_reset(void);
3637

shared-bindings/rotaryio/IncrementalEncoder.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type,
7878
self->base.type = &rotaryio_incrementalencoder_type;
7979

8080
common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b);
81-
8281
common_hal_rotaryio_incrementalencoder_set_divisor(self, args[ARG_divisor].u_int);
82+
8383
return MP_OBJ_FROM_PTR(self);
8484
}
8585

0 commit comments

Comments
 (0)