mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 13:14:32 +02:00
Merge branch 'bugfix/channel_clk_independent' into 'master'
rmt: clean up and support esp32-s3 (no DMA support) Closes IDF-3296 and IDFGH-5350 See merge request espressif/esp-idf!13244
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "esp_compiler.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "driver/rmt.h"
|
||||
@@ -42,12 +43,7 @@
|
||||
#define RMT_TRANSLATOR_UNINIT_STR "RMT translator not init"
|
||||
#define RMT_PARAM_ERR_STR "RMT param error"
|
||||
|
||||
static const char *RMT_TAG = "rmt";
|
||||
#define RMT_CHECK(a, str, ret_val, ...) \
|
||||
if (unlikely(!(a))) { \
|
||||
ESP_LOGE(RMT_TAG, "%s(%d): "str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
return (ret_val); \
|
||||
}
|
||||
static const char *TAG = "rmt";
|
||||
|
||||
// Spinlock for protecting concurrent register-level access only
|
||||
#define RMT_ENTER_CRITICAL() portENTER_CRITICAL_SAFE(&(rmt_contex.rmt_spinlock))
|
||||
@@ -114,7 +110,7 @@ static rmt_contex_t rmt_contex = {
|
||||
|
||||
static rmt_obj_t *p_rmt_obj[RMT_CHANNEL_MAX] = {0};
|
||||
|
||||
#if SOC_RMT_SOURCE_CLK_INDEPENDENT
|
||||
#if SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
static uint32_t s_rmt_source_clock_hz[RMT_CHANNEL_MAX];
|
||||
#else
|
||||
static uint32_t s_rmt_source_clock_hz;
|
||||
@@ -125,8 +121,8 @@ static void rmt_module_enable(void)
|
||||
{
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (rmt_contex.rmt_module_enabled == false) {
|
||||
periph_module_reset(rmt_periph_signals.module);
|
||||
periph_module_enable(rmt_periph_signals.module);
|
||||
periph_module_reset(rmt_periph_signals.groups[0].module);
|
||||
periph_module_enable(rmt_periph_signals.groups[0].module);
|
||||
rmt_contex.rmt_module_enabled = true;
|
||||
}
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -137,7 +133,7 @@ static void rmt_module_disable(void)
|
||||
{
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (rmt_contex.rmt_module_enabled == true) {
|
||||
periph_module_disable(rmt_periph_signals.module);
|
||||
periph_module_disable(rmt_periph_signals.groups[0].module);
|
||||
rmt_contex.rmt_module_enabled = false;
|
||||
}
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -145,7 +141,7 @@ static void rmt_module_disable(void)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
rmt_ll_rx_set_channel_clock_div(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), div_cnt);
|
||||
@@ -158,8 +154,8 @@ esp_err_t rmt_set_clk_div(rmt_channel_t channel, uint8_t div_cnt)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(div_cnt, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
*div_cnt = (uint8_t)rmt_ll_rx_get_channel_clock_div(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
@@ -172,7 +168,7 @@ esp_err_t rmt_get_clk_div(rmt_channel_t channel, uint8_t *div_cnt)
|
||||
|
||||
esp_err_t rmt_set_rx_idle_thresh(rmt_channel_t channel, uint16_t thresh)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_rx_set_idle_thres(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), thresh);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -181,8 +177,8 @@ esp_err_t rmt_set_rx_idle_thresh(rmt_channel_t channel, uint16_t thresh)
|
||||
|
||||
esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(thresh != NULL, RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(thresh, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
*thresh = (uint16_t)rmt_ll_rx_get_idle_thres(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -191,8 +187,8 @@ esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(rmt_mem_num <= RMT_CHANNEL_MAX - channel, ESP_ERR_INVALID_ARG, TAG, RMT_MEM_CNT_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
rmt_ll_rx_set_mem_blocks(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), rmt_mem_num);
|
||||
@@ -205,8 +201,8 @@ esp_err_t rmt_set_mem_block_num(rmt_channel_t channel, uint8_t rmt_mem_num)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(rmt_mem_num, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
*rmt_mem_num = (uint8_t)rmt_ll_rx_get_mem_blocks(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
@@ -220,8 +216,8 @@ esp_err_t rmt_get_mem_block_num(rmt_channel_t channel, uint8_t *rmt_mem_num)
|
||||
esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t high_level, uint16_t low_level,
|
||||
rmt_carrier_level_t carrier_level)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(carrier_level < RMT_CARRIER_LEVEL_MAX, RMT_CARRIER_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(carrier_level < RMT_CARRIER_LEVEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CARRIER_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_set_carrier_high_low_ticks(rmt_contex.hal.regs, channel, high_level, low_level);
|
||||
rmt_ll_tx_set_carrier_level(rmt_contex.hal.regs, channel, carrier_level);
|
||||
@@ -232,7 +228,7 @@ esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t hi
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_power_down_mem(rmt_contex.hal.regs, pd_en);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -241,7 +237,7 @@ esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
*pd_en = rmt_ll_is_mem_power_down(rmt_contex.hal.regs);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -250,7 +246,7 @@ esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool *pd_en)
|
||||
|
||||
esp_err_t rmt_tx_start(rmt_channel_t channel, bool tx_idx_rst)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (tx_idx_rst) {
|
||||
rmt_ll_tx_reset_pointer(rmt_contex.hal.regs, channel);
|
||||
@@ -274,7 +270,7 @@ esp_err_t rmt_tx_start(rmt_channel_t channel, bool tx_idx_rst)
|
||||
|
||||
esp_err_t rmt_tx_stop(rmt_channel_t channel)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_stop(rmt_contex.hal.regs, channel);
|
||||
rmt_ll_tx_reset_pointer(rmt_contex.hal.regs, channel);
|
||||
@@ -284,7 +280,7 @@ esp_err_t rmt_tx_stop(rmt_channel_t channel)
|
||||
|
||||
esp_err_t rmt_rx_start(rmt_channel_t channel, bool rx_idx_rst)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_rx_enable(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), false);
|
||||
if (rx_idx_rst) {
|
||||
@@ -307,7 +303,7 @@ esp_err_t rmt_rx_start(rmt_channel_t channel, bool rx_idx_rst)
|
||||
|
||||
esp_err_t rmt_rx_stop(rmt_channel_t channel)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_enable_rx_end_interrupt(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), false);
|
||||
rmt_ll_rx_enable(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), false);
|
||||
@@ -321,7 +317,7 @@ esp_err_t rmt_rx_stop(rmt_channel_t channel)
|
||||
|
||||
esp_err_t rmt_tx_memory_reset(rmt_channel_t channel)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_reset_pointer(rmt_contex.hal.regs, channel);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -330,7 +326,7 @@ esp_err_t rmt_tx_memory_reset(rmt_channel_t channel)
|
||||
|
||||
esp_err_t rmt_rx_memory_reset(rmt_channel_t channel)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_rx_reset_pointer(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -339,8 +335,8 @@ esp_err_t rmt_rx_memory_reset(rmt_channel_t channel)
|
||||
|
||||
esp_err_t rmt_set_memory_owner(rmt_channel_t channel, rmt_mem_owner_t owner)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && 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);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(owner < RMT_MEM_OWNER_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_MEM_OWNER_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_rx_set_mem_owner(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), owner);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -349,8 +345,8 @@ esp_err_t rmt_set_memory_owner(rmt_channel_t channel, rmt_mem_owner_t owner)
|
||||
|
||||
esp_err_t rmt_get_memory_owner(rmt_channel_t channel, rmt_mem_owner_t *owner)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && 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);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(owner, ESP_ERR_INVALID_ARG, TAG, RMT_MEM_OWNER_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
*owner = (rmt_mem_owner_t)rmt_ll_rx_get_mem_owner(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -359,7 +355,7 @@ esp_err_t rmt_get_memory_owner(rmt_channel_t channel, rmt_mem_owner_t *owner)
|
||||
|
||||
esp_err_t rmt_set_tx_loop_mode(rmt_channel_t channel, bool loop_en)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_enable_loop(rmt_contex.hal.regs, channel, loop_en);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -368,7 +364,7 @@ esp_err_t rmt_set_tx_loop_mode(rmt_channel_t channel, bool loop_en)
|
||||
|
||||
esp_err_t rmt_get_tx_loop_mode(rmt_channel_t channel, bool *loop_en)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
*loop_en = rmt_ll_is_tx_loop_enabled(rmt_contex.hal.regs, channel);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -377,7 +373,7 @@ esp_err_t rmt_get_tx_loop_mode(rmt_channel_t channel, bool *loop_en)
|
||||
|
||||
esp_err_t rmt_set_rx_filter(rmt_channel_t channel, bool rx_filter_en, uint8_t thresh)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_rx_enable_filter(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), rx_filter_en);
|
||||
rmt_ll_rx_set_filter_thres(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), thresh);
|
||||
@@ -387,8 +383,8 @@ esp_err_t rmt_set_rx_filter(rmt_channel_t channel, bool rx_filter_en, uint8_t th
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(base_clk < RMT_BASECLK_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_BASECLK_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_set_group_clock_src(rmt_contex.hal.regs, channel, base_clk, 0, 0, 0);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -397,7 +393,7 @@ esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
*src_clk = (rmt_source_clk_t)rmt_ll_get_group_clock_src(rmt_contex.hal.regs, channel);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -406,8 +402,8 @@ esp_err_t rmt_get_source_clk(rmt_channel_t channel, rmt_source_clk_t *src_clk)
|
||||
|
||||
esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_level_t level)
|
||||
{
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(level < RMT_IDLE_LEVEL_MAX, ESP_ERR_INVALID_ARG, TAG, "RMT IDLE LEVEL ERR");
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_enable_idle(rmt_contex.hal.regs, channel, idle_out_en);
|
||||
rmt_ll_tx_set_idle_level(rmt_contex.hal.regs, channel, level);
|
||||
@@ -417,7 +413,7 @@ esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_l
|
||||
|
||||
esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool *idle_out_en, rmt_idle_level_t *level)
|
||||
{
|
||||
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
*idle_out_en = rmt_ll_is_tx_idle_enabled(rmt_contex.hal.regs, channel);
|
||||
*level = rmt_ll_tx_get_idle_level(rmt_contex.hal.regs, channel);
|
||||
@@ -427,7 +423,7 @@ esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool *idle_out_en, rmt_idle_
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
*status = rmt_ll_rx_get_channel_status(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
@@ -441,20 +437,20 @@ esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t *status)
|
||||
void rmt_set_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_set_intr_enable_mask(mask);
|
||||
rmt_ll_enable_interrupt(rmt_contex.hal.regs, mask, true);
|
||||
RMT_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void rmt_clr_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_clr_intr_enable_mask(mask);
|
||||
rmt_ll_enable_interrupt(rmt_contex.hal.regs, mask, false);
|
||||
RMT_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
esp_err_t rmt_set_rx_intr_en(rmt_channel_t channel, bool en)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_enable_rx_end_interrupt(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), en);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -464,10 +460,10 @@ esp_err_t rmt_set_rx_intr_en(rmt_channel_t channel, bool en)
|
||||
#if SOC_RMT_SUPPORT_RX_PINGPONG
|
||||
esp_err_t rmt_set_rx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_thresh)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel) && channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
if (en) {
|
||||
uint32_t item_block_len = rmt_ll_rx_get_mem_blocks(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel)) * RMT_MEM_ITEM_NUM;
|
||||
RMT_CHECK(evt_thresh <= item_block_len, "RMT EVT THRESH ERR", ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(evt_thresh <= item_block_len, ESP_ERR_INVALID_ARG, TAG, "RMT EVT THRESH ERR");
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_rx_set_limit(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), evt_thresh);
|
||||
rmt_ll_enable_rx_thres_interrupt(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), true);
|
||||
@@ -483,7 +479,7 @@ esp_err_t rmt_set_rx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_th
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
rmt_ll_enable_rx_err_interrupt(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel), en);
|
||||
@@ -496,7 +492,7 @@ esp_err_t rmt_set_err_intr_en(rmt_channel_t channel, bool en)
|
||||
|
||||
esp_err_t rmt_set_tx_intr_en(rmt_channel_t channel, bool en)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_enable_tx_end_interrupt(rmt_contex.hal.regs, channel, en);
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -505,10 +501,10 @@ esp_err_t rmt_set_tx_intr_en(rmt_channel_t channel, bool en)
|
||||
|
||||
esp_err_t rmt_set_tx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_thresh)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
if (en) {
|
||||
uint32_t item_block_len = rmt_ll_tx_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);
|
||||
ESP_RETURN_ON_FALSE(evt_thresh <= item_block_len, ESP_ERR_INVALID_ARG, TAG, "RMT EVT THRESH ERR");
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_set_limit(rmt_contex.hal.regs, channel, evt_thresh);
|
||||
rmt_ll_enable_tx_thres_interrupt(rmt_contex.hal.regs, channel, true);
|
||||
@@ -523,21 +519,20 @@ esp_err_t rmt_set_tx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_th
|
||||
|
||||
esp_err_t rmt_set_gpio(rmt_channel_t channel, rmt_mode_t mode, gpio_num_t gpio_num, bool invert_signal)
|
||||
{
|
||||
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(mode < RMT_MODE_MAX, RMT_MODE_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(((GPIO_IS_VALID_GPIO(gpio_num) && (mode == RMT_MODE_RX)) ||
|
||||
(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) && (mode == RMT_MODE_TX))),
|
||||
RMT_GPIO_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(mode < RMT_MODE_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_MODE_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(((GPIO_IS_VALID_GPIO(gpio_num) && (mode == RMT_MODE_RX)) ||
|
||||
(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) && (mode == RMT_MODE_TX))), ESP_ERR_INVALID_ARG, TAG, RMT_GPIO_ERROR_STR);
|
||||
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
|
||||
if (mode == RMT_MODE_TX) {
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, rmt_periph_signals.channels[channel].tx_sig, invert_signal, 0);
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, rmt_periph_signals.groups[0].channels[channel].tx_sig, invert_signal, 0);
|
||||
} else {
|
||||
RMT_CHECK(RMT_IS_RX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_RX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
|
||||
esp_rom_gpio_connect_in_signal(gpio_num, rmt_periph_signals.channels[channel].rx_sig, invert_signal);
|
||||
esp_rom_gpio_connect_in_signal(gpio_num, rmt_periph_signals.groups[0].channels[channel].rx_sig, invert_signal);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -569,12 +564,12 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
|
||||
bool carrier_en = rmt_param->tx_config.carrier_en;
|
||||
uint32_t rmt_source_clk_hz;
|
||||
|
||||
RMT_CHECK(rmt_is_channel_number_valid(channel, mode), 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);
|
||||
RMT_CHECK((clk_div > 0), RMT_CLK_DIV_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(rmt_is_channel_number_valid(channel, mode), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(mem_cnt + channel <= 8 && mem_cnt > 0, ESP_ERR_INVALID_ARG, TAG, RMT_MEM_CNT_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(clk_div > 0, ESP_ERR_INVALID_ARG, TAG, RMT_CLK_DIV_ERROR_STR);
|
||||
|
||||
if (mode == RMT_MODE_TX) {
|
||||
RMT_CHECK((!carrier_en || carrier_freq_hz > 0), "RMT carrier frequency can't be zero", ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(!carrier_en || carrier_freq_hz > 0, ESP_ERR_INVALID_ARG, TAG, "RMT carrier frequency can't be zero");
|
||||
}
|
||||
|
||||
RMT_ENTER_CRITICAL();
|
||||
@@ -597,15 +592,15 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
|
||||
}
|
||||
RMT_EXIT_CRITICAL();
|
||||
|
||||
#if SOC_RMT_SOURCE_CLK_INDEPENDENT
|
||||
#if SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
s_rmt_source_clock_hz[channel] = rmt_source_clk_hz;
|
||||
#else
|
||||
if (s_rmt_source_clock_hz && rmt_source_clk_hz != s_rmt_source_clock_hz) {
|
||||
ESP_LOGW(RMT_TAG, "RMT clock source has been configured to %d by other channel, now reconfigure it to %d", s_rmt_source_clock_hz, rmt_source_clk_hz);
|
||||
ESP_LOGW(TAG, "RMT clock source has been configured to %d by other channel, now reconfigure it to %d", s_rmt_source_clock_hz, rmt_source_clk_hz);
|
||||
}
|
||||
s_rmt_source_clock_hz = rmt_source_clk_hz;
|
||||
#endif
|
||||
ESP_LOGD(RMT_TAG, "rmt_source_clk_hz: %d\n", rmt_source_clk_hz);
|
||||
ESP_LOGD(TAG, "rmt_source_clk_hz: %d\n", rmt_source_clk_hz);
|
||||
|
||||
if (mode == RMT_MODE_TX) {
|
||||
uint16_t carrier_duty_percent = rmt_param->tx_config.carrier_duty_percent;
|
||||
@@ -642,7 +637,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
|
||||
}
|
||||
RMT_EXIT_CRITICAL();
|
||||
|
||||
ESP_LOGD(RMT_TAG, "Rmt Tx Channel %u|Gpio %u|Sclk_Hz %u|Div %u|Carrier_Hz %u|Duty %u",
|
||||
ESP_LOGD(TAG, "Rmt Tx Channel %u|Gpio %u|Sclk_Hz %u|Div %u|Carrier_Hz %u|Duty %u",
|
||||
channel, gpio_num, rmt_source_clk_hz, clk_div, carrier_freq_hz, carrier_duty_percent);
|
||||
} else if (RMT_MODE_RX == mode) {
|
||||
uint8_t filter_cnt = rmt_param->rx_config.filter_ticks_thresh;
|
||||
@@ -676,7 +671,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par
|
||||
#endif
|
||||
RMT_EXIT_CRITICAL();
|
||||
|
||||
ESP_LOGD(RMT_TAG, "Rmt Rx Channel %u|Gpio %u|Sclk_Hz %u|Div %u|Thresold %u|Filter %u",
|
||||
ESP_LOGD(TAG, "Rmt Rx Channel %u|Gpio %u|Sclk_Hz %u|Div %u|Thresold %u|Filter %u",
|
||||
channel, gpio_num, rmt_source_clk_hz, clk_div, threshold, filter_cnt);
|
||||
}
|
||||
|
||||
@@ -687,11 +682,8 @@ esp_err_t rmt_config(const rmt_config_t *rmt_param)
|
||||
{
|
||||
rmt_module_enable();
|
||||
|
||||
RMT_CHECK(rmt_set_gpio(rmt_param->channel, rmt_param->rmt_mode, rmt_param->gpio_num, rmt_param->flags & RMT_CHANNEL_FLAGS_INVERT_SIG) == ESP_OK,
|
||||
"set gpio for RMT driver failed", ESP_ERR_INVALID_ARG);
|
||||
|
||||
RMT_CHECK(rmt_internal_config(&RMT, rmt_param) == ESP_OK,
|
||||
"initialize RMT driver failed", ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_ERROR(rmt_set_gpio(rmt_param->channel, rmt_param->rmt_mode, rmt_param->gpio_num, rmt_param->flags & RMT_CHANNEL_FLAGS_INVERT_SIG), TAG, "set gpio for RMT driver failed");
|
||||
ESP_RETURN_ON_ERROR(rmt_internal_config(&RMT, rmt_param), TAG, "initialize RMT driver failed");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -706,23 +698,23 @@ static void IRAM_ATTR rmt_fill_memory(rmt_channel_t channel, const rmt_item32_t
|
||||
|
||||
esp_err_t rmt_fill_tx_items(rmt_channel_t channel, const rmt_item32_t *item, uint16_t item_num, uint16_t mem_offset)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, (0));
|
||||
RMT_CHECK((item != NULL), RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK((item_num > 0), RMT_DRIVER_LENGTH_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), (0), TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(item, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(item_num > 0, ESP_ERR_INVALID_ARG, TAG, RMT_DRIVER_LENGTH_ERROR_STR);
|
||||
|
||||
/*Each block has 64 x 32 bits of data*/
|
||||
uint8_t mem_cnt = rmt_ll_tx_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);
|
||||
ESP_RETURN_ON_FALSE(mem_cnt * RMT_MEM_ITEM_NUM >= item_num, ESP_ERR_INVALID_ARG, TAG, RMT_WR_MEM_OVF_ERROR_STR);
|
||||
rmt_fill_memory(channel, item, item_num, mem_offset);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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(rmt_contex.rmt_driver_channels == 0, "RMT driver installed, can not install generic ISR handler", ESP_FAIL);
|
||||
ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(rmt_contex.rmt_driver_channels == 0, ESP_FAIL, TAG, "RMT driver installed, can not install generic ISR handler");
|
||||
|
||||
return esp_intr_alloc(rmt_periph_signals.irq, intr_alloc_flags, fn, arg, handle);
|
||||
return esp_intr_alloc(rmt_periph_signals.groups[0].irq, intr_alloc_flags, fn, arg, handle);
|
||||
}
|
||||
|
||||
esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle)
|
||||
@@ -769,7 +761,7 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
p_rmt->tx_sub_len = 0;
|
||||
p_rmt->sample_cur = NULL;
|
||||
p_rmt->translator = false;
|
||||
if (rmt_contex.rmt_tx_end_callback.function != NULL) {
|
||||
if (rmt_contex.rmt_tx_end_callback.function) {
|
||||
rmt_contex.rmt_tx_end_callback.function(channel, rmt_contex.rmt_tx_end_callback.arg);
|
||||
}
|
||||
}
|
||||
@@ -848,10 +840,10 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
BaseType_t res = xRingbufferSendFromISR(p_rmt->rx_buf, (void *)addr, item_len * 4, &HPTaskAwoken);
|
||||
#endif
|
||||
if (res == pdFALSE) {
|
||||
ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER FULL");
|
||||
ESP_EARLY_LOGE(TAG, "RMT RX BUFFER FULL");
|
||||
}
|
||||
} else {
|
||||
ESP_EARLY_LOGE(RMT_TAG, "RMT RX BUFFER ERROR");
|
||||
ESP_EARLY_LOGE(TAG, "RMT RX BUFFER ERROR");
|
||||
}
|
||||
|
||||
#if SOC_RMT_SUPPORT_RX_PINGPONG
|
||||
@@ -886,7 +878,7 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
p_rmt->rx_item_start_idx = 0;
|
||||
}
|
||||
} else {
|
||||
ESP_EARLY_LOGE(RMT_TAG, "---RX buffer too small: %d", sizeof(p_rmt->rx_item_buf));
|
||||
ESP_EARLY_LOGE(TAG, "---RX buffer too small: %d", sizeof(p_rmt->rx_item_buf));
|
||||
}
|
||||
rmt_ll_clear_rx_thres_interrupt(hal->regs, channel);
|
||||
}
|
||||
@@ -901,7 +893,7 @@ 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_contex.rmt_tx_end_callback.function != NULL) {
|
||||
if (rmt_contex.rmt_tx_end_callback.function) {
|
||||
rmt_contex.rmt_tx_end_callback.function(channel, rmt_contex.rmt_tx_end_callback.arg);
|
||||
}
|
||||
}
|
||||
@@ -918,8 +910,8 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
if (p_rmt) {
|
||||
// Reset the receiver's write/read addresses to prevent endless err interrupts.
|
||||
rmt_ll_rx_reset_pointer(rmt_contex.hal.regs, channel);
|
||||
ESP_EARLY_LOGD(RMT_TAG, "RMT RX channel %d error", channel);
|
||||
ESP_EARLY_LOGD(RMT_TAG, "status: 0x%08x", rmt_ll_rx_get_channel_status(rmt_contex.hal.regs, channel));
|
||||
ESP_EARLY_LOGD(TAG, "RMT RX channel %d error", channel);
|
||||
ESP_EARLY_LOGD(TAG, "status: 0x%08x", rmt_ll_rx_get_channel_status(rmt_contex.hal.regs, channel));
|
||||
}
|
||||
rmt_ll_clear_rx_err_interrupt(hal->regs, channel);
|
||||
}
|
||||
@@ -933,8 +925,8 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
if (p_rmt) {
|
||||
// Reset the transmitter's write/read addresses to prevent endless err interrupts.
|
||||
rmt_ll_tx_reset_pointer(rmt_contex.hal.regs, channel);
|
||||
ESP_EARLY_LOGD(RMT_TAG, "RMT TX channel %d error", channel);
|
||||
ESP_EARLY_LOGD(RMT_TAG, "status: 0x%08x", rmt_ll_tx_get_channel_status(rmt_contex.hal.regs, channel));
|
||||
ESP_EARLY_LOGD(TAG, "RMT TX channel %d error", channel);
|
||||
ESP_EARLY_LOGD(TAG, "status: 0x%08x", rmt_ll_tx_get_channel_status(rmt_contex.hal.regs, channel));
|
||||
}
|
||||
rmt_ll_clear_tx_err_interrupt(hal->regs, channel);
|
||||
}
|
||||
@@ -947,8 +939,8 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg)
|
||||
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((rmt_contex.rmt_driver_channels & BIT(channel)) != 0, "No RMT driver for this channel", ESP_ERR_INVALID_STATE);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(rmt_contex.rmt_driver_channels & BIT(channel), ESP_ERR_INVALID_STATE, TAG, "No RMT driver for this channel");
|
||||
if (p_rmt_obj[channel] == NULL) {
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1016,14 +1008,13 @@ 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((rmt_contex.rmt_driver_channels & BIT(channel)) == 0,
|
||||
"RMT driver already installed for channel", ESP_ERR_INVALID_STATE);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE((rmt_contex.rmt_driver_channels & BIT(channel)) == 0, ESP_ERR_INVALID_STATE, TAG, "RMT driver already installed for channel");
|
||||
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if (p_rmt_obj[channel] != NULL) {
|
||||
ESP_LOGD(RMT_TAG, "RMT driver already installed");
|
||||
if (p_rmt_obj[channel]) {
|
||||
ESP_LOGD(TAG, "RMT driver already installed");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
@@ -1038,7 +1029,7 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr
|
||||
#endif
|
||||
|
||||
if (p_rmt_obj[channel] == NULL) {
|
||||
ESP_LOGE(RMT_TAG, "RMT driver malloc error");
|
||||
ESP_LOGE(TAG, "RMT driver malloc error");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
@@ -1079,7 +1070,7 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr
|
||||
}
|
||||
#endif
|
||||
if (p_rmt_obj[channel]->rx_item_buf == NULL) {
|
||||
ESP_LOGE(RMT_TAG, "RMT malloc fail");
|
||||
ESP_LOGE(TAG, "RMT malloc fail");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
p_rmt_obj[channel]->rx_item_buf_size = rx_buf_size;
|
||||
@@ -1110,14 +1101,14 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr
|
||||
|
||||
esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, int item_num, bool wait_tx_done)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
RMT_CHECK(rmt_item != NULL, RMT_ADDR_ERROR_STR, ESP_FAIL);
|
||||
RMT_CHECK(item_num > 0, RMT_DRIVER_LENGTH_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(rmt_item, ESP_FAIL, TAG, RMT_ADDR_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(item_num > 0, ESP_ERR_INVALID_ARG, TAG, RMT_DRIVER_LENGTH_ERROR_STR);
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
if (p_rmt_obj[channel]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) {
|
||||
if (!esp_ptr_internal(rmt_item)) {
|
||||
ESP_LOGE(RMT_TAG, RMT_PSRAM_BUFFER_WARN_STR);
|
||||
ESP_LOGE(TAG, RMT_PSRAM_BUFFER_WARN_STR);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
@@ -1164,8 +1155,8 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, i
|
||||
|
||||
esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR);
|
||||
if (xSemaphoreTake(p_rmt_obj[channel]->tx_sem, wait_time) == pdTRUE) {
|
||||
p_rmt_obj[channel]->wait_done = false;
|
||||
xSemaphoreGive(p_rmt_obj[channel]->tx_sem);
|
||||
@@ -1173,7 +1164,7 @@ esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time)
|
||||
} else {
|
||||
if (wait_time != 0) {
|
||||
// Don't emit error message if just polling.
|
||||
ESP_LOGE(RMT_TAG, "Timeout on wait_tx_done");
|
||||
ESP_LOGE(TAG, "Timeout on wait_tx_done");
|
||||
}
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
@@ -1181,9 +1172,9 @@ esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time)
|
||||
|
||||
esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t *buf_handle)
|
||||
{
|
||||
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);
|
||||
RMT_CHECK(buf_handle != NULL, RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(buf_handle, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR);
|
||||
*buf_handle = p_rmt_obj[channel]->rx_buf;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1198,9 +1189,9 @@ rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, voi
|
||||
|
||||
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(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, RMT_TRANSLATOR_NULL_STR);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR);
|
||||
const uint32_t block_size = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel) *
|
||||
RMT_MEM_ITEM_NUM * sizeof(rmt_item32_t);
|
||||
if (p_rmt_obj[channel]->tx_buf == NULL) {
|
||||
@@ -1214,7 +1205,7 @@ esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn)
|
||||
}
|
||||
#endif
|
||||
if (p_rmt_obj[channel]->tx_buf == NULL) {
|
||||
ESP_LOGE(RMT_TAG, "RMT translator buffer create fail");
|
||||
ESP_LOGE(TAG, "RMT translator buffer create fail");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
@@ -1222,14 +1213,14 @@ esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn)
|
||||
p_rmt_obj[channel]->tx_context = NULL;
|
||||
p_rmt_obj[channel]->sample_size_remain = 0;
|
||||
p_rmt_obj[channel]->sample_cur = NULL;
|
||||
ESP_LOGD(RMT_TAG, "RMT translator init done");
|
||||
ESP_LOGD(TAG, "RMT translator init done");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t rmt_translator_set_context(rmt_channel_t channel, void *context)
|
||||
{
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR);
|
||||
|
||||
p_rmt_obj[channel]->tx_context = context;
|
||||
return ESP_OK;
|
||||
@@ -1237,7 +1228,7 @@ esp_err_t rmt_translator_set_context(rmt_channel_t channel, void *context)
|
||||
|
||||
esp_err_t rmt_translator_get_context(const size_t *item_num, void **context)
|
||||
{
|
||||
RMT_CHECK(item_num && context, "invalid arguments", ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(item_num && context, ESP_ERR_INVALID_ARG, TAG, "invalid arguments");
|
||||
|
||||
// the address of tx_len_rem is directlly passed to the callback,
|
||||
// so it's possible to get the object address from that
|
||||
@@ -1249,13 +1240,13 @@ esp_err_t rmt_translator_get_context(const size_t *item_num, void **context)
|
||||
|
||||
esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src_size, bool wait_tx_done)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
RMT_CHECK(p_rmt_obj[channel] != NULL, RMT_DRIVER_ERROR_STR, ESP_FAIL);
|
||||
RMT_CHECK(p_rmt_obj[channel]->sample_to_rmt != NULL, RMT_TRANSLATOR_UNINIT_STR, ESP_FAIL);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(p_rmt_obj[channel]->sample_to_rmt, ESP_FAIL, TAG, RMT_TRANSLATOR_UNINIT_STR);
|
||||
#if CONFIG_SPIRAM_USE_MALLOC
|
||||
if (p_rmt_obj[channel]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) {
|
||||
if (!esp_ptr_internal(src)) {
|
||||
ESP_LOGE(RMT_TAG, RMT_PSRAM_BUFFER_WARN_STR);
|
||||
ESP_LOGE(TAG, RMT_PSRAM_BUFFER_WARN_STR);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
@@ -1293,11 +1284,11 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src
|
||||
|
||||
esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status)
|
||||
{
|
||||
RMT_CHECK(channel_status != NULL, RMT_PARAM_ERR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(channel_status, ESP_ERR_INVALID_ARG, TAG, RMT_PARAM_ERR_STR);
|
||||
for (int i = 0; i < RMT_CHANNEL_MAX; i++) {
|
||||
channel_status->status[i] = RMT_CHANNEL_UNINIT;
|
||||
if (p_rmt_obj[i] != NULL) {
|
||||
if (p_rmt_obj[i]->tx_sem != NULL) {
|
||||
if (p_rmt_obj[i]) {
|
||||
if (p_rmt_obj[i]->tx_sem) {
|
||||
if (xSemaphoreTake(p_rmt_obj[i]->tx_sem, (TickType_t)0) == pdTRUE) {
|
||||
channel_status->status[i] = RMT_CHANNEL_IDLE;
|
||||
xSemaphoreGive(p_rmt_obj[i]->tx_sem);
|
||||
@@ -1312,11 +1303,11 @@ esp_err_t rmt_get_channel_status(rmt_channel_status_result_t *channel_status)
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
ESP_RETURN_ON_FALSE(clock_hz, ESP_ERR_INVALID_ARG, TAG, "parameter clock_hz can't be null");
|
||||
RMT_ENTER_CRITICAL();
|
||||
uint32_t rmt_source_clk_hz = 0;
|
||||
#if SOC_RMT_SOURCE_CLK_INDEPENDENT
|
||||
#if SOC_RMT_CHANNEL_CLK_INDEPENDENT
|
||||
rmt_source_clk_hz = s_rmt_source_clock_hz[channel];
|
||||
#else
|
||||
rmt_source_clk_hz = s_rmt_source_clock_hz;
|
||||
@@ -1333,7 +1324,7 @@ esp_err_t rmt_get_counter_clock(rmt_channel_t channel, uint32_t *clock_hz)
|
||||
#if SOC_RMT_SUPPORT_TX_SYNCHRO
|
||||
esp_err_t rmt_add_channel_to_group(rmt_channel_t channel)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_enable_sync(rmt_contex.hal.regs, true);
|
||||
rmt_contex.synchro_channel_mask |= (1 << channel);
|
||||
@@ -1345,7 +1336,7 @@ esp_err_t rmt_add_channel_to_group(rmt_channel_t channel)
|
||||
|
||||
esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_contex.synchro_channel_mask &= ~(1 << channel);
|
||||
rmt_ll_tx_remove_from_sync_group(rmt_contex.hal.regs, channel);
|
||||
@@ -1355,10 +1346,11 @@ esp_err_t rmt_remove_channel_from_group(rmt_channel_t channel)
|
||||
RMT_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (RMT_IS_RX_CHANNEL(channel)) {
|
||||
rmt_ll_rx_reset_pointer(rmt_contex.hal.regs, RMT_DECODE_RX_CHANNEL(channel));
|
||||
@@ -1368,12 +1360,11 @@ esp_err_t rmt_memory_rw_rst(rmt_channel_t channel)
|
||||
RMT_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_RMT_SUPPORT_TX_LOOP_COUNT
|
||||
esp_err_t rmt_set_tx_loop_count(rmt_channel_t channel, uint32_t count)
|
||||
{
|
||||
RMT_CHECK(RMT_IS_TX_CHANNEL(channel), RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
|
||||
ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR);
|
||||
RMT_ENTER_CRITICAL();
|
||||
rmt_ll_tx_set_loop_count(rmt_contex.hal.regs, channel, count);
|
||||
RMT_EXIT_CRITICAL();
|
||||
|
@@ -14,8 +14,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "soc/rmt_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -174,6 +174,11 @@ static inline bool rmt_ll_is_tx_loop_enabled(rmt_dev_t *dev, uint32_t channel)
|
||||
return dev->conf_ch[channel].conf1.tx_conti_mode;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_reset_loop(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
// RMT on esp32 doesn't support loop count, adding this only for HAL API consistency
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->conf_ch[channel].conf1.rx_filter_en = enable;
|
||||
@@ -219,6 +224,15 @@ static inline void rmt_ll_tx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_
|
||||
dev->tx_lim_ch[channel].limit = limit;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rmt_ll_enable_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->int_ena.val &= ~(1 << (channel * 3));
|
||||
@@ -330,33 +344,17 @@ static inline void rmt_ll_tx_set_carrier_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.
|
||||
//Writes items to the specified TX channel memory with the given offset and length.
|
||||
//the caller should ensure that (length + off) <= (memory block * SOC_RMT_MEM_WORDS_PER_CHANNEL)
|
||||
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)
|
||||
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const void *data, size_t length_in_words, size_t off)
|
||||
{
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
mem->chan[channel].data32[i + off].val = data[i].val;
|
||||
volatile uint32_t *to = (volatile uint32_t *)&mem->chan[channel].data32[off];
|
||||
uint32_t *from = (uint32_t *)data;
|
||||
while (length_in_words--) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rmt_ll_config_update(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Following Low Level APIs only used for backward compatible, will be deprecated in the IDF v5.0
|
||||
***********************************************************************************************/
|
||||
|
||||
static inline void rmt_ll_set_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val |= mask;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_clr_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -15,8 +15,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "soc/rmt_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -279,6 +279,15 @@ static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
|
||||
return dev->rx_lim[channel].rx_lim;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rmt_ll_enable_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
@@ -469,12 +478,14 @@ static inline void rmt_ll_tx_set_carrier_always_on(rmt_dev_t *dev, uint32_t chan
|
||||
dev->tx_conf[channel].carrier_eff_en = !enable;
|
||||
}
|
||||
|
||||
//Writes items to the specified TX channel memory with the given offset and writen length.
|
||||
//Writes items to the specified TX channel memory with the given offset and length.
|
||||
//the caller should ensure that (length + off) <= (memory block * SOC_RMT_MEM_WORDS_PER_CHANNEL)
|
||||
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)
|
||||
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const void *data, size_t length_in_words, size_t off)
|
||||
{
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
mem->chan[channel].data32[i + off].val = data[i].val;
|
||||
volatile uint32_t *to = (volatile uint32_t *)&mem->chan[channel].data32[off];
|
||||
uint32_t *from = (uint32_t *)data;
|
||||
while (length_in_words--) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,20 +494,6 @@ static inline void rmt_ll_rx_enable_pingpong(rmt_dev_t *dev, uint32_t channel, b
|
||||
dev->rx_conf[channel].conf1.mem_rx_wrap_en = enable;
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Following Low Level APIs only used for backward compatible, will be deprecated in the IDF v5.0
|
||||
***********************************************************************************************/
|
||||
|
||||
static inline void rmt_ll_set_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val |= mask;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_clr_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include <stddef.h>
|
||||
#include "soc/rmt_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -267,6 +267,15 @@ static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
|
||||
return dev->tx_lim_ch[channel].rx_lim;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rmt_ll_enable_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->int_ena.val &= ~(1 << (channel * 3));
|
||||
@@ -443,12 +452,14 @@ 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.
|
||||
//Writes items to the specified TX channel memory with the given offset and length.
|
||||
//the caller should ensure that (length + off) <= (memory block * SOC_RMT_MEM_WORDS_PER_CHANNEL)
|
||||
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)
|
||||
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const void *data, size_t length_in_words, size_t off)
|
||||
{
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
mem->chan[channel].data32[i + off].val = data[i].val;
|
||||
volatile uint32_t *to = (volatile uint32_t *)&mem->chan[channel].data32[off];
|
||||
uint32_t *from = (uint32_t *)data;
|
||||
while (length_in_words--) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,24 +468,6 @@ static inline void rmt_ll_rx_enable_pingpong(rmt_dev_t *dev, uint32_t channel, b
|
||||
dev->conf_ch[channel].conf1.chk_rx_carrier_en = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_config_update(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Following Low Level APIs only used for backward compatible, will be deprecated in the IDF v5.0
|
||||
***********************************************************************************************/
|
||||
|
||||
static inline void rmt_ll_set_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val |= mask;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_clr_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -13,10 +13,9 @@
|
||||
// limitations under the License.
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/rmt_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -50,7 +49,7 @@ static inline bool rmt_ll_is_mem_power_down(rmt_dev_t *dev)
|
||||
|
||||
static inline void rmt_ll_enable_mem_access(rmt_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->sys_conf.fifo_mask = enable;
|
||||
dev->sys_conf.apb_fifo_mask = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, uint8_t src, uint8_t div_num, uint8_t div_a, uint8_t div_b)
|
||||
@@ -86,132 +85,132 @@ static inline void rmt_ll_rx_reset_channel_clock_div(rmt_dev_t *dev, uint32_t ch
|
||||
|
||||
static inline void rmt_ll_tx_reset_pointer(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_conf[channel].mem_rd_rst = 1;
|
||||
dev->tx_conf[channel].mem_rd_rst = 0;
|
||||
dev->tx_conf[channel].mem_rst = 1;
|
||||
dev->tx_conf[channel].mem_rst = 0;
|
||||
dev->chnconf0[channel].mem_rd_rst_n = 1;
|
||||
dev->chnconf0[channel].mem_rd_rst_n = 0;
|
||||
dev->chnconf0[channel].apb_mem_rst_n = 1;
|
||||
dev->chnconf0[channel].apb_mem_rst_n = 0;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.mem_wr_rst = 1;
|
||||
dev->rx_conf[channel].conf1.mem_wr_rst = 0;
|
||||
dev->rx_conf[channel].conf1.mem_rst = 1;
|
||||
dev->rx_conf[channel].conf1.mem_rst = 0;
|
||||
dev->chmconf[channel].conf1.mem_wr_rst_m = 1;
|
||||
dev->chmconf[channel].conf1.mem_wr_rst_m = 0;
|
||||
dev->chmconf[channel].conf1.apb_mem_rst_m = 1;
|
||||
dev->chmconf[channel].conf1.apb_mem_rst_m = 0;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_start(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_conf[channel].conf_update = 1;
|
||||
dev->tx_conf[channel].tx_start = 1;
|
||||
dev->chnconf0[channel].conf_update_n = 1;
|
||||
dev->chnconf0[channel].tx_start_n = 1;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_stop(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_conf[channel].tx_stop = 1;
|
||||
dev->tx_conf[channel].conf_update = 1;
|
||||
dev->chnconf0[channel].tx_stop_n = 1;
|
||||
dev->chnconf0[channel].conf_update_n = 1;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_enable(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.rx_en = enable;
|
||||
dev->rx_conf[channel].conf1.conf_update = 1;
|
||||
dev->chmconf[channel].conf1.rx_en_m = enable;
|
||||
dev->chmconf[channel].conf1.conf_update_m = 1;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
|
||||
{
|
||||
dev->tx_conf[channel].mem_size = block_num;
|
||||
dev->chnconf0[channel].mem_size_n = block_num;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, uint8_t block_num)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.mem_size = block_num;
|
||||
dev->chmconf[channel].conf0.mem_size_m = block_num;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_tx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].mem_size;
|
||||
return dev->chnconf0[channel].mem_size_n;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf0.mem_size;
|
||||
return dev->chmconf[channel].conf0.mem_size_m;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
|
||||
{
|
||||
dev->tx_conf[channel].div_cnt = div;
|
||||
dev->chnconf0[channel].div_cnt_n = div;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t channel, uint32_t div)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.div_cnt = div;
|
||||
dev->chmconf[channel].conf0.div_cnt_m = div;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_tx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].div_cnt;
|
||||
return dev->chnconf0[channel].div_cnt_n;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_rx_get_channel_clock_div(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf0.div_cnt;
|
||||
return dev->chmconf[channel].conf0.div_cnt_m;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_enable_pingpong(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].mem_tx_wrap_en = enable;
|
||||
dev->chnconf0[channel].mem_tx_wrap_en_n = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.idle_thres = thres;
|
||||
dev->chmconf[channel].conf0.idle_thres_m = thres;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_rx_get_idle_thres(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf0.idle_thres;
|
||||
return dev->chmconf[channel].conf0.idle_thres_m;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, uint8_t owner)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.mem_owner = owner;
|
||||
dev->chmconf[channel].conf1.mem_owner_m = owner;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_rx_get_mem_owner(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_conf[channel].conf1.mem_owner;
|
||||
return dev->chmconf[channel].conf1.mem_owner_m;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_enable_loop(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].tx_conti_mode = enable;
|
||||
dev->chnconf0[channel].tx_conti_mode_n = enable;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_tx_loop_enabled(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].tx_conti_mode;
|
||||
return dev->chnconf0[channel].tx_conti_mode_n;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_set_loop_count(rmt_dev_t *dev, uint32_t channel, uint32_t count)
|
||||
{
|
||||
dev->tx_lim[channel].tx_loop_num = count;
|
||||
dev->chn_tx_lim[channel].tx_loop_num_chn = count;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_reset_loop(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
dev->tx_lim[channel].loop_count_reset = 1;
|
||||
dev->tx_lim[channel].loop_count_reset = 0;
|
||||
dev->chn_tx_lim[channel].loop_count_reset_chn = 1;
|
||||
dev->chn_tx_lim[channel].loop_count_reset_chn = 0;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_enable_loop_count(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_lim[channel].tx_loop_cnt_en = enable;
|
||||
dev->chn_tx_lim[channel].tx_loop_cnt_en_chn = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_enable_sync(rmt_dev_t *dev, bool enable)
|
||||
{
|
||||
dev->tx_sim.en = enable;
|
||||
dev->tx_sim.tx_sim_en = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_add_to_sync_group(rmt_dev_t *dev, uint32_t channel)
|
||||
@@ -226,57 +225,66 @@ static inline void rmt_ll_tx_remove_from_sync_group(rmt_dev_t *dev, uint32_t cha
|
||||
|
||||
static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.rx_filter_en = enable;
|
||||
dev->chmconf[channel].conf1.rx_filter_en_m = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.rx_filter_thres = thres;
|
||||
dev->chmconf[channel].conf1.rx_filter_thres_m = thres;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_enable_idle(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].idle_out_en = enable;
|
||||
dev->chnconf0[channel].idle_out_en_n = enable;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_tx_idle_enabled(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].idle_out_en;
|
||||
return dev->chnconf0[channel].idle_out_en_n;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_set_idle_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
|
||||
{
|
||||
dev->tx_conf[channel].idle_out_lv = level;
|
||||
dev->chnconf0[channel].idle_out_lv_n = level;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_conf[channel].idle_out_lv;
|
||||
return dev->chnconf0[channel].idle_out_lv_n;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_rx_get_channel_status(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_status[channel].val;
|
||||
return dev->chmstatus[channel].val;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_tx_get_channel_status(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->tx_status[channel].val;
|
||||
return dev->chnstatus[channel].val;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
|
||||
{
|
||||
dev->tx_lim[channel].limit = limit;
|
||||
dev->chn_tx_lim[channel].tx_lim_chn = limit;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_limit(rmt_dev_t *dev, uint32_t channel, uint32_t limit)
|
||||
{
|
||||
dev->rx_lim[channel].rx_lim = limit;
|
||||
dev->chm_rx_lim[channel].chm_rx_lim_reg = limit;
|
||||
}
|
||||
|
||||
static inline uint32_t rmt_ll_rx_get_limit(rmt_dev_t *dev, uint32_t channel)
|
||||
{
|
||||
return dev->rx_lim[channel].rx_lim;
|
||||
return dev->chm_rx_lim[channel].chm_rx_lim_reg;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rmt_ll_enable_tx_end_interrupt(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
@@ -416,85 +424,73 @@ static inline void rmt_ll_tx_set_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t
|
||||
{
|
||||
// In case the compiler optimise a 32bit instruction (e.g. s32i) into two 16bit instruction (e.g. s16i, which is not allowed to access a register)
|
||||
// We take care of the "read-modify-write" procedure by ourselves.
|
||||
typeof(dev->tx_carrier[0]) reg;
|
||||
reg.high = high_ticks;
|
||||
reg.low = low_ticks;
|
||||
dev->tx_carrier[channel].val = reg.val;
|
||||
rmt_chncarrier_duty_reg_t reg;
|
||||
reg.carrier_high_chn = high_ticks;
|
||||
reg.carrier_low_chn = low_ticks;
|
||||
dev->chncarrier_duty[channel].val = reg.val;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
typeof(dev->rx_carrier[0]) reg;
|
||||
reg.high_thres = high_ticks;
|
||||
reg.low_thres = low_ticks;
|
||||
dev->rx_carrier[channel].val = reg.val;
|
||||
rmt_chm_rx_carrier_rm_reg_t reg;
|
||||
reg.carrier_high_thres_chm = high_ticks;
|
||||
reg.carrier_low_thres_chm = low_ticks;
|
||||
dev->chm_rx_carrier_rm[channel].val = reg.val;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_get_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t *high_ticks, uint32_t *low_ticks )
|
||||
{
|
||||
*high_ticks = dev->tx_carrier[channel].high;
|
||||
*low_ticks = dev->tx_carrier[channel].low;
|
||||
*high_ticks = dev->chncarrier_duty[channel].carrier_high_chn;
|
||||
*low_ticks = dev->chncarrier_duty[channel].carrier_low_chn;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_get_carrier_high_low_ticks(rmt_dev_t *dev, uint32_t channel, uint32_t *high_ticks, uint32_t *low_ticks)
|
||||
{
|
||||
*high_ticks = dev->rx_carrier[channel].high_thres;
|
||||
*low_ticks = dev->rx_carrier[channel].low_thres;
|
||||
*high_ticks = dev->chm_rx_carrier_rm[channel].carrier_high_thres_chm;
|
||||
*low_ticks = dev->chm_rx_carrier_rm[channel].carrier_low_thres_chm;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_enable_carrier_modulation(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].carrier_en = enable;
|
||||
dev->chnconf0[channel].carrier_en_n = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_enable_carrier_demodulation(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.carrier_en = enable;
|
||||
dev->chmconf[channel].conf0.carrier_en_m = enable;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
|
||||
{
|
||||
dev->tx_conf[channel].carrier_out_lv = level;
|
||||
dev->chnconf0[channel].carrier_out_lv_n = level;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_set_carrier_level(rmt_dev_t *dev, uint32_t channel, uint8_t level)
|
||||
{
|
||||
dev->rx_conf[channel].conf0.carrier_out_lv = level;
|
||||
dev->chmconf[channel].conf0.carrier_out_lv_m = level;
|
||||
}
|
||||
|
||||
// set true, enable carrier in all RMT state (idle, reading, sending)
|
||||
// set false, enable carrier only in sending state (i.e. there're effective data in RAM to be sent)
|
||||
static inline void rmt_ll_tx_set_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->tx_conf[channel].carrier_eff_en = !enable;
|
||||
dev->chnconf0[channel].carrier_eff_en_n = !enable;
|
||||
}
|
||||
|
||||
//Writes items to the specified TX channel memory with the given offset and writen length.
|
||||
//Writes items to the specified TX channel memory with the given offset and length.
|
||||
//the caller should ensure that (length + off) <= (memory block * SOC_RMT_MEM_WORDS_PER_CHANNEL)
|
||||
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)
|
||||
static inline void rmt_ll_write_memory(rmt_mem_t *mem, uint32_t channel, const void *data, size_t length_in_words, size_t off)
|
||||
{
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
mem->chan[channel].data32[i + off].val = data[i].val;
|
||||
volatile uint32_t *to = (volatile uint32_t *)&mem->chan[channel].data32[off];
|
||||
uint32_t *from = (uint32_t *)data;
|
||||
while (length_in_words--) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void rmt_ll_rx_enable_pingpong(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
dev->rx_conf[channel].conf1.mem_rx_wrap_en = enable;
|
||||
}
|
||||
|
||||
/************************************************************************************************
|
||||
* Following Low Level APIs only used for backward compatible, will be deprecated in the IDF v5.0
|
||||
***********************************************************************************************/
|
||||
|
||||
static inline void rmt_ll_set_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val |= mask;
|
||||
}
|
||||
|
||||
static inline void rmt_ll_clr_intr_enable_mask(uint32_t mask)
|
||||
{
|
||||
RMT.int_ena.val &= (~mask);
|
||||
dev->chmconf[channel].conf1.mem_rx_wrap_en_m = enable;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -14,12 +14,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
/**
|
||||
* @brief RMT channel ID
|
||||
*
|
||||
|
@@ -24,6 +24,7 @@ void rmt_hal_init(rmt_hal_context_t *hal)
|
||||
void rmt_hal_tx_channel_reset(rmt_hal_context_t *hal, uint32_t channel)
|
||||
{
|
||||
rmt_ll_tx_reset_pointer(hal->regs, channel);
|
||||
rmt_ll_tx_reset_loop(hal->regs, channel);
|
||||
rmt_ll_enable_tx_err_interrupt(hal->regs, channel, false);
|
||||
rmt_ll_enable_tx_end_interrupt(hal->regs, channel, false);
|
||||
rmt_ll_enable_tx_thres_interrupt(hal->regs, channel, false);
|
||||
|
@@ -17,40 +17,44 @@
|
||||
#include "soc/soc.h"
|
||||
|
||||
const rmt_signal_conn_t rmt_periph_signals = {
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
.groups = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = RMT_SIG_OUT2_IDX,
|
||||
.rx_sig = RMT_SIG_IN2_IDX
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = RMT_SIG_OUT3_IDX,
|
||||
.rx_sig = RMT_SIG_IN3_IDX
|
||||
},
|
||||
[4] = {
|
||||
.tx_sig = RMT_SIG_OUT4_IDX,
|
||||
.rx_sig = RMT_SIG_IN4_IDX
|
||||
},
|
||||
[5] = {
|
||||
.tx_sig = RMT_SIG_OUT5_IDX,
|
||||
.rx_sig = RMT_SIG_IN5_IDX
|
||||
},
|
||||
[6] = {
|
||||
.tx_sig = RMT_SIG_OUT6_IDX,
|
||||
.rx_sig = RMT_SIG_IN6_IDX
|
||||
},
|
||||
[7] = {
|
||||
.tx_sig = RMT_SIG_OUT7_IDX,
|
||||
.rx_sig = RMT_SIG_IN7_IDX
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = RMT_SIG_OUT2_IDX,
|
||||
.rx_sig = RMT_SIG_IN2_IDX
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = RMT_SIG_OUT3_IDX,
|
||||
.rx_sig = RMT_SIG_IN3_IDX
|
||||
},
|
||||
[4] = {
|
||||
.tx_sig = RMT_SIG_OUT4_IDX,
|
||||
.rx_sig = RMT_SIG_IN4_IDX
|
||||
},
|
||||
[5] = {
|
||||
.tx_sig = RMT_SIG_OUT5_IDX,
|
||||
.rx_sig = RMT_SIG_IN5_IDX
|
||||
},
|
||||
[6] = {
|
||||
.tx_sig = RMT_SIG_OUT6_IDX,
|
||||
.rx_sig = RMT_SIG_IN6_IDX
|
||||
},
|
||||
[7] = {
|
||||
.tx_sig = RMT_SIG_OUT7_IDX,
|
||||
.rx_sig = RMT_SIG_IN7_IDX
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -16,24 +16,28 @@
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
const rmt_signal_conn_t rmt_periph_signals = {
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
.groups = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -299,22 +299,11 @@ typedef struct {
|
||||
};
|
||||
} rmt_item32_t;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint16_t duration :15;
|
||||
uint16_t level :1;
|
||||
};
|
||||
uint16_t val;
|
||||
};
|
||||
} rmt_item16_t;
|
||||
|
||||
//Allow access to RMT memory using RMTMEM.chan[0].data32[8]
|
||||
typedef volatile struct {
|
||||
struct {
|
||||
union {
|
||||
rmt_item32_t data32[64];
|
||||
rmt_item16_t data16[128];
|
||||
};
|
||||
} chan[4];
|
||||
} rmt_mem_t;
|
||||
|
@@ -16,24 +16,28 @@
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
const rmt_signal_conn_t rmt_periph_signals = {
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
.groups = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = RMT_SIG_OUT2_IDX,
|
||||
.rx_sig = RMT_SIG_IN2_IDX
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = RMT_SIG_OUT3_IDX,
|
||||
.rx_sig = RMT_SIG_IN3_IDX
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = RMT_SIG_OUT2_IDX,
|
||||
.rx_sig = RMT_SIG_IN2_IDX
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = RMT_SIG_OUT3_IDX,
|
||||
.rx_sig = RMT_SIG_IN3_IDX
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,30 +0,0 @@
|
||||
// Copyright 2019-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SOC_RMT_CHANNEL_MEM_WORDS (64) /*!< Each channel owns 64 words memory (1 word = 4 Bytes) */
|
||||
#define SOC_RMT_CHANNELS_NUM (4) /*!< Total 4 channels */
|
||||
#define SOC_RMT_SUPPORT_RX_PINGPONG (1) /*!< Support Ping-Pong mode on RX path */
|
||||
#define SOC_RMT_SUPPORT_RX_DEMODULATION (1) /*!< Support signal demodulation on RX path (i.e. remove carrier) */
|
||||
#define SOC_RMT_SUPPORT_TX_LOOP_COUNT (1) /*!< Support transmit specified number of cycles in loop mode */
|
||||
#define SOC_RMT_SUPPORT_TX_GROUP (1) /*!< Support a group of TX channels to transmit simultaneously */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,40 +16,44 @@
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
const rmt_signal_conn_t rmt_periph_signals = {
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
.groups = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = RMT_SIG_OUT2_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = RMT_SIG_OUT3_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[4] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[5] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
[6] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN2_IDX
|
||||
},
|
||||
[7] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN3_IDX
|
||||
.module = PERIPH_RMT_MODULE,
|
||||
.irq = ETS_RMT_INTR_SOURCE,
|
||||
.channels = {
|
||||
[0] = {
|
||||
.tx_sig = RMT_SIG_OUT0_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[1] = {
|
||||
.tx_sig = RMT_SIG_OUT1_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[2] = {
|
||||
.tx_sig = RMT_SIG_OUT2_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[3] = {
|
||||
.tx_sig = RMT_SIG_OUT3_IDX,
|
||||
.rx_sig = -1
|
||||
},
|
||||
[4] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN0_IDX
|
||||
},
|
||||
[5] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN1_IDX
|
||||
},
|
||||
[6] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN2_IDX
|
||||
},
|
||||
[7] = {
|
||||
.tx_sig = -1,
|
||||
.rx_sig = RMT_SIG_IN3_IDX
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -23,13 +23,15 @@ extern "C" {
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
const int irq;
|
||||
const periph_module_t module;
|
||||
struct {
|
||||
const int tx_sig;
|
||||
const int rx_sig;
|
||||
};
|
||||
} channels[SOC_RMT_CHANNELS_PER_GROUP];
|
||||
const int irq;
|
||||
const periph_module_t module;
|
||||
struct {
|
||||
const int tx_sig;
|
||||
const int rx_sig;
|
||||
};
|
||||
} channels[SOC_RMT_CHANNELS_PER_GROUP];
|
||||
} groups[SOC_RMT_GROUPS];
|
||||
} rmt_signal_conn_t;
|
||||
|
||||
extern const rmt_signal_conn_t rmt_periph_signals;
|
||||
|
@@ -103,6 +103,10 @@ There couple of typical steps to setup and operate the RMT and they are discusse
|
||||
|
||||
The RMT has four channels numbered from zero to three. The first half (i.e. Channel 0 ~ 1) channels can only be configured for transmitting, and the other half (i.e. Channel 2 ~ 3) channels can only be configured for receiving. They are referred to using indexes defined in structure :cpp:type:`rmt_channel_t`.
|
||||
|
||||
.. only:: esp32s3
|
||||
|
||||
The RMT has eight channels numbered from zero to seven. The first half (i.e. Channel 0 ~ 3) channels can only be configured for transmitting, and the other half (i.e. Channel 4 ~ 7) channels can only be configured for receiving. They are referred to using indexes defined in structure :cpp:type:`rmt_channel_t`.
|
||||
|
||||
Configure Driver
|
||||
----------------
|
||||
|
||||
@@ -144,7 +148,7 @@ When configuring channel in transmit mode, set **tx_config** and the following m
|
||||
* Level of the RMT output, when the carrier is applied - **carrier_level**
|
||||
* Enable the RMT output if idle - **idle_output_en**
|
||||
* Set the signal level on the RMT output if idle - **idle_level**
|
||||
:esp32s2: * Specify maximum number of transmissions in a loop - **loop_count**
|
||||
:SOC_RMT_SUPPORT_TX_LOOP_COUNT: * Specify maximum number of transmissions in a loop - **loop_count**
|
||||
|
||||
Receive Mode
|
||||
^^^^^^^^^^^^
|
||||
@@ -156,10 +160,10 @@ In receive mode, set **rx_config** and the following members of :cpp:type:`rmt_r
|
||||
* Enable a filter on the input of the RMT receiver - **filter_en**
|
||||
* A threshold of the filter, set in the number of ticks - **filter_ticks_thresh**. Pulses shorter than this setting will be filtered out. Note, that the range of entered tick values is [0..255].
|
||||
* A pulse length threshold that will turn the RMT receiver idle, set in number of ticks - **idle_threshold**. The receiver will ignore pulses longer than this setting.
|
||||
:esp32s2: * Enable the RMT carrier demodulation - **carrier_rm**
|
||||
:esp32s2: * Frequency of the carrier in Hz - **carrier_freq_hz**
|
||||
:esp32s2: * Duty cycle of the carrier signal in percent (%) - **carrier_duty_percent**
|
||||
:esp32s2: * Level of the RMT input, where the carrier is modulated to - **carrier_level**
|
||||
:SOC_RMT_SUPPORT_RX_DEMODULATION: * Enable the RMT carrier demodulation - **carrier_rm**
|
||||
:SOC_RMT_SUPPORT_RX_DEMODULATION: * Frequency of the carrier in Hz - **carrier_freq_hz**
|
||||
:SOC_RMT_SUPPORT_RX_DEMODULATION: * Duty cycle of the carrier signal in percent (%) - **carrier_duty_percent**
|
||||
:SOC_RMT_SUPPORT_RX_DEMODULATION: * Level of the RMT input, where the carrier is modulated to - **carrier_level**
|
||||
|
||||
Finalize Configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -207,6 +211,11 @@ Another way to provide data for transmission is by calling :cpp:func:`rmt_fill_t
|
||||
Receive Data
|
||||
------------
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
.. warning::
|
||||
RMT RX channel can't receive packet whose items are larger than its memory block size. If you set the memory block number to 1, then this RX channel can't receive packet with more than 64 items. This is a hardware limitation.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
Before starting the receiver we need some storage for incoming items. The RMT controller has 512 x 32-bits of internal RAM shared between all eight channels.
|
||||
@@ -219,6 +228,10 @@ Receive Data
|
||||
|
||||
Before starting the receiver we need some storage for incoming items. The RMT controller has 192 x 32-bits of internal RAM shared between all four channels.
|
||||
|
||||
.. only:: esp32s3
|
||||
|
||||
Before starting the receiver we need some storage for incoming items. The RMT controller has 384 x 32-bits of internal RAM shared between all eight channels.
|
||||
|
||||
In typical scenarios it is not enough as an ultimate storage for all incoming (and outgoing) items. Therefore this API supports retrieval of incoming items on the fly to save them in a ring buffer of a size defined by the user. The size is provided when calling :cpp:func:`rmt_driver_install` discussed above. To get a handle to this buffer call :cpp:func:`rmt_get_ringbuf_handle`.
|
||||
|
||||
With the above steps complete we can start the receiver by calling :cpp:func:`rmt_rx_start` and then move to checking what's inside the buffer. To do so, you can use common FreeRTOS functions that interact with the ring buffer. Please see an example how to do it in :example:`peripherals/rmt/ir_protocols`.
|
||||
|
Reference in New Issue
Block a user