summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Moore <nick@zoic.org>2018-06-06 17:07:09 +1000
committerNick Moore <nick@zoic.org>2018-06-08 15:28:05 +1000
commitc4cf1c5221b3d098925530377052d5f6d3922136 (patch)
tree9767cf414ec05effaf1b5c4f7974da690c087ae2
parent7adc69baf98bfe17a1e94a23bd24ae5b5a32f963 (diff)
Initial pulseio.PulseOut implementation for #716 ESP8266
-rw-r--r--ports/esp8266/common-hal/pulseio/PulseOut.c66
-rw-r--r--ports/esp8266/common-hal/pulseio/PulseOut.h9
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