From 85db016b8c6464ba256f155000a5946b78109ad6 Mon Sep 17 00:00:00 2001 From: Sola85 Date: Mon, 2 Jun 2025 09:01:29 +0200 Subject: [PATCH 1/4] espressif: use dma for pulseio --- ports/espressif/common-hal/pulseio/PulseIn.c | 22 ++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ports/espressif/common-hal/pulseio/PulseIn.c b/ports/espressif/common-hal/pulseio/PulseIn.c index f7e500790562a..e292761d3bbf2 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -80,8 +80,9 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu } // We add one to the maxlen version to ensure that two symbols at lease are // captured because we may skip the first portion of a symbol. - self->raw_symbols_size = MIN(64, maxlen / 2 + 1) * sizeof(rmt_symbol_word_t); - self->raw_symbols = (rmt_symbol_word_t *)m_malloc_without_collect(self->raw_symbols_size); + self->raw_symbols_size = (maxlen / 2 + 1) * sizeof(rmt_symbol_word_t); + // RMT DMA mode cannot access PSRAM -> ensure raw_symbols is in internal ram + self->raw_symbols = (rmt_symbol_word_t *)heap_caps_malloc(self->raw_symbols_size, MALLOC_CAP_INTERNAL); if (self->raw_symbols == NULL) { m_free(self->buffer); m_malloc_fail(self->raw_symbols_size); @@ -109,17 +110,26 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu .clk_src = RMT_CLK_SRC_DEFAULT, // 2 us resolution so we can capture 65ms pulses. The RMT period is only 15 bits. .resolution_hz = 1000000 / 2, - .mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL, + .mem_block_symbols = self->raw_symbols_size, + .flags.with_dma = 1 }; - // If we fail here, the buffers allocated above will be garbage collected. - CHECK_ESP_RESULT(rmt_new_rx_channel(&config, &self->channel)); + // If we fail here, the self->buffer will be garbage collected. + esp_err_t result = rmt_new_rx_channel(&config, &self->channel); + if (result != ESP_OK){ + heap_caps_free(self->raw_symbols); + raise_esp_error(result); + } rmt_rx_event_callbacks_t rx_callback = { .on_recv_done = _done_callback }; rmt_rx_register_event_callbacks(self->channel, &rx_callback, self); rmt_enable(self->channel); - rmt_receive(self->channel, self->raw_symbols, self->raw_symbols_size, &rx_config); + result = rmt_receive(self->channel, self->raw_symbols, self->raw_symbols_size, &rx_config); + if (result != ESP_OK){ + heap_caps_free(self->raw_symbols); + raise_esp_error(result); + } } bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t *self) { From dde4a40c594783f037c927546a11eef51f0352f6 Mon Sep 17 00:00:00 2001 From: Sola85 Date: Mon, 2 Jun 2025 16:16:17 +0200 Subject: [PATCH 2/4] fix whitespaces --- ports/espressif/common-hal/pulseio/PulseIn.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/espressif/common-hal/pulseio/PulseIn.c b/ports/espressif/common-hal/pulseio/PulseIn.c index e292761d3bbf2..d76542b07c5ac 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -115,7 +115,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu }; // If we fail here, the self->buffer will be garbage collected. esp_err_t result = rmt_new_rx_channel(&config, &self->channel); - if (result != ESP_OK){ + if (result != ESP_OK) { heap_caps_free(self->raw_symbols); raise_esp_error(result); } @@ -126,7 +126,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu rmt_rx_register_event_callbacks(self->channel, &rx_callback, self); rmt_enable(self->channel); result = rmt_receive(self->channel, self->raw_symbols, self->raw_symbols_size, &rx_config); - if (result != ESP_OK){ + if (result != ESP_OK) { heap_caps_free(self->raw_symbols); raise_esp_error(result); } From a2ad339de06745f9cc894bbbea938e32cc6dd63b Mon Sep 17 00:00:00 2001 From: Sola85 Date: Tue, 10 Jun 2025 19:05:33 +0200 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Dan Halbert --- ports/espressif/common-hal/pulseio/PulseIn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/espressif/common-hal/pulseio/PulseIn.c b/ports/espressif/common-hal/pulseio/PulseIn.c index d76542b07c5ac..a90f9796ab8c5 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -82,7 +82,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu // captured because we may skip the first portion of a symbol. self->raw_symbols_size = (maxlen / 2 + 1) * sizeof(rmt_symbol_word_t); // RMT DMA mode cannot access PSRAM -> ensure raw_symbols is in internal ram - self->raw_symbols = (rmt_symbol_word_t *)heap_caps_malloc(self->raw_symbols_size, MALLOC_CAP_INTERNAL); + self->raw_symbols = (rmt_symbol_word_t *)port_malloc(self->raw_symbols_size, true); if (self->raw_symbols == NULL) { m_free(self->buffer); m_malloc_fail(self->raw_symbols_size); @@ -116,7 +116,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu // If we fail here, the self->buffer will be garbage collected. esp_err_t result = rmt_new_rx_channel(&config, &self->channel); if (result != ESP_OK) { - heap_caps_free(self->raw_symbols); + port_free(self->raw_symbols); raise_esp_error(result); } @@ -127,7 +127,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu rmt_enable(self->channel); result = rmt_receive(self->channel, self->raw_symbols, self->raw_symbols_size, &rx_config); if (result != ESP_OK) { - heap_caps_free(self->raw_symbols); + port_free(self->raw_symbols); raise_esp_error(result); } } From f999afd2c8d53ca3a3525fdf4fc3d9f592d114eb Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 11 Jun 2025 12:45:48 -0400 Subject: [PATCH 4/4] espressif: port_malloc() shoud not use SPIRAM when dma_capable=true --- ports/espressif/supervisor/port.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index 121335245dc33..6785fffcd2288 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -304,18 +304,18 @@ void port_heap_init(void) { } void *port_malloc(size_t size, bool dma_capable) { - size_t caps = MALLOC_CAP_8BIT; if (dma_capable) { - caps |= MALLOC_CAP_DMA; + // SPIRAM is not DMA-capable, so don't bother to ask for it. + return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA); } void *ptr = NULL; - // Try SPIRAM first when available. + // Try SPIRAM first if available. #ifdef CONFIG_SPIRAM - ptr = heap_caps_malloc(size, caps | MALLOC_CAP_SPIRAM); + ptr = heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); #endif if (ptr == NULL) { - ptr = heap_caps_malloc(size, caps); + ptr = heap_caps_malloc(size, MALLOC_CAP_8BIT); } return ptr; }