diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 03deac5b25..7e8b7d5ef3 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -441,14 +441,14 @@ 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(); } diff --git a/components/hal/esp32/include/hal/rmt_ll.h b/components/hal/esp32/include/hal/rmt_ll.h index af7e8b5a2f..edd4f27912 100644 --- a/components/hal/esp32/include/hal/rmt_ll.h +++ b/components/hal/esp32/include/hal/rmt_ll.h @@ -14,8 +14,8 @@ #pragma once #include +#include #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 diff --git a/components/hal/esp32c3/include/hal/rmt_ll.h b/components/hal/esp32c3/include/hal/rmt_ll.h index a323adfbc1..f5427d150a 100644 --- a/components/hal/esp32c3/include/hal/rmt_ll.h +++ b/components/hal/esp32c3/include/hal/rmt_ll.h @@ -15,8 +15,8 @@ #include #include +#include #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 diff --git a/components/hal/esp32s2/include/hal/rmt_ll.h b/components/hal/esp32s2/include/hal/rmt_ll.h index 0a71250dfc..0354afc766 100644 --- a/components/hal/esp32s2/include/hal/rmt_ll.h +++ b/components/hal/esp32s2/include/hal/rmt_ll.h @@ -14,7 +14,7 @@ #pragma once #include -#include "soc/soc_caps.h" +#include #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 diff --git a/components/hal/esp32s3/include/hal/rmt_ll.h b/components/hal/esp32s3/include/hal/rmt_ll.h index 03795f6fae..b5ef90004d 100644 --- a/components/hal/esp32s3/include/hal/rmt_ll.h +++ b/components/hal/esp32s3/include/hal/rmt_ll.h @@ -14,6 +14,7 @@ #pragma once #include +#include #include #include "soc/rmt_struct.h" #include "soc/soc_caps.h" @@ -279,6 +280,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 +479,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 +495,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 diff --git a/components/hal/rmt_hal.c b/components/hal/rmt_hal.c index 7c885784fb..bdb6942690 100644 --- a/components/hal/rmt_hal.c +++ b/components/hal/rmt_hal.c @@ -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); diff --git a/components/soc/esp32s2/include/soc/rmt_struct.h b/components/soc/esp32s2/include/soc/rmt_struct.h index e33fb3aff0..b92c42a775 100644 --- a/components/soc/esp32s2/include/soc/rmt_struct.h +++ b/components/soc/esp32s2/include/soc/rmt_struct.h @@ -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;