diff options
Diffstat (limited to 'ports/esp32/esp32_rmt.c')
| -rw-r--r-- | ports/esp32/esp32_rmt.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/ports/esp32/esp32_rmt.c b/ports/esp32/esp32_rmt.c index 1a7e77b9d..941f20818 100644 --- a/ports/esp32/esp32_rmt.c +++ b/ports/esp32/esp32_rmt.c @@ -27,10 +27,11 @@ #include "py/runtime.h" #include "modmachine.h" #include "mphalport.h" -#include "driver/rmt.h" - #include "modesp32.h" +#include "esp_task.h" +#include "driver/rmt.h" + // This exposes the ESP32's RMT module to MicroPython. RMT is provided by the Espressif ESP-IDF: // // https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html @@ -59,6 +60,34 @@ typedef struct _esp32_rmt_obj_t { bool loop_en; } esp32_rmt_obj_t; +typedef struct _rmt_install_state_t { + SemaphoreHandle_t handle; + uint8_t channel_id; + esp_err_t ret; +} rmt_install_state_t; + +STATIC void rmt_install_task(void *pvParameter) { + rmt_install_state_t *state = pvParameter; + state->ret = rmt_driver_install(state->channel_id, 0, 0); + xSemaphoreGive(state->handle); + vTaskDelete(NULL); + for (;;) { + } +} + +// Call rmt_driver_install on core 1. This ensures that the RMT interrupt handler is +// serviced on core 1, so that WiFi (if active) does not interrupt it and cause glitches. +esp_err_t rmt_driver_install_core1(uint8_t channel_id) { + TaskHandle_t th; + rmt_install_state_t state; + state.handle = xSemaphoreCreateBinary(); + state.channel_id = channel_id; + xTaskCreatePinnedToCore(rmt_install_task, "rmt_install_task", 2048 / sizeof(StackType_t), &state, ESP_TASK_PRIO_MIN + 1, &th, 1); + xSemaphoreTake(state.handle, portMAX_DELAY); + vSemaphoreDelete(state.handle); + return state.ret; +} + 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) { static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} }, @@ -125,7 +154,7 @@ 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_config(&config)); - check_esp_err(rmt_driver_install(config.channel, 0, 0)); + check_esp_err(rmt_driver_install_core1(config.channel)); return MP_OBJ_FROM_PTR(self); } |
