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
|
#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 nchanges = 2;
|
||||||
mp_uint_t start = mp_hal_ticks_us();
|
mp_uint_t start = mp_hal_ticks_us();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|||||||
@@ -27,11 +27,20 @@
|
|||||||
#include "user_interface.h"
|
#include "user_interface.h"
|
||||||
#include "py/ringbuf.h"
|
#include "py/ringbuf.h"
|
||||||
#include "shared/runtime/interrupt_char.h"
|
#include "shared/runtime/interrupt_char.h"
|
||||||
|
#include "ets_alt_task.h"
|
||||||
#include "xtirq.h"
|
#include "xtirq.h"
|
||||||
|
|
||||||
#define MICROPY_BEGIN_ATOMIC_SECTION() esp_disable_irq()
|
#define MICROPY_BEGIN_ATOMIC_SECTION() esp_disable_irq()
|
||||||
#define MICROPY_END_ATOMIC_SECTION(state) esp_enable_irq(state)
|
#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);
|
void mp_sched_keyboard_interrupt(void);
|
||||||
|
|
||||||
struct _mp_print_t;
|
struct _mp_print_t;
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
#include "os_type.h"
|
#include "os_type.h"
|
||||||
#include "osapi.h"
|
#include "osapi.h"
|
||||||
#include "etshal.h"
|
#include "etshal.h"
|
||||||
#include "ets_alt_task.h"
|
|
||||||
#include "user_interface.h"
|
#include "user_interface.h"
|
||||||
|
|
||||||
// #define MACHINE_WAKE_IDLE (0x01)
|
// #define MACHINE_WAKE_IDLE (0x01)
|
||||||
@@ -327,32 +326,3 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
|||||||
print, esp_timer_print,
|
print, esp_timer_print,
|
||||||
locals_dict, &esp_timer_locals_dict
|
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