diff options
| author | Nick Moore <nick@zoic.org> | 2018-06-06 17:07:09 +1000 |
|---|---|---|
| committer | Nick Moore <nick@zoic.org> | 2018-06-08 15:28:05 +1000 |
| commit | c4cf1c5221b3d098925530377052d5f6d3922136 (patch) | |
| tree | 9767cf414ec05effaf1b5c4f7974da690c087ae2 | |
| parent | 7adc69baf98bfe17a1e94a23bd24ae5b5a32f963 (diff) | |
Initial pulseio.PulseOut implementation for #716 ESP8266
| -rw-r--r-- | ports/esp8266/common-hal/pulseio/PulseOut.c | 66 | ||||
| -rw-r--r-- | ports/esp8266/common-hal/pulseio/PulseOut.h | 9 |
2 files changed, 72 insertions, 3 deletions
diff --git a/ports/esp8266/common-hal/pulseio/PulseOut.c b/ports/esp8266/common-hal/pulseio/PulseOut.c index db2f7cbd9..f1bf00cf9 100644 --- a/ports/esp8266/common-hal/pulseio/PulseOut.c +++ b/ports/esp8266/common-hal/pulseio/PulseOut.c @@ -24,23 +24,85 @@ * THE SOFTWARE. */ +#include "common-hal/pulseio/PulseOut.h" #include <stdint.h> +#include <pwm.h> + +#include "ets_alt_task.h" +#include "py/obj.h" #include "py/runtime.h" +#include "mpconfigport.h" #include "shared-bindings/pulseio/PulseOut.h" +#define NO_CHANNEL (255) + +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; + +void pulseout_set(pulseio_pulseout_obj_t *self, bool state) { + // XXX double kludge + //uint32_t duty = state ? pwm_get_period() * 11 : 0; + uint32_t duty = state ? 1000 : 500; + pwm_set_duty(duty, self->channel); + pwm_start(); +} + +void pulseout_interrupt_handler(void *data) { + pulseio_pulseout_obj_t *self = data; + + if (pulse_buffer == NULL || self->channel == NO_CHANNEL) return; + if (pulse_index >= pulse_length) return; + pulse_index++; + pulseout_set(self, pulse_index % 2 == 0); + + os_timer_arm(&self->timer, pulse_buffer[pulse_index], 0); +} + +void pulseout_reset() { + pulse_buffer = NULL; +} + void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, const pulseio_pwmout_obj_t* carrier) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "No hardware support for PulseOut.")); + self->channel = carrier->channel; } bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) { - return true; + return self->channel == NO_CHANNEL; } void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + os_timer_disarm(&self->timer); + self->channel = NO_CHANNEL; + pulseout_set(self, true); } void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { + if (pulse_buffer != NULL) { + mp_raise_RuntimeError("Another send is already active"); + } + pulse_buffer = pulses; + pulse_index = 0; + pulse_length = length; + + os_timer_disarm(&self->timer); + os_timer_setfn(&self->timer, pulseout_interrupt_handler, self); + os_timer_arm(&self->timer, pulse_buffer[0], 0); + pulseout_set(self, true); + + // XXX in the circumstances, is it worth messing with os_timer? + // it isn't especially accurate anyway ... + // might it not be simpler to just call mp_hal_delay_us() a lot? + while(pulse_index < length) { + ets_loop_iter(); + } + + os_timer_disarm(&self->timer); + pulseout_set(self, false); + + pulse_buffer = NULL; } diff --git a/ports/esp8266/common-hal/pulseio/PulseOut.h b/ports/esp8266/common-hal/pulseio/PulseOut.h index f4b8b910f..4af41ae6c 100644 --- a/ports/esp8266/common-hal/pulseio/PulseOut.h +++ b/ports/esp8266/common-hal/pulseio/PulseOut.h @@ -27,12 +27,19 @@ #ifndef MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H #define MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H +#include "common-hal/microcontroller/Pin.h" + +#include "esp_mphal.h" + #include "py/obj.h" typedef struct { mp_obj_base_t base; + os_timer_t timer; + uint8_t channel; } pulseio_pulseout_obj_t; -void pwmout_reset(void); +void pulseout_reset(void); +void pulseout_interrupt_handler(void *); #endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H |
