esp8266/modmachine: Use common machine_time_pulse_us implementation.
Testing shows that for frequencies which the esp8266 can handle -- up to about 1kHz -- `machine.time_pulse_us()` now gives more accurate results. Prior to this commit it would measure on average about 1us lower, but now the average is much closer to the true value. For example a pulse that is 1000us long, it would measure between 998 and 1000us. Now it measures between 999us and 1001us. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
|
||||
#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_uint_t machine_time_pulse_us(mp_hal_pin_obj_t pin, int pulse_level, mp_uint_t timeout_us) {
|
||||
mp_uint_t nchanges = 2;
|
||||
mp_uint_t start = mp_hal_ticks_us();
|
||||
for (;;) {
|
||||
|
||||
@@ -27,11 +27,20 @@
|
||||
#include "user_interface.h"
|
||||
#include "py/ringbuf.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "xtirq.h"
|
||||
|
||||
#define MICROPY_BEGIN_ATOMIC_SECTION() esp_disable_irq()
|
||||
#define MICROPY_END_ATOMIC_SECTION(state) esp_enable_irq(state)
|
||||
|
||||
// During machine.time_pulse_us, feed WDT every now and then.
|
||||
#define MICROPY_PY_MACHINE_TIME_PULSE_US_HOOK(dt) \
|
||||
do { \
|
||||
if ((dt & 0xffff) == 0xffff && !ets_loop_dont_feed_sw_wdt) { \
|
||||
system_soft_wdt_feed(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void mp_sched_keyboard_interrupt(void);
|
||||
|
||||
struct _mp_print_t;
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "os_type.h"
|
||||
#include "osapi.h"
|
||||
#include "etshal.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
// #define MACHINE_WAKE_IDLE (0x01)
|
||||
@@ -327,32 +326,3 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
||||
print, esp_timer_print,
|
||||
locals_dict, &esp_timer_locals_dict
|
||||
);
|
||||
|
||||
// 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) {
|
||||
int nchanges = 2;
|
||||
uint32_t start = system_get_time(); // in microseconds
|
||||
for (;;) {
|
||||
uint32_t dt = system_get_time() - start;
|
||||
|
||||
// Check if pin changed to wanted value
|
||||
if (mp_hal_pin_read(pin) == pulse_level) {
|
||||
if (--nchanges == 0) {
|
||||
return dt;
|
||||
}
|
||||
pulse_level = 1 - pulse_level;
|
||||
start = system_get_time();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for timeout
|
||||
if (dt >= timeout_us) {
|
||||
return (mp_uint_t)-nchanges;
|
||||
}
|
||||
|
||||
// Only feed WDT every now and then, to make sure edge timing is accurate
|
||||
if ((dt & 0xffff) == 0xffff && !ets_loop_dont_feed_sw_wdt) {
|
||||
system_soft_wdt_feed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user