mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 03:34:32 +02:00
fix(rmt): power up memory block
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -152,10 +152,10 @@ 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);
|
||||
|
||||
/**
|
||||
* @brief Get RMT memory low power mode.
|
||||
* @brief Check if the RMT memory is force powered down
|
||||
*
|
||||
* @param channel RMT channel
|
||||
* @param pd_en Pointer to accept RMT memory low power mode.
|
||||
* @param channel RMT channel (actually this function is configured for all channels)
|
||||
* @param pd_en Pointer to accept the result
|
||||
*
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
|
@@ -142,6 +142,7 @@ static void rmt_module_enable(void)
|
||||
rmt_ll_enable_bus_clock(0, true);
|
||||
rmt_ll_reset_register(0);
|
||||
}
|
||||
rmt_ll_mem_power_by_pmu(rmt_contex.hal.regs);
|
||||
rmt_contex.rmt_module_enabled = true;
|
||||
}
|
||||
RMT_EXIT_CRITICAL();
|
||||
@@ -152,6 +153,7 @@ static void rmt_module_disable(void)
|
||||
{
|
||||
RMT_ENTER_CRITICAL();
|
||||
if (rmt_contex.rmt_module_enabled == true) {
|
||||
rmt_ll_mem_force_power_off(rmt_contex.hal.regs);
|
||||
RMT_RCC_ATOMIC() {
|
||||
rmt_ll_enable_bus_clock(0, false);
|
||||
}
|
||||
@@ -251,7 +253,11 @@ esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en)
|
||||
{
|
||||
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);
|
||||
if (pd_en) {
|
||||
rmt_ll_mem_force_power_off(rmt_contex.hal.regs);
|
||||
} else {
|
||||
rmt_ll_mem_power_by_pmu(rmt_contex.hal.regs);
|
||||
}
|
||||
RMT_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -260,7 +266,7 @@ esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool *pd_en)
|
||||
{
|
||||
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_powered_down(rmt_contex.hal.regs);
|
||||
*pd_en = rmt_ll_is_mem_force_powered_down(rmt_contex.hal.regs);
|
||||
RMT_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@@ -88,14 +88,33 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->conf_ch[0].conf0.mem_pd = enable; // Only conf0 register of channel0 has `mem_pd`
|
||||
(void)dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->conf_ch[0].conf0.mem_pd = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->conf_ch[0].conf0.mem_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +139,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable)
|
||||
* @param divider_numerator Numerator part of the divider
|
||||
*/
|
||||
static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src,
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
{
|
||||
(void)divider_integral;
|
||||
(void)divider_denominator;
|
||||
@@ -485,7 +504,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -631,7 +650,7 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->conf_ch[channel].conf1.idle_out_lv;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// Only conf0 register of channel0 has `mem_pd`
|
||||
return dev->conf_ch[0].conf0.mem_pd;
|
||||
|
@@ -87,15 +87,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
dev->sys_conf.mem_force_pu = 1;
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 1;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,7 +448,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -658,7 +679,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -812,12 +833,9 @@ 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;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
return dev->sys_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -82,15 +82,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
dev->sys_conf.mem_force_pu = 1;
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 1;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +136,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable)
|
||||
* @param divider_numerator Numerator part of the divider
|
||||
*/
|
||||
static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src,
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
{
|
||||
// Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b)
|
||||
(void)channel; // the source clock is set for all channels
|
||||
@@ -436,7 +457,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -667,7 +688,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -821,12 +842,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->chnconf0[channel].idle_out_lv_chn;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
return dev->sys_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -79,15 +79,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
dev->sys_conf.mem_force_pu = 1;
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 1;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -433,7 +454,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -664,7 +685,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -818,12 +839,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->chnconf0[channel].idle_out_lv_chn;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
return dev->sys_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -79,15 +79,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
dev->sys_conf.mem_force_pu = 1;
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 1;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,7 +451,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -661,7 +682,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -812,12 +833,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->chnconf0[channel].idle_out_lv_chn;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
return dev->sys_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -85,7 +85,7 @@ static inline void rmt_ll_reset_register(int group_id)
|
||||
* @param divider_numerator Numerator part of the divider
|
||||
*/
|
||||
static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src,
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator)
|
||||
{
|
||||
(void)dev;
|
||||
// Formula: rmt_sclk = module_clock_src / (1 + div_num + div_a / div_b)
|
||||
@@ -143,15 +143,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
dev->sys_conf.mem_force_pu = 1;
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 1;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,7 +484,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -706,7 +727,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -860,12 +881,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->chnconf0[channel].idle_out_lv_chn;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
return dev->sys_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -90,15 +90,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->apb_conf.mem_force_pu = !enable;
|
||||
dev->apb_conf.mem_force_pd = enable;
|
||||
dev->apb_conf.mem_force_pu = 1;
|
||||
dev->apb_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->apb_conf.mem_force_pd = 1;
|
||||
dev->apb_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->apb_conf.mem_force_pd = 0;
|
||||
dev->apb_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,7 +444,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -628,7 +649,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -774,12 +795,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->conf_ch[channel].conf1.idle_out_lv_chn;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->apb_conf.mem_force_pd) || !(dev->apb_conf.mem_force_pu);
|
||||
return dev->apb_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -87,15 +87,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power down memory
|
||||
* @brief Force power on the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param enable True to power down, False to power up
|
||||
*/
|
||||
static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable)
|
||||
static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pu = !enable;
|
||||
dev->sys_conf.mem_force_pd = enable;
|
||||
dev->sys_conf.mem_force_pu = 1;
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force power off the RMT memory block, regardless of the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 1;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power control the RMT memory block by the outside PMU logic
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
*/
|
||||
static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev)
|
||||
{
|
||||
dev->sys_conf.mem_force_pd = 0;
|
||||
dev->sys_conf.mem_force_pu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,7 +474,7 @@ static inline void rmt_ll_tx_set_carrier_level(rmt_dev_t *dev, uint32_t channel,
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param channel RMT TX channel number
|
||||
* @param enable True to output carrier signal in all RMT state, False to only ouput carrier signal for effective data
|
||||
* @param enable True to output carrier signal in all RMT state, False to only output carrier signal for effective data
|
||||
*/
|
||||
static inline void rmt_ll_tx_enable_carrier_always_on(rmt_dev_t *dev, uint32_t channel, bool enable)
|
||||
{
|
||||
@@ -696,7 +717,7 @@ static inline void rmt_ll_enable_interrupt(rmt_dev_t *dev, uint32_t mask, bool e
|
||||
* @brief Clear RMT interrupt status by mask
|
||||
*
|
||||
* @param dev Peripheral instance address
|
||||
* @param mask Interupt status mask
|
||||
* @param mask Interrupt status mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void rmt_ll_clear_interrupt_status(rmt_dev_t *dev, uint32_t mask)
|
||||
@@ -850,12 +871,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel
|
||||
return dev->chnconf0[channel].idle_out_lv_chn;
|
||||
}
|
||||
|
||||
static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev)
|
||||
static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev)
|
||||
{
|
||||
// the RTC domain can also power down RMT memory
|
||||
// so it's probably not enough to detect whether it's powered down or not
|
||||
// mem_force_pd has higher priority than mem_force_pu
|
||||
return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu);
|
||||
return dev->sys_conf.mem_force_pd;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
|
@@ -10,9 +10,9 @@
|
||||
void rmt_hal_init(rmt_hal_context_t *hal)
|
||||
{
|
||||
hal->regs = &RMT;
|
||||
rmt_ll_power_down_mem(hal->regs, false); // turn on RMTMEM power domain
|
||||
rmt_ll_mem_power_by_pmu(hal->regs);
|
||||
rmt_ll_enable_mem_access_nonfifo(hal->regs, true); // APB access the RMTMEM in nonfifo mode
|
||||
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events
|
||||
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events
|
||||
rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events
|
||||
#if SOC_RMT_SUPPORT_TX_SYNCHRO
|
||||
rmt_ll_tx_clear_sync_group(hal->regs);
|
||||
@@ -21,9 +21,9 @@ void rmt_hal_init(rmt_hal_context_t *hal)
|
||||
|
||||
void rmt_hal_deinit(rmt_hal_context_t *hal)
|
||||
{
|
||||
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events
|
||||
rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interrupt events
|
||||
rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events
|
||||
rmt_ll_power_down_mem(hal->regs, true); // turn off RMTMEM power domain
|
||||
rmt_ll_mem_force_power_off(hal->regs); // power off RMTMEM power domain forcefully
|
||||
hal->regs = NULL;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user