diff --git a/components/driver/include/driver/rmt.h b/components/driver/include/driver/rmt.h index a7e2aad5f2..bc07954a08 100644 --- a/components/driver/include/driver/rmt.h +++ b/components/driver/include/driver/rmt.h @@ -856,16 +856,35 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel); #if SOC_RMT_SUPPORT_TX_LOOP_COUNT /** - * @brief Set loop count for RMT TX channel + * @brief Set loop count threshold value for RMT TX channel + * + * When tx loop count reaches this value, an ISR callback will notify user * * @param channel RMT channel - * @param count loop count + * @param count loop count, 1 ~ 1023 * @return * - ESP_ERR_INVALID_ARG Parameter error * - ESP_OK Success */ esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count); -#endif + +/** + * @brief Enable or disable the feature that when loop count reaches the threshold, RMT will stop transmitting. + * + * - When the loop auto-stop feature is enabled will halt RMT transmission after the loop count reaches a certain threshold + * - When disabled, the RMT transmission continue indefinitely until halted by the users + * + * @note The auto-stop feature is implemented in hardware on particular targets (i.e. those with SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP defined). + * Otherwise, the auto-stop feature is implemented in software via the interrupt. + * + * @param channel RMT channel + * @param en enable bit + * @return + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_OK Success + */ +esp_err_t rmt_enable_tx_loop_autostop(rmt_channel_t channel, bool en); +#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT /** * @brief Reset RMT TX/RX memory index. diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 3165ae59af..e9cbe41f6f 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -74,6 +74,7 @@ typedef struct { size_t tx_sub_len; bool translator; bool wait_done; //Mark whether wait tx done. + bool loop_autostop; // mark whether loop auto-stop is enabled rmt_channel_t channel; const rmt_item32_t *tx_data; xSemaphoreHandle tx_sem; @@ -892,6 +893,13 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg) status &= ~(1 << channel); rmt_obj_t *p_rmt = p_rmt_obj[channel]; if (p_rmt) { + if (p_rmt->loop_autostop) { +#ifndef SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP + // hardware doesn't support automatically stop output so driver should stop output here (possibility already overshotted several us) + rmt_ll_tx_stop(rmt_contex.hal.regs, channel); + rmt_ll_tx_reset_pointer(rmt_contex.hal.regs, channel); +#endif + } xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken); if (rmt_contex.rmt_tx_end_callback.function) { rmt_contex.rmt_tx_end_callback.function(channel, rmt_contex.rmt_tx_end_callback.arg); @@ -1039,6 +1047,7 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr p_rmt_obj[channel]->tx_offset = 0; p_rmt_obj[channel]->tx_sub_len = 0; p_rmt_obj[channel]->wait_done = false; + p_rmt_obj[channel]->loop_autostop = false; p_rmt_obj[channel]->translator = false; p_rmt_obj[channel]->sample_to_rmt = NULL; if (p_rmt_obj[channel]->tx_sem == NULL) { @@ -1365,9 +1374,22 @@ esp_err_t rmt_memory_rw_rst(rmt_channel_t channel) esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count) { ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); + ESP_RETURN_ON_FALSE(count <= RMT_LL_MAX_LOOP_COUNT, ESP_ERR_INVALID_ARG, TAG, "Invalid count value"); RMT_ENTER_CRITICAL(); rmt_ll_tx_set_loop_count(rmt_contex.hal.regs, channel, count); RMT_EXIT_CRITICAL(); return ESP_OK; } + +esp_err_t rmt_enable_tx_loop_autostop(rmt_channel_t channel, bool en) +{ + ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); + p_rmt_obj[channel]->loop_autostop = en; +#if SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP + RMT_ENTER_CRITICAL(); + rmt_ll_tx_enable_loop_autostop(rmt_contex.hal.regs, channel, en); + RMT_EXIT_CRITICAL(); +#endif + return ESP_OK; +} #endif diff --git a/components/hal/esp32c3/include/hal/rmt_ll.h b/components/hal/esp32c3/include/hal/rmt_ll.h index 0f703aebc7..662e63f784 100644 --- a/components/hal/esp32c3/include/hal/rmt_ll.h +++ b/components/hal/esp32c3/include/hal/rmt_ll.h @@ -1,16 +1,9 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #pragma once #include @@ -23,6 +16,9 @@ extern "C" { #endif + +#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */ + #define RMT_LL_HW_BASE (&RMT) #define RMT_LL_MEM_BASE (&RMTMEM) diff --git a/components/hal/esp32h2/include/hal/rmt_ll.h b/components/hal/esp32h2/include/hal/rmt_ll.h index 6aa3655075..0403741429 100644 --- a/components/hal/esp32h2/include/hal/rmt_ll.h +++ b/components/hal/esp32h2/include/hal/rmt_ll.h @@ -1,16 +1,9 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #pragma once #include @@ -23,6 +16,8 @@ extern "C" { #endif +#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */ + #define RMT_LL_HW_BASE (&RMT) #define RMT_LL_MEM_BASE (&RMTMEM) diff --git a/components/hal/esp32s2/include/hal/rmt_ll.h b/components/hal/esp32s2/include/hal/rmt_ll.h index 958fe7aef5..ba73eaa2b7 100644 --- a/components/hal/esp32s2/include/hal/rmt_ll.h +++ b/components/hal/esp32s2/include/hal/rmt_ll.h @@ -1,16 +1,9 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #pragma once #include @@ -22,6 +15,8 @@ extern "C" { #endif +#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */ + #define RMT_LL_HW_BASE (&RMT) #define RMT_LL_MEM_BASE (&RMTMEM) diff --git a/components/hal/esp32s3/include/hal/rmt_ll.h b/components/hal/esp32s3/include/hal/rmt_ll.h index 2ef9273be1..2e6ddd563a 100644 --- a/components/hal/esp32s3/include/hal/rmt_ll.h +++ b/components/hal/esp32s3/include/hal/rmt_ll.h @@ -1,16 +1,9 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + #pragma once #include @@ -22,6 +15,7 @@ extern "C" { #endif +#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */ #define RMT_LL_HW_BASE (&RMT) #define RMT_LL_MEM_BASE (&RMTMEM) @@ -193,6 +187,11 @@ static inline bool rmt_ll_is_tx_loop_enabled(rmt_dev_t *dev, uint32_t channel) return dev->chnconf0[channel].tx_conti_mode_n; } +static inline void rmt_ll_tx_enable_loop_autostop(rmt_dev_t *dev, uint32_t channel, bool enable) +{ + dev->chn_tx_lim[channel].loop_stop_en_chn = enable; +} + static inline void rmt_ll_tx_set_loop_count(rmt_dev_t *dev, uint32_t channel, uint32_t count) { dev->chn_tx_lim[channel].tx_loop_num_chn = count; diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index b33af28f36..ac99759a96 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /* * Soc capabilities file, describing the following chip attributes: diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 05efa28328..c52f828d90 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -132,16 +132,17 @@ #define SOC_PCNT_THRES_POINT_PER_UNIT (2) /*-------------------------- RMT CAPS ----------------------------------------*/ -#define SOC_RMT_GROUPS (1) /*!< One RMT group */ -#define SOC_RMT_TX_CANDIDATES_PER_GROUP (4) /*!< Number of channels that capable of Transmit in each group */ -#define SOC_RMT_RX_CANDIDATES_PER_GROUP (4) /*!< Number of channels that capable of Receive in each group */ -#define SOC_RMT_CHANNELS_PER_GROUP (8) /*!< Total 8 channels */ -#define SOC_RMT_MEM_WORDS_PER_CHANNEL (48) /*!< Each channel owns 48 words memory (1 word = 4 Bytes) */ -#define SOC_RMT_SUPPORT_RX_PINGPONG (1) /*!< Support Ping-Pong mode on RX path */ -#define SOC_RMT_SUPPORT_RX_DEMODULATION (1) /*!< Support signal demodulation on RX path (i.e. remove carrier) */ -#define SOC_RMT_SUPPORT_TX_LOOP_COUNT (1) /*!< Support transmit specified number of cycles in loop mode */ -#define SOC_RMT_SUPPORT_TX_SYNCHRO (1) /*!< Support coordinate a group of TX channels to start simultaneously */ -#define SOC_RMT_SUPPORT_XTAL (1) /*!< Support set XTAL clock as the RMT clock source */ +#define SOC_RMT_GROUPS (1) /*!< One RMT group */ +#define SOC_RMT_TX_CANDIDATES_PER_GROUP (4) /*!< Number of channels that capable of Transmit in each group */ +#define SOC_RMT_RX_CANDIDATES_PER_GROUP (4) /*!< Number of channels that capable of Receive in each group */ +#define SOC_RMT_CHANNELS_PER_GROUP (8) /*!< Total 8 channels */ +#define SOC_RMT_MEM_WORDS_PER_CHANNEL (48) /*!< Each channel owns 48 words memory (1 word = 4 Bytes) */ +#define SOC_RMT_SUPPORT_RX_PINGPONG (1) /*!< Support Ping-Pong mode on RX path */ +#define SOC_RMT_SUPPORT_RX_DEMODULATION (1) /*!< Support signal demodulation on RX path (i.e. remove carrier) */ +#define SOC_RMT_SUPPORT_TX_LOOP_COUNT (1) /*!< Support transmit specified number of cycles in loop mode */ +#define SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP (1) /*!< Hardware support of auto-stop in loop mode */ +#define SOC_RMT_SUPPORT_TX_SYNCHRO (1) /*!< Support coordinate a group of TX channels to start simultaneously */ +#define SOC_RMT_SUPPORT_XTAL (1) /*!< Support set XTAL clock as the RMT clock source */ /*-------------------------- LCD CAPS ----------------------------------------*/ diff --git a/docs/en/api-reference/peripherals/rmt.rst b/docs/en/api-reference/peripherals/rmt.rst index b0758e7897..7495ebcee5 100644 --- a/docs/en/api-reference/peripherals/rmt.rst +++ b/docs/en/api-reference/peripherals/rmt.rst @@ -261,6 +261,11 @@ Transmit Mode Parameters * Binary level on the output to apply the carrier - :cpp:func:`rmt_set_tx_carrier`, selected from :cpp:type:`rmt_carrier_level_t` * Determines the binary level on the output when transmitter is idle - :cpp:func:`rmt_set_idle_level()`, selected from :cpp:type:`rmt_idle_level_t` +.. only:: SOC_RMT_SUPPORT_TX_LOOP_COUNT + + * Enable or disable loop count feature to automatically transmit items for N iterations, then trigger an ISR callback - :cpp:func:`rmt_set_tx_loop_count` + * Enable automatically stopping when the number of iterations matches the set loop count. Note this is not reliable for target that doesn't support `SOC_RMT_SUPPORT_TX_LOOP_AUTOSTOP`. - :cpp:func:`rmt_enable_tx_loop_autostop` + Receive Mode Parameters ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index ba948ef930..5bcf28c70f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1525,7 +1525,6 @@ components/hal/esp32c3/include/hal/ledc_ll.h components/hal/esp32c3/include/hal/memprot_ll.h components/hal/esp32c3/include/hal/mpu_ll.h components/hal/esp32c3/include/hal/mwdt_ll.h -components/hal/esp32c3/include/hal/rmt_ll.h components/hal/esp32c3/include/hal/rtc_cntl_ll.h components/hal/esp32c3/include/hal/rwdt_ll.h components/hal/esp32c3/include/hal/sha_ll.h @@ -1564,7 +1563,6 @@ components/hal/esp32h2/include/hal/ledc_ll.h components/hal/esp32h2/include/hal/memprot_ll.h components/hal/esp32h2/include/hal/mpu_ll.h components/hal/esp32h2/include/hal/mwdt_ll.h -components/hal/esp32h2/include/hal/rmt_ll.h components/hal/esp32h2/include/hal/rtc_cntl_ll.h components/hal/esp32h2/include/hal/rwdt_ll.h components/hal/esp32h2/include/hal/sha_ll.h @@ -1609,7 +1607,6 @@ components/hal/esp32s2/include/hal/memprot_peri_ll.h components/hal/esp32s2/include/hal/mpu_ll.h components/hal/esp32s2/include/hal/mwdt_ll.h components/hal/esp32s2/include/hal/pcnt_ll.h -components/hal/esp32s2/include/hal/rmt_ll.h components/hal/esp32s2/include/hal/rtc_cntl_ll.h components/hal/esp32s2/include/hal/rtc_io_ll.h components/hal/esp32s2/include/hal/rwdt_ll.h @@ -1648,7 +1645,6 @@ components/hal/esp32s3/include/hal/memprot_ll.h components/hal/esp32s3/include/hal/mpu_ll.h components/hal/esp32s3/include/hal/mwdt_ll.h components/hal/esp32s3/include/hal/pcnt_ll.h -components/hal/esp32s3/include/hal/rmt_ll.h components/hal/esp32s3/include/hal/rtc_cntl_ll.h components/hal/esp32s3/include/hal/rtc_io_ll.h components/hal/esp32s3/include/hal/rwdt_ll.h @@ -2564,7 +2560,6 @@ components/soc/esp32s2/include/soc/sens_reg.h components/soc/esp32s2/include/soc/sens_struct.h components/soc/esp32s2/include/soc/sensitive_reg.h components/soc/esp32s2/include/soc/soc.h -components/soc/esp32s2/include/soc/soc_caps.h components/soc/esp32s2/include/soc/soc_pins.h components/soc/esp32s2/include/soc/soc_ulp.h components/soc/esp32s2/include/soc/spi_mem_reg.h