Merge branch 'bugfix/fix_rmt_driver_breaking_change_issue' into 'master'

Bugfix(RMT):   Fix the breaking change issue of RMT driver.

Closes IDFGH-2837, IDFGH-2579, and IDFGH-2915

See merge request espressif/esp-idf!8006
This commit is contained in:
Michael (XIAO Xufeng) 2020-05-25 15:27:24 +08:00
commit 0d90861984
5 changed files with 182 additions and 155 deletions

View file

@ -52,19 +52,21 @@ static const char *RMT_TAG = "rmt";
return (ret_val); \
}
static uint8_t s_rmt_driver_channels; // Bitmask of installed drivers' channels
// Spinlock for protecting concurrent register-level access only
static portMUX_TYPE rmt_spinlock = portMUX_INITIALIZER_UNLOCKED;
#define RMT_ENTER_CRITICAL() portENTER_CRITICAL_SAFE(&rmt_spinlock)
#define RMT_EXIT_CRITICAL() portEXIT_CRITICAL_SAFE(&rmt_spinlock)
// Mutex lock for protecting concurrent register/unregister of RMT channels' ISR
static _lock_t rmt_driver_isr_lock;
static rmt_isr_handle_t s_rmt_driver_intr_handle;
#define RMT_ENTER_CRITICAL() portENTER_CRITICAL_SAFE(&(rmt_contex.rmt_spinlock))
#define RMT_EXIT_CRITICAL() portEXIT_CRITICAL_SAFE(&(rmt_contex.rmt_spinlock))
typedef struct {
rmt_hal_context_t hal;
_lock_t rmt_driver_isr_lock;
portMUX_TYPE rmt_spinlock; // Mutex lock for protecting concurrent register/unregister of RMT channels' ISR
rmt_isr_handle_t rmt_driver_intr_handle;
rmt_tx_end_callback_t rmt_tx_end_callback;// Event called when transmission is ended
uint8_t rmt_driver_channels; // Bitmask of installed drivers' channels
bool rmt_module_enabled;
} rmt_contex_t;
typedef struct {
size_t tx_offset;
size_t tx_len_rem;
size_t tx_sub_len;
@ -90,17 +92,48 @@ typedef struct {
const uint8_t *sample_cur;
} rmt_obj_t;
static rmt_obj_t *p_rmt_obj[RMT_CHANNEL_MAX] = {0};
static uint32_t s_rmt_src_clock_hz[RMT_CHANNEL_MAX] = {0};
static rmt_contex_t rmt_contex = {
.hal.regs = RMT_LL_HW_BASE,
.hal.mem = RMT_LL_MEM_BASE,
.rmt_spinlock = portMUX_INITIALIZER_UNLOCKED,
.rmt_driver_intr_handle = NULL,
.rmt_tx_end_callback = {
.function = NULL,
},
.rmt_driver_channels = 0,
.rmt_module_enabled = false,
};
// Event called when transmission is ended
static rmt_tx_end_callback_t rmt_tx_end_callback;
static rmt_obj_t *p_rmt_obj[RMT_CHANNEL_MAX] = {0};
//Enable RMT module
static void rmt_module_enable(void)
{
RMT_ENTER_CRITICAL();
if (rmt_contex.rmt_module_enabled == false) {
periph_module_reset(PERIPH_RMT_MODULE);
periph_module_enable(PERIPH_RMT_MODULE);
rmt_contex.rmt_module_enabled = true;
}
RMT_EXIT_CRITICAL();
}
//Disable RMT module
static void rmt_module_disable(void)
{
RMT_ENTER_CRITICAL();
if (rmt_contex.rmt_module_enabled == true) {
periph_module_disable(PERIPH_RMT_MODULE);
rmt_contex.rmt_module_enabled = false;
}
RMT_EXIT_CRITICAL();
}
esp_err_t rmt_set_clk_div(rmt_channel_t channel, uint8_t div_cnt)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_counter_clock_div(p_rmt_obj[channel]->hal.regs, channel, div_cnt);
rmt_ll_set_counter_clock_div(rmt_contex.hal.regs, channel, div_cnt);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -110,7 +143,7 @@ esp_err_t rmt_get_clk_div(rmt_channel_t channel, uint8_t *div_cnt)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(div_cnt != NULL, RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*div_cnt = (uint8_t)rmt_ll_get_counter_clock_div(p_rmt_obj[channel]->hal.regs, channel);
*div_cnt = (uint8_t)rmt_ll_get_counter_clock_div(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -119,7 +152,7 @@ esp_err_t rmt_set_rx_idle_thresh(rmt_channel_t channel, uint16_t thresh)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_rx_idle_thres(p_rmt_obj[channel]->hal.regs, channel, thresh);
rmt_ll_set_rx_idle_thres(rmt_contex.hal.regs, channel, thresh);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -129,7 +162,7 @@ esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(thresh != NULL, RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*thresh = (uint16_t)rmt_ll_get_rx_idle_thres(p_rmt_obj[channel]->hal.regs, channel);
*thresh = (uint16_t)rmt_ll_get_rx_idle_thres(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -139,7 +172,7 @@ esp_err_t rmt_set_mem_block_num(rmt_channel_t channel, uint8_t rmt_mem_num)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(rmt_mem_num <= RMT_CHANNEL_MAX - channel, RMT_MEM_CNT_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_mem_blocks(p_rmt_obj[channel]->hal.regs, channel, rmt_mem_num);
rmt_ll_set_mem_blocks(rmt_contex.hal.regs, channel, rmt_mem_num);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -149,7 +182,7 @@ esp_err_t rmt_get_mem_block_num(rmt_channel_t channel, uint8_t *rmt_mem_num)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(rmt_mem_num != NULL, RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*rmt_mem_num = (uint8_t)rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel);
*rmt_mem_num = (uint8_t)rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -160,9 +193,9 @@ esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t hi
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(carrier_level < RMT_CARRIER_LEVEL_MAX, RMT_CARRIER_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_tx_carrier_high_low_ticks(p_rmt_obj[channel]->hal.regs, channel, high_level, low_level);
rmt_ll_set_carrier_on_level(p_rmt_obj[channel]->hal.regs, channel, carrier_level);
rmt_ll_enable_carrier(p_rmt_obj[channel]->hal.regs, channel, carrier_en);
rmt_ll_set_tx_carrier_high_low_ticks(rmt_contex.hal.regs, channel, high_level, low_level);
rmt_ll_set_carrier_on_level(rmt_contex.hal.regs, channel, carrier_level);
rmt_ll_enable_carrier(rmt_contex.hal.regs, channel, carrier_en);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -171,7 +204,7 @@ esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_power_down_mem(p_rmt_obj[channel]->hal.regs, pd_en);
rmt_ll_power_down_mem(rmt_contex.hal.regs, pd_en);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -180,7 +213,7 @@ esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool *pd_en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*pd_en = rmt_ll_is_mem_power_down(p_rmt_obj[channel]->hal.regs);
*pd_en = rmt_ll_is_mem_power_down(rmt_contex.hal.regs);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -190,21 +223,21 @@ esp_err_t rmt_tx_start(rmt_channel_t channel, bool tx_idx_rst)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
if (tx_idx_rst) {
rmt_ll_reset_tx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_tx_pointer(rmt_contex.hal.regs, channel);
}
rmt_ll_clear_tx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_clear_tx_end_interrupt(rmt_contex.hal.regs, channel);
// enable tx end interrupt in non-loop mode
if (!rmt_ll_is_tx_loop_enabled(p_rmt_obj[channel]->hal.regs, channel)) {
rmt_ll_enable_tx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel, true);
if (!rmt_ll_is_tx_loop_enabled(rmt_contex.hal.regs, channel)) {
rmt_ll_enable_tx_end_interrupt(rmt_contex.hal.regs, channel, true);
} else {
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
rmt_ll_reset_tx_loop(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_enable_tx_loop_count(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_clear_tx_loop_interrupt(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_enable_tx_loop_interrupt(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_reset_tx_loop(rmt_contex.hal.regs, channel);
rmt_ll_enable_tx_loop_count(rmt_contex.hal.regs, channel, true);
rmt_ll_clear_tx_loop_interrupt(rmt_contex.hal.regs, channel);
rmt_ll_enable_tx_loop_interrupt(rmt_contex.hal.regs, channel, true);
#endif
}
rmt_ll_start_tx(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_start_tx(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -213,8 +246,8 @@ esp_err_t rmt_tx_stop(rmt_channel_t channel)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_stop_tx(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_tx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_stop_tx(rmt_contex.hal.regs, channel);
rmt_ll_reset_tx_pointer(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -223,21 +256,21 @@ esp_err_t rmt_rx_start(rmt_channel_t channel, bool rx_idx_rst)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_rx(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_enable_rx(rmt_contex.hal.regs, channel, false);
if (rx_idx_rst) {
rmt_ll_reset_rx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_rx_pointer(rmt_contex.hal.regs, channel);
}
rmt_ll_clear_rx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_enable_rx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_clear_rx_end_interrupt(rmt_contex.hal.regs, channel);
rmt_ll_enable_rx_end_interrupt(rmt_contex.hal.regs, channel, true);
#if SOC_RMT_SUPPORT_RX_PINGPONG
const uint32_t item_block_len = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) * RMT_MEM_ITEM_NUM;
const uint32_t item_block_len = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM;
p_rmt_obj[channel]->rx_item_start_idx = 0;
p_rmt_obj[channel]->rx_item_len = 0;
rmt_set_rx_thr_intr_en(channel, true, item_block_len / 2);
#endif
rmt_ll_enable_rx(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_enable_rx(rmt_contex.hal.regs, channel, true);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -246,11 +279,11 @@ esp_err_t rmt_rx_stop(rmt_channel_t channel)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_rx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_enable_rx(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_reset_rx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_enable_rx_end_interrupt(rmt_contex.hal.regs, channel, false);
rmt_ll_enable_rx(rmt_contex.hal.regs, channel, false);
rmt_ll_reset_rx_pointer(rmt_contex.hal.regs, channel);
#if SOC_RMT_SUPPORT_RX_PINGPONG
rmt_ll_enable_rx_thres_interrupt(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_enable_rx_thres_interrupt(rmt_contex.hal.regs, channel, false);
#endif
RMT_EXIT_CRITICAL();
return ESP_OK;
@ -260,8 +293,8 @@ esp_err_t rmt_memory_rw_rst(rmt_channel_t channel)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_reset_tx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_rx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_tx_pointer(rmt_contex.hal.regs, channel);
rmt_ll_reset_rx_pointer(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -271,7 +304,7 @@ esp_err_t rmt_set_memory_owner(rmt_channel_t channel, rmt_mem_owner_t owner)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(owner < RMT_MEM_OWNER_MAX, RMT_MEM_OWNER_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, owner);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, owner);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -281,7 +314,7 @@ esp_err_t rmt_get_memory_owner(rmt_channel_t channel, rmt_mem_owner_t *owner)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(owner != NULL, RMT_MEM_OWNER_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*owner = (rmt_mem_owner_t)rmt_ll_get_mem_owner(p_rmt_obj[channel]->hal.regs, channel);
*owner = (rmt_mem_owner_t)rmt_ll_get_mem_owner(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -290,7 +323,7 @@ esp_err_t rmt_set_tx_loop_mode(rmt_channel_t channel, bool loop_en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_tx_loop(p_rmt_obj[channel]->hal.regs, channel, loop_en);
rmt_ll_enable_tx_loop(rmt_contex.hal.regs, channel, loop_en);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -299,7 +332,7 @@ esp_err_t rmt_get_tx_loop_mode(rmt_channel_t channel, bool *loop_en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*loop_en = rmt_ll_is_tx_loop_enabled(p_rmt_obj[channel]->hal.regs, channel);
*loop_en = rmt_ll_is_tx_loop_enabled(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -308,8 +341,8 @@ esp_err_t rmt_set_rx_filter(rmt_channel_t channel, bool rx_filter_en, uint8_t th
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_rx_filter(p_rmt_obj[channel]->hal.regs, channel, rx_filter_en);
rmt_ll_set_rx_filter_thres(p_rmt_obj[channel]->hal.regs, channel, thresh);
rmt_ll_enable_rx_filter(rmt_contex.hal.regs, channel, rx_filter_en);
rmt_ll_set_rx_filter_thres(rmt_contex.hal.regs, channel, thresh);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -319,7 +352,7 @@ esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(base_clk < RMT_BASECLK_MAX, RMT_BASECLK_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_counter_clock_src(p_rmt_obj[channel]->hal.regs, channel, base_clk);
rmt_ll_set_counter_clock_src(rmt_contex.hal.regs, channel, base_clk);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -328,7 +361,7 @@ esp_err_t rmt_get_source_clk(rmt_channel_t channel, rmt_source_clk_t *src_clk)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*src_clk = (rmt_source_clk_t)rmt_ll_get_counter_clock_src(p_rmt_obj[channel]->hal.regs, channel);
*src_clk = (rmt_source_clk_t)rmt_ll_get_counter_clock_src(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -338,8 +371,8 @@ esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_l
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(level < RMT_IDLE_LEVEL_MAX, "RMT IDLE LEVEL ERR", ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_tx_idle(p_rmt_obj[channel]->hal.regs, channel, idle_out_en);
rmt_ll_set_tx_idle_level(p_rmt_obj[channel]->hal.regs, channel, level);
rmt_ll_enable_tx_idle(rmt_contex.hal.regs, channel, idle_out_en);
rmt_ll_set_tx_idle_level(rmt_contex.hal.regs, channel, level);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -348,8 +381,8 @@ esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool *idle_out_en, rmt_idle_
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*idle_out_en = rmt_ll_is_tx_idle_enabled(p_rmt_obj[channel]->hal.regs, channel);
*level = rmt_ll_get_tx_idle_level(p_rmt_obj[channel]->hal.regs, channel);
*idle_out_en = rmt_ll_is_tx_idle_enabled(rmt_contex.hal.regs, channel);
*level = rmt_ll_get_tx_idle_level(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -358,7 +391,7 @@ esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t *status)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*status = rmt_ll_get_channel_status(p_rmt_obj[channel]->hal.regs, channel);
*status = rmt_ll_get_channel_status(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -381,7 +414,7 @@ esp_err_t rmt_set_rx_intr_en(rmt_channel_t channel, bool en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_rx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel, en);
rmt_ll_enable_rx_end_interrupt(rmt_contex.hal.regs, channel, en);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -391,15 +424,15 @@ esp_err_t rmt_set_rx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_th
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
if (en) {
uint32_t item_block_len = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) * RMT_MEM_ITEM_NUM;
uint32_t item_block_len = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM;
RMT_CHECK(evt_thresh <= item_block_len, "RMT EVT THRESH ERR", ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_rx_limit(p_rmt_obj[channel]->hal.regs, channel, evt_thresh);
rmt_ll_enable_rx_thres_interrupt(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_set_rx_limit(rmt_contex.hal.regs, channel, evt_thresh);
rmt_ll_enable_rx_thres_interrupt(rmt_contex.hal.regs, channel, true);
RMT_EXIT_CRITICAL();
} else {
RMT_ENTER_CRITICAL();
rmt_ll_enable_rx_thres_interrupt(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_enable_rx_thres_interrupt(rmt_contex.hal.regs, channel, false);
RMT_EXIT_CRITICAL();
}
return ESP_OK;
@ -410,7 +443,7 @@ esp_err_t rmt_set_err_intr_en(rmt_channel_t channel, bool en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_err_interrupt(p_rmt_obj[channel]->hal.regs, channel, en);
rmt_ll_enable_err_interrupt(rmt_contex.hal.regs, channel, en);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -419,7 +452,7 @@ esp_err_t rmt_set_tx_intr_en(rmt_channel_t channel, bool en)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_tx_end_interrupt(p_rmt_obj[channel]->hal.regs, channel, en);
rmt_ll_enable_tx_end_interrupt(rmt_contex.hal.regs, channel, en);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -428,15 +461,15 @@ esp_err_t rmt_set_tx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_th
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
if (en) {
uint32_t item_block_len = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) * RMT_MEM_ITEM_NUM;
uint32_t item_block_len = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM;
RMT_CHECK(evt_thresh <= item_block_len, "RMT EVT THRESH ERR", ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_set_tx_limit(p_rmt_obj[channel]->hal.regs, channel, evt_thresh);
rmt_ll_enable_tx_thres_interrupt(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_set_tx_limit(rmt_contex.hal.regs, channel, evt_thresh);
rmt_ll_enable_tx_thres_interrupt(rmt_contex.hal.regs, channel, true);
RMT_EXIT_CRITICAL();
} else {
RMT_ENTER_CRITICAL();
rmt_ll_enable_tx_thres_interrupt(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_enable_tx_thres_interrupt(rmt_contex.hal.regs, channel, false);
RMT_EXIT_CRITICAL();
}
return ESP_OK;
@ -470,7 +503,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
uint8_t clk_div = rmt_param->clk_div;
uint32_t carrier_freq_hz = rmt_param->tx_config.carrier_freq_hz;
bool carrier_en = rmt_param->tx_config.carrier_en;
uint32_t rmt_source_clk_hz = 0;
uint32_t rmt_source_clk_hz;
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK((mem_cnt + channel <= 8 && mem_cnt > 0), RMT_MEM_CNT_ERROR_STR, ESP_ERR_INVALID_ARG);
@ -498,8 +531,6 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
rmt_ll_set_mem_owner(dev, channel, RMT_MEM_OWNER_HW);
RMT_EXIT_CRITICAL();
s_rmt_src_clock_hz[channel] = rmt_source_clk_hz;
if (mode == RMT_MODE_TX) {
uint16_t carrier_duty_percent = rmt_param->tx_config.carrier_duty_percent;
uint8_t carrier_level = rmt_param->tx_config.carrier_level;
@ -570,13 +601,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
esp_err_t rmt_config(const rmt_config_t *rmt_param)
{
// reset the RMT module at the first time initialize RMT driver
static bool rmt_module_enabled = false;
if (rmt_module_enabled == false) {
periph_module_reset(PERIPH_RMT_MODULE);
rmt_module_enabled = true;
}
periph_module_enable(PERIPH_RMT_MODULE);
rmt_module_enable();
RMT_CHECK(rmt_set_pin(rmt_param->channel, rmt_param->rmt_mode, rmt_param->gpio_num) == ESP_OK,
"set gpio for RMT driver failed", ESP_ERR_INVALID_ARG);
@ -591,9 +616,9 @@ static void IRAM_ATTR rmt_fill_memory(rmt_channel_t channel, const rmt_item32_t
uint16_t item_num, uint16_t mem_offset)
{
RMT_ENTER_CRITICAL();
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, RMT_MEM_OWNER_SW);
rmt_ll_write_memory(p_rmt_obj[channel]->hal.mem, channel, item, item_num, mem_offset);
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, RMT_MEM_OWNER_HW);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, RMT_MEM_OWNER_SW);
rmt_ll_write_memory(rmt_contex.hal.mem, channel, item, item_num, mem_offset);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, RMT_MEM_OWNER_HW);
RMT_EXIT_CRITICAL();
}
@ -604,7 +629,7 @@ esp_err_t rmt_fill_tx_items(rmt_channel_t channel, const rmt_item32_t *item, uin
RMT_CHECK((item_num > 0), RMT_DRIVER_LENGTH_ERROR_STR, ESP_ERR_INVALID_ARG);
/*Each block has 64 x 32 bits of data*/
uint8_t mem_cnt = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel);
uint8_t mem_cnt = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel);
RMT_CHECK((mem_cnt * RMT_MEM_ITEM_NUM >= item_num), RMT_WR_MEM_OVF_ERROR_STR, ESP_ERR_INVALID_ARG);
rmt_fill_memory(channel, item, item_num, mem_offset);
return ESP_OK;
@ -613,7 +638,7 @@ esp_err_t rmt_fill_tx_items(rmt_channel_t channel, const rmt_item32_t *item, uin
esp_err_t rmt_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, rmt_isr_handle_t *handle)
{
RMT_CHECK((fn != NULL), RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(s_rmt_driver_channels == 0, "RMT driver installed, can not install generic ISR handler", ESP_FAIL);
RMT_CHECK(rmt_contex.rmt_driver_channels == 0, "RMT driver installed, can not install generic ISR handler", ESP_FAIL);
return esp_intr_alloc(ETS_RMT_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
}
@ -625,7 +650,7 @@ esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle)
static int IRAM_ATTR rmt_get_mem_len(rmt_channel_t channel)
{
int block_num = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel);
int block_num = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel);
int item_block_len = block_num * RMT_MEM_ITEM_NUM;
volatile rmt_item32_t *data = (rmt_item32_t *)RMTMEM.chan[channel].data32;
int idx;
@ -655,15 +680,15 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
rmt_obj_t *p_rmt = p_rmt_obj[channel];
if (p_rmt) {
xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken);
rmt_ll_reset_tx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_tx_pointer(rmt_contex.hal.regs, channel);
p_rmt->tx_data = NULL;
p_rmt->tx_len_rem = 0;
p_rmt->tx_offset = 0;
p_rmt->tx_sub_len = 0;
p_rmt->sample_cur = NULL;
p_rmt->translator = false;
if (rmt_tx_end_callback.function != NULL) {
rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg);
if (rmt_contex.rmt_tx_end_callback.function != NULL) {
rmt_contex.rmt_tx_end_callback.function(channel, rmt_contex.rmt_tx_end_callback.arg);
}
}
rmt_ll_clear_tx_end_interrupt(hal->regs, channel);
@ -701,11 +726,11 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
p_rmt->tx_len_rem -= p_rmt->tx_sub_len;
} else if (len_rem == 0) {
rmt_item32_t stop_data = {0};
rmt_ll_write_memory(p_rmt_obj[channel]->hal.mem, channel, &stop_data, 1, p_rmt->tx_offset);
rmt_ll_write_memory(rmt_contex.hal.mem, channel, &stop_data, 1, p_rmt->tx_offset);
} else {
rmt_fill_memory(channel, pdata, len_rem, p_rmt->tx_offset);
rmt_item32_t stop_data = {0};
rmt_ll_write_memory(p_rmt_obj[channel]->hal.mem, channel, &stop_data, 1, p_rmt->tx_offset + len_rem);
rmt_ll_write_memory(rmt_contex.hal.mem, channel, &stop_data, 1, p_rmt->tx_offset + len_rem);
p_rmt->tx_data += len_rem;
p_rmt->tx_len_rem -= len_rem;
}
@ -725,9 +750,9 @@ 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) {
rmt_ll_enable_rx(p_rmt_obj[channel]->hal.regs, channel, false);
rmt_ll_enable_rx(rmt_contex.hal.regs, channel, false);
int item_len = rmt_get_mem_len(channel);
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, RMT_MEM_OWNER_SW);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, RMT_MEM_OWNER_SW);
if (p_rmt->rx_buf) {
addr = RMTMEM.chan[channel].data32;
#if SOC_RMT_SUPPORT_RX_PINGPONG
@ -752,9 +777,9 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
p_rmt->rx_item_len = 0;
memset((void *)p_rmt->rx_item_buf, 0, p_rmt->rx_item_buf_size);
#endif
rmt_ll_reset_rx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, RMT_MEM_OWNER_HW);
rmt_ll_enable_rx(p_rmt_obj[channel]->hal.regs, channel, true);
rmt_ll_reset_rx_pointer(rmt_contex.hal.regs, channel);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, RMT_MEM_OWNER_HW);
rmt_ll_enable_rx(rmt_contex.hal.regs, channel, true);
}
rmt_ll_clear_rx_end_interrupt(hal->regs, channel);
}
@ -766,13 +791,13 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
channel = __builtin_ffs(status) - 1;
status &= ~(1 << channel);
rmt_obj_t *p_rmt = p_rmt_obj[channel];
int mem_item_size = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) * RMT_MEM_ITEM_NUM;
int rx_thres_lim = rmt_ll_get_rx_limit(p_rmt_obj[channel]->hal.regs, channel);
int mem_item_size = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM;
int rx_thres_lim = rmt_ll_get_rx_limit(rmt_contex.hal.regs, channel);
int item_len = (p_rmt->rx_item_start_idx == 0) ? rx_thres_lim : (mem_item_size - rx_thres_lim);
if ((p_rmt->rx_item_len + item_len) < (p_rmt->rx_item_buf_size / 4)) {
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, RMT_MEM_OWNER_SW);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, RMT_MEM_OWNER_SW);
memcpy((void *)(p_rmt->rx_item_buf + p_rmt->rx_item_len), (void *)(RMTMEM.chan[channel].data32 + p_rmt->rx_item_start_idx), item_len * 4);
rmt_ll_set_mem_owner(p_rmt_obj[channel]->hal.regs, channel, RMT_MEM_OWNER_HW);
rmt_ll_set_mem_owner(rmt_contex.hal.regs, channel, RMT_MEM_OWNER_HW);
p_rmt->rx_item_len += item_len;
p_rmt->rx_item_start_idx += item_len;
if (p_rmt->rx_item_start_idx >= mem_item_size) {
@ -794,8 +819,8 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
rmt_obj_t *p_rmt = p_rmt_obj[channel];
if (p_rmt) {
xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken);
if (rmt_tx_end_callback.function != NULL) {
rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg);
if (rmt_contex.rmt_tx_end_callback.function != NULL) {
rmt_contex.rmt_tx_end_callback.function(channel, rmt_contex.rmt_tx_end_callback.arg);
}
}
rmt_ll_clear_tx_loop_interrupt(hal->regs, channel);
@ -810,10 +835,10 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
rmt_obj_t *p_rmt = p_rmt_obj[channel];
if (p_rmt) {
// Reset the receiver/transmitter's write/read addresses to prevent endless err interrupts.
rmt_ll_reset_tx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_rx_pointer(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_tx_pointer(rmt_contex.hal.regs, channel);
rmt_ll_reset_rx_pointer(rmt_contex.hal.regs, channel);
ESP_EARLY_LOGD(RMT_TAG, "RMT[%d] ERR", channel);
ESP_EARLY_LOGD(RMT_TAG, "status: 0x%08x", rmt_ll_get_channel_status(p_rmt_obj[channel]->hal.regs, channel));
ESP_EARLY_LOGD(RMT_TAG, "status: 0x%08x", rmt_ll_get_channel_status(rmt_contex.hal.regs, channel));
}
rmt_ll_clear_err_interrupt(hal->regs, channel);
}
@ -827,7 +852,7 @@ esp_err_t rmt_driver_uninstall(rmt_channel_t channel)
{
esp_err_t err = ESP_OK;
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK((s_rmt_driver_channels & BIT(channel)) != 0, "No RMT driver for this channel", ESP_ERR_INVALID_STATE);
RMT_CHECK((rmt_contex.rmt_driver_channels & BIT(channel)) != 0, "No RMT driver for this channel", ESP_ERR_INVALID_STATE);
if (p_rmt_obj[channel] == NULL) {
return ESP_OK;
}
@ -843,16 +868,17 @@ esp_err_t rmt_driver_uninstall(rmt_channel_t channel)
rmt_set_rx_thr_intr_en(channel, false, 0xffff);
#endif
_lock_acquire_recursive(&rmt_driver_isr_lock);
_lock_acquire_recursive(&(rmt_contex.rmt_driver_isr_lock));
s_rmt_driver_channels &= ~BIT(channel);
if (s_rmt_driver_channels == 0) {
rmt_contex.rmt_driver_channels &= ~BIT(channel);
if (rmt_contex.rmt_driver_channels == 0) {
rmt_module_disable();
// all channels have driver disabled
err = rmt_isr_deregister(s_rmt_driver_intr_handle);
s_rmt_driver_intr_handle = NULL;
err = rmt_isr_deregister(rmt_contex.rmt_driver_intr_handle);
rmt_contex.rmt_driver_intr_handle = NULL;
}
_lock_release_recursive(&rmt_driver_isr_lock);
_lock_release_recursive(&(rmt_contex.rmt_driver_isr_lock));
if (err != ESP_OK) {
return err;
@ -889,7 +915,7 @@ esp_err_t rmt_driver_uninstall(rmt_channel_t channel)
esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr_alloc_flags)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK((s_rmt_driver_channels & BIT(channel)) == 0,
RMT_CHECK((rmt_contex.rmt_driver_channels & BIT(channel)) == 0,
"RMT driver already installed for channel", ESP_ERR_INVALID_STATE);
esp_err_t err = ESP_OK;
@ -914,9 +940,6 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr
return ESP_ERR_NO_MEM;
}
rmt_hal_init(&p_rmt_obj[channel]->hal);
rmt_hal_channel_reset(&p_rmt_obj[channel]->hal, channel);
p_rmt_obj[channel]->tx_len_rem = 0;
p_rmt_obj[channel]->tx_data = NULL;
p_rmt_obj[channel]->channel = channel;
@ -961,17 +984,20 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr
}
#endif
rmt_set_err_intr_en(channel, 1);
_lock_acquire_recursive(&rmt_driver_isr_lock);
_lock_acquire_recursive(&(rmt_contex.rmt_driver_isr_lock));
if (s_rmt_driver_channels == 0) {
if (rmt_contex.rmt_driver_channels == 0) {
// first RMT channel using driver
err = rmt_isr_register(rmt_driver_isr_default, &p_rmt_obj[channel]->hal, intr_alloc_flags, &s_rmt_driver_intr_handle);
err = rmt_isr_register(rmt_driver_isr_default, &rmt_contex.hal, intr_alloc_flags, &(rmt_contex.rmt_driver_intr_handle));
}
if (err == ESP_OK) {
s_rmt_driver_channels |= BIT(channel);
rmt_contex.rmt_driver_channels |= BIT(channel);
}
_lock_release_recursive(&rmt_driver_isr_lock);
_lock_release_recursive(&(rmt_contex.rmt_driver_isr_lock));
rmt_module_enable();
rmt_set_err_intr_en(channel, 0);
rmt_hal_channel_reset(&rmt_contex.hal, channel);
rmt_set_err_intr_en(channel, 1);
return err;
}
@ -991,7 +1017,7 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, i
}
#endif
rmt_obj_t *p_rmt = p_rmt_obj[channel];
int block_num = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel);
int block_num = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel);
int item_block_len = block_num * RMT_MEM_ITEM_NUM;
int item_sub_len = block_num * RMT_MEM_ITEM_NUM / 2;
int len_rem = item_num;
@ -1009,14 +1035,14 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, i
} else {
rmt_fill_memory(channel, rmt_item, len_rem, 0);
rmt_item32_t stop_data = {0};
rmt_ll_write_memory(p_rmt_obj[channel]->hal.mem, channel, &stop_data, 1, len_rem);
rmt_ll_write_memory(rmt_contex.hal.mem, channel, &stop_data, 1, len_rem);
p_rmt->tx_len_rem = 0;
}
rmt_tx_start(channel, true);
p_rmt->wait_done = wait_tx_done;
if (wait_tx_done) {
// wait loop done
if (rmt_ll_is_tx_loop_enabled(p_rmt_obj[channel]->hal.regs, channel)) {
if (rmt_ll_is_tx_loop_enabled(rmt_contex.hal.regs, channel)) {
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
xSemaphoreTake(p_rmt->tx_sem, portMAX_DELAY);
xSemaphoreGive(p_rmt->tx_sem);
@ -1058,9 +1084,9 @@ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t *buf_han
rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, void *arg)
{
rmt_tx_end_callback_t previous = rmt_tx_end_callback;
rmt_tx_end_callback.function = function;
rmt_tx_end_callback.arg = arg;
rmt_tx_end_callback_t previous = rmt_contex.rmt_tx_end_callback;
rmt_contex.rmt_tx_end_callback.function = function;
rmt_contex.rmt_tx_end_callback.arg = arg;
return previous;
}
@ -1069,7 +1095,7 @@ esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn)
RMT_CHECK(fn != NULL, RMT_TRANSLATOR_NULL_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
const uint32_t block_size = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) *
const uint32_t block_size = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel) *
RMT_MEM_ITEM_NUM * sizeof(rmt_item32_t);
if (p_rmt_obj[channel]->tx_buf == NULL) {
#if !CONFIG_SPIRAM_USE_MALLOC
@ -1109,7 +1135,7 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src
size_t item_num = 0;
size_t translated_size = 0;
rmt_obj_t *p_rmt = p_rmt_obj[channel];
const uint32_t item_block_len = rmt_ll_get_mem_blocks(p_rmt_obj[channel]->hal.regs, channel) * RMT_MEM_ITEM_NUM;
const uint32_t item_block_len = rmt_ll_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM;
const uint32_t item_sub_len = item_block_len / 2;
xSemaphoreTake(p_rmt->tx_sem, portMAX_DELAY);
p_rmt->sample_to_rmt((void *)src, p_rmt->tx_buf, src_size, item_block_len, &translated_size, &item_num);
@ -1124,7 +1150,7 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src
p_rmt->translator = true;
} else {
rmt_item32_t stop_data = {0};
rmt_ll_write_memory(p_rmt_obj[channel]->hal.mem, channel, &stop_data, 1, item_num);
rmt_ll_write_memory(rmt_contex.hal.mem, channel, &stop_data, 1, item_num);
p_rmt->tx_len_rem = 0;
p_rmt->sample_cur = NULL;
p_rmt->translator = false;
@ -1162,7 +1188,11 @@ esp_err_t rmt_get_counter_clock(rmt_channel_t channel, uint32_t *clock_hz)
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_CHECK(clock_hz, "parameter clock_hz can't be null", ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
*clock_hz = rmt_hal_get_counter_clock(&p_rmt_obj[channel]->hal, channel, s_rmt_src_clock_hz[channel]);
if (rmt_ll_get_counter_clock_src(rmt_contex.hal.regs, channel) == RMT_BASECLK_REF) {
*clock_hz = rmt_hal_get_counter_clock(&rmt_contex.hal, channel, REF_CLK_FREQ);
} else {
*clock_hz = rmt_hal_get_counter_clock(&rmt_contex.hal, channel, APB_CLK_FREQ);
}
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -1172,9 +1202,9 @@ esp_err_t rmt_add_channel_to_group(rmt_channel_t channel)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
rmt_ll_enable_tx_sync(p_rmt_obj[channel]->hal.regs, true);
rmt_ll_add_channel_to_group(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_reset_counter_clock_div(p_rmt_obj[channel]->hal.regs, channel);
rmt_ll_enable_tx_sync(rmt_contex.hal.regs, true);
rmt_ll_add_channel_to_group(rmt_contex.hal.regs, channel);
rmt_ll_reset_counter_clock_div(rmt_contex.hal.regs, channel);
RMT_EXIT_CRITICAL();
return ESP_OK;
}
@ -1183,8 +1213,8 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
RMT_ENTER_CRITICAL();
if (rmt_ll_remove_channel_from_group(p_rmt_obj[channel]->hal.regs, channel) == 0) {
rmt_ll_enable_tx_sync(p_rmt_obj[channel]->hal.regs, false);
if (rmt_ll_remove_channel_from_group(rmt_contex.hal.regs, channel) == 0) {
rmt_ll_enable_tx_sync(rmt_contex.hal.regs, false);
}
RMT_EXIT_CRITICAL();
return ESP_OK;

View file

@ -39,13 +39,6 @@ typedef struct {
*/
void rmt_hal_init(rmt_hal_context_t *hal);
/**
* @brief Reset RMT HAL driver
*
* @param hal: RMT HAL context
*/
void rmt_hal_reset(rmt_hal_context_t *hal);
/**
* @brief Reset RMT Channel specific HAL driver
*
@ -133,7 +126,8 @@ uint32_t rmt_hal_receive(rmt_hal_context_t *hal, uint32_t channel, rmt_item32_t
* @param channel: RMT channel number
* @param src: RMT items to transmit
* @param length: length of RMT items to transmit
* @param offset: offset of RMT internal memory to store the items
* @param offset: offset of RMT internal memory to store the items.
* Note: the caller should ensure that (length + offset) <= (memory block * SOC_RMT_CHANNEL_MEM_WORDS).
*/
void rmt_hal_transmit(rmt_hal_context_t *hal, uint32_t channel, const rmt_item32_t *src, uint32_t length, uint32_t offset);

View file

@ -21,6 +21,9 @@ extern "C" {
#include "soc/rmt_struct.h"
#include "soc/rmt_caps.h"
#define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM)
static inline void rmt_ll_enable_drive_clock(rmt_dev_t *dev, bool enable)
{
dev->conf_ch[0].conf0.clk_en = enable;
@ -276,9 +279,10 @@ static inline void rmt_ll_set_carrier_on_level(rmt_dev_t *dev, uint32_t channel,
dev->conf_ch[channel].conf0.carrier_out_lv = level;
}
//Writes items to the specified TX channel memory with the given offset and writen length.
//the caller should ensure that (length + off) <= (memory block * SOC_RMT_CHANNEL_MEM_WORDS)
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const rmt_item32_t *data, uint32_t length, uint32_t off)
{
length = (off + length) > SOC_RMT_CHANNEL_MEM_WORDS ? (SOC_RMT_CHANNEL_MEM_WORDS - off) : length;
for (uint32_t i = 0; i < length; i++) {
mem->chan[channel].data32[i + off].val = data[i].val;
}

View file

@ -21,6 +21,9 @@ extern "C" {
#include "soc/rmt_struct.h"
#include "soc/rmt_caps.h"
#define RMT_LL_HW_BASE (&RMT)
#define RMT_LL_MEM_BASE (&RMTMEM)
static inline void rmt_ll_enable_drive_clock(rmt_dev_t *dev, bool enable)
{
dev->apb_conf.clk_en = enable; // register clock gating
@ -367,9 +370,10 @@ static inline void rmt_ll_tx_set_carrier_always_on(rmt_dev_t *dev, uint32_t chan
dev->conf_ch[channel].conf0.carrier_eff_en = !enable;
}
//Writes items to the specified TX channel memory with the given offset and writen length.
//the caller should ensure that (length + off) <= (memory block * SOC_RMT_CHANNEL_MEM_WORDS)
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const rmt_item32_t *data, uint32_t length, uint32_t off)
{
length = (off + length) > SOC_RMT_CHANNEL_MEM_WORDS ? (SOC_RMT_CHANNEL_MEM_WORDS - off) : length;
for (uint32_t i = 0; i < length; i++) {
mem->chan[channel].data32[i + off].val = data[i].val;
}

View file

@ -20,11 +20,6 @@ void rmt_hal_init(rmt_hal_context_t *hal)
hal->mem = &RMTMEM;
}
void rmt_hal_reset(rmt_hal_context_t *hal)
{
}
void rmt_hal_channel_reset(rmt_hal_context_t *hal, uint32_t channel)
{
rmt_ll_reset_tx_pointer(hal->regs, channel);