From 11ef36d09dbbe24aa8dd4f50f732b862d73f765b Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 May 2021 16:24:45 -0500 Subject: [PATCH] Implement pulseout for RP2040 --- ports/raspberrypi/Makefile | 2 +- .../raspberrypi/common-hal/pulseio/PulseOut.c | 46 ++++++++++++------- .../raspberrypi/common-hal/pulseio/PulseOut.h | 4 +- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index 9333f5d1f4..ac13a061b7 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -106,7 +106,7 @@ INC += -I. \ -I$(BUILD) # Pico specific configuration -CFLAGS += -DRASPBERRYPI -DPICO_ON_DEVICE=1 -DPICO_NO_BINARY_INFO=0 -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1 -DPICO_DIVIDER_CALL_IDIV0=0 -DPICO_DIVIDER_CALL_LDIV0=0 -DPICO_DIVIDER_HARDWARE=1 -DPICO_DOUBLE_ROM=1 -DPICO_FLOAT_ROM=1 -DPICO_MULTICORE=1 -DPICO_BITS_IN_RAM=0 -DPICO_DIVIDER_IN_RAM=0 -DPICO_DOUBLE_PROPAGATE_NANS=0 -DPICO_DOUBLE_IN_RAM=0 -DPICO_MEM_IN_RAM=0 -DPICO_FLOAT_IN_RAM=0 -DPICO_FLOAT_PROPAGATE_NANS=1 -DPICO_NO_FLASH=0 -DPICO_COPY_TO_RAM=0 -DPICO_DISABLE_SHARED_IRQ_HANDLERS=0 -DPICO_NO_BI_BOOTSEL_VIA_DOUBLE_RESET=0 +CFLAGS += -DRASPBERRYPI -DPICO_ON_DEVICE=1 -DPICO_NO_BINARY_INFO=0 -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=0 -DPICO_DIVIDER_CALL_IDIV0=0 -DPICO_DIVIDER_CALL_LDIV0=0 -DPICO_DIVIDER_HARDWARE=1 -DPICO_DOUBLE_ROM=1 -DPICO_FLOAT_ROM=1 -DPICO_MULTICORE=1 -DPICO_BITS_IN_RAM=0 -DPICO_DIVIDER_IN_RAM=0 -DPICO_DOUBLE_PROPAGATE_NANS=0 -DPICO_DOUBLE_IN_RAM=0 -DPICO_MEM_IN_RAM=0 -DPICO_FLOAT_IN_RAM=0 -DPICO_FLOAT_PROPAGATE_NANS=1 -DPICO_NO_FLASH=0 -DPICO_COPY_TO_RAM=0 -DPICO_DISABLE_SHARED_IRQ_HANDLERS=0 -DPICO_NO_BI_BOOTSEL_VIA_DOUBLE_RESET=0 OPTIMIZATION_FLAGS ?= -O3 # TinyUSB defines CFLAGS += -DTUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024 diff --git a/ports/raspberrypi/common-hal/pulseio/PulseOut.c b/ports/raspberrypi/common-hal/pulseio/PulseOut.c index c3536af04b..1a7b5892c1 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseOut.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseOut.c @@ -27,31 +27,38 @@ #include "common-hal/pulseio/PulseOut.h" #include - -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" - #include "mpconfigport.h" -#include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pwmio/PWMOut.h" +#include "common-hal/pwmio/PWMOut.h" #include "supervisor/shared/translate.h" +#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" +#include "src/common/pico_time/include/pico/time.h" static uint8_t refcount = 0; - - static uint16_t *pulse_buffer = NULL; static volatile uint16_t pulse_index = 0; static uint16_t pulse_length; -static volatile uint32_t current_compare = 0; +pwmio_pwmout_obj_t *pwmout_obj; +volatile uint16_t current_duty_cycle; void pulse_finish(void) { pulse_index++; - - // Always turn it off. + // Turn pwm pin off by settting duty cyle to 1. + common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,1); if (pulse_index >= pulse_length) { return; } - current_compare = (current_compare + pulse_buffer[pulse_index] * 3 / 4) & 0xffff; + add_alarm_in_us( pulse_buffer[pulse_index], pulseout_interrupt_handler, NULL, false); + if (pulse_index % 2 == 0) { + common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,current_duty_cycle); + } +} + +int64_t pulseout_interrupt_handler(alarm_id_t id, void *user_data) { + pulse_finish(); + return 0; } void pulseout_reset() { @@ -63,12 +70,13 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self, const mcu_pin_obj_t *pin, uint32_t frequency, uint16_t duty_cycle) { - mp_raise_NotImplementedError(translate("Unsupported operation")); refcount++; - + pwmout_obj = (pwmio_pwmout_obj_t *)carrier; + current_duty_cycle = common_hal_pwmio_pwmout_get_duty_cycle(pwmout_obj); self->pin = carrier->pin->number; - + self->slice = carrier->slice; + pwm_set_enabled (pwmout_obj->slice,false); } bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t *self) { @@ -79,8 +87,6 @@ void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t *self) { if (common_hal_pulseio_pulseout_deinited(self)) { return; } - - refcount--; self->pin = NO_PIN; } @@ -90,6 +96,14 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu pulse_index = 0; pulse_length = length; - current_compare = pulses[0] * 3 / 4; + add_alarm_in_us( pulses[0], pulseout_interrupt_handler, NULL, false); + common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,current_duty_cycle); + pwm_set_enabled (pwmout_obj->slice,true); + while(pulse_index < length) { + // Do other things while we wait. The interrupts will handle sending the + // signal. + RUN_BACKGROUND_TASKS; + } + pwm_set_enabled (pwmout_obj->slice,false); } diff --git a/ports/raspberrypi/common-hal/pulseio/PulseOut.h b/ports/raspberrypi/common-hal/pulseio/PulseOut.h index 4f1bb9fa7a..8dcebdba98 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseOut.h +++ b/ports/raspberrypi/common-hal/pulseio/PulseOut.h @@ -28,6 +28,7 @@ #define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H #include "common-hal/microcontroller/Pin.h" +#include "src/common/pico_time/include/pico/time.h" #include "py/obj.h" @@ -36,9 +37,10 @@ typedef struct { mp_obj_base_t base; uint8_t pin; + uint8_t slice; } pulseio_pulseout_obj_t; void pulseout_reset(void); -void pulseout_interrupt_handler(uint8_t index); +int64_t pulseout_interrupt_handler(alarm_id_t id, void *user_data); #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H