diff options
author | Jonathan Hogg <me@jonathanhogg.com> | 2020-06-26 14:55:07 +0100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2020-07-21 00:57:14 +1000 |
commit | 7dbef5377cd86a4f20a16acd3ad7798c4160aabc (patch) | |
tree | d574d78407ebc35097f50f9356bf765ecbb4b849 | |
parent | 5264478007c78b7737972404bda18ab39d792e17 (diff) |
esp32/esp32_rmt: Properly fix looping behaviour of RMT.
A previous commit 3a9d948032e27f690e1fb09084c36bd47b1a75a0 can cause
lock-ups of the RMT driver, so this commit reverses that, adds a loop_en
flag, and explicitly controls the TX interrupt in write_pulses(). This
provides correct looping, non-blocking writes and sensible behaviour for
wait_done().
See also #6167.
-rw-r--r-- | ports/esp32/esp32_rmt.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index 2ed4c9f69..7971ca5d1 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -56,6 +56,7 @@ typedef struct _esp32_rmt_obj_t { uint32_t carrier_freq; mp_uint_t num_items; rmt_item32_t *items; + bool loop_en; } esp32_rmt_obj_t; STATIC mp_obj_t esp32_rmt_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { @@ -93,6 +94,7 @@ STATIC mp_obj_t esp32_rmt_make_new(const mp_obj_type_t *type, size_t n_args, siz self->clock_div = clock_div; self->carrier_duty_percent = carrier_duty_percent; self->carrier_freq = carrier_freq; + self->loop_en = false; rmt_config_t config; config.rmt_mode = RMT_MODE_TX; @@ -110,8 +112,8 @@ STATIC mp_obj_t esp32_rmt_make_new(const mp_obj_type_t *type, size_t n_args, siz config.clk_div = self->clock_div; - check_esp_err(rmt_driver_install(config.channel, 0, 0)); check_esp_err(rmt_config(&config)); + check_esp_err(rmt_driver_install(config.channel, 0, 0)); return MP_OBJ_FROM_PTR(self); } @@ -180,7 +182,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_rmt_wait_done_obj, 1, esp32_rmt_wait_don STATIC mp_obj_t esp32_rmt_loop(mp_obj_t self_in, mp_obj_t loop) { esp32_rmt_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_esp_err(rmt_set_tx_loop_mode(self->channel_id, mp_obj_get_int(loop))); + self->loop_en = mp_obj_get_int(loop); + if (!self->loop_en) { + bool loop_en; + check_esp_err(rmt_get_tx_loop_mode(self->channel_id, &loop_en)); + if (loop_en) { + check_esp_err(rmt_set_tx_loop_mode(self->channel_id, false)); + check_esp_err(rmt_set_tx_intr_en(self->channel_id, true)); + } + } return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_rmt_loop_obj, esp32_rmt_loop); @@ -222,8 +232,24 @@ STATIC mp_obj_t esp32_rmt_write_pulses(size_t n_args, const mp_obj_t *pos_args, self->items[item_index].level1 = start++; } } + + if (self->loop_en) { + bool loop_en; + check_esp_err(rmt_get_tx_loop_mode(self->channel_id, &loop_en)); + if (loop_en) { + check_esp_err(rmt_set_tx_intr_en(self->channel_id, true)); + check_esp_err(rmt_set_tx_loop_mode(self->channel_id, false)); + } + check_esp_err(rmt_wait_tx_done(self->channel_id, portMAX_DELAY)); + check_esp_err(rmt_set_tx_intr_en(self->channel_id, false)); + } + check_esp_err(rmt_write_items(self->channel_id, self->items, num_items, false /* non-blocking */)); + if (self->loop_en) { + check_esp_err(rmt_set_tx_loop_mode(self->channel_id, true)); + } + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_rmt_write_pulses_obj, 2, esp32_rmt_write_pulses); |