Merge branch 'feat/rmt_support_esp32c5mp' into 'master'

feat(rmt): add driver support on esp32c5

Closes IDF-8726

See merge request espressif/esp-idf!30879
This commit is contained in:
morris 2024-05-24 16:30:48 +08:00
commit 404ffa299b
23 changed files with 42 additions and 42 deletions

View File

@ -74,7 +74,7 @@ typedef dma_descriptor_align4_t rmt_dma_descriptor_t;
#define ALIGN_DOWN(num, align) ((num) & ~((align) - 1))
// Use retention link only when the target supports sleep retention and PM is enabled
#define RMT_USE_RETENTION_LINK (SOC_RMT_SUPPORT_SLEEP_BACKUP && CONFIG_PM_ENABLE && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
#define RMT_USE_RETENTION_LINK (SOC_RMT_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
typedef struct {
struct {

View File

@ -70,7 +70,8 @@ static esp_err_t rmt_rx_init_dma_link(rmt_rx_channel_t *rx_channel, const rmt_rx
gdma_rx_event_callbacks_t cbs = {
.on_recv_done = rmt_dma_rx_one_block_cb,
};
gdma_register_rx_event_callbacks(rx_channel->base.dma_chan, &cbs, rx_channel);
// register the DMA callbacks may fail if the interrupt service can not be installed successfully
ESP_RETURN_ON_ERROR(gdma_register_rx_event_callbacks(rx_channel->base.dma_chan, &cbs, rx_channel), TAG, "register DMA callbacks failed");
return ESP_OK;
}
#endif // SOC_RMT_SUPPORT_DMA
@ -188,9 +189,9 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_
ESP_RETURN_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA not supported");
#endif // SOC_RMT_SUPPORT_DMA
#if !SOC_RMT_SUPPORT_SLEEP_BACKUP
#if !SOC_RMT_SUPPORT_SLEEP_RETENTION
ESP_RETURN_ON_FALSE(config->flags.backup_before_sleep == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
#endif // SOC_RMT_SUPPORT_SLEEP_BACKUP
#endif // SOC_RMT_SUPPORT_SLEEP_RETENTION
// malloc channel memory
uint32_t mem_caps = RMT_MEM_ALLOC_CAPS;

View File

@ -92,7 +92,8 @@ static esp_err_t rmt_tx_init_dma_link(rmt_tx_channel_t *tx_channel, const rmt_tx
gdma_tx_event_callbacks_t cbs = {
.on_trans_eof = rmt_dma_tx_eof_cb,
};
gdma_register_tx_event_callbacks(tx_channel->base.dma_chan, &cbs, tx_channel);
// register the DMA callbacks may fail if the interrupt service can not be installed successfully
ESP_RETURN_ON_ERROR(gdma_register_tx_event_callbacks(tx_channel->base.dma_chan, &cbs, tx_channel), TAG, "register DMA callbacks failed");
return ESP_OK;
}
#endif // SOC_RMT_SUPPORT_DMA
@ -256,9 +257,9 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
ESP_RETURN_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA not supported");
#endif
#if !SOC_RMT_SUPPORT_SLEEP_BACKUP
#if !SOC_RMT_SUPPORT_SLEEP_RETENTION
ESP_RETURN_ON_FALSE(config->flags.backup_before_sleep == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
#endif // SOC_RMT_SUPPORT_SLEEP_BACKUP
#endif // SOC_RMT_SUPPORT_SLEEP_RETENTION
// malloc channel memory
uint32_t mem_caps = RMT_MEM_ALLOC_CAPS;

View File

@ -132,7 +132,7 @@ static void test_rmt_tx_rx_sleep_retention(bool back_up_before_sleep)
TEST_CASE("rmt tx+rx after light sleep", "[rmt]")
{
test_rmt_tx_rx_sleep_retention(false);
#if SOC_RMT_SUPPORT_SLEEP_BACKUP
#if SOC_RMT_SUPPORT_SLEEP_RETENTION
test_rmt_tx_rx_sleep_retention(true);
#endif
}

View File

@ -149,7 +149,7 @@ bool peripheral_domain_pd_allowed(void)
const uint32_t created_modules = sleep_retention_get_created_modules();
uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH));
#if SOC_RMT_SUPPORT_SLEEP_BACKUP
#if SOC_RMT_SUPPORT_SLEEP_RETENTION
mask |= BIT(SLEEP_RETENTION_MODULE_RMT0);
#endif

View File

@ -485,7 +485,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
* @param mask Interrupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)

View File

@ -427,7 +427,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
*/
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
@ -658,7 +658,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
* @param mask Interrupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)

View File

@ -13,7 +13,6 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "sdkconfig.h" // TODO: [ESP32C5] IDF-8726
#include "hal/misc.h"
#include "hal/assert.h"
#include "hal/rmt_types.h"
@ -24,8 +23,6 @@
extern "C" {
#endif
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
#define RMT_LL_EVENT_TX_DONE(channel) (1 << (channel))
#define RMT_LL_EVENT_TX_THRES(channel) (1 << ((channel) + 8))
#define RMT_LL_EVENT_TX_LOOP_END(channel) (1 << ((channel) + 12))
@ -436,7 +433,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
*/
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
@ -667,7 +664,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
* @param mask Interrupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
@ -883,8 +880,6 @@ static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
return (dev->int_st.val >> 12) & 0x03;
}
#endif // CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
#ifdef __cplusplus
}
#endif

View File

@ -463,7 +463,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
*/
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
@ -706,7 +706,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
* @param mask Interrupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)

View File

@ -423,7 +423,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
*/
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
@ -628,7 +628,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
* @param mask Interrupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)

View File

@ -453,7 +453,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
*/
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
@ -696,7 +696,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
* @param mask Interrupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)

View File

@ -12,7 +12,7 @@ void rmt_hal_init(rmt_hal_context_t *hal)
hal->regs = &RMT;
rmt_ll_power_down_mem(hal->regs, false); // turn on RMTMEM power domain
rmt_ll_enable_mem_access_nonfifo(hal->regs, true); // APB access the RMTMEM in nonfifo mode
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events
rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events
#if SOC_RMT_SUPPORT_TX_SYNCHRO
rmt_ll_tx_clear_sync_group(hal->regs);
@ -21,7 +21,7 @@ void rmt_hal_init(rmt_hal_context_t *hal)
void rmt_hal_deinit(rmt_hal_context_t *hal)
{
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events
rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events
rmt_ll_power_down_mem(hal->regs, true); // turn off RMTMEM power domain
hal->regs = NULL;

View File

@ -51,6 +51,10 @@ config SOC_I2S_SUPPORTED
bool
default y
config SOC_RMT_SUPPORTED
bool
default y
config SOC_GPSPI_SUPPORTED
bool
default y

View File

@ -821,13 +821,13 @@ typedef union {
} rmt_date_reg_t;
typedef struct {
typedef struct rmt_dev_t {
volatile rmt_chndata_reg_t chndata[4];
volatile rmt_chnconf0_reg_t chnconf0[2];
volatile rmt_chmconf0_reg_t ch2conf0;
volatile rmt_chmconf1_reg_t ch2conf1;
volatile rmt_chmconf0_reg_t ch3conf0;
volatile rmt_chmconf1_reg_t ch3conf1;
volatile struct {
rmt_chmconf0_reg_t conf0;
rmt_chmconf1_reg_t conf1;
} chmconf[2];;
volatile rmt_chnstatus_reg_t chnstatus[2];
volatile rmt_chmstatus_reg_t chmstatus[2];
volatile rmt_int_raw_reg_t int_raw;

View File

@ -39,7 +39,7 @@
#define SOC_RTC_FAST_MEM_SUPPORTED 1
#define SOC_RTC_MEM_SUPPORTED 1
#define SOC_I2S_SUPPORTED 1
// #define SOC_RMT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8726
#define SOC_RMT_SUPPORTED 1
// #define SOC_SDM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8687
#define SOC_GPSPI_SUPPORTED 1
// #define SOC_LEDC_SUPPORTED 1 // TODO: [ESP32C5] IDF-8684

View File

@ -799,7 +799,7 @@ config SOC_RMT_SUPPORT_RC_FAST
bool
default y
config SOC_RMT_SUPPORT_SLEEP_BACKUP
config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y

View File

@ -314,7 +314,7 @@
#define SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY 1 /*!< TX carrier can be modulated to data phase only */
#define SOC_RMT_SUPPORT_XTAL 1 /*!< Support set XTAL clock as the RMT clock source */
#define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST as the RMT clock source */
#define SOC_RMT_SUPPORT_SLEEP_BACKUP 1 /*!< Support back up registers before sleep */
#define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)

View File

@ -783,7 +783,7 @@ config SOC_RMT_SUPPORT_RC_FAST
bool
default y
config SOC_RMT_SUPPORT_SLEEP_BACKUP
config SOC_RMT_SUPPORT_SLEEP_RETENTION
bool
default y

View File

@ -306,7 +306,7 @@
#define SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY 1 /*!< TX carrier can be modulated to data phase only */
#define SOC_RMT_SUPPORT_XTAL 1 /*!< Support set XTAL clock as the RMT clock source */
#define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST as the RMT clock source */
#define SOC_RMT_SUPPORT_SLEEP_BACKUP 1 /*!< Support back up registers before sleep */
#define SOC_RMT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up RMT registers before sleep */
/*-------------------------- MCPWM CAPS --------------------------------------*/
#define SOC_MCPWM_GROUPS (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)

View File

@ -30,7 +30,7 @@ typedef struct {
extern const rmt_signal_conn_t rmt_periph_signals;
#if SOC_RMT_SUPPORT_SLEEP_BACKUP
#if SOC_RMT_SUPPORT_SLEEP_RETENTION
typedef struct {
const regdma_entries_config_t *regdma_entry_array;
uint32_t array_size;
@ -40,7 +40,7 @@ typedef struct {
// - save memory when not all RMT channels are used
// - specify different retention dependency, e.g. only RMT channel x is capable to use DMA, we only want to add the DMA dependency for that channel
extern const rmt_reg_retention_info_t rmt_reg_retention_info[SOC_RMT_GROUPS];
#endif // SOC_RMT_SUPPORT_SLEEP_BACKUP
#endif // SOC_RMT_SUPPORT_SLEEP_RETENTION
#endif // SOC_RMT_SUPPORTED

View File

@ -138,7 +138,6 @@ api-reference/peripherals/spi_master.rst
api-reference/peripherals/index.rst
api-reference/peripherals/sdmmc_host.rst
api-reference/peripherals/ecdsa.rst
api-reference/peripherals/rmt.rst
api-reference/kconfig.rst
api-reference/network/esp_openthread.rst
api-reference/network/esp_eth.rst

View File

@ -555,7 +555,7 @@ When power management is enabled, i.e., :ref:`CONFIG_PM_ENABLE` is on, the syste
The driver can prevent the above issue by creating a power management lock. The lock type is set based on different clock sources. The driver will acquire the lock in :cpp:func:`rmt_enable`, and release it in :cpp:func:`rmt_disable`. That means, any RMT transactions in between these two functions are guaranteed to work correctly, regardless of the power management strategy. The clock source won't be disabled or adjusted its frequency during this time.
.. only:: SOC_RMT_SUPPORT_SLEEP_BACKUP
.. only:: SOC_RMT_SUPPORT_SLEEP_RETENTION
Besides the potential changes to the clock source, when the power management is enabled, the system can also power down a domain where RMT register located. To ensure the RMT driver can continue work after sleep, we can either backup the RMT registers to the RAM, or just refuse to power down. You can choose what to do in :cpp:member:`rmt_tx_channel_config_t::backup_before_sleep` and :cpp:member:`rmt_rx_channel_config_t::backup_before_sleep`. It's a balance between power saving and memory consumption. Set it based on your application requirements.

View File

@ -555,7 +555,7 @@ RMT 编码器是 RMT TX 事务的一部分,用于在特定时间生成正确
驱动程序可以通过创建一个电源管理锁来防止上述问题。锁的类型会根据不同的时钟源来设置。驱动程序将在 :cpp:func:`rmt_enable` 中拿锁,并在 :cpp:func:`rmt_disable` 中释放锁。这意味着,无论电源管理策略如何,在这两个函数之间的任何 RMT 事务都可以保证正常工作。在此期间,时钟源不会被禁用或调整频率。
.. only:: SOC_RMT_SUPPORT_SLEEP_BACKUP
.. only:: SOC_RMT_SUPPORT_SLEEP_RETENTION
除了时钟源的潜在变化外,当启用电源管理时,系统还可以关闭 RMT 寄存器所在的电源域。为确保 RMT 驱动程序在睡眠后继续工作,用户要么选择将 RMT 相关的寄存器备份到 RAM 中,要么拒绝关闭电源域。你可以根据应用需求在 :cpp:member:`rmt_tx_channel_config_t::backup_before_sleep`:cpp:member:`rmt_rx_channel_config_t::backup_before_sleep` 中设置是否需要启用寄存器备份,在功耗和内存使用之间做权衡。