diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 9ab26ac5d0..d7e14eabe5 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -3126,10 +3126,6 @@ msgstr "" msgid "division by zero" msgstr "" -#: ports/espressif/common-hal/rotaryio/IncrementalEncoder.c -msgid "divisor must be 4" -msgstr "" - #: extmod/ulab/code/numpy/vector.c msgid "dtype must be float, or complex" msgstr "" diff --git a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c index 676e99289d..15e7fc4b8f 100644 --- a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c @@ -29,7 +29,6 @@ #include "common-hal/microcontroller/Pin.h" #include "py/runtime.h" -#include "supervisor/shared/translate.h" void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { @@ -37,7 +36,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode claim_pin(pin_b); // Prepare configuration for the PCNT unit - const pcnt_config_t pcnt_config = { + pcnt_config_t pcnt_config = { // Set PCNT input signal and control GPIOs .pulse_gpio_num = pin_a->number, .ctrl_gpio_num = pin_b->number, @@ -51,11 +50,32 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode }; // Initialize PCNT unit - const int8_t unit = peripherals_pcnt_init(pcnt_config); + const int8_t unit = peripherals_pcnt_get_unit(pcnt_config); if (unit == -1) { mp_raise_RuntimeError(translate("All PCNT units in use")); } + pcnt_unit_config(&pcnt_config); + + pcnt_config.pulse_gpio_num = pin_b->number; // What was control is now signal + pcnt_config.ctrl_gpio_num = pin_a->number; // What was signal is now control + pcnt_config.channel = PCNT_CHANNEL_1; + // What to do on the positive / negative edge of pulse input? + pcnt_config.pos_mode = PCNT_COUNT_DEC; // Count up on the positive edge + pcnt_config.neg_mode = PCNT_COUNT_INC; // Keep the counter value on the negative edge + // What to do when control input is low or high? + pcnt_config.lctrl_mode = PCNT_MODE_KEEP; // Keep the primary counter mode if low + pcnt_config.hctrl_mode = PCNT_MODE_REVERSE; // Reverse counting direction if high + + pcnt_unit_config(&pcnt_config); + + // Initialize PCNT's counter + pcnt_counter_pause(pcnt_config.unit); + pcnt_counter_clear(pcnt_config.unit); + + // Everything is set up, now go to counting + pcnt_counter_resume(pcnt_config.unit); + self->pin_a = pin_a->number; self->pin_b = pin_b->number; self->unit = (pcnt_unit_t)unit; @@ -77,21 +97,20 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t *self) { int16_t count; pcnt_get_counter_value(self->unit, &count); - return (count / 2) + self->position; + + return (count + self->position) / self->divisor; } void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t *self, mp_int_t new_position) { - self->position = new_position; + self->position = new_position * self->divisor; pcnt_counter_clear(self->unit); } mp_int_t common_hal_rotaryio_incrementalencoder_get_divisor(rotaryio_incrementalencoder_obj_t *self) { - return 4; + return self->divisor; } void common_hal_rotaryio_incrementalencoder_set_divisor(rotaryio_incrementalencoder_obj_t *self, mp_int_t divisor) { - if (divisor != 4) { - mp_raise_ValueError(translate("divisor must be 4")); - } + self->divisor = divisor; } diff --git a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.h b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.h index 4982c39103..c43cd62bf6 100644 --- a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.h +++ b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.h @@ -35,6 +35,7 @@ typedef struct { uint8_t pin_a, pin_b; mp_int_t position; pcnt_unit_t unit; + int8_t divisor; // Number of quadrature edges required per count } rotaryio_incrementalencoder_obj_t; #endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_ROTARYIO_INCREMENTALENCODER_H diff --git a/ports/espressif/peripherals/pcnt.c b/ports/espressif/peripherals/pcnt.c index e4578a2791..d1b85fbb13 100644 --- a/ports/espressif/peripherals/pcnt.c +++ b/ports/espressif/peripherals/pcnt.c @@ -37,7 +37,7 @@ void peripherals_pcnt_reset(void) { } } -int peripherals_pcnt_init(pcnt_config_t pcnt_config) { +int peripherals_pcnt_get_unit(pcnt_config_t pcnt_config) { // Look for available pcnt unit for (uint8_t i = 0; i <= 3; i++) { if (pcnt_unit_state[i] == PCNT_UNIT_INACTIVE) { @@ -49,6 +49,17 @@ int peripherals_pcnt_init(pcnt_config_t pcnt_config) { } } + return pcnt_config.unit; +} + +int peripherals_pcnt_init(pcnt_config_t pcnt_config) { + // Look for available pcnt unit + + const int8_t unit = peripherals_pcnt_get_unit(pcnt_config); + if (unit == -1) { + return -1; + } + // Initialize PCNT unit pcnt_unit_config(&pcnt_config); diff --git a/ports/espressif/peripherals/pcnt.h b/ports/espressif/peripherals/pcnt.h index b2bae7b371..c73c41a232 100644 --- a/ports/espressif/peripherals/pcnt.h +++ b/ports/espressif/peripherals/pcnt.h @@ -31,6 +31,7 @@ #include "soc/pcnt_struct.h" extern int peripherals_pcnt_init(pcnt_config_t pcnt_config); +extern int peripherals_pcnt_get_unit(pcnt_config_t pcnt_config); extern void peripherals_pcnt_deinit(pcnt_unit_t *unit); extern void peripherals_pcnt_reset(void); diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index ef218ba024..7793e12837 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -78,8 +78,8 @@ STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, self->base.type = &rotaryio_incrementalencoder_type; common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b); - common_hal_rotaryio_incrementalencoder_set_divisor(self, args[ARG_divisor].u_int); + return MP_OBJ_FROM_PTR(self); }