diff --git a/ports/espressif/common-hal/countio/Counter.c b/ports/espressif/common-hal/countio/Counter.c index d18196051f..4203356d12 100644 --- a/ports/espressif/common-hal/countio/Counter.c +++ b/ports/espressif/common-hal/countio/Counter.c @@ -36,7 +36,7 @@ void common_hal_countio_counter_construct(countio_counter_obj_t *self, claim_pin(pin); // 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->number, .ctrl_gpio_num = PCNT_PIN_NOT_USED, @@ -48,7 +48,7 @@ void common_hal_countio_counter_construct(countio_counter_obj_t *self, }; // Initialize PCNT unit - const int8_t unit = peripherals_pcnt_init(pcnt_config); + const int8_t unit = peripherals_pcnt_init(&pcnt_config); if (unit == -1) { mp_raise_RuntimeError(translate("All PCNT units in use")); } diff --git a/ports/espressif/common-hal/frequencyio/FrequencyIn.c b/ports/espressif/common-hal/frequencyio/FrequencyIn.c index e4d65c95bd..a6bef57f10 100644 --- a/ports/espressif/common-hal/frequencyio/FrequencyIn.c +++ b/ports/espressif/common-hal/frequencyio/FrequencyIn.c @@ -69,7 +69,7 @@ static void IRAM_ATTR timer_interrupt_handler(void *self_in) { static void init_pcnt(frequencyio_frequencyin_obj_t *self) { // 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 = self->pin, .ctrl_gpio_num = PCNT_PIN_NOT_USED, @@ -83,7 +83,7 @@ static void init_pcnt(frequencyio_frequencyin_obj_t *self) { }; // initialize PCNT - const int8_t unit = peripherals_pcnt_init(pcnt_config); + const int8_t unit = peripherals_pcnt_init(&pcnt_config); if (unit == -1) { mp_raise_RuntimeError(translate("All PCNT units in use")); } diff --git a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c index 15e7fc4b8f..07b97cf9a3 100644 --- a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c @@ -36,45 +36,41 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode claim_pin(pin_b); // Prepare configuration for the PCNT unit - pcnt_config_t pcnt_config = { + pcnt_config_t pcnt_config_channel_0 = { // Set PCNT input signal and control GPIOs .pulse_gpio_num = pin_a->number, .ctrl_gpio_num = pin_b->number, .channel = PCNT_CHANNEL_0, // What to do on the positive / negative edge of pulse input? - .pos_mode = PCNT_COUNT_DEC, // Count up on the positive edge - .neg_mode = PCNT_COUNT_INC, // Keep the counter value on the negative edge + .pos_mode = PCNT_COUNT_DEC, // Count up on the positive edge + .neg_mode = PCNT_COUNT_INC, // Keep the counter value on the negative edge // What to do when control input is low or high? .lctrl_mode = PCNT_MODE_REVERSE, // Reverse counting direction if low .hctrl_mode = PCNT_MODE_KEEP, // Keep the primary counter mode if high }; - // Initialize PCNT unit - const int8_t unit = peripherals_pcnt_get_unit(pcnt_config); + // Allocate and initialize PCNT unit, CHANNEL_0. + const int8_t unit = peripherals_pcnt_init(&pcnt_config_channel_0); if (unit == -1) { mp_raise_RuntimeError(translate("All PCNT units in use")); } - pcnt_unit_config(&pcnt_config); + pcnt_config_t pcnt_config_channel_1 = { + // Set PCNT input signal and control GPIOs + .pulse_gpio_num = pin_b->number, // Pins are reversed from above + .ctrl_gpio_num = pin_a->number, + .channel = PCNT_CHANNEL_1, + // What to do on the positive / negative edge of pulse input? + .pos_mode = PCNT_COUNT_DEC, // Count up on the positive edge + .neg_mode = PCNT_COUNT_INC, // Keep the counter value on the negative edge + // What to do when control input is low or high? + .lctrl_mode = PCNT_MODE_KEEP, // Keep the primary counter mode if low + .hctrl_mode = PCNT_MODE_REVERSE, // Reverse counting direction if high + .unit = unit, + }; - 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); + // Reinitalize same unit, CHANNEL_1 with different parameters. + peripherals_pcnt_reinit(&pcnt_config_channel_1); self->pin_a = pin_a->number; self->pin_b = pin_b->number; diff --git a/ports/espressif/peripherals/pcnt.c b/ports/espressif/peripherals/pcnt.c index d1b85fbb13..fa8a3e05d1 100644 --- a/ports/espressif/peripherals/pcnt.c +++ b/ports/espressif/peripherals/pcnt.c @@ -29,48 +29,50 @@ #define PCNT_UNIT_ACTIVE 1 #define PCNT_UNIT_INACTIVE 0 -static uint8_t pcnt_unit_state[4]; +static uint8_t pcnt_unit_state[PCNT_UNIT_MAX]; void peripherals_pcnt_reset(void) { - for (uint8_t i = 0; i <= 3; i++) { + for (uint8_t i = 0; i < PCNT_UNIT_MAX; i++) { pcnt_unit_state[i] = PCNT_UNIT_INACTIVE; } } -int peripherals_pcnt_get_unit(pcnt_config_t pcnt_config) { +static int peripherals_pcnt_get_unit(pcnt_config_t *pcnt_config) { // Look for available pcnt unit - for (uint8_t i = 0; i <= 3; i++) { + for (uint8_t i = 0; i < PCNT_UNIT_MAX; i++) { if (pcnt_unit_state[i] == PCNT_UNIT_INACTIVE) { - pcnt_config.unit = (pcnt_unit_t)i; + pcnt_config->unit = (pcnt_unit_t)i; pcnt_unit_state[i] = PCNT_UNIT_ACTIVE; - break; - } else if (i == 3) { - return -1; + return i; } } - return pcnt_config.unit; + return -1; } -int peripherals_pcnt_init(pcnt_config_t pcnt_config) { - // Look for available pcnt unit +void peripherals_pcnt_reinit(pcnt_config_t *pcnt_config) { + // Reinitialize a pcnt unit that has already been allocated. + // Initialize PCNT unit + 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); +} + +int peripherals_pcnt_init(pcnt_config_t *pcnt_config) { const int8_t unit = peripherals_pcnt_get_unit(pcnt_config); if (unit == -1) { return -1; } - // Initialize PCNT unit - pcnt_unit_config(&pcnt_config); + peripherals_pcnt_reinit(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); - - return pcnt_config.unit; + return pcnt_config->unit; } void peripherals_pcnt_deinit(pcnt_unit_t *unit) { diff --git a/ports/espressif/peripherals/pcnt.h b/ports/espressif/peripherals/pcnt.h index c73c41a232..d34d971601 100644 --- a/ports/espressif/peripherals/pcnt.h +++ b/ports/espressif/peripherals/pcnt.h @@ -30,8 +30,8 @@ #include "driver/pcnt.h" #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 int peripherals_pcnt_init(pcnt_config_t *pcnt_config); +extern void peripherals_pcnt_reinit(pcnt_config_t *pcnt_config); extern void peripherals_pcnt_deinit(pcnt_unit_t *unit); extern void peripherals_pcnt_reset(void);