From 379f454ce6480376eccc8ccf378524d30fdace7a Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 23 Feb 2021 19:26:11 -0600 Subject: Adding countio to rp2040 --- ports/raspberrypi/common-hal/countio/Counter.c | 81 +++++++++++++++++++++++++ ports/raspberrypi/common-hal/countio/Counter.h | 19 ++++++ ports/raspberrypi/common-hal/countio/__init__.c | 1 + ports/raspberrypi/mpconfigport.h | 5 +- ports/raspberrypi/mpconfigport.mk | 1 - 5 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 ports/raspberrypi/common-hal/countio/Counter.c create mode 100644 ports/raspberrypi/common-hal/countio/Counter.h create mode 100644 ports/raspberrypi/common-hal/countio/__init__.c (limited to 'ports') diff --git a/ports/raspberrypi/common-hal/countio/Counter.c b/ports/raspberrypi/common-hal/countio/Counter.c new file mode 100644 index 000000000..c5a47d2a4 --- /dev/null +++ b/ports/raspberrypi/common-hal/countio/Counter.c @@ -0,0 +1,81 @@ +#include "common-hal/countio/Counter.h" + +#include "py/runtime.h" +#include "py/mpstate.h" +#include "supervisor/shared/translate.h" + +#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" +#include "src/rp2_common/hardware_irq/include/hardware/irq.h" + + +void common_hal_countio_counter_construct(countio_counter_obj_t* self, + const mcu_pin_obj_t* pin_a) { + + if (pwm_gpio_to_channel(pin_a->number) != PWM_CHAN_B) { + mp_raise_RuntimeError(translate("Pin must be on PWM Channel B")); + } + + self->pin_a = pin_a->number; + self->slice_num = pwm_gpio_to_slice_num(self->pin_a); + + pwm_clear_irq(self->slice_num); + pwm_set_irq_enabled(self->slice_num, true); + irq_set_exclusive_handler(PWM_IRQ_WRAP, counter_interrupt_handler); + irq_set_enabled(PWM_IRQ_WRAP, true); + + pwm_config cfg = pwm_get_default_config(); + pwm_config_set_clkdiv_mode(&cfg, PWM_DIV_B_RISING); + pwm_init(self->slice_num, &cfg, false); + gpio_set_function(self->pin_a, GPIO_FUNC_PWM); + + self->count = 0; + + claim_pin(pin_a); + + MP_STATE_PORT(counting) = self; + + pwm_set_enabled(self->slice_num, true); +} + +bool common_hal_countio_counter_deinited(countio_counter_obj_t* self) { + return self->pin_a == 0; +} + +void common_hal_countio_counter_deinit(countio_counter_obj_t* self) { + if (common_hal_countio_counter_deinited(self)) { + return; + } + + pwm_set_enabled(self->slice_num, false); + pwm_set_irq_enabled(self->slice_num, false); + + reset_pin_number(self->pin_a); + gpio_init(self->pin_a); + self->pin_a = 0; + self->slice_num = 0; + MP_STATE_PORT(counting) = NULL; +} + +mp_int_t common_hal_countio_counter_get_count(countio_counter_obj_t* self) { + self->count += pwm_get_counter(self->slice_num); + pwm_set_counter(self->slice_num, 0); + return self->count; +} + +void common_hal_countio_counter_set_count(countio_counter_obj_t* self, + mp_int_t new_count) { + pwm_set_counter(self->slice_num, 0); + self->count = new_count; +} + +void common_hal_countio_counter_reset(countio_counter_obj_t* self){ + pwm_set_counter(self->slice_num, 0); + self->count = 0; +} + +void counter_interrupt_handler() { + countio_counter_obj_t *self = MP_STATE_PORT(counting); + pwm_clear_irq(self->slice_num); + self->count += 65536; +} diff --git a/ports/raspberrypi/common-hal/countio/Counter.h b/ports/raspberrypi/common-hal/countio/Counter.h new file mode 100644 index 000000000..201034cf4 --- /dev/null +++ b/ports/raspberrypi/common-hal/countio/Counter.h @@ -0,0 +1,19 @@ + +#ifndef MICROPY_INCLUDED_RASPBERRRYPI_COMMON_HAL_COUNTIO_COUNTER_H +#define MICROPY_INCLUDED_RASPBERRRYPI_COMMON_HAL_COUNTIO_COUNTER_H + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t pin_a; + uint8_t slice_num; + mp_int_t count; +} countio_counter_obj_t; + + +void counter_interrupt_handler(); + +#endif // MICROPY_INCLUDED_RASPBERRRYPI_COMMON_HAL_COUNTIO_COUNTER_H diff --git a/ports/raspberrypi/common-hal/countio/__init__.c b/ports/raspberrypi/common-hal/countio/__init__.c new file mode 100644 index 000000000..b95b20d15 --- /dev/null +++ b/ports/raspberrypi/common-hal/countio/__init__.c @@ -0,0 +1 @@ +//No countio module functions diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index 77d1ff080..b1165a3ba 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -40,7 +40,10 @@ // This also includes mpconfigboard.h. #include "py/circuitpy_mpconfig.h" +//#include "peripherals/samd/dma.h" + #define MICROPY_PORT_ROOT_POINTERS \ - CIRCUITPY_COMMON_ROOT_POINTERS; + CIRCUITPY_COMMON_ROOT_POINTERS \ + mp_obj_t counting; #endif // __INCLUDED_MPCONFIGPORT_H diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 138896d41..15e17cd6f 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -29,7 +29,6 @@ CIRCUITPY_PWMIO = 1 # Things that need to be implemented. CIRCUITPY_AUDIOBUSIO = 0 # Use PIO interally for I2S CIRCUITPY_AUDIOMP3 = 0 -CIRCUITPY_COUNTIO = 0 # Use PWM interally CIRCUITPY_FREQUENCYIO = 0 # Use PWM interally CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_NVM = 0 -- cgit v1.2.3 From d7bc8a46a5f244069c2bc9b62961bc43dcee03a7 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 27 Feb 2021 15:17:27 -0600 Subject: Added counters per slice --- locale/circuitpython.pot | 6 +++++- ports/raspberrypi/common-hal/countio/Counter.c | 29 +++++++++++++++++++------- ports/raspberrypi/mpconfigport.h | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) (limited to 'ports') diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index e5ed6149a..7414c3973 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -539,7 +539,6 @@ msgstr "" #: ports/atmel-samd/common-hal/displayio/ParallelBus.c #: ports/esp32s2/common-hal/displayio/ParallelBus.c #: ports/nrf/common-hal/displayio/ParallelBus.c -#: ports/raspberrypi/common-hal/displayio/ParallelBus.c #, c-format msgid "Bus pin %d is already in use" msgstr "" @@ -1688,6 +1687,10 @@ msgid "" "PWM frequency not writable when variable_frequency is False on construction." msgstr "" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice already in use" +msgstr "" + #: ports/mimxrt10xx/common-hal/displayio/ParallelBus.c #: ports/raspberrypi/common-hal/displayio/ParallelBus.c #: ports/stm/common-hal/displayio/ParallelBus.c @@ -3687,6 +3690,7 @@ msgstr "" #: ports/esp32s2/boards/targett_module_clip_wrover/mpconfigboard.h #: ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.h #: ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h +#: ports/esp32s2/boards/unexpectedmaker_tinys2/mpconfigboard.h msgid "pressing boot button at start up.\n" msgstr "" diff --git a/ports/raspberrypi/common-hal/countio/Counter.c b/ports/raspberrypi/common-hal/countio/Counter.c index c5a47d2a4..4a1ccad0c 100644 --- a/ports/raspberrypi/common-hal/countio/Counter.c +++ b/ports/raspberrypi/common-hal/countio/Counter.c @@ -19,6 +19,10 @@ void common_hal_countio_counter_construct(countio_counter_obj_t* self, self->pin_a = pin_a->number; self->slice_num = pwm_gpio_to_slice_num(self->pin_a); + if (MP_STATE_PORT(counting)[self->slice_num] != NULL) { + mp_raise_RuntimeError(translate("PWM slice already in use")); + } + pwm_clear_irq(self->slice_num); pwm_set_irq_enabled(self->slice_num, true); irq_set_exclusive_handler(PWM_IRQ_WRAP, counter_interrupt_handler); @@ -29,12 +33,11 @@ void common_hal_countio_counter_construct(countio_counter_obj_t* self, pwm_init(self->slice_num, &cfg, false); gpio_set_function(self->pin_a, GPIO_FUNC_PWM); - self->count = 0; - claim_pin(pin_a); - MP_STATE_PORT(counting) = self; + MP_STATE_PORT(counting)[self->slice_num] = self; + self->count = 0; pwm_set_enabled(self->slice_num, true); } @@ -51,10 +54,10 @@ void common_hal_countio_counter_deinit(countio_counter_obj_t* self) { pwm_set_irq_enabled(self->slice_num, false); reset_pin_number(self->pin_a); - gpio_init(self->pin_a); + + MP_STATE_PORT(counting)[self->slice_num] = NULL; self->pin_a = 0; self->slice_num = 0; - MP_STATE_PORT(counting) = NULL; } mp_int_t common_hal_countio_counter_get_count(countio_counter_obj_t* self) { @@ -75,7 +78,17 @@ void common_hal_countio_counter_reset(countio_counter_obj_t* self){ } void counter_interrupt_handler() { - countio_counter_obj_t *self = MP_STATE_PORT(counting); - pwm_clear_irq(self->slice_num); - self->count += 65536; + uint32_t mask = pwm_get_irq_status_mask(); + + uint8_t i = 1, pos = 1; + while (!(i & mask)) { + i = i << 1; + ++pos; + } + + countio_counter_obj_t *self = MP_STATE_PORT(counting)[pos-1]; + if (self != NULL) { + pwm_clear_irq(self->slice_num); + self->count += 65536; + } } diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index eb0754e38..ccc8e8b03 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -43,7 +43,7 @@ #include "py/circuitpy_mpconfig.h" #define MICROPY_PORT_ROOT_POINTERS \ - mp_obj_t counting; \ + mp_obj_t counting[NUM_PWM_SLICES]; \ mp_obj_t playing_audio[NUM_DMA_CHANNELS]; \ CIRCUITPY_COMMON_ROOT_POINTERS; -- cgit v1.2.3 From 4246cc3f6d718e2f28fbeb73fc8c3c39dfb9d7f0 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 2 Mar 2021 19:32:06 -0600 Subject: Counter and PWMOut slice conflict check --- locale/circuitpython.pot | 4 ++++ ports/raspberrypi/common-hal/countio/Counter.c | 9 +++++++++ ports/raspberrypi/common-hal/pwmio/PWMOut.c | 23 +++++++++++++++++++++++ ports/raspberrypi/common-hal/pwmio/PWMOut.h | 4 ++++ 4 files changed, 40 insertions(+) (limited to 'ports') diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 7414c3973..7a9d0ce4b 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -1691,6 +1691,10 @@ msgstr "" msgid "PWM slice already in use" msgstr "" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice channel A already in use" +msgstr "" + #: ports/mimxrt10xx/common-hal/displayio/ParallelBus.c #: ports/raspberrypi/common-hal/displayio/ParallelBus.c #: ports/stm/common-hal/displayio/ParallelBus.c diff --git a/ports/raspberrypi/common-hal/countio/Counter.c b/ports/raspberrypi/common-hal/countio/Counter.c index 4a1ccad0c..69629a084 100644 --- a/ports/raspberrypi/common-hal/countio/Counter.c +++ b/ports/raspberrypi/common-hal/countio/Counter.c @@ -4,6 +4,8 @@ #include "py/mpstate.h" #include "supervisor/shared/translate.h" +#include "common-hal/pwmio/PWMOut.h" + #include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" #include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" #include "src/rp2_common/hardware_irq/include/hardware/irq.h" @@ -23,6 +25,11 @@ void common_hal_countio_counter_construct(countio_counter_obj_t* self, mp_raise_RuntimeError(translate("PWM slice already in use")); } + uint8_t channel = pwm_gpio_to_channel(self->pin_a); + if (!pwmio_claim_slice_channels(self->slice_num)) { + mp_raise_RuntimeError(translate("PWM slice channel A already in use")); + } + pwm_clear_irq(self->slice_num); pwm_set_irq_enabled(self->slice_num, true); irq_set_exclusive_handler(PWM_IRQ_WRAP, counter_interrupt_handler); @@ -53,6 +60,8 @@ void common_hal_countio_counter_deinit(countio_counter_obj_t* self) { pwm_set_enabled(self->slice_num, false); pwm_set_irq_enabled(self->slice_num, false); + pwmio_release_slice_channels(self->slice_num); + reset_pin_number(self->pin_a); MP_STATE_PORT(counting)[self->slice_num] = NULL; diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index 00b461880..348d99ebe 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -61,6 +61,29 @@ static uint32_t _mask(uint8_t slice, uint8_t channel) { return 1 << (slice * CHANNELS_PER_SLICE + channel); } +bool pwmio_claim_slice_channels(uint8_t slice) { + uint32_t channel_use_mask_a = _mask(slice, 0); + uint32_t channel_use_mask_b = _mask(slice, 1); + + if ((channel_use & channel_use_mask_a) != 0) { + return false; + } + if ((channel_use & channel_use_mask_b) != 0) { + return false; + } + + channel_use |= channel_use_mask_a; + channel_use |= channel_use_mask_b; + return true; +} + +void pwmio_release_slice_channels(uint8_t slice) { + uint32_t channel_mask = _mask(slice, 0); + channel_use &= ~channel_mask; + channel_mask = _mask(slice, 1); + channel_use &= ~channel_mask; +} + void common_hal_pwmio_pwmout_never_reset(pwmio_pwmout_obj_t *self) { never_reset_channel |= _mask(self->slice, self->channel); diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.h b/ports/raspberrypi/common-hal/pwmio/PWMOut.h index 0070e188b..6c0dda2db 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.h +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.h @@ -46,4 +46,8 @@ void pwmout_reset(void); // Private API for AudioPWMOut. void pwmio_pwmout_set_top(pwmio_pwmout_obj_t* self, uint16_t top); +// Private API for countio to claim both channels on a slice +bool pwmio_claim_slice_channels(uint8_t slice); +void pwmio_release_slice_channels(uint8_t slice); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PWMIO_PWMOUT_H -- cgit v1.2.3 From 98075c525515f9104e93100c180cadc3b9e8fc69 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 2 Mar 2021 22:32:59 -0600 Subject: Fixed merge --- ports/raspberrypi/common-hal/pwmio/PWMOut.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ports') diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index 4343b9e5c..fd85fbf55 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -82,6 +82,7 @@ void pwmio_release_slice_channels(uint8_t slice) { channel_use &= ~channel_mask; channel_mask = _mask(slice, 1); channel_use &= ~channel_mask; +} void pwmout_never_reset(uint8_t slice, uint8_t channel) { never_reset_channel |= _mask(slice, channel); -- cgit v1.2.3