rmt: support esp32h2

This commit is contained in:
morris 2023-01-06 15:27:19 +08:00
parent 57d9cb5ef6
commit b589fff0af
25 changed files with 915 additions and 47 deletions

View File

@ -186,6 +186,12 @@ typedef struct {
};
} rmt_config_t;
#if CONFIG_IDF_TARGET_ESP32H2
#define RMT_DEFAULT_CLK_DIV 32
#else
#define RMT_DEFAULT_CLK_DIV 80
#endif
/**
* @brief Default configuration for Tx channel
*
@ -195,7 +201,7 @@ typedef struct {
.rmt_mode = RMT_MODE_TX, \
.channel = channel_id, \
.gpio_num = gpio, \
.clk_div = 80, \
.clk_div = RMT_DEFAULT_CLK_DIV, \
.mem_block_num = 1, \
.flags = 0, \
.tx_config = { \
@ -219,7 +225,7 @@ typedef struct {
.rmt_mode = RMT_MODE_RX, \
.channel = channel_id, \
.gpio_num = gpio, \
.clk_div = 80, \
.clk_div = RMT_DEFAULT_CLK_DIV, \
.mem_block_num = 1, \
.flags = 0, \
.rx_config = { \

View File

@ -58,6 +58,16 @@ static const char *TAG = "rmt(legacy)";
#define RMT_DECODE_RX_CHANNEL(encode_chan) ((encode_chan - RMT_RX_CHANNEL_ENCODING_START))
#define RMT_ENCODE_RX_CHANNEL(decode_chan) ((decode_chan + RMT_RX_CHANNEL_ENCODING_START))
#if SOC_RMT_SUPPORT_APB
#define RMT_DEFAULT_CLOCK_FREQ esp_clk_apb_freq()
#elif SOC_RMT_SUPPORT_PLL_F80M
#define RMT_DEFAULT_CLOCK_FREQ (80*1000*1000)
#elif SOC_RMT_SUPPORT_XTAL
#define RMT_DEFAULT_CLOCK_FREQ esp_clk_xtal_freq()
#else
#error "RMT unknow default clock"
#endif
typedef struct {
rmt_hal_context_t hal;
_lock_t rmt_driver_isr_lock;
@ -577,7 +587,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
#endif
} else {
// fallback to use default clock source
rmt_source_clk_hz = APB_CLK_FREQ;
rmt_source_clk_hz = RMT_DEFAULT_CLOCK_FREQ;
rmt_ll_set_group_clock_src(dev, channel, (rmt_clock_source_t)RMT_BASECLK_DEFAULT, 1, 0, 0);
}
RMT_EXIT_CRITICAL();

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

View File

@ -10,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
@pytest.mark.parametrize('config', [
'release',

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

View File

@ -10,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
@pytest.mark.parametrize(
'config',

View File

@ -0,0 +1,849 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @note TX and RX channels are index from 0 in the LL driver, i.e. tx_channel = [0,1], rx_channel = [0,1]
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "hal/misc.h"
#include "hal/assert.h"
#include "hal/rmt_types.h"
#include "soc/rmt_struct.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
#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))
#define RMT_LL_EVENT_TX_ERROR(channel) (1 << ((channel) + 4))
#define RMT_LL_EVENT_RX_DONE(channel) (1 << ((channel) + 2))
#define RMT_LL_EVENT_RX_THRES(channel) (1 << ((channel) + 10))
#define RMT_LL_EVENT_RX_ERROR(channel) (1 << ((channel) + 6))
#define RMT_LL_EVENT_TX_MASK(channel) (RMT_LL_EVENT_TX_DONE(channel) | RMT_LL_EVENT_TX_THRES(channel) | RMT_LL_EVENT_TX_LOOP_END(channel))
#define RMT_LL_EVENT_RX_MASK(channel) (RMT_LL_EVENT_RX_DONE(channel) | RMT_LL_EVENT_RX_THRES(channel))
#define RMT_LL_MAX_LOOP_COUNT_PER_BATCH 1023
typedef enum {
RMT_LL_MEM_OWNER_SW = 0,
RMT_LL_MEM_OWNER_HW = 1,
} rmt_ll_mem_owner_t;
/**
* @brief Enable clock gate for register and memory
*
* @param dev Peripheral instance address
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
{
dev->sys_conf.clk_en = enable; // register clock gating
dev->sys_conf.mem_clk_force_on = enable; // memory clock gating
}
/**
* @brief Power down memory
*
* @param dev Peripheral instance address
* @param enable True to power down, False to power up
*/
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
{
dev->sys_conf.mem_force_pu = !enable;
dev->sys_conf.mem_force_pd = enable;
}
/**
* @brief Enable APB accessing RMT memory in nonfifo mode
*
* @param dev Peripheral instance address
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable)
{
dev->sys_conf.apb_fifo_mask = enable;
}
/**
* @brief Set clock source and divider for RMT channel group
*
* @param dev Peripheral instance address
* @param channel not used as clock source is set for all channels
* @param src Clock source
* @param divider_integral Integral part of the divider
* @param divider_denominator Denominator part of the divider
* @param divider_numerator Numerator part of the divider
*/
static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src,
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
{
// Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b)
(void)channel; // the source clock is set for all channels
HAL_ASSERT(divider_integral >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.rmt_sclk_conf, rmt_sclk_div_num, divider_integral - 1);
PCR.rmt_sclk_conf.rmt_sclk_div_a = divider_numerator;
PCR.rmt_sclk_conf.rmt_sclk_div_b = divider_denominator;
switch (src) {
case RMT_CLK_SRC_XTAL:
PCR.rmt_sclk_conf.rmt_sclk_sel = 0;
break;
case RMT_CLK_SRC_RC_FAST:
PCR.rmt_sclk_conf.rmt_sclk_sel = 1;
break;
default:
HAL_ASSERT(false);
break;
}
}
/**
* @brief Enable RMT peripheral source clock
*
* @param dev Peripheral instance address
* @param en True to enable, False to disable
*/
static inline void rmt_ll_enable_group_clock(rmt_dev_t *dev, bool en)
{
(void)dev;
PCR.rmt_sclk_conf.rmt_sclk_en = en;
}
////////////////////////////////////////TX Channel Specific/////////////////////////////////////////////////////////////
/**
* @brief Reset clock divider for TX channels by mask
*
* @param dev Peripheral instance address
* @param channel_mask Mask of TX channels
*/
static inline void rmt_ll_tx_reset_channels_clock_div(rmt_dev_t *dev, uint32_t channel_mask)
{
// write 1 to reset
dev->ref_cnt_rst.val |= channel_mask & 0x03;
}
/**
* @brief Set TX channel clock divider
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param div Division value
*/
static inline void rmt_ll_tx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
{
HAL_ASSERT(div >= 1 && div <= 256 && "divider out of range");
// limit the maximum divider to 256
if (div >= 256) {
div = 0; // 0 means 256 division
}
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn, div);
}
/**
* @brief Reset RMT reading pointer for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_reset_pointer(rmt_dev_t *dev, uint32_t channel)
{
dev->chnconf0[channel].mem_rd_rst_chn = 1;
dev->chnconf0[channel].mem_rd_rst_chn = 0;
dev->chnconf0[channel].apb_mem_rst_chn = 1;
dev->chnconf0[channel].apb_mem_rst_chn = 0;
}
/**
* @brief Start transmitting for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_start(rmt_dev_t *dev, uint32_t channel)
{
// update other configuration registers before start transmitting
dev->chnconf0[channel].conf_update_chn = 1;
dev->chnconf0[channel].tx_start_chn = 1;
}
/**
* @brief Stop transmitting for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_stop(rmt_dev_t *dev, uint32_t channel)
{
dev->chnconf0[channel].tx_stop_chn = 1;
// stop won't take place until configurations updated
dev->chnconf0[channel].conf_update_chn = 1;
}
/**
* @brief Set memory block number for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param block_num memory block number
*/
static inline void rmt_ll_tx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
{
dev->chnconf0[channel].mem_size_chn = block_num;
}
/**
* @brief Enable TX wrap
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_tx_enable_wrap(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chnconf0[channel].mem_tx_wrap_en_chn = enable;
}
/**
* @brief Enable transmitting in a loop
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to enable, False to disable
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_enable_loop(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chnconf0[channel].tx_conti_mode_chn = enable;
}
/**
* @brief Set loop count for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param count TX loop count
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_set_loop_count(rmt_dev_t *dev, uint32_t channel, uint32_t count)
{
HAL_ASSERT(count <= RMT_LL_MAX_LOOP_COUNT_PER_BATCH && "loop count out of range");
dev->chn_tx_lim[channel].tx_loop_num_chn = count;
}
/**
* @brief Reset loop count for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_reset_loop_count(rmt_dev_t *dev, uint32_t channel)
{
dev->chn_tx_lim[channel].loop_count_reset_chn = 1;
dev->chn_tx_lim[channel].loop_count_reset_chn = 0;
}
/**
* @brief Enable loop count for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to enable, False to disable
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_enable_loop_count(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chn_tx_lim[channel].tx_loop_cnt_en_chn = enable;
}
/**
* @brief Enable loop stop at count value automatically
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to enable, False to disable
*/
__attribute__((always_inline))
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;
}
/**
* @brief Enable transmit multiple channels synchronously
*
* @param dev Peripheral instance address
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_tx_enable_sync(rmt_dev_t *dev, bool enable)
{
dev->tx_sim.tx_sim_en = enable;
}
/**
* @brief Clear the TX channels synchronous group
*
* @param dev Peripheral instance address
*/
static inline void rmt_ll_tx_clear_sync_group(rmt_dev_t *dev)
{
dev->tx_sim.val &= ~(0x03);
}
/**
* @brief Add TX channels to the synchronous group
*
* @param dev Peripheral instance address
* @param channel_mask Mask of TX channels to be added to the synchronous group
*/
static inline void rmt_ll_tx_sync_group_add_channels(rmt_dev_t *dev, uint32_t channel_mask)
{
dev->tx_sim.val |= (channel_mask & 0x03);
}
/**
* @brief Remove TX channels from the synchronous group
*
* @param dev Peripheral instance address
* @param channel_mask Mask of TX channels to be removed from the synchronous group
*/
static inline void rmt_ll_tx_sync_group_remove_channels(rmt_dev_t *dev, uint32_t channel_mask)
{
dev->tx_sim.val &= ~channel_mask;
}
/**
* @brief Fix the output level when TX channel is in IDLE state
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param level IDLE level (1 => high, 0 => low)
* @param enable True to fix the IDLE level, otherwise the IDLE level is determined by EOF encoder
*/
__attribute__((always_inline))
static inline void rmt_ll_tx_fix_idle_level(rmt_dev_t *dev, uint32_t channel, uint8_t level, bool enable)
{
dev->chnconf0[channel].idle_out_en_chn = enable;
dev->chnconf0[channel].idle_out_lv_chn = level;
}
/**
* @brief Set the amount of RMT symbols that can trigger the limitation interrupt
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param limit Specify the number of symbols
*/
static inline void rmt_ll_tx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
{
dev->chn_tx_lim[channel].tx_lim_chn = limit;
}
/**
* @brief Set high and low duration of carrier signal
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param high_ticks Duration of high level
* @param low_ticks Duration of low level
*/
static inline void rmt_ll_tx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks)
{
HAL_ASSERT(high_ticks >= 1 && high_ticks <= 65536 && low_ticks >= 1 && low_ticks <= 65536 && "out of range high/low ticks");
// ticks=0 means 65536 in hardware
if (high_ticks >= 65536) {
high_ticks = 0;
}
if (low_ticks >= 65536) {
low_ticks = 0;
}
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chncarrier_duty[channel], carrier_high_chn, high_ticks);
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chncarrier_duty[channel], carrier_low_chn, low_ticks);
}
/**
* @brief Enable modulating carrier signal to TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_tx_enable_carrier_modulation(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chnconf0[channel].carrier_en_chn = enable;
}
/**
* @brief Set on high or low to modulate the carrier signal
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @param level Which level to modulate on (0=>low level, 1=>high level)
*/
static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
{
dev->chnconf0[channel].carrier_out_lv_chn = level;
}
/**
* @brief Enable to always output carrier signal, regardless of a valid data transmission
*
* @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
*/
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chnconf0[channel].carrier_eff_en_chn = !enable;
}
////////////////////////////////////////RX Channel Specific/////////////////////////////////////////////////////////////
/**
* @brief Reset clock divider for RX channels by mask
*
* @param dev Peripheral instance address
* @param channel_mask Mask of RX channels
*/
static inline void rmt_ll_rx_reset_channels_clock_div(rmt_dev_t *dev, uint32_t channel_mask)
{
// write 1 to reset
dev->ref_cnt_rst.val |= ((channel_mask & 0x03) << 2);
}
/**
* @brief Set RX channel clock divider
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param div Division value
*/
static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
{
HAL_ASSERT(div >= 1 && div <= 256 && "divider out of range");
// limit the maximum divider to 256
if (div >= 256) {
div = 0; // 0 means 256 division
}
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm, div);
}
/**
* @brief Reset RMT writing pointer for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
*/
static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel)
{
dev->chmconf[channel].conf1.mem_wr_rst_chm = 1;
dev->chmconf[channel].conf1.mem_wr_rst_chm = 0;
dev->chmconf[channel].conf1.apb_mem_rst_chm = 1;
dev->chmconf[channel].conf1.apb_mem_rst_chm = 0;
}
/**
* @brief Enable receiving for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param enable True to enable, False to disable
*/
__attribute__((always_inline))
static inline void rmt_ll_rx_enable(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chmconf[channel].conf1.rx_en_chm = enable;
// rx won't be enabled until configurations updated
dev->chmconf[channel].conf1.conf_update_chm = 1;
}
/**
* @brief Set memory block number for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param block_num memory block number
*/
static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
{
dev->chmconf[channel].conf0.mem_size_chm = block_num;
}
/**
* @brief Set the time length for RX channel before going into IDLE state
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param thres Time length threshold
*/
static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
{
dev->chmconf[channel].conf0.idle_thres_chm = thres;
}
/**
* @brief Set RMT memory owner for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param owner Memory owner
*/
__attribute__((always_inline))
static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt_ll_mem_owner_t owner)
{
dev->chmconf[channel].conf1.mem_owner_chm = owner;
}
/**
* @brief Enable filter for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX chanenl number
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chmconf[channel].conf1.rx_filter_en_chm = enable;
}
/**
* @brief Set RX channel filter threshold (i.e. the maximum width of one pulse signal that would be treated as a noise)
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param thres Filter threshold
*/
static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf1, rx_filter_thres_chm, thres);
}
/**
* @brief Get RMT memory write cursor offset
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @return writer offset
*/
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_memory_writer_offset(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].mem_waddr_ex_chm - (channel + 2) * 48;
}
/**
* @brief Set the amount of RMT symbols that can trigger the limitation interrupt
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param limit Specify the number of symbols
*/
static inline void rmt_ll_rx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
{
dev->chm_rx_lim[channel].rmt_rx_lim_chm = limit;
}
/**
* @brief Set high and low duration of carrier signal
*
* @param dev dev Peripheral instance address
* @param channel RMT TX channel number
* @param high_ticks Duration of high level
* @param low_ticks Duration of low level
*/
static inline void rmt_ll_rx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t high_ticks, uint32_t low_ticks)
{
HAL_ASSERT(high_ticks >= 1 && high_ticks <= 65536 && low_ticks >= 1 && low_ticks <= 65536 && "out of range high/low ticks");
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chm_rx_carrier_rm[channel], carrier_high_thres_chm, high_ticks - 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chm_rx_carrier_rm[channel], carrier_low_thres_chm, low_ticks - 1);
}
/**
* @brief Enable demodulating the carrier on RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_rx_enable_carrier_demodulation(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chmconf[channel].conf0.carrier_en_chm = enable;
}
/**
* @brief Set on high or low to demodulate the carrier signal
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param level Which level to demodulate (0=>low level, 1=>high level)
*/
static inline void rmt_ll_rx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
{
dev->chmconf[channel].conf0.carrier_out_lv_chm = level;
}
/**
* @brief Enable RX wrap
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @param enable True to enable, False to disable
*/
static inline void rmt_ll_rx_enable_wrap(rmt_dev_t *dev, uint32_t channel, bool enable)
{
dev->chmconf[channel].conf1.mem_rx_wrap_en_chm = enable;
}
//////////////////////////////////////////Interrupt Specific////////////////////////////////////////////////////////////
/**
* @brief Enable RMT interrupt for specific event mask
*
* @param dev Peripheral instance address
* @param mask Event mask
* @param enable True to enable, False to disable
*/
__attribute__((always_inline))
static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool enable)
{
if (enable) {
dev->int_ena.val |= mask;
} else {
dev->int_ena.val &= ~mask;
}
}
/**
* @brief Clear RMT interrupt status by mask
*
* @param dev Peripheral instance address
* @param mask Interupt status mask
*/
__attribute__((always_inline))
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
{
dev->int_clr.val = mask;
}
/**
* @brief Get interrupt status register address
*
* @param dev Peripheral instance address
* @return Register address
*/
static inline volatile void *rmt_ll_get_interrupt_status_reg(rmt_dev_t *dev)
{
return &dev->int_st;
}
/**
* @brief Get interrupt status for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @return Interrupt status
*/
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_interrupt_status(rmt_dev_t *dev, uint32_t channel)
{
return dev->int_st.val & RMT_LL_EVENT_TX_MASK(channel);
}
/**
* @brief Get interrupt raw status for TX channel
*
* @param dev Peripheral instance address
* @param channel RMT TX channel number
* @return Interrupt raw status
*/
static inline uint32_t rmt_ll_tx_get_interrupt_status_raw(rmt_dev_t *dev, uint32_t channel)
{
return dev->int_raw.val & (RMT_LL_EVENT_TX_MASK(channel) | RMT_LL_EVENT_TX_ERROR(channel));
}
/**
* @brief Get interrupt raw status for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @return Interrupt raw status
*/
static inline uint32_t rmt_ll_rx_get_interrupt_status_raw(rmt_dev_t *dev, uint32_t channel)
{
return dev->int_raw.val & (RMT_LL_EVENT_RX_MASK(channel) | RMT_LL_EVENT_RX_ERROR(channel));
}
/**
* @brief Get interrupt status for RX channel
*
* @param dev Peripheral instance address
* @param channel RMT RX channel number
* @return Interrupt status
*/
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_interrupt_status(rmt_dev_t *dev, uint32_t channel)
{
return dev->int_st.val & RMT_LL_EVENT_RX_MASK(channel);
}
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_status_word(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmstatus[channel].val;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chnconf0[channel], div_cnt_chn);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
{
uint32_t div = HAL_FORCE_READ_U32_REG_FIELD(dev->chmconf[channel].conf0, div_cnt_chm);
return div == 0 ? 256 : div;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.idle_thres_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].mem_size_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf0.mem_size_chm;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].tx_conti_mode_chn;
}
__attribute__((always_inline))
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
{
rmt_clock_source_t clk_src = RMT_CLK_SRC_XTAL;
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
case 1:
clk_src = RMT_CLK_SRC_RC_FAST;
break;
case 0:
clk_src = RMT_CLK_SRC_XTAL;
break;
}
return clk_src;
}
__attribute__((always_inline))
static inline bool rmt_ll_tx_is_idle_enabled(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_en_chn;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
{
return dev->chnconf0[channel].idle_out_lv_chn;
}
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
{
// the RTC domain can also power down RMT memory
// so it's probably not enough to detect whether it's powered down or not
// mem_force_pd has higher priority than mem_force_pu
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
{
return dev->chmconf[channel].conf1.mem_owner_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
{
return dev->chm_rx_lim[channel].rmt_rx_lim_chm;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_end_interrupt_status(rmt_dev_t *dev)
{
return dev->int_st.val & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_end_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 2) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 4) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_err_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 6) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 8) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_rx_thres_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 10) & 0x03;
}
__attribute__((always_inline))
static inline uint32_t rmt_ll_get_tx_loop_interrupt_status(rmt_dev_t *dev)
{
return (dev->int_st.val >> 12) & 0x03;
}
#ifdef __cplusplus
}
#endif

View File

@ -43,6 +43,10 @@ config SOC_SDM_SUPPORTED
bool
default y
config SOC_RMT_SUPPORTED
bool
default y
config SOC_SYSTIMER_SUPPORTED
bool
default y
@ -391,6 +395,14 @@ config SOC_RMT_SUPPORT_TX_ASYNC_STOP
bool
default y
config SOC_RMT_SUPPORT_TX_LOOP_COUNT
bool
default y
config SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP
bool
default y
config SOC_RMT_SUPPORT_TX_SYNCHRO
bool
default y
@ -403,10 +415,6 @@ config SOC_RMT_SUPPORT_XTAL
bool
default y
config SOC_RMT_SUPPORT_APB
bool
default y
config SOC_MCPWM_GROUPS
int
default 1

View File

@ -193,7 +193,7 @@ typedef enum {
#if CONFIG_IDF_ENV_FPGA
#define SOC_RMT_CLKS {SOC_MOD_CLK_XTAL}
#else
#define SOC_RMT_CLKS {SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
#define SOC_RMT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
#endif
/**

View File

@ -45,8 +45,8 @@
#define SOC_RTC_FAST_MEM_SUPPORTED 1
#define SOC_RTC_MEM_SUPPORTED 1
// #define SOC_I2S_SUPPORTED 1 // TODO: IDF-6219
// #define SOC_RMT_SUPPORTED 1 // TODO: IDF-6224
#define SOC_SDM_SUPPORTED 1
#define SOC_RMT_SUPPORTED 1
// #define SOC_GPSPI_SUPPORTED 1 // TODO: IDF-6264
#define SOC_SYSTIMER_SUPPORTED 1
// #define SOC_SUPPORT_COEXISTENCE 1 // TODO: IDF-6416
@ -219,7 +219,6 @@
#define SOC_PCNT_THRES_POINT_PER_UNIT 2
#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
// TODO: IDF-6224
/*--------------------------- RMT CAPS ---------------------------------------*/
#define SOC_RMT_GROUPS 1U /*!< One RMT group */
#define SOC_RMT_TX_CANDIDATES_PER_GROUP 2 /*!< Number of channels that capable of Transmit */
@ -229,12 +228,12 @@
#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_ASYNC_STOP 1 /*!< Support stop transmission asynchronously */
// #define SOC_RMT_SUPPORT_TX_LOOP_COUNT 1 /*!< Support transmit specified number of cycles in loop mode */
// #define SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP 1 /*!< Hardware support of auto-stop 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_LOOP_AUTO_STOP 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_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_APB 1 /*!< Support set APB as the RMT clock source */
// #define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST as the RMT clock source */
// TODO: IDF-6237
/*-------------------------- MCPWM CAPS --------------------------------------*/
@ -379,7 +378,7 @@
#define SOC_FLASH_ENCRYPTION_XTS_AES 1
#define SOC_FLASH_ENCRYPTION_XTS_AES_128 1
// TODO: IDF-6332 (Copy from esp32c6, need check)
// TODO: IDF-6332 (Copy from esp32c6, need check)
/*-------------------------- MEMPROT CAPS ------------------------------------*/
#define SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE 16
#define SOC_MEMPROT_MEM_ALIGN_SIZE 512

View File

@ -113,8 +113,6 @@ api-reference/peripherals/dac
api-reference/peripherals/spi_slave
api-reference/peripherals/etm
api-reference/peripherals/i2s
api-reference/peripherals/gptimer
api-reference/peripherals/pcnt
api-reference/peripherals/touch_element
api-reference/peripherals/lcd
api-reference/peripherals/mcpwm
@ -130,7 +128,6 @@ api-reference/peripherals/spi_flash/spi_flash_override_driver
api-reference/peripherals/spi_flash/spi_flash_optional_feature
api-reference/peripherals/spi_flash/index
api-reference/peripherals/spi_flash/auto_suspend.inc
api-reference/peripherals/sdm
api-reference/peripherals/touch_pad
api-reference/peripherals/adc_calibration
api-reference/peripherals/spi_slave_hd
@ -142,7 +139,6 @@ api-reference/peripherals/spi_master
api-reference/peripherals/index
api-reference/peripherals/sdmmc_host
api-reference/peripherals/uart
api-reference/peripherals/rmt
api-reference/kconfig
api-reference/network/esp_openthread
api-reference/network/esp_eth
@ -164,7 +160,6 @@ api-reference/system/esp_function_with_shared_stack
api-reference/system/efuse
api-reference/system/chip_revision
api-reference/system/ulp_instruction_set
api-reference/system/async_memcpy
api-reference/system/random
api-reference/system/esp_timer
api-reference/system/esp_event

View File

@ -1,10 +1,5 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
examples/get-started/blink:
disable:
- if: IDF_TARGET == "esp32h2" # RMT support IDF-6224
reason: RMT has not been supported
examples/get-started/hello_world:
enable:
- if: INCLUDE_DEFAULT == 1 or IDF_TARGET in ["esp32h4"] # preview targets

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# Blink Example

View File

@ -4,7 +4,7 @@ menu "Example Configuration"
choice BLINK_LED
prompt "Blink LED type"
default BLINK_LED_GPIO if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C2
default BLINK_LED_GPIO if IDF_TARGET_ESP32 || !SOC_RMT_SUPPORTED
default BLINK_LED_RMT
help
Defines the default peripheral for blink example
@ -18,10 +18,10 @@ menu "Example Configuration"
config BLINK_GPIO
int "Blink GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 8 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C6
default 5 if IDF_TARGET_ESP32
default 18 if IDF_TARGET_ESP32S2
default 48 if IDF_TARGET_ESP32S3
default 5
default 8
help
GPIO number (IOxx) to blink on and off or the RMT signal for the addressable LED.
Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink.

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# RMT Infinite Loop Transmit Example -- Dshot ESC (Electronic Speed Controller)
(See the README.md file in the upper level 'examples' directory for more information about examples.)

View File

@ -10,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
def test_dshot_esc_example(dut: Dut) -> None:
dut.expect_exact('example: Create RMT TX channel')

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# IR NEC Encoding and Decoding Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# RMT Transmit Example -- LED Strip
(See the README.md file in the upper level 'examples' directory for more information about examples.)

View File

@ -10,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
def test_led_strip_example(dut: Dut) -> None:
dut.expect_exact('example: Create RMT TX channel')

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | -------- |
# RMT Transmit Loop Count Example -- Musical Buzzer

View File

@ -9,7 +9,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
# @pytest.mark.esp32h4 TODO: uncomment this when remove --preview for h4
@pytest.mark.esp32h2
@pytest.mark.generic
def test_musical_buzzer_example(dut: Dut) -> None:
dut.expect_exact('example: Create RMT TX channel')

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# RMT Transmit & Receive Example -- 1-Wire bus

View File

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
@ -9,6 +9,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
def test_onewire_ds18b20_example(dut: Dut) -> None:
dut.expect_exact('onewire_rmt: RMT Tx channel created for 1-wire bus')

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32-C6 | ESP32-S3 |
| ----------------- | -------- | -------- |
| Supported Targets | ESP32-C6 | ESP32-H2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- |
# RMT Based Stepper Motor Smooth Controller

View File

@ -7,6 +7,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.generic
def test_stepper_motor_example(dut: Dut) -> None:
dut.expect_exact('example: Initialize EN + DIR GPIO')