From 284239e94df71891219fc10d97a5df5b3628ef79 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 21 Mar 2021 14:17:35 -0500 Subject: [PATCH] PulseIn: add frequency selection .. implemented only on raspberrypi, where it's easiest. If this is considered useful enough, we can potentially implement it on at least SOME other ports. However, each port is a bit different so for now I just made them ignore the frequency= constructor parameter and return 1_000_000 for the frequency property. This is useful to me because using a frequency of 1000 lets me track the length of WWWB symbols, which range in length from 200ms to 800ms long. --- ports/atmel-samd/common-hal/pulseio/PulseIn.c | 6 +++- ports/cxd56/common-hal/pulseio/PulseIn.c | 8 +++-- ports/esp32s2/common-hal/pulseio/PulseIn.c | 8 +++-- ports/mimxrt10xx/common-hal/pulseio/PulseIn.c | 8 +++-- ports/nrf/common-hal/pulseio/PulseIn.c | 7 ++++- .../raspberrypi/common-hal/pulseio/PulseIn.c | 8 +++-- ports/stm/common-hal/pulseio/PulseIn.c | 8 +++-- shared-bindings/pulseio/PulseIn.c | 31 +++++++++++++++++-- shared-bindings/pulseio/PulseIn.h | 3 +- 9 files changed, 71 insertions(+), 16 deletions(-) diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index f65d583640b1e..3a3bda88b5d68 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -145,7 +145,7 @@ void pulsein_reset() { } void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, - const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { + const mcu_pin_obj_t* pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { if (!pin->has_extint) { mp_raise_RuntimeError(translate("No hardware support on pin")); } @@ -324,6 +324,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { return self->maxlen; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t* self) { + return 1000000; +} + uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { return self->len; } diff --git a/ports/cxd56/common-hal/pulseio/PulseIn.c b/ports/cxd56/common-hal/pulseio/PulseIn.c index 0d2fbbfd968a4..ccac19bdde13d 100644 --- a/ports/cxd56/common-hal/pulseio/PulseIn.c +++ b/ports/cxd56/common-hal/pulseio/PulseIn.c @@ -83,8 +83,8 @@ static int pulsein_interrupt_handler(int irq, FAR void *context, FAR void *arg) return 0; } -void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, - const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); if (self->buffer == NULL) { mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); @@ -175,6 +175,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self) { return self->maxlen; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t* self) { + return 1000000; +} + bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self) { return self->paused; } diff --git a/ports/esp32s2/common-hal/pulseio/PulseIn.c b/ports/esp32s2/common-hal/pulseio/PulseIn.c index a9533179bb3ba..54e23cde6f5c4 100644 --- a/ports/esp32s2/common-hal/pulseio/PulseIn.c +++ b/ports/esp32s2/common-hal/pulseio/PulseIn.c @@ -83,8 +83,8 @@ void pulsein_reset(void) { refcount = 0; } -void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, - uint16_t maxlen, bool idle_state) { +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); if (self->buffer == NULL) { mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t)); @@ -203,6 +203,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self) { return self->maxlen; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t* self) { + return 1000000; +} + bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self) { return self->paused; } diff --git a/ports/mimxrt10xx/common-hal/pulseio/PulseIn.c b/ports/mimxrt10xx/common-hal/pulseio/PulseIn.c index c1f7ce20b62e0..49c6161627ec4 100644 --- a/ports/mimxrt10xx/common-hal/pulseio/PulseIn.c +++ b/ports/mimxrt10xx/common-hal/pulseio/PulseIn.c @@ -101,8 +101,8 @@ // self->last_us = current_us; // } -void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, - const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { // if (!pin->has_extint) { // mp_raise_RuntimeError(translate("No hardware support on pin")); // } @@ -218,6 +218,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self) { return 0; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t* self) { + return 1000000; +} + uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t *self) { // return self->len; return 0; diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index f8f877d965c8e..c7f4df4e8f534 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -125,7 +125,8 @@ void pulsein_reset(void) { memset(_objs, 0, sizeof(_objs)); } -void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { int idx = _find_pulsein_obj(NULL); if (idx < 0) { mp_raise_NotImplementedError(NULL); @@ -308,6 +309,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self) { return self->maxlen; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t* self) { + return 1000000; +} + bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self) { return self->paused; } diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 278c0cd66202b..d236731a10676 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -49,7 +49,7 @@ uint16_t pulsein_program[] = { }; void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, - const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { + const mcu_pin_obj_t *pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); if (self->buffer == NULL) { @@ -67,7 +67,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, bool ok = rp2pio_statemachine_construct(&state_machine, pulsein_program, sizeof(pulsein_program) / sizeof(pulsein_program[0]), - 1000000, + frequency, NULL, 0, NULL, 0, pin, 1, @@ -206,6 +206,10 @@ uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t *self) { return self->len; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t *self) { + return common_hal_rp2pio_statemachine_get_frequency(&self->state_machine); +} + bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self) { return true; } diff --git a/ports/stm/common-hal/pulseio/PulseIn.c b/ports/stm/common-hal/pulseio/PulseIn.c index ece02f66a8f60..a79d5f94dc6ac 100644 --- a/ports/stm/common-hal/pulseio/PulseIn.c +++ b/ports/stm/common-hal/pulseio/PulseIn.c @@ -108,8 +108,8 @@ void pulsein_reset(void) { refcount = 0; } -void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, - uint16_t maxlen, bool idle_state) { +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint32_t frequency, uint16_t maxlen, bool idle_state) { // STM32 has one shared EXTI for each pin number, 0-15 uint8_t p_num = pin->number; if (_objs[p_num]) { @@ -272,6 +272,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self) { return self->maxlen; } +uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t* self) { + return 1000000; +} + bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self) { return self->paused; } diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 18a5d3f3e57a0..765b12f56c480 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -40,7 +40,7 @@ //| and low cost temperature sensors (DHT). The pulsed signal consists of timed active and //| idle periods. Unlike PWM, there is no set duration for active and idle pairs.""" //| -//| def __init__(self, pin: microcontroller.Pin, maxlen: int = 2, *, idle_state: bool = False) -> None: +//| def __init__(self, pin: microcontroller.Pin, maxlen: int = 2, *, idle_state: bool = False, frequency : int = 1_000_000) -> None: //| """Create a PulseIn object associated with the given pin. The object acts as //| a read-only sequence of pulse lengths with a given max length. When it is //| active, new pulse lengths are added to the end of the list. When there is @@ -49,6 +49,10 @@ //| //| :param ~microcontroller.Pin pin: Pin to read pulses from. //| :param int maxlen: Maximum number of pulse durations to store at once +//| :param int frequency: Pulses are measured in number of +//| cycles. The default makes 1 = 1µs. This value may be +//| rounded, the actual value can be retrieved via the +//| `PulseIn.frequency` property. //| :param bool idle_state: Idle state of the pin. At start and after `resume` //| the first recorded pulse will the opposite state from idle. //| @@ -77,10 +81,11 @@ //| ... //| STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_pin, ARG_maxlen, ARG_idle_state }; + enum { ARG_pin, ARG_maxlen, ARG_frequency, ARG_idle_state }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_maxlen, MP_ARG_INT, {.u_int = 2} }, + { MP_QSTR_frequency, MP_ARG_INT, {.u_int = 1000000} }, { MP_QSTR_idle_state, MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -90,7 +95,7 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg pulseio_pulsein_obj_t *self = m_new_obj(pulseio_pulsein_obj_t); self->base.type = &pulseio_pulsein_type; - common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, + common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, args[ARG_frequency].u_int, args[ARG_idle_state].u_bool); return MP_OBJ_FROM_PTR(self); @@ -196,6 +201,25 @@ STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_popleft); +//| frequency: int +//| """The frequency of the counter in Hz. 1_000_000 indicates that +//| pulse lengths are in units of microseconds.""" +//| +STATIC mp_obj_t pulseio_pulsein_obj_get_frequency(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_frequency(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_frequency_obj, pulseio_pulsein_obj_get_frequency); + +const mp_obj_property_t pulseio_pulsein_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pulsein_get_frequency_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| maxlen: int //| """The maximum length of the PulseIn. When len() is equal to maxlen, //| it is unclear which pulses are active and which are idle.""" @@ -302,6 +326,7 @@ STATIC const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&pulseio_pulsein_popleft_obj) }, // Properties + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&pulseio_pulsein_frequency_obj) }, { MP_ROM_QSTR(MP_QSTR_maxlen), MP_ROM_PTR(&pulseio_pulsein_maxlen_obj) }, { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&pulseio_pulsein_paused_obj) }, }; diff --git a/shared-bindings/pulseio/PulseIn.h b/shared-bindings/pulseio/PulseIn.h index 09d01fded75ef..381d940dea200 100644 --- a/shared-bindings/pulseio/PulseIn.h +++ b/shared-bindings/pulseio/PulseIn.h @@ -33,13 +33,14 @@ extern const mp_obj_type_t pulseio_pulsein_type; extern void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, - const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state); + const mcu_pin_obj_t *pin, uint32_t frequency, uint16_t maxlen, bool idle_state); extern void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self); extern bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t *self); extern void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t *self); extern void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, uint16_t trigger_duration); extern void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t *self); extern uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self); +extern uint32_t common_hal_pulseio_pulsein_get_frequency(pulseio_pulsein_obj_t *self); extern uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self); extern bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self); extern uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t *self);