Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/platforms/esp/32/clockless_rmt_esp32.cpp')
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.cpp114
1 files changed, 104 insertions, 10 deletions
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.cpp b/src/platforms/esp/32/clockless_rmt_esp32.cpp
index 90ca046f..0f8ad9b3 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.cpp
+++ b/src/platforms/esp/32/clockless_rmt_esp32.cpp
@@ -108,12 +108,14 @@ uint8_t * ESP32RMTController::getPixelBuffer(int size_in_bytes)
void ESP32RMTController::init(gpio_num_t pin)
{
if (gInitialized) return;
+ esp_err_t espErr = ESP_OK;
for (int i = 0; i < gMaxChannel; i += gMemBlocks) {
gOnChannel[i] = NULL;
// -- RMT configuration for transmission
rmt_config_t rmt_tx;
+ memset(&rmt_tx, 0, sizeof(rmt_config_t));
rmt_tx.channel = rmt_channel_t(i);
rmt_tx.rmt_mode = RMT_MODE_TX;
rmt_tx.gpio_num = pin;
@@ -126,7 +128,8 @@ void ESP32RMTController::init(gpio_num_t pin)
rmt_tx.tx_config.idle_output_en = true;
// -- Apply the configuration
- rmt_config(&rmt_tx);
+ espErr = rmt_config(&rmt_tx);
+ FASTLED_DEBUG("rmt_config result: %d", espErr);
if (FASTLED_RMT_BUILTIN_DRIVER) {
rmt_driver_install(rmt_channel_t(i), 0, 0);
@@ -134,7 +137,8 @@ void ESP32RMTController::init(gpio_num_t pin)
// -- Set up the RMT to send 32 bits of the pulse buffer and then
// generate an interrupt. When we get this interrupt we
// fill the other part in preparation (like double-buffering)
- rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, PULSES_PER_FILL);
+ espErr = rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, PULSES_PER_FILL);
+ FASTLED_DEBUG("rmt_set_tx_thr_intr_en result: %d", espErr);
}
}
@@ -232,6 +236,7 @@ void IRAM_ATTR ESP32RMTController::startNext(int channel)
// for it to finish.
void IRAM_ATTR ESP32RMTController::startOnChannel(int channel)
{
+ esp_err_t espErr = ESP_OK;
// -- Assign this channel and configure the RMT
mRMT_channel = rmt_channel_t(channel);
@@ -240,7 +245,13 @@ void IRAM_ATTR ESP32RMTController::startOnChannel(int channel)
gOnChannel[channel] = this;
// -- Assign the pin to this channel
- rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin);
+#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)
+ espErr = rmt_set_gpio(mRMT_channel, RMT_MODE_TX, mPin, false);
+ FASTLED_DEBUG("rmt_set_gpio result: %d", espErr);
+#else
+ espErr = rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin);
+ FASTLED_DEBUG("rrmt_set_pin result: %d", espErr);
+#endif
if (FASTLED_RMT_BUILTIN_DRIVER) {
// -- Use the built-in RMT driver to send all the data in one shot
@@ -262,7 +273,8 @@ void IRAM_ATTR ESP32RMTController::startOnChannel(int channel)
fillNext(false);
// -- Turn on the interrupts
- rmt_set_tx_intr_en(mRMT_channel, true);
+ espErr = rmt_set_tx_intr_en(mRMT_channel, true);
+ FASTLED_DEBUG("rmt_set_tx_intr_en result: %d", espErr);
// -- Kick off the transmission
tx_start();
@@ -275,11 +287,46 @@ void IRAM_ATTR ESP32RMTController::tx_start()
{
// rmt_tx_start(mRMT_channel, true);
// Inline the code for rmt_tx_start, so it can be placed in IRAM
+#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
+ // rmt_ll_tx_reset_pointer(&RMT, mRMT_channel)
+ RMT.tx_conf[mRMT_channel].mem_rd_rst = 1;
+ RMT.tx_conf[mRMT_channel].mem_rd_rst = 0;
+ RMT.tx_conf[mRMT_channel].mem_rst = 1;
+ RMT.tx_conf[mRMT_channel].mem_rst = 0;
+ // rmt_ll_clear_tx_end_interrupt(&RMT, mRMT_channel)
+ RMT.int_clr.val = (1 << (mRMT_channel));
+ // rmt_ll_enable_tx_end_interrupt(&RMT, mRMT_channel, true)
+ RMT.int_ena.val |= (1 << mRMT_channel);
+ // rmt_ll_tx_start(&RMT, mRMT_channel)
+ RMT.tx_conf[mRMT_channel].conf_update = 1;
+ RMT.tx_conf[mRMT_channel].tx_start = 1;
+#elif CONFIG_IDF_TARGET_ESP32S3
+ // rmt_ll_tx_reset_pointer(&RMT, mRMT_channel)
+ RMT.chnconf0[mRMT_channel].mem_rd_rst_n = 1;
+ RMT.chnconf0[mRMT_channel].mem_rd_rst_n = 0;
+ RMT.chnconf0[mRMT_channel].apb_mem_rst_n = 1;
+ RMT.chnconf0[mRMT_channel].apb_mem_rst_n = 0;
+ // rmt_ll_clear_tx_end_interrupt(&RMT, mRMT_channel)
+ RMT.int_clr.val = (1 << (mRMT_channel));
+ // rmt_ll_enable_tx_end_interrupt(&RMT, mRMT_channel, true)
+ RMT.int_ena.val |= (1 << mRMT_channel);
+ // rmt_ll_tx_start(&RMT, mRMT_channel)
+ RMT.chnconf0[mRMT_channel].conf_update_n = 1;
+ RMT.chnconf0[mRMT_channel].tx_start_n = 1;
+#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32
+ // rmt_ll_tx_reset_pointer(&RMT, mRMT_channel)
RMT.conf_ch[mRMT_channel].conf1.mem_rd_rst = 1;
RMT.conf_ch[mRMT_channel].conf1.mem_rd_rst = 0;
+ // rmt_ll_clear_tx_end_interrupt(&RMT, mRMT_channel)
+ RMT.int_clr.val = (1 << (mRMT_channel * 3));
+ // rmt_ll_enable_tx_end_interrupt(&RMT, mRMT_channel, true)
RMT.int_ena.val &= ~(1 << (mRMT_channel * 3));
RMT.int_ena.val |= (1 << (mRMT_channel * 3));
+ // rmt_ll_tx_start(&RMT, mRMT_channel)
RMT.conf_ch[mRMT_channel].conf1.tx_start = 1;
+#else
+ #error Not yet implemented for unknown ESP32 target
+#endif
mLastFill = __clock_cycles();
}
@@ -299,10 +346,51 @@ void IRAM_ATTR ESP32RMTController::doneOnChannel(rmt_channel_t channel, void * a
// -- Turn off the interrupts
// rmt_set_tx_intr_en(channel, false);
- // Inline the code for rmt_tx_stop, so it can be placed in IRAM
+
+ // Inline the code for rmt_set_tx_intr_en(channel, false) and rmt_tx_stop, so it can be placed in IRAM
+#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
+ // rmt_ll_enable_tx_end_interrupt(&RMT, channel)
+ RMT.int_ena.val &= ~(1 << channel);
+ // rmt_ll_tx_stop(&RMT, channel)
+ RMT.tx_conf[channel].tx_stop = 1;
+ RMT.tx_conf[channel].conf_update = 1;
+ // rmt_ll_tx_reset_pointer(&RMT, channel)
+ RMT.tx_conf[channel].mem_rd_rst = 1;
+ RMT.tx_conf[channel].mem_rd_rst = 0;
+ RMT.tx_conf[channel].mem_rst = 1;
+ RMT.tx_conf[channel].mem_rst = 0;
+#elif CONFIG_IDF_TARGET_ESP32S3
+ // rmt_ll_enable_tx_end_interrupt(&RMT, channel)
+ RMT.int_ena.val &= ~(1 << channel);
+ // rmt_ll_tx_stop(&RMT, channel)
+ RMT.chnconf0[channel].tx_stop_n = 1;
+ RMT.chnconf0[channel].conf_update_n = 1;
+ // rmt_ll_tx_reset_pointer(&RMT, channel)
+ RMT.chnconf0[channel].mem_rd_rst_n = 1;
+ RMT.chnconf0[channel].mem_rd_rst_n = 0;
+ RMT.chnconf0[channel].apb_mem_rst_n = 1;
+ RMT.chnconf0[channel].apb_mem_rst_n = 0;
+#elif CONFIG_IDF_TARGET_ESP32S2
+ // rmt_ll_enable_tx_end_interrupt(&RMT, channel)
+ RMT.int_ena.val &= ~(1 << (channel * 3));
+ // rmt_ll_tx_stop(&RMT, channel)
+ RMT.conf_ch[channel].conf1.tx_stop = 1;
+ // rmt_ll_tx_reset_pointer(&RMT, channel)
+ RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
+ RMT.conf_ch[channel].conf1.mem_rd_rst = 0;
+#elif CONFIG_IDF_TARGET_ESP32
+ // rmt_ll_enable_tx_end_interrupt(&RMT, channel)
RMT.int_ena.val &= ~(1 << (channel * 3));
+ // rmt_ll_tx_stop(&RMT, channel)
+ RMT.conf_ch[channel].conf1.tx_start = 0;
RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
RMT.conf_ch[channel].conf1.mem_rd_rst = 0;
+ // rmt_ll_tx_reset_pointer(&RMT, channel)
+ // RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
+ // RMT.conf_ch[channel].conf1.mem_rd_rst = 0;
+#else
+ #error Not yet implemented for unknown ESP32 target
+#endif
gOnChannel[channel] = NULL;
gNumDone++;
@@ -337,11 +425,17 @@ void IRAM_ATTR ESP32RMTController::interruptHandler(void *arg)
uint8_t channel;
for (channel = 0; channel < gMaxChannel; channel++) {
+ #if CONFIG_IDF_TARGET_ESP32S2
int tx_done_bit = channel * 3;
- #ifdef CONFIG_IDF_TARGET_ESP32S2
int tx_next_bit = channel + 12;
- #else
+ #elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
+ int tx_done_bit = channel;
+ int tx_next_bit = channel + 8;
+ #elif CONFIG_IDF_TARGET_ESP32
+ int tx_done_bit = channel * 3;
int tx_next_bit = channel + 24;
+ #else
+ #error Not yet implemented for unknown ESP32 target
#endif
ESP32RMTController * pController = gOnChannel[channel];
@@ -369,9 +463,9 @@ void IRAM_ATTR ESP32RMTController::fillNext(bool check_time)
{
uint32_t now = __clock_cycles();
if (check_time) {
- if (mLastFill != 0 and now > mLastFill) {
- uint32_t delta = (now - mLastFill);
- if (delta > mMaxCyclesPerFill) {
+ if (mLastFill != 0) {
+ int32_t delta = (now - mLastFill);
+ if (delta > (int32_t)mMaxCyclesPerFill) {
// Serial.print(delta);
// Serial.print(" BAIL ");
// Serial.println(mCur);