summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucian Copeland <hierophect@gmail.com>2020-08-04 10:59:05 -0400
committerLucian Copeland <hierophect@gmail.com>2020-08-14 12:21:41 -0400
commitf9512983ff0c63a719d7708496e1a827a2ca8a64 (patch)
treead4348994c8ff40faa4ea733940fc75195d78af5
parent98469322b7d35748f0f2cb03cc5bd4d470ea6339 (diff)
Add PulseOut
-rw-r--r--ports/esp32s2/common-hal/pulseio/PulseOut.c48
-rw-r--r--ports/esp32s2/common-hal/pulseio/PulseOut.h6
-rw-r--r--ports/esp32s2/mpconfigport.h13
-rw-r--r--ports/esp32s2/peripherals/rmt.c8
-rw-r--r--ports/esp32s2/peripherals/rmt.h1
-rw-r--r--ports/esp32s2/supervisor/port.c3
-rw-r--r--shared-bindings/pulseio/PulseOut.c26
-rw-r--r--shared-bindings/pulseio/PulseOut.h6
8 files changed, 82 insertions, 29 deletions
diff --git a/ports/esp32s2/common-hal/pulseio/PulseOut.c b/ports/esp32s2/common-hal/pulseio/PulseOut.c
index c448c578d..dc93d7e96 100644
--- a/ports/esp32s2/common-hal/pulseio/PulseOut.c
+++ b/ports/esp32s2/common-hal/pulseio/PulseOut.c
@@ -29,32 +29,52 @@
#include "shared-bindings/pulseio/PWMOut.h"
#include "py/runtime.h"
-// STATIC void turn_on(pulseio_pulseout_obj_t *pulseout) {
-// }
+// Requires rmt.c void esp32s2_peripherals_reset_all(void) to reset
-// STATIC void turn_off(pulseio_pulseout_obj_t *pulseout) {
-// }
+void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
+ const mcu_pin_obj_t* pin,
+ uint32_t frequency) {
-// STATIC void start_timer(void) {
-// }
+ rmt_channel_t channel = esp32s2_peripherals_find_and_reserve_rmt();
-// STATIC void pulseout_event_handler(void) {
-// }
+ // Configure Channel
+ rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin->number, channel);
+ config.tx_config.carrier_en = true;
+ config.tx_config.carrier_duty_percent = 50;
+ config.tx_config.carrier_freq_hz = frequency;
+ config.clk_div = 80;
-void pulseout_reset() {
-}
+ rmt_config(&config);
+ rmt_driver_install(channel, 0, 0);
-void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
- const pulseio_pwmout_obj_t* carrier) {
- mp_raise_NotImplementedError(translate("PulseOut not supported on this chip"));
+ self->channel = channel;
}
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
- return false;
+ return (self->channel == RMT_CHANNEL_MAX);
}
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
+ esp32s2_peripherals_free_rmt(self->channel);
+ self->channel = RMT_CHANNEL_MAX;
+
}
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
+ rmt_item32_t items[length];
+
+ // Circuitpython allows 16 bit pulse values, while ESP32 only allows 15 bits
+ // Thus, we use entire items for one pulse, rather than switching inside each item
+ for (size_t i = 0; i < length; i++) {
+ // Setting the RMT duration to 0 has undefined behavior, so avoid that pre-emptively.
+ if (pulses[i] == 0) {
+ pulses[i] = 1;
+ }
+ uint32_t level = (i % 2) ? 0 : 1;
+ const rmt_item32_t item = {{{ (pulses[i] & 0x8000 ? 0x7FFF : 1), level, (pulses[i] & 0x7FFF), level}}};
+ items[i] = item;
+ }
+
+ rmt_write_items(self->channel, items, length, true);
+ rmt_wait_tx_done(self->channel, pdMS_TO_TICKS(100));
}
diff --git a/ports/esp32s2/common-hal/pulseio/PulseOut.h b/ports/esp32s2/common-hal/pulseio/PulseOut.h
index f465d0079..513905992 100644
--- a/ports/esp32s2/common-hal/pulseio/PulseOut.h
+++ b/ports/esp32s2/common-hal/pulseio/PulseOut.h
@@ -29,14 +29,14 @@
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/pulseio/PWMOut.h"
+#include "driver/rmt.h"
+#include "rmt.h"
#include "py/obj.h"
typedef struct {
mp_obj_base_t base;
- pulseio_pwmout_obj_t *pwmout;
+ rmt_channel_t channel;
} pulseio_pulseout_obj_t;
-void pulseout_reset(void);
-
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_PULSEIO_PULSEOUT_H
diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h
index d340bb480..6b070afea 100644
--- a/ports/esp32s2/mpconfigport.h
+++ b/ports/esp32s2/mpconfigport.h
@@ -28,19 +28,20 @@
#ifndef ESP32S2_MPCONFIGPORT_H__
#define ESP32S2_MPCONFIGPORT_H__
-#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
-#define MICROPY_NLR_THUMB (0)
+#define CIRCUITPY_INTERNAL_NVM_SIZE (0)
+#define MICROPY_NLR_THUMB (0)
-#define MICROPY_PY_UJSON (0)
-#define MICROPY_USE_INTERNAL_PRINTF (0)
+#define MICROPY_PY_UJSON (0)
+#define MICROPY_USE_INTERNAL_PRINTF (0)
#include "py/circuitpy_mpconfig.h"
+#define CPY_PULSEOUT_USES_DIGITALIO (1)
#define MICROPY_PORT_ROOT_POINTERS \
CIRCUITPY_COMMON_ROOT_POINTERS
-#define MICROPY_NLR_SETJMP (1)
-#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000
+#define MICROPY_NLR_SETJMP (1)
+#define CIRCUITPY_DEFAULT_STACK_SIZE (0x6000)
#endif // __INCLUDED_ESP32S2_MPCONFIGPORT_H
diff --git a/ports/esp32s2/peripherals/rmt.c b/ports/esp32s2/peripherals/rmt.c
index f17957c1c..16605edf5 100644
--- a/ports/esp32s2/peripherals/rmt.c
+++ b/ports/esp32s2/peripherals/rmt.c
@@ -29,6 +29,14 @@
bool rmt_reserved_channels[RMT_CHANNEL_MAX];
+void esp32s2_peripherals_rmt_reset(void) {
+ for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
+ if (rmt_reserved_channels[i]) {
+ esp32s2_peripherals_free_rmt(i);
+ }
+ }
+}
+
rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void) {
for (size_t i = 0; i < RMT_CHANNEL_MAX; i++) {
if (!rmt_reserved_channels[i]) {
diff --git a/ports/esp32s2/peripherals/rmt.h b/ports/esp32s2/peripherals/rmt.h
index 4741a5bc5..01ed09907 100644
--- a/ports/esp32s2/peripherals/rmt.h
+++ b/ports/esp32s2/peripherals/rmt.h
@@ -31,6 +31,7 @@
#include "driver/rmt.h"
#include <stdint.h>
+void esp32s2_peripherals_rmt_reset(void);
rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void);
void esp32s2_peripherals_free_rmt(rmt_channel_t chan);
diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c
index e4767e514..d287079b7 100644
--- a/ports/esp32s2/supervisor/port.c
+++ b/ports/esp32s2/supervisor/port.c
@@ -42,6 +42,8 @@
#include "supervisor/memory.h"
#include "supervisor/shared/tick.h"
+#include "rmt.h"
+
STATIC esp_timer_handle_t _tick_timer;
void tick_timer_cb(void* arg) {
@@ -66,6 +68,7 @@ void reset_port(void) {
vTaskDelay(4);
#if CIRCUITPY_PULSEIO
+ esp32s2_peripherals_rmt_reset();
pwmout_reset();
#endif
#if CIRCUITPY_BUSIO
diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c
index 3d35f0544..10524f51b 100644
--- a/shared-bindings/pulseio/PulseOut.c
+++ b/shared-bindings/pulseio/PulseOut.c
@@ -64,19 +64,33 @@
//| pulse.send(pulses)"""
//| ...
//|
-STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+
+ pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t);
+ self->base.type = &pulseio_pulseout_type;
+
+ #ifndef CPY_PULSEOUT_USES_DIGITALIO
+ // Most ports pass a PWMOut
mp_arg_check_num(n_args, kw_args, 1, 1, false);
mp_obj_t carrier_obj = args[0];
-
if (!MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) {
mp_raise_TypeError_varg(translate("Expected a %q"), pulseio_pwmout_type.name);
}
+ common_hal_pulseio_pulseout_construct(self, (pulseio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj));
+ #else
+ // ESP32-S2 Special Case
+ enum { ARG_pin, ARG_frequency};
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 38000} },
+ };
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- // create Pulse object from the given pin
- pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t);
- self->base.type = &pulseio_pulseout_type;
+ const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj);
- common_hal_pulseio_pulseout_construct(self, (pulseio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj));
+ common_hal_pulseio_pulseout_construct(self, pin, args[ARG_frequency].u_int);
+ #endif
return MP_OBJ_FROM_PTR(self);
}
diff --git a/shared-bindings/pulseio/PulseOut.h b/shared-bindings/pulseio/PulseOut.h
index 390910ff6..090f6d15c 100644
--- a/shared-bindings/pulseio/PulseOut.h
+++ b/shared-bindings/pulseio/PulseOut.h
@@ -33,8 +33,14 @@
extern const mp_obj_type_t pulseio_pulseout_type;
+#ifndef CPY_PULSEOUT_USES_DIGITALIO
extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
const pulseio_pwmout_obj_t* carrier);
+#else
+extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
+ const mcu_pin_obj_t* pin, uint32_t frequency);
+#endif
+
extern void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self);
extern bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self);
extern void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self,