RMT: add loop_autostop driver support for esp32s3

This commit is contained in:
SalimTerryLi
2021-07-30 08:40:17 +08:00
parent b857c86535
commit bd89dcc683
10 changed files with 102 additions and 83 deletions

View File

@@ -856,16 +856,35 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel);
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT #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 channel RMT channel
* @param count loop count * @param count loop count, 1 ~ 1023
* @return * @return
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success * - ESP_OK Success
*/ */
esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count); 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. * @brief Reset RMT TX/RX memory index.

View File

@@ -74,6 +74,7 @@ typedef struct {
size_t tx_sub_len; size_t tx_sub_len;
bool translator; bool translator;
bool wait_done; //Mark whether wait tx done. bool wait_done; //Mark whether wait tx done.
bool loop_autostop; // mark whether loop auto-stop is enabled
rmt_channel_t channel; rmt_channel_t channel;
const rmt_item32_t *tx_data; const rmt_item32_t *tx_data;
xSemaphoreHandle tx_sem; xSemaphoreHandle tx_sem;
@@ -892,6 +893,13 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
status &= ~(1 << channel); status &= ~(1 << channel);
rmt_obj_t *p_rmt = p_rmt_obj[channel]; rmt_obj_t *p_rmt = p_rmt_obj[channel];
if (p_rmt) { 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); xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken);
if (rmt_contex.rmt_tx_end_callback.function) { if (rmt_contex.rmt_tx_end_callback.function) {
rmt_contex.rmt_tx_end_callback.function(channel, rmt_contex.rmt_tx_end_callback.arg); 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_offset = 0;
p_rmt_obj[channel]->tx_sub_len = 0; p_rmt_obj[channel]->tx_sub_len = 0;
p_rmt_obj[channel]->wait_done = false; p_rmt_obj[channel]->wait_done = false;
p_rmt_obj[channel]->loop_autostop = false;
p_rmt_obj[channel]->translator = false; p_rmt_obj[channel]->translator = false;
p_rmt_obj[channel]->sample_to_rmt = NULL; p_rmt_obj[channel]->sample_to_rmt = NULL;
if (p_rmt_obj[channel]->tx_sem == 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_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(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_ENTER_CRITICAL();
rmt_ll_tx_set_loop_count(rmt_contex.hal.regs, channel, count); rmt_ll_tx_set_loop_count(rmt_contex.hal.regs, channel, count);
RMT_EXIT_CRITICAL(); RMT_EXIT_CRITICAL();
return ESP_OK; 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 #endif

View File

@@ -1,16 +1,9 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
@@ -23,6 +16,9 @@
extern "C" { extern "C" {
#endif #endif
#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */
#define RMT_LL_HW_BASE (&RMT) #define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM) #define RMT_LL_MEM_BASE (&RMTMEM)

View File

@@ -1,16 +1,9 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
@@ -23,6 +16,8 @@
extern "C" { extern "C" {
#endif #endif
#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */
#define RMT_LL_HW_BASE (&RMT) #define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM) #define RMT_LL_MEM_BASE (&RMTMEM)

View File

@@ -1,16 +1,9 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
@@ -22,6 +15,8 @@
extern "C" { extern "C" {
#endif #endif
#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */
#define RMT_LL_HW_BASE (&RMT) #define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM) #define RMT_LL_MEM_BASE (&RMTMEM)

View File

@@ -1,16 +1,9 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#pragma once #pragma once
#include <stddef.h> #include <stddef.h>
@@ -22,6 +15,7 @@
extern "C" { extern "C" {
#endif #endif
#define RMT_LL_MAX_LOOP_COUNT (1023)/*!< Max loop count that hardware is supported */
#define RMT_LL_HW_BASE (&RMT) #define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM) #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; 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) 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; dev->chn_tx_lim[channel].tx_loop_num_chn = count;

View File

@@ -1,16 +1,8 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD /*
// * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
/* /*
* Soc capabilities file, describing the following chip attributes: * Soc capabilities file, describing the following chip attributes:

View File

@@ -132,16 +132,17 @@
#define SOC_PCNT_THRES_POINT_PER_UNIT (2) #define SOC_PCNT_THRES_POINT_PER_UNIT (2)
/*-------------------------- RMT CAPS ----------------------------------------*/ /*-------------------------- RMT CAPS ----------------------------------------*/
#define SOC_RMT_GROUPS (1) /*!< One RMT group */ #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_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_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_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_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_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_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_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_TX_LOOP_AUTOSTOP (1) /*!< Hardware support of auto-stop in loop mode */
#define SOC_RMT_SUPPORT_XTAL (1) /*!< Support set XTAL clock as the RMT clock source */ #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 ----------------------------------------*/ /*-------------------------- LCD CAPS ----------------------------------------*/

View File

@@ -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` * 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` * 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 Receive Mode Parameters
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -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/memprot_ll.h
components/hal/esp32c3/include/hal/mpu_ll.h components/hal/esp32c3/include/hal/mpu_ll.h
components/hal/esp32c3/include/hal/mwdt_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/rtc_cntl_ll.h
components/hal/esp32c3/include/hal/rwdt_ll.h components/hal/esp32c3/include/hal/rwdt_ll.h
components/hal/esp32c3/include/hal/sha_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/memprot_ll.h
components/hal/esp32h2/include/hal/mpu_ll.h components/hal/esp32h2/include/hal/mpu_ll.h
components/hal/esp32h2/include/hal/mwdt_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/rtc_cntl_ll.h
components/hal/esp32h2/include/hal/rwdt_ll.h components/hal/esp32h2/include/hal/rwdt_ll.h
components/hal/esp32h2/include/hal/sha_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/mpu_ll.h
components/hal/esp32s2/include/hal/mwdt_ll.h components/hal/esp32s2/include/hal/mwdt_ll.h
components/hal/esp32s2/include/hal/pcnt_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_cntl_ll.h
components/hal/esp32s2/include/hal/rtc_io_ll.h components/hal/esp32s2/include/hal/rtc_io_ll.h
components/hal/esp32s2/include/hal/rwdt_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/mpu_ll.h
components/hal/esp32s3/include/hal/mwdt_ll.h components/hal/esp32s3/include/hal/mwdt_ll.h
components/hal/esp32s3/include/hal/pcnt_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_cntl_ll.h
components/hal/esp32s3/include/hal/rtc_io_ll.h components/hal/esp32s3/include/hal/rtc_io_ll.h
components/hal/esp32s3/include/hal/rwdt_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/sens_struct.h
components/soc/esp32s2/include/soc/sensitive_reg.h components/soc/esp32s2/include/soc/sensitive_reg.h
components/soc/esp32s2/include/soc/soc.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_pins.h
components/soc/esp32s2/include/soc/soc_ulp.h components/soc/esp32s2/include/soc/soc_ulp.h
components/soc/esp32s2/include/soc/spi_mem_reg.h components/soc/esp32s2/include/soc/spi_mem_reg.h