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 --- ports/raspberrypi/common-hal/countio/Counter.c | 9 +++++++++ ports/raspberrypi/common-hal/pwmio/PWMOut.c | 23 +++++++++++++++++++++++ ports/raspberrypi/common-hal/pwmio/PWMOut.h | 4 ++++ 3 files changed, 36 insertions(+) (limited to 'ports') 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