mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
Merge branch 'feat/support_pcnt_on_h21' into 'master'
feat(pcnt): support pcnt on esp32h21 Closes IDF-11566, IDF-11567, IDF-9907, IDF-9739, IDF-8469, and IDF-9768 See merge request espressif/esp-idf!40889
This commit is contained in:
@@ -62,12 +62,9 @@ typedef struct pcnt_group_t pcnt_group_t;
|
||||
typedef struct pcnt_unit_t pcnt_unit_t;
|
||||
typedef struct pcnt_chan_t pcnt_chan_t;
|
||||
|
||||
// Use retention link only when the target supports sleep retention
|
||||
#define PCNT_USE_RETENTION_LINK (SOC_PCNT_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
|
||||
|
||||
#if PCNT_USE_RETENTION_LINK
|
||||
static esp_err_t pcnt_create_sleep_retention_link_cb(void *arg);
|
||||
#endif
|
||||
// The count register is read only and can't be restored after power down
|
||||
// Use retention link to prevent power down
|
||||
#define PCNT_USE_RETENTION_LINK CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
|
||||
struct pcnt_platform_t {
|
||||
_lock_t mutex; // platform level mutex lock
|
||||
@@ -915,18 +912,7 @@ static pcnt_group_t *pcnt_acquire_group_handle(int group_id)
|
||||
pcnt_ll_reset_register(group_id);
|
||||
}
|
||||
#if PCNT_USE_RETENTION_LINK
|
||||
sleep_retention_module_t module_id = pcnt_reg_retention_info[group_id].retention_module;
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = {
|
||||
.create = {
|
||||
.handle = pcnt_create_sleep_retention_link_cb,
|
||||
.arg = group,
|
||||
},
|
||||
},
|
||||
.depends = RETENTION_MODULE_BITMAP_INIT(CLOCK_SYSTEM)
|
||||
};
|
||||
// we only do retention init here. Allocate retention module in the unit initialization
|
||||
if (sleep_retention_module_init(module_id, &init_param) != ESP_OK) {
|
||||
if (sleep_retention_power_lock_acquire() != ESP_OK) {
|
||||
// even though the sleep retention module init failed, PCNT driver should still work, so just warning here
|
||||
ESP_LOGW(TAG, "init sleep retention failed %d, power domain may be turned off during sleep", group_id);
|
||||
}
|
||||
@@ -973,10 +959,7 @@ static void pcnt_release_group_handle(pcnt_group_t *group)
|
||||
pcnt_ll_enable_bus_clock(group_id, false);
|
||||
}
|
||||
#if PCNT_USE_RETENTION_LINK
|
||||
const periph_retention_module_t module_id = pcnt_reg_retention_info[group_id].retention_module;
|
||||
if (sleep_retention_is_module_inited(module_id)) {
|
||||
sleep_retention_module_deinit(module_id);
|
||||
}
|
||||
sleep_retention_power_lock_release();
|
||||
#endif // PCNT_USE_RETENTION_LINK
|
||||
}
|
||||
_lock_release(&s_platform.mutex);
|
||||
@@ -1101,20 +1084,6 @@ IRAM_ATTR static void pcnt_default_isr(void *args)
|
||||
}
|
||||
}
|
||||
|
||||
#if PCNT_USE_RETENTION_LINK
|
||||
static esp_err_t pcnt_create_sleep_retention_link_cb(void *arg)
|
||||
{
|
||||
pcnt_group_t *group = (pcnt_group_t *)arg;
|
||||
int group_id = group->group_id;
|
||||
sleep_retention_module_t module_id = pcnt_reg_retention_info[group_id].retention_module;
|
||||
esp_err_t err = sleep_retention_entries_create(pcnt_reg_retention_info[group_id].regdma_entry_array,
|
||||
pcnt_reg_retention_info[group_id].array_size,
|
||||
REGDMA_LINK_PRI_PCNT, module_id);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "create retention link failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // PCNT_USE_RETENTION_LINK
|
||||
|
||||
#if CONFIG_PCNT_ENABLE_DEBUG_LOG
|
||||
__attribute__((constructor))
|
||||
static void pcnt_override_default_log_level(void)
|
||||
|
@@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -98,10 +98,12 @@ static void test_pcnt_sleep_retention(void)
|
||||
|
||||
printf("check if the sleep happened as expected\r\n");
|
||||
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
|
||||
#if SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
|
||||
#if SOC_PMU_SUPPORTED && !SOC_PM_TOP_PD_NOT_ALLOWED
|
||||
// check if the power domain also is powered down
|
||||
TEST_ASSERT_EQUAL(0, (sleep_ctx.sleep_flags) & PMU_SLEEP_PD_TOP);
|
||||
#endif
|
||||
|
||||
esp_sleep_set_sleep_context(NULL);
|
||||
|
||||
gpio_hold_dis(TEST_PCNT_GPIO_A);
|
||||
|
@@ -287,10 +287,6 @@ bool peripheral_domain_pd_allowed(void)
|
||||
mask.bitmap[SLEEP_RETENTION_MODULE_LEDC >> 5] |= BIT(SLEEP_RETENTION_MODULE_LEDC % 32);
|
||||
#endif
|
||||
|
||||
#if SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
mask.bitmap[SLEEP_RETENTION_MODULE_PCNT0 >> 5] |= BIT(SLEEP_RETENTION_MODULE_PCNT0 % 32);
|
||||
#endif
|
||||
|
||||
#if SOC_MCPWM_SUPPORT_SLEEP_RETENTION
|
||||
mask.bitmap[SLEEP_RETENTION_MODULE_MCPWM0 >> 5] |= BIT(SLEEP_RETENTION_MODULE_MCPWM0 % 32);
|
||||
#endif
|
||||
|
504
components/hal/esp32h21/include/hal/pcnt_ll.h
Normal file
504
components/hal/esp32h21/include/hal/pcnt_ll.h
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/pcnt_struct.h"
|
||||
#include "hal/pcnt_types.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
|
||||
#define PCNT_LL_MAX_GLITCH_WIDTH 1023
|
||||
#define PCNT_LL_MAX_LIM SHRT_MAX
|
||||
#define PCNT_LL_MIN_LIM SHRT_MIN
|
||||
|
||||
typedef enum {
|
||||
PCNT_LL_WATCH_EVENT_INVALID = -1,
|
||||
PCNT_LL_WATCH_EVENT_THRES1,
|
||||
PCNT_LL_WATCH_EVENT_THRES0,
|
||||
PCNT_LL_WATCH_EVENT_LOW_LIMIT,
|
||||
PCNT_LL_WATCH_EVENT_HIGH_LIMIT,
|
||||
PCNT_LL_WATCH_EVENT_ZERO_CROSS,
|
||||
PCNT_LL_WATCH_EVENT_MAX
|
||||
} pcnt_ll_watch_event_id_t;
|
||||
|
||||
typedef enum {
|
||||
PCNT_LL_STEP_EVENT_REACH_INTERVAL_FORWARD = PCNT_LL_WATCH_EVENT_MAX,
|
||||
PCNT_LL_STEP_EVENT_REACH_INTERVAL_BACKWARD,
|
||||
} pcnt_ll_step_event_id_t;
|
||||
|
||||
#define PCNT_LL_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1)
|
||||
#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id))
|
||||
|
||||
/**
|
||||
* @brief Set PCNT channel edge action
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param channel PCNT channel number
|
||||
* @param pos_act Counter action when detecting positive edge
|
||||
* @param neg_act Counter action when detecting negative edge
|
||||
*/
|
||||
static inline void pcnt_ll_set_edge_action(pcnt_dev_t *hw, uint32_t unit, uint32_t channel, pcnt_channel_edge_action_t pos_act, pcnt_channel_edge_action_t neg_act)
|
||||
{
|
||||
if (channel == 0) {
|
||||
hw->conf_unit[unit].conf0.ch0_pos_mode_un = pos_act;
|
||||
hw->conf_unit[unit].conf0.ch0_neg_mode_un = neg_act;
|
||||
} else {
|
||||
hw->conf_unit[unit].conf0.ch1_pos_mode_un = pos_act;
|
||||
hw->conf_unit[unit].conf0.ch1_neg_mode_un = neg_act;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCNT channel level action
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param channel PCNT channel number
|
||||
* @param high_act Counter action when control signal is high level
|
||||
* @param low_act Counter action when control signal is low level
|
||||
*/
|
||||
static inline void pcnt_ll_set_level_action(pcnt_dev_t *hw, uint32_t unit, uint32_t channel, pcnt_channel_level_action_t high_act, pcnt_channel_level_action_t low_act)
|
||||
{
|
||||
if (channel == 0) {
|
||||
hw->conf_unit[unit].conf0.ch0_hctrl_mode_un = high_act;
|
||||
hw->conf_unit[unit].conf0.ch0_lctrl_mode_un = low_act;
|
||||
} else {
|
||||
hw->conf_unit[unit].conf0.ch1_hctrl_mode_un = high_act;
|
||||
hw->conf_unit[unit].conf0.ch1_lctrl_mode_un = low_act;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get pulse counter value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit Pulse Counter unit number
|
||||
* @return PCNT count value (a signed integer)
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline int pcnt_ll_get_count(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
pcnt_un_cnt_reg_t cnt_reg;
|
||||
cnt_reg.val = hw->cnt_unit[unit].val;
|
||||
|
||||
int16_t value = cnt_reg.pulse_cnt_un;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pause PCNT counter of PCNT unit
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void pcnt_ll_stop_count(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
hw->ctrl.val |= 1 << (2 * unit + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume counting for PCNT counter
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number, select from uint32_t
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void pcnt_ll_start_count(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
hw->ctrl.val &= ~(1 << (2 * unit + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear PCNT counter value to zero
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number, select from uint32_t
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void pcnt_ll_clear_count(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
hw->ctrl.val |= 1 << (2 * unit);
|
||||
hw->ctrl.val &= ~(1 << (2 * unit));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT step comparator event
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void pcnt_ll_enable_step_notify(pcnt_dev_t *hw, uint32_t unit, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
hw->ctrl.val |= 1 << (8 + unit);
|
||||
} else {
|
||||
hw->ctrl.val &= ~(1 << (8 + unit));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCNT step value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param direction PCNT step direction
|
||||
* @param value PCNT step value
|
||||
*/
|
||||
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, pcnt_step_direction_t direction, uint16_t value)
|
||||
{
|
||||
if (direction == PCNT_STEP_FORWARD) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf_unit[unit].conf3, cnt_h_step_un, value);
|
||||
} else {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf_unit[unit].conf3, cnt_l_step_un, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT interrupt for PCNT unit
|
||||
* @note Each PCNT unit has five watch point events that share the same interrupt bit.
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit_mask PCNT units mask
|
||||
* @param enable True to enable interrupt, False to disable interrupt
|
||||
*/
|
||||
static inline void pcnt_ll_enable_intr(pcnt_dev_t *hw, uint32_t unit_mask, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
hw->int_ena.val |= unit_mask;
|
||||
} else {
|
||||
hw->int_ena.val &= ~unit_mask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT interrupt status
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @return Interrupt status word
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t pcnt_ll_get_intr_status(pcnt_dev_t *hw)
|
||||
{
|
||||
return hw->int_st.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear PCNT interrupt status
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param status value to clear interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void pcnt_ll_clear_intr_status(pcnt_dev_t *hw, uint32_t status)
|
||||
{
|
||||
hw->int_clr.val = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT high limit event
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void pcnt_ll_enable_high_limit_event(pcnt_dev_t *hw, uint32_t unit, bool enable)
|
||||
{
|
||||
hw->conf_unit[unit].conf0.thr_h_lim_en_un = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT low limit event
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void pcnt_ll_enable_low_limit_event(pcnt_dev_t *hw, uint32_t unit, bool enable)
|
||||
{
|
||||
hw->conf_unit[unit].conf0.thr_l_lim_en_un = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT zero cross event
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void pcnt_ll_enable_zero_cross_event(pcnt_dev_t *hw, uint32_t unit, bool enable)
|
||||
{
|
||||
hw->conf_unit[unit].conf0.thr_zero_en_un = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT threshold event
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param thres Threshold ID
|
||||
* @param enable true to enable, false to disable
|
||||
*/
|
||||
static inline void pcnt_ll_enable_thres_event(pcnt_dev_t *hw, uint32_t unit, uint32_t thres, bool enable)
|
||||
{
|
||||
if (thres == 0) {
|
||||
hw->conf_unit[unit].conf0.thr_thres0_en_un = enable;
|
||||
} else {
|
||||
hw->conf_unit[unit].conf0.thr_thres1_en_un = enable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all PCNT threshold events
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit unit number
|
||||
*/
|
||||
static inline void pcnt_ll_disable_all_events(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
hw->conf_unit[unit].conf0.val &= ~(PCNT_LL_WATCH_EVENT_MASK << 11);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCNT high limit value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param value PCNT high limit value
|
||||
*/
|
||||
static inline void pcnt_ll_set_high_limit_value(pcnt_dev_t *hw, uint32_t unit, int value)
|
||||
{
|
||||
pcnt_un_conf2_reg_t conf2_reg;
|
||||
conf2_reg.val = hw->conf_unit[unit].conf2.val;
|
||||
|
||||
conf2_reg.cnt_h_lim_un = value;
|
||||
hw->conf_unit[unit].conf2.val = conf2_reg.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCNT low limit value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param value PCNT low limit value
|
||||
*/
|
||||
static inline void pcnt_ll_set_low_limit_value(pcnt_dev_t *hw, uint32_t unit, int value)
|
||||
{
|
||||
pcnt_un_conf2_reg_t conf2_reg;
|
||||
conf2_reg.val = hw->conf_unit[unit].conf2.val;
|
||||
|
||||
conf2_reg.cnt_l_lim_un = value;
|
||||
hw->conf_unit[unit].conf2.val = conf2_reg.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCNT threshold value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param thres Threshold ID
|
||||
* @param value PCNT threshold value
|
||||
*/
|
||||
static inline void pcnt_ll_set_thres_value(pcnt_dev_t *hw, uint32_t unit, uint32_t thres, int value)
|
||||
{
|
||||
pcnt_un_conf1_reg_t conf1_reg;
|
||||
conf1_reg.val = hw->conf_unit[unit].conf1.val;
|
||||
|
||||
if (thres == 0) {
|
||||
conf1_reg.cnt_thres0_un = value;
|
||||
} else {
|
||||
conf1_reg.cnt_thres1_un = value;
|
||||
}
|
||||
hw->conf_unit[unit].conf1.val = conf1_reg.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT high limit value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @return PCNT high limit value
|
||||
*/
|
||||
static inline int pcnt_ll_get_high_limit_value(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
pcnt_un_conf2_reg_t conf2_reg;
|
||||
conf2_reg.val = hw->conf_unit[unit].conf2.val;
|
||||
|
||||
int16_t value = conf2_reg.cnt_h_lim_un;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT low limit value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @return PCNT high limit value
|
||||
*/
|
||||
static inline int pcnt_ll_get_low_limit_value(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
pcnt_un_conf2_reg_t conf2_reg;
|
||||
conf2_reg.val = hw->conf_unit[unit].conf2.val;
|
||||
|
||||
int16_t value = conf2_reg.cnt_l_lim_un ;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT threshold value
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param thres Threshold ID
|
||||
* @return PCNT threshold value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline int pcnt_ll_get_thres_value(pcnt_dev_t *hw, uint32_t unit, uint32_t thres)
|
||||
{
|
||||
int16_t value;
|
||||
pcnt_un_conf1_reg_t conf1_reg;
|
||||
conf1_reg.val = hw->conf_unit[unit].conf1.val;
|
||||
|
||||
if (thres == 0) {
|
||||
value = conf1_reg.cnt_thres0_un ;
|
||||
} else {
|
||||
value = conf1_reg.cnt_thres1_un ;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT unit runtime status
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @return PCNT unit runtime status
|
||||
*/
|
||||
static inline uint32_t pcnt_ll_get_unit_status(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
return hw->status_unit[unit].val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT zero cross mode
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @return Zero cross mode
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline pcnt_unit_zero_cross_mode_t pcnt_ll_get_zero_cross_mode(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
return (pcnt_unit_zero_cross_mode_t)(hw->status_unit[unit].val & 0x03);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT event status
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @return Event status word
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
return hw->status_unit[unit].val >> 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set PCNT glitch filter threshold
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param filter_val PCNT signal filter value, counter in APB_CLK cycles.
|
||||
* Any pulses lasting shorter than this will be ignored when the filter is enabled.
|
||||
*/
|
||||
static inline void pcnt_ll_set_glitch_filter_thres(pcnt_dev_t *hw, uint32_t unit, uint32_t filter_val)
|
||||
{
|
||||
hw->conf_unit[unit].conf0.filter_thres_un = filter_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get PCNT glitch filter threshold
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @return glitch filter threshold
|
||||
*/
|
||||
static inline uint32_t pcnt_ll_get_glitch_filter_thres(pcnt_dev_t *hw, uint32_t unit)
|
||||
{
|
||||
return hw->conf_unit[unit].conf0.filter_thres_un;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable PCNT glitch filter
|
||||
*
|
||||
* @param hw Peripheral PCNT hardware instance address.
|
||||
* @param unit PCNT unit number
|
||||
* @param enable True to enable the filter, False to disable the filter
|
||||
*/
|
||||
static inline void pcnt_ll_enable_glitch_filter(pcnt_dev_t *hw, uint32_t unit, bool enable)
|
||||
{
|
||||
hw->conf_unit[unit].conf0.filter_en_un = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status register address.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return Interrupt status register address
|
||||
*/
|
||||
static inline volatile void *pcnt_ll_get_intr_status_reg(pcnt_dev_t *hw)
|
||||
{
|
||||
return &hw->int_st.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the bus clock for the PCNT module
|
||||
*
|
||||
* @param set_bit True to set bit, false to clear bit
|
||||
*/
|
||||
static inline void pcnt_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.pcnt_conf.pcnt_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the PCNT module
|
||||
*/
|
||||
static inline void pcnt_ll_reset_register(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
PCR.pcnt_conf.pcnt_rst_en = 1;
|
||||
PCR.pcnt_conf.pcnt_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the step notify is supported
|
||||
*/
|
||||
static inline bool pcnt_ll_is_step_notify_supported(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -871,10 +871,6 @@ config SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RMT_GROUPS
|
||||
int
|
||||
default 1
|
||||
|
@@ -43,8 +43,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 19,
|
||||
SLEEP_RETENTION_MODULE_GPSPI2 = 20,
|
||||
SLEEP_RETENTION_MODULE_LEDC = 21,
|
||||
SLEEP_RETENTION_MODULE_PCNT0 = 22,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 23,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 22,
|
||||
|
||||
/* modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
@@ -80,7 +79,6 @@ typedef enum periph_retention_module {
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PARLIO0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_GPSPI2) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_LEDC) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PCNT0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM0) ? true \
|
||||
: false)
|
||||
|
||||
|
@@ -348,7 +348,6 @@
|
||||
#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
|
||||
#define SOC_PCNT_SUPPORT_CLEAR_SIGNAL 1
|
||||
#define SOC_PCNT_SUPPORT_STEP_NOTIFY 1
|
||||
#define SOC_PCNT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up PCNT registers before sleep */
|
||||
|
||||
/*--------------------------- RMT CAPS ---------------------------------------*/
|
||||
#define SOC_RMT_GROUPS 1U /*!< One RMT group */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -70,33 +70,3 @@ const pcnt_signal_conn_t pcnt_periph_signals = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* PCNT Registers to be saved during sleep retention
|
||||
* - Configuration registers, e.g.: PCNT_CTRL_REG, PCNT_U0_CONF0_REG, PCNT_U0_CONF1_REG, PCNT_U0_CONF2_REG, PCNT_U1_CONF0_REG...
|
||||
* - Step Configuration registers, e.g.: PCNT_U0_CHANGE_CONF_REG, PCNT_U1_CHANGE_CONF_REG, PCNT_U2_CHANGE_CONF_REG, PCNT_U3_CHANGE_CONF_REG
|
||||
* - Interrupt enable registers, e.g.: PCNT_INT_ENA_REG
|
||||
*/
|
||||
#define PCNT_RETENTION_REGS_CNT 18
|
||||
#define PCNT_RETENTION_REGS_BASE (DR_REG_PCNT_BASE + 0x0)
|
||||
static const uint32_t pcnt_regs_map[4] = {0x1f040fff, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t pcnt_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCNT_LINK(0x00), \
|
||||
PCNT_RETENTION_REGS_BASE, PCNT_RETENTION_REGS_BASE, \
|
||||
PCNT_RETENTION_REGS_CNT, 0, 0, \
|
||||
pcnt_regs_map[0], pcnt_regs_map[1], \
|
||||
pcnt_regs_map[2], pcnt_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)
|
||||
}, \
|
||||
};
|
||||
|
||||
const pcnt_reg_retention_info_t pcnt_reg_retention_info[SOC_PCNT_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = pcnt_regs_retention,
|
||||
.array_size = ARRAY_SIZE(pcnt_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PCNT0
|
||||
},
|
||||
};
|
||||
|
@@ -803,10 +803,6 @@ config SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RMT_GROUPS
|
||||
int
|
||||
default 1
|
||||
|
@@ -45,8 +45,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 21,
|
||||
SLEEP_RETENTION_MODULE_GPSPI2 = 22,
|
||||
SLEEP_RETENTION_MODULE_LEDC = 23,
|
||||
SLEEP_RETENTION_MODULE_PCNT0 = 24,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 25,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 24,
|
||||
|
||||
/* Modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
@@ -82,7 +81,6 @@ typedef enum periph_retention_module {
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PARLIO0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_GPSPI2) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_LEDC) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PCNT0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM0) ? true \
|
||||
: false)
|
||||
|
||||
|
@@ -320,7 +320,6 @@
|
||||
#define SOC_PCNT_CHANNELS_PER_UNIT 2
|
||||
#define SOC_PCNT_THRES_POINT_PER_UNIT 2
|
||||
#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
|
||||
#define SOC_PCNT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up PCNT registers before sleep */
|
||||
|
||||
/*--------------------------- RMT CAPS ---------------------------------------*/
|
||||
#define SOC_RMT_GROUPS 1U /*!< One RMT group */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -66,32 +66,3 @@ const pcnt_signal_conn_t pcnt_periph_signals = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* PCNT Registers to be saved during sleep retention
|
||||
* - Configuration registers, e.g.: PCNT_CTRL_REG, PCNT_U0_CONF0_REG, PCNT_U0_CONF1_REG, PCNT_U0_CONF2_REG, PCNT_U1_CONF0_REG...
|
||||
* - Interrupt enable registers, e.g.: PCNT_INT_ENA_REG
|
||||
*/
|
||||
#define PCNT_RETENTION_REGS_CNT 14
|
||||
#define PCNT_RETENTION_REGS_BASE (DR_REG_PCNT_BASE + 0x0)
|
||||
static const uint32_t pcnt_regs_map[4] = {0x1040fff, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t pcnt_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCNT_LINK(0x00), \
|
||||
PCNT_RETENTION_REGS_BASE, PCNT_RETENTION_REGS_BASE, \
|
||||
PCNT_RETENTION_REGS_CNT, 0, 0, \
|
||||
pcnt_regs_map[0], pcnt_regs_map[1], \
|
||||
pcnt_regs_map[2], pcnt_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)
|
||||
}, \
|
||||
};
|
||||
|
||||
const pcnt_reg_retention_info_t pcnt_reg_retention_info[SOC_PCNT_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = pcnt_regs_retention,
|
||||
.array_size = ARRAY_SIZE(pcnt_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PCNT0
|
||||
},
|
||||
};
|
||||
|
@@ -799,10 +799,6 @@ config SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RMT_GROUPS
|
||||
int
|
||||
default 1
|
||||
|
@@ -45,8 +45,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 21,
|
||||
SLEEP_RETENTION_MODULE_GPSPI2 = 22,
|
||||
SLEEP_RETENTION_MODULE_LEDC = 23,
|
||||
SLEEP_RETENTION_MODULE_PCNT0 = 24,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 25,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 24,
|
||||
|
||||
/* Modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
|
||||
@@ -80,7 +79,6 @@ typedef enum periph_retention_module {
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PARLIO0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_GPSPI2) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_LEDC) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PCNT0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM0) ? true \
|
||||
: false)
|
||||
|
||||
|
@@ -334,7 +334,6 @@
|
||||
#define SOC_PCNT_THRES_POINT_PER_UNIT 2
|
||||
#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
|
||||
#define SOC_PCNT_SUPPORT_STEP_NOTIFY 1 /*!< Only avliable in chip version above 1.2*/
|
||||
#define SOC_PCNT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up PCNT registers before sleep */
|
||||
|
||||
/*--------------------------- RMT CAPS ---------------------------------------*/
|
||||
#define SOC_RMT_GROUPS 1U /*!< One RMT group */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -66,32 +66,3 @@ const pcnt_signal_conn_t pcnt_periph_signals = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* PCNT Registers to be saved during sleep retention
|
||||
* - Configuration registers, e.g.: PCNT_CTRL_REG, PCNT_U0_CONF0_REG, PCNT_U0_CONF1_REG, PCNT_U0_CONF2_REG, PCNT_U1_CONF0_REG...
|
||||
* - Interrupt enable registers, e.g.: PCNT_INT_ENA_REG
|
||||
*/
|
||||
#define PCNT_RETENTION_REGS_CNT 14
|
||||
#define PCNT_RETENTION_REGS_BASE (DR_REG_PCNT_BASE + 0x0)
|
||||
static const uint32_t pcnt_regs_map[4] = {0x1040fff, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t pcnt_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCNT_LINK(0x00), \
|
||||
PCNT_RETENTION_REGS_BASE, PCNT_RETENTION_REGS_BASE, \
|
||||
PCNT_RETENTION_REGS_CNT, 0, 0, \
|
||||
pcnt_regs_map[0], pcnt_regs_map[1], \
|
||||
pcnt_regs_map[2], pcnt_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)
|
||||
}, \
|
||||
};
|
||||
|
||||
const pcnt_reg_retention_info_t pcnt_reg_retention_info[SOC_PCNT_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = pcnt_regs_retention,
|
||||
.array_size = ARRAY_SIZE(pcnt_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PCNT0
|
||||
},
|
||||
};
|
||||
|
@@ -115,6 +115,10 @@ config SOC_REG_I2C_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TWAI_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@@ -467,6 +471,34 @@ config SOC_LEDC_CHANNEL_NUM
|
||||
int
|
||||
default 6
|
||||
|
||||
config SOC_PCNT_GROUPS
|
||||
int
|
||||
default 1
|
||||
|
||||
config SOC_PCNT_UNITS_PER_GROUP
|
||||
int
|
||||
default 4
|
||||
|
||||
config SOC_PCNT_CHANNELS_PER_UNIT
|
||||
int
|
||||
default 2
|
||||
|
||||
config SOC_PCNT_THRES_POINT_PER_UNIT
|
||||
int
|
||||
default 2
|
||||
|
||||
config SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_CLEAR_SIGNAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RMT_GROUPS
|
||||
int
|
||||
default 1
|
||||
|
@@ -45,8 +45,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_PARLIO0 = 21,
|
||||
SLEEP_RETENTION_MODULE_GPSPI2 = 22,
|
||||
SLEEP_RETENTION_MODULE_LEDC = 23,
|
||||
SLEEP_RETENTION_MODULE_PCNT0 = 24,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 25,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 24,
|
||||
|
||||
/* Modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
|
||||
@@ -80,7 +79,6 @@ typedef enum periph_retention_module {
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PARLIO0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_GPSPI2) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_LEDC) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PCNT0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM0) ? true \
|
||||
: false)
|
||||
|
||||
|
@@ -72,7 +72,7 @@
|
||||
#define SOC_MODEM_CLOCK_SUPPORTED 1
|
||||
#define SOC_REG_I2C_SUPPORTED 1
|
||||
// #define SOC_PHY_SUPPORTED 1
|
||||
// #define SOC_PCNT_SUPPORTED 1 //TODO: [ESP32H21] IDF-11566
|
||||
#define SOC_PCNT_SUPPORTED 1
|
||||
// #define SOC_MCPWM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11601
|
||||
#define SOC_TWAI_SUPPORTED 1
|
||||
// #define SOC_ETM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11576
|
||||
@@ -303,11 +303,13 @@
|
||||
// #define SOC_MPU_REGION_WO_SUPPORTED 0
|
||||
|
||||
/*-------------------------- PCNT CAPS ---------------------------------------*/
|
||||
// #define SOC_PCNT_GROUPS 1U
|
||||
// #define SOC_PCNT_UNITS_PER_GROUP 4
|
||||
// #define SOC_PCNT_CHANNELS_PER_UNIT 2
|
||||
// #define SOC_PCNT_THRES_POINT_PER_UNIT 2
|
||||
// #define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
|
||||
#define SOC_PCNT_GROUPS 1U
|
||||
#define SOC_PCNT_UNITS_PER_GROUP 4
|
||||
#define SOC_PCNT_CHANNELS_PER_UNIT 2
|
||||
#define SOC_PCNT_THRES_POINT_PER_UNIT 2
|
||||
#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
|
||||
#define SOC_PCNT_SUPPORT_CLEAR_SIGNAL 1
|
||||
#define SOC_PCNT_SUPPORT_STEP_NOTIFY 1
|
||||
|
||||
/*--------------------------- RMT CAPS ---------------------------------------*/
|
||||
#define SOC_RMT_GROUPS 1U /*!< One RMT group */
|
||||
|
72
components/soc/esp32h21/pcnt_periph.c
Normal file
72
components/soc/esp32h21/pcnt_periph.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/pcnt_periph.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/pcnt_reg.h"
|
||||
|
||||
const pcnt_signal_conn_t pcnt_periph_signals = {
|
||||
.groups = {
|
||||
[0] = {
|
||||
.irq = ETS_PCNT_INTR_SOURCE,
|
||||
.module_name = "pcnt0",
|
||||
.units = {
|
||||
[0] = {
|
||||
.channels = {
|
||||
[0] = {
|
||||
.control_sig = PCNT_CTRL_CH0_IN0_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH0_IN0_IDX
|
||||
},
|
||||
[1] = {
|
||||
.control_sig = PCNT_CTRL_CH1_IN0_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH1_IN0_IDX
|
||||
}
|
||||
},
|
||||
.clear_sig = PCNT_RST_IN0_IDX
|
||||
},
|
||||
[1] = {
|
||||
.channels = {
|
||||
[0] = {
|
||||
.control_sig = PCNT_CTRL_CH0_IN1_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH0_IN1_IDX,
|
||||
},
|
||||
[1] = {
|
||||
.control_sig = PCNT_CTRL_CH1_IN1_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH1_IN1_IDX
|
||||
}
|
||||
},
|
||||
.clear_sig = PCNT_RST_IN1_IDX
|
||||
},
|
||||
[2] = {
|
||||
.channels = {
|
||||
[0] = {
|
||||
.control_sig = PCNT_CTRL_CH0_IN2_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH0_IN2_IDX,
|
||||
},
|
||||
[1] = {
|
||||
.control_sig = PCNT_CTRL_CH1_IN2_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH1_IN2_IDX
|
||||
}
|
||||
},
|
||||
.clear_sig = PCNT_RST_IN2_IDX
|
||||
},
|
||||
[3] = {
|
||||
.channels = {
|
||||
[0] = {
|
||||
.control_sig = PCNT_CTRL_CH0_IN3_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH0_IN3_IDX,
|
||||
},
|
||||
[1] = {
|
||||
.control_sig = PCNT_CTRL_CH1_IN3_IDX,
|
||||
.pulse_sig = PCNT_SIG_CH1_IN3_IDX
|
||||
}
|
||||
},
|
||||
.clear_sig = PCNT_RST_IN3_IDX
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -156,65 +156,14 @@ typedef union {
|
||||
/** cnt_h_step_u0 : R/W; bitpos: [15:0]; default: 0;
|
||||
* Configures the forward rotation step value for unit 0.
|
||||
*/
|
||||
uint32_t cnt_h_step_u0:16;
|
||||
uint32_t cnt_h_step_un:16;
|
||||
/** cnt_l_step_u0 : R/W; bitpos: [31:16]; default: 0;
|
||||
* Configures the reverse rotation step value for unit 0.
|
||||
*/
|
||||
uint32_t cnt_l_step_u0:16;
|
||||
uint32_t cnt_l_step_un:16;
|
||||
};
|
||||
uint32_t val;
|
||||
} pcnt_u0_conf3_reg_t;
|
||||
|
||||
/** Type of u1_conf3 register
|
||||
* Configuration register for unit $n's step value.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** cnt_h_step_u1 : R/W; bitpos: [15:0]; default: 0;
|
||||
* Configures the forward rotation step value for unit 1.
|
||||
*/
|
||||
uint32_t cnt_h_step_u1:16;
|
||||
/** cnt_l_step_u1 : R/W; bitpos: [31:16]; default: 0;
|
||||
* Configures the reverse rotation step value for unit 1.
|
||||
*/
|
||||
uint32_t cnt_l_step_u1:16;
|
||||
};
|
||||
uint32_t val;
|
||||
} pcnt_u1_conf3_reg_t;
|
||||
|
||||
/** Type of u2_conf3 register
|
||||
* Configuration register for unit $n's step value.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** cnt_h_step_u2 : R/W; bitpos: [15:0]; default: 0;
|
||||
* Configures the forward rotation step value for unit 2.
|
||||
*/
|
||||
uint32_t cnt_h_step_u2:16;
|
||||
/** cnt_l_step_u2 : R/W; bitpos: [31:16]; default: 0;
|
||||
* Configures the reverse rotation step value for unit 2.
|
||||
*/
|
||||
uint32_t cnt_l_step_u2:16;
|
||||
};
|
||||
uint32_t val;
|
||||
} pcnt_u2_conf3_reg_t;
|
||||
|
||||
/** Type of u3_conf3 register
|
||||
* Configuration register for unit $n's step value.
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** cnt_h_step_u3 : R/W; bitpos: [15:0]; default: 0;
|
||||
* Configures the forward rotation step value for unit 3.
|
||||
*/
|
||||
uint32_t cnt_h_step_u3:16;
|
||||
/** cnt_l_step_u3 : R/W; bitpos: [31:16]; default: 0;
|
||||
* Configures the reverse rotation step value for unit 3.
|
||||
*/
|
||||
uint32_t cnt_l_step_u3:16;
|
||||
};
|
||||
uint32_t val;
|
||||
} pcnt_u3_conf3_reg_t;
|
||||
} pcnt_un_conf3_reg_t;
|
||||
|
||||
/** Type of ctrl register
|
||||
* Control register for all counters
|
||||
@@ -484,29 +433,19 @@ typedef union {
|
||||
} pcnt_date_reg_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
volatile pcnt_un_conf0_reg_t u0_conf0;
|
||||
volatile pcnt_un_conf1_reg_t u0_conf1;
|
||||
volatile pcnt_un_conf2_reg_t u0_conf2;
|
||||
volatile pcnt_u0_conf3_reg_t u0_conf3;
|
||||
volatile pcnt_un_conf0_reg_t u1_conf0;
|
||||
volatile pcnt_un_conf1_reg_t u1_conf1;
|
||||
volatile pcnt_un_conf2_reg_t u1_conf2;
|
||||
volatile pcnt_u1_conf3_reg_t u1_conf3;
|
||||
volatile pcnt_un_conf0_reg_t u2_conf0;
|
||||
volatile pcnt_un_conf1_reg_t u2_conf1;
|
||||
volatile pcnt_un_conf2_reg_t u2_conf2;
|
||||
volatile pcnt_u2_conf3_reg_t u2_conf3;
|
||||
volatile pcnt_un_conf0_reg_t u3_conf0;
|
||||
volatile pcnt_un_conf1_reg_t u3_conf1;
|
||||
volatile pcnt_un_conf2_reg_t u3_conf2;
|
||||
volatile pcnt_u3_conf3_reg_t u3_conf3;
|
||||
volatile pcnt_un_cnt_reg_t un_cnt[4];
|
||||
typedef struct pcnt_dev_t {
|
||||
volatile struct {
|
||||
pcnt_un_conf0_reg_t conf0;
|
||||
pcnt_un_conf1_reg_t conf1;
|
||||
pcnt_un_conf2_reg_t conf2;
|
||||
pcnt_un_conf3_reg_t conf3;
|
||||
} conf_unit[4];
|
||||
volatile pcnt_un_cnt_reg_t cnt_unit[4];
|
||||
volatile pcnt_int_raw_reg_t int_raw;
|
||||
volatile pcnt_int_st_reg_t int_st;
|
||||
volatile pcnt_int_ena_reg_t int_ena;
|
||||
volatile pcnt_int_clr_reg_t int_clr;
|
||||
volatile pcnt_un_status_reg_t un_status[4];
|
||||
volatile pcnt_un_status_reg_t status_unit[4];
|
||||
volatile pcnt_ctrl_reg_t ctrl;
|
||||
uint32_t reserved_074[34];
|
||||
volatile pcnt_date_reg_t date;
|
||||
|
@@ -48,8 +48,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_GPSPI2 = 24,
|
||||
SLEEP_RETENTION_MODULE_GPSPI3 = 25,
|
||||
SLEEP_RETENTION_MODULE_LEDC = 26,
|
||||
SLEEP_RETENTION_MODULE_PCNT0 = 27,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 28,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 27,
|
||||
|
||||
/* Modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 29,
|
||||
@@ -86,7 +85,6 @@ typedef enum periph_retention_module {
|
||||
: ((m) == SLEEP_RETENTION_MODULE_GPSPI2) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_GPSPI3) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_LEDC) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PCNT0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM0) ? true \
|
||||
: false)
|
||||
|
||||
|
@@ -1175,10 +1175,6 @@ config SOC_PCNT_SUPPORT_CLEAR_SIGNAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RMT_GROUPS
|
||||
int
|
||||
default 1
|
||||
|
@@ -59,7 +59,6 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_LEDC = 33,
|
||||
SLEEP_RETENTION_MODULE_MCPWM0 = 34,
|
||||
SLEEP_RETENTION_MODULE_MCPWM1 = 35,
|
||||
SLEEP_RETENTION_MODULE_PCNT0 = 36,
|
||||
|
||||
SLEEP_RETENTION_MODULE_MAX = SOC_PM_RETENTION_MODULE_NUM - 1
|
||||
} periph_retention_module_t;
|
||||
@@ -101,7 +100,6 @@ typedef enum periph_retention_module {
|
||||
: ((m) == SLEEP_RETENTION_MODULE_LEDC) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM0) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_MCPWM1) ? true \
|
||||
: ((m) == SLEEP_RETENTION_MODULE_PCNT0) ? true \
|
||||
: false)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -427,7 +427,6 @@
|
||||
#define SOC_PCNT_THRES_POINT_PER_UNIT 2
|
||||
#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1
|
||||
#define SOC_PCNT_SUPPORT_CLEAR_SIGNAL 1 /*!< Support clear signal input */
|
||||
#define SOC_PCNT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up PCNT registers before sleep */
|
||||
|
||||
/*--------------------------- RMT CAPS ---------------------------------------*/
|
||||
#define SOC_RMT_GROUPS 1U /*!< One RMT group */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -70,35 +70,3 @@ const pcnt_signal_conn_t pcnt_periph_signals = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
/**
|
||||
* PCNT Registers to be saved during sleep retention
|
||||
* - Configuration registers, e.g.: PCNT_CTRL_REG, PCNT_U0_CONF0_REG, PCNT_U0_CONF1_REG, PCNT_U0_CONF2_REG, PCNT_U1_CONF0_REG...
|
||||
* - Step Configuration registers, e.g.: PCNT_U0_CHANGE_CONF_REG, PCNT_U1_CHANGE_CONF_REG, PCNT_U2_CHANGE_CONF_REG, PCNT_U3_CHANGE_CONF_REG
|
||||
* - Interrupt enable registers, e.g.: PCNT_INT_ENA_REG
|
||||
*/
|
||||
#define PCNT_RETENTION_REGS_CNT 18
|
||||
#define PCNT_RETENTION_REGS_BASE (DR_REG_PCNT_BASE + 0x0)
|
||||
static const uint32_t pcnt_regs_map[4] = {0x1f040fff, 0x0, 0x0, 0x0};
|
||||
static const regdma_entries_config_t pcnt_regs_retention[] = {
|
||||
// backup stage: save configuration registers
|
||||
// restore stage: restore the configuration registers
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCNT_LINK(0x00), \
|
||||
PCNT_RETENTION_REGS_BASE, PCNT_RETENTION_REGS_BASE, \
|
||||
PCNT_RETENTION_REGS_CNT, 0, 0, \
|
||||
pcnt_regs_map[0], pcnt_regs_map[1], \
|
||||
pcnt_regs_map[2], pcnt_regs_map[3]), \
|
||||
.owner = ENTRY(0)
|
||||
}, \
|
||||
};
|
||||
|
||||
const pcnt_reg_retention_info_t pcnt_reg_retention_info[SOC_PCNT_GROUPS] = {
|
||||
[0] = {
|
||||
.regdma_entry_array = pcnt_regs_retention,
|
||||
.array_size = ARRAY_SIZE(pcnt_regs_retention),
|
||||
.retention_module = SLEEP_RETENTION_MODULE_PCNT0
|
||||
},
|
||||
};
|
||||
#endif // SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
|
@@ -9,10 +9,6 @@
|
||||
#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/regdma.h"
|
||||
#if SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
#include "soc/retention_periph_defs.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -36,16 +32,6 @@ typedef struct {
|
||||
|
||||
extern const pcnt_signal_conn_t pcnt_periph_signals;
|
||||
|
||||
#if SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
typedef struct {
|
||||
const periph_retention_module_t retention_module;
|
||||
const regdma_entries_config_t *regdma_entry_array;
|
||||
uint32_t array_size;
|
||||
} pcnt_reg_retention_info_t;
|
||||
|
||||
extern const pcnt_reg_retention_info_t pcnt_reg_retention_info[SOC_PCNT_GROUPS];
|
||||
#endif // SOC_PCNT_SUPPORT_SLEEP_RETENTION
|
||||
|
||||
#endif // SOC_PCNT_SUPPORTED
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -63,8 +63,7 @@ extern "C" {
|
||||
#define REGDMA_PARLIO_LINK(_pri) ((0x22 << 8) | _pri)
|
||||
#define REGDMA_GPSPI_LINK(_pri) ((0x23 << 8) | _pri)
|
||||
#define REGDMA_LEDC_LINK(_pri) ((0x24 << 8) | _pri)
|
||||
#define REGDMA_PCNT_LINK(_pri) ((0x25 << 8) | _pri)
|
||||
#define REGDMA_MCPWM_LINK(_pri) ((0x26 << 8) | _pri)
|
||||
#define REGDMA_MCPWM_LINK(_pri) ((0x25 << 8) | _pri)
|
||||
|
||||
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)
|
||||
|
||||
@@ -85,7 +84,6 @@ extern "C" {
|
||||
#define REGDMA_LINK_PRI_I2C REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_I2S REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_PARLIO REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_PCNT REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_UART REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_TEMPERATURE_SENSOR REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_TWAI REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
|
@@ -177,7 +177,6 @@ api-reference/peripherals/lcd/i2c_lcd.rst
|
||||
api-reference/peripherals/lcd/spi_lcd.rst
|
||||
api-reference/peripherals/lcd/rgb_lcd.rst
|
||||
api-reference/peripherals/lcd/parl_lcd.rst
|
||||
api-reference/peripherals/pcnt.rst
|
||||
api-reference/peripherals/spi_features.rst
|
||||
api-reference/peripherals/ppa.rst
|
||||
api-reference/peripherals/ledc.rst
|
||||
|
@@ -122,16 +122,6 @@ The following drivers hold the ``ESP_PM_APB_FREQ_MAX`` lock while the driver is
|
||||
:SOC_SDM_SUPPORTED: - **Sigma-delta**: between calls to :cpp:func:`sdm_channel_enable` and :cpp:func:`sdm_channel_disable`.
|
||||
:SOC_MCPWM_SUPPORTED: - **MCPWM**: between calls to :cpp:func:`mcpwm_timer_enable` and :cpp:func:`mcpwm_timer_disable`, as well as :cpp:func:`mcpwm_capture_timer_enable` and :cpp:func:`mcpwm_capture_timer_disable`.
|
||||
|
||||
The following peripheral drivers are not aware of DFS yet. Applications need to acquire/release locks themselves, when necessary:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_PCNT_SUPPORTED: - The legacy PCNT driver
|
||||
:SOC_SDM_SUPPORTED: - The legacy Sigma-delta driver
|
||||
- The legacy timer group driver
|
||||
:SOC_MCPWM_SUPPORTED: - The legacy MCPWM driver
|
||||
|
||||
|
||||
.. only:: SOC_PM_SUPPORT_TOP_PD
|
||||
|
||||
Light-sleep Peripheral Power Down
|
||||
|
@@ -122,16 +122,6 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
|
||||
:SOC_SDM_SUPPORTED: - **Sigma-delta**:从调用 :cpp:func:`sdm_channel_enable` 至 :cpp:func:`sdm_channel_disable` 期间。
|
||||
:SOC_MCPWM_SUPPORTED: - **MCPWM**: 从调用 :cpp:func:`mcpwm_timer_enable` 至 :cpp:func:`mcpwm_timer_disable` 期间,以及调用 :cpp:func:`mcpwm_capture_timer_enable` 至 :cpp:func:`mcpwm_capture_timer_disable` 期间。
|
||||
|
||||
以下外设驱动程序无法感知动态调频,应用程序需自己获取/释放管理锁:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_PCNT_SUPPORTED: - 旧版 PCNT 驱动
|
||||
:SOC_SDM_SUPPORTED: - 旧版 Sigma-delta 驱动
|
||||
- 旧版定时器驱动 (Timer Group)
|
||||
:SOC_MCPWM_SUPPORTED: - 旧版 MCPWM 驱动
|
||||
|
||||
|
||||
.. only:: SOC_PM_SUPPORT_TOP_PD
|
||||
|
||||
Light-sleep 外设下电
|
||||
|
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
||||
# Rotary Encoder Example
|
||||
|
||||
|
Reference in New Issue
Block a user