Skip to content

Commit

Permalink
machine: Add wait_opposite to time_pulse_us func.
Browse files Browse the repository at this point in the history
If the pin is initially equal to *pulse_level* then first waits until
the pin input becomes different from *pulse_level*.
Then the function waits until the pin input becomes equal to *pulse_level*,
then the func counts the duration that the pin is equal to *pulse_level*.

Signed-off-by: IhorNehrutsa <[email protected]>
Co-Authored-By: Robert Hammelrath <[email protected]>
  • Loading branch information
IhorNehrutsa and robert-hh committed Dec 16, 2024
1 parent ee8d8b3 commit dd7b953
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 13 deletions.
13 changes: 8 additions & 5 deletions docs/library/machine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,22 @@ Miscellaneous functions
varies by hardware (so use substring of a full value if you expect a short
ID). In some MicroPython ports, ID corresponds to the network MAC address.

.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000, /)
.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000, wait_opposite=false, /)

Time a pulse on the given *pin*, and return the duration of the pulse in
microseconds. The *pulse_level* argument should be 0 to time a low pulse
or 1 to time a high pulse.

If the current input value of the pin is different to *pulse_level*,
the function first (*) waits until the pin input becomes equal to *pulse_level*,
then (**) times the duration that the pin is equal to *pulse_level*.
If *wait_opposite* is true, if the pin is initially equal to *pulse_level* then first
waits until the pin input becomes different from *pulse_level* (***).
Then if the current input value of the pin is different to *pulse_level*,
the function first (**) waits until the pin input becomes equal to *pulse_level*,
then (*) times the duration that the pin is equal to *pulse_level*.
If the pin is already equal to *pulse_level* then timing starts straight away.

The function returns -3 if there was timeout waiting for condition marked (***) above.
The function will return -2 if there was timeout waiting for condition marked
(*) above, and -1 if there was timeout during the main measurement, marked (**)
(**) above, and -1 if there was timeout during the main measurement, marked (*)
above. The timeout is the same for both cases and given by *timeout_us* (which
is in microseconds).

Expand Down
5 changes: 3 additions & 2 deletions drivers/dht/dht.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ static mp_obj_t dht_readinto(mp_obj_t pin_in, mp_obj_t buf_in) {
}
}

#define WAIT_OPPOSITE false
// time pulse, should be 80us
ticks = machine_time_pulse_us(pin, 1, 150);
ticks = machine_time_pulse_us(pin, 1, 150, WAIT_OPPOSITE);
if ((mp_int_t)ticks < 0) {
goto timeout;
}

// time 40 pulses for data (either 26us or 70us)
uint8_t *buf = bufinfo.buf;
for (int i = 0; i < 40; ++i) {
ticks = machine_time_pulse_us(pin, 1, 100);
ticks = machine_time_pulse_us(pin, 1, 100, WAIT_OPPOSITE);
if ((mp_int_t)ticks < 0) {
goto timeout;
}
Expand Down
18 changes: 14 additions & 4 deletions extmod/machine_pulse.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@

#if MICROPY_PY_MACHINE_PULSE

MP_WEAK mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
MP_WEAK mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us, bool wait_opposite) {
mp_uint_t start = mp_hal_ticks_us();
while (wait_opposite && (mp_hal_pin_read(pin) == pulse_level)) {
if ((uint64_t)(mp_hal_ticks_us() - start) >= (uint64_t)timeout_us) {
return (mp_uint_t)-3;
}
}
start = mp_hal_ticks_us();
while (mp_hal_pin_read(pin) != pulse_level) {
if ((mp_uint_t)(mp_hal_ticks_us() - start) >= timeout_us) {
return (mp_uint_t)-2;
Expand All @@ -56,10 +62,14 @@ static mp_obj_t machine_time_pulse_us_(size_t n_args, const mp_obj_t *args) {
if (n_args > 2) {
timeout_us = mp_obj_get_int(args[2]);
}
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us);
// May return -1 or -2 in case of timeout
bool wait_opposite = false;
if (n_args > 3) {
wait_opposite = mp_obj_is_true(args[3]);
}
mp_uint_t us = machine_time_pulse_us(pin, level, timeout_us, wait_opposite);
// May return -1 or -2 or -3 in case of timeout
return mp_obj_new_int(us);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 3, machine_time_pulse_us_);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_time_pulse_us_obj, 2, 4, machine_time_pulse_us_);

#endif
2 changes: 1 addition & 1 deletion extmod/modmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ uintptr_t MICROPY_MACHINE_MEM_GET_WRITE_ADDR(mp_obj_t addr_o, uint align);

NORETURN mp_obj_t machine_bootloader(size_t n_args, const mp_obj_t *args);
void machine_bitstream_high_low(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len);
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us);
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us, bool wait_opposite);

MP_DECLARE_CONST_FUN_OBJ_0(machine_unique_id_obj);
MP_DECLARE_CONST_FUN_OBJ_0(machine_reset_obj);
Expand Down
2 changes: 1 addition & 1 deletion ports/esp8266/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
);

// Custom version of this function that feeds system WDT if necessary
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
mp_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us, bool wait_opposite) {
int nchanges = 2;
uint32_t start = system_get_time(); // in microseconds
for (;;) {
Expand Down

0 comments on commit dd7b953

Please sign in to comment.