diff --git a/components/driver/pcnt.c b/components/driver/pcnt.c index b6818644ec..dbfdb8d00c 100644 --- a/components/driver/pcnt.c +++ b/components/driver/pcnt.c @@ -1,4 +1,4 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-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. @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "soc/soc_caps.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "freertos/xtensa_api.h" #include "esp_log.h" -#include "driver/pcnt.h" +#include "soc/soc_caps.h" +#if SOC_PCNT_SUPPORTED #include "driver/periph_ctrl.h" +#include "driver/pcnt.h" #include "hal/pcnt_hal.h" #include "esp_rom_gpio.h" @@ -85,28 +85,18 @@ static inline esp_err_t _pcnt_set_pin(pcnt_port_t pcnt_port, pcnt_unit_t unit, p PCNT_CHECK(GPIO_IS_VALID_GPIO(pulse_io) || pulse_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG); PCNT_CHECK(GPIO_IS_VALID_GPIO(ctrl_io) || ctrl_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG); - int sig_base = (channel == 0) ? PCNT_SIG_CH0_IN0_IDX : PCNT_SIG_CH1_IN0_IDX; - int ctrl_base = (channel == 0) ? PCNT_CTRL_CH0_IN0_IDX : PCNT_CTRL_CH1_IN0_IDX; - if (unit > 4) { - sig_base += 12; // GPIO matrix assignments have a gap between units 4 & 5 - ctrl_base += 12; - } - - int input_sig_index = sig_base + (4 * unit); - int ctrl_sig_index = ctrl_base + (4 * unit); - if (pulse_io >= 0) { PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pulse_io], PIN_FUNC_GPIO); gpio_set_direction(pulse_io, GPIO_MODE_INPUT); gpio_set_pull_mode(pulse_io, GPIO_PULLUP_ONLY); - esp_rom_gpio_connect_in_signal(pulse_io, input_sig_index, 0); + esp_rom_gpio_connect_in_signal(pulse_io, pcnt_periph_signals.units[unit].channels[channel].pulse_sig, 0); } if (ctrl_io >= 0) { PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[ctrl_io], PIN_FUNC_GPIO); gpio_set_direction(ctrl_io, GPIO_MODE_INPUT); gpio_set_pull_mode(ctrl_io, GPIO_PULLUP_ONLY); - esp_rom_gpio_connect_in_signal(ctrl_io, ctrl_sig_index, 0); + esp_rom_gpio_connect_in_signal(ctrl_io, pcnt_periph_signals.units[unit].channels[channel].control_sig, 0); } return ESP_OK; @@ -284,11 +274,11 @@ static inline esp_err_t _pcnt_isr_handler_remove(pcnt_port_t pcnt_port, pcnt_uni // pcnt interrupt service static void IRAM_ATTR pcnt_intr_service(void *arg) { - uint32_t status, mask = 0; + uint32_t status = 0; pcnt_port_t pcnt_port = (pcnt_port_t)arg; pcnt_hal_get_intr_status(&(p_pcnt_obj[pcnt_port]->hal), &status); + pcnt_hal_clear_intr_status(&(p_pcnt_obj[pcnt_port]->hal), status); - mask = status; while (status) { int unit = __builtin_ffs(status) - 1; status &= ~(1 << unit); @@ -297,7 +287,6 @@ static void IRAM_ATTR pcnt_intr_service(void *arg) (pcnt_isr_func[unit].fn)(pcnt_isr_func[unit].args); } } - pcnt_hal_clear_intr_status(&(p_pcnt_obj[pcnt_port]->hal), mask); } static inline esp_err_t _pcnt_isr_service_install(pcnt_port_t pcnt_port, int intr_alloc_flags) @@ -351,10 +340,10 @@ static inline esp_err_t _pcnt_unit_config(pcnt_port_t pcnt_port, const pcnt_conf /*Enalbe hardware module*/ static bool pcnt_enable = false; if (pcnt_enable == false) { - periph_module_reset(PERIPH_PCNT_MODULE); + periph_module_reset(pcnt_periph_signals.module); pcnt_enable = true; } - periph_module_enable(PERIPH_PCNT_MODULE); + periph_module_enable(pcnt_periph_signals.module); /*Set counter range*/ _pcnt_set_event_value(pcnt_port, unit, PCNT_EVT_H_LIM, pcnt_config->counter_h_lim); _pcnt_set_event_value(pcnt_port, unit, PCNT_EVT_L_LIM, pcnt_config->counter_l_lim); @@ -504,7 +493,7 @@ esp_err_t pcnt_isr_register(void (*fun)(void *), void *arg, int intr_alloc_flags esp_err_t ret = ESP_FAIL; PCNT_CHECK(fun != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG); PCNT_ENTER_CRITICAL(&pcnt_spinlock); - ret = esp_intr_alloc(ETS_PCNT_INTR_SOURCE, intr_alloc_flags, fun, arg, handle); + ret = esp_intr_alloc(pcnt_periph_signals.irq, intr_alloc_flags, fun, arg, handle); PCNT_EXIT_CRITICAL(&pcnt_spinlock); return ret; } @@ -529,3 +518,5 @@ void pcnt_isr_service_uninstall() { _pcnt_isr_service_uninstall(PCNT_PORT_0); } + +#endif // #if SOC_PCNT_SUPPORTED diff --git a/components/hal/esp32/include/hal/pcnt_ll.h b/components/hal/esp32/include/hal/pcnt_ll.h index d0a5c12686..0dce4bfe57 100644 --- a/components/hal/esp32/include/hal/pcnt_ll.h +++ b/components/hal/esp32/include/hal/pcnt_ll.h @@ -32,6 +32,50 @@ extern "C" { // Get PCNT hardware instance with giving pcnt num #define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL) +/** + * @brief Set PCNT channel edge mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param pos_mode Counter mode when detecting positive edge + * @param neg_mode Counter mode when detecting negative edge + */ +static inline void pcnt_ll_set_edge_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode) +{ + typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; + if (channel == 0) { + conf0_reg.ch0_pos_mode = pos_mode; + conf0_reg.ch0_neg_mode = neg_mode; + } else { + conf0_reg.ch1_pos_mode = pos_mode; + conf0_reg.ch1_neg_mode = neg_mode; + } + hw->conf_unit[unit].conf0 = conf0_reg; +} + +/** + * @brief Set PCNT channel level mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param hctrl_mode Counter mode when control signal is high level + * @param lctrl_mode Counter mode when control signal is low level + */ +static inline void pcnt_ll_set_level_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode) +{ + typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; + if (channel == 0) { + conf0_reg.ch0_hctrl_mode = hctrl_mode; + conf0_reg.ch0_lctrl_mode = lctrl_mode; + } else { + conf0_reg.ch1_hctrl_mode = hctrl_mode; + conf0_reg.ch1_lctrl_mode = lctrl_mode; + } + hw->conf_unit[unit].conf0 = conf0_reg; +} + /** * @brief Set PCNT counter mode * @@ -45,19 +89,8 @@ extern "C" { */ static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode) { - typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; - if (channel == 0) { - conf0_reg.ch0_pos_mode = pos_mode; - conf0_reg.ch0_neg_mode = neg_mode; - conf0_reg.ch0_hctrl_mode = hctrl_mode; - conf0_reg.ch0_lctrl_mode = lctrl_mode; - } else { - conf0_reg.ch1_pos_mode = pos_mode; - conf0_reg.ch1_neg_mode = neg_mode; - conf0_reg.ch1_hctrl_mode = hctrl_mode; - conf0_reg.ch1_lctrl_mode = lctrl_mode; - } - hw->conf_unit[unit].conf0 = conf0_reg; + pcnt_ll_set_edge_mode(hw, unit, channel, pos_mode, neg_mode); + pcnt_ll_set_level_mode(hw, unit, channel, hctrl_mode, lctrl_mode); } /** @@ -247,6 +280,18 @@ static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcn } } +/** + * @brief Get PCNT event status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return event status word + */ +static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, pcnt_unit_t unit) +{ + return hw->status_unit[unit].val; +} + /** * @brief Set PCNT filter value * diff --git a/components/hal/esp32s2/include/hal/pcnt_ll.h b/components/hal/esp32s2/include/hal/pcnt_ll.h index 73cecac8cb..7b2d9ee069 100644 --- a/components/hal/esp32s2/include/hal/pcnt_ll.h +++ b/components/hal/esp32s2/include/hal/pcnt_ll.h @@ -32,6 +32,50 @@ extern "C" { // Get PCNT hardware instance with giving pcnt num #define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL) +/** + * @brief Set PCNT channel edge mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param pos_mode Counter mode when detecting positive edge + * @param neg_mode Counter mode when detecting negative edge + */ +static inline void pcnt_ll_set_edge_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode) +{ + typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; + if (channel == 0) { + conf0_reg.ch0_pos_mode = pos_mode; + conf0_reg.ch0_neg_mode = neg_mode; + } else { + conf0_reg.ch1_pos_mode = pos_mode; + conf0_reg.ch1_neg_mode = neg_mode; + } + hw->conf_unit[unit].conf0 = conf0_reg; +} + +/** + * @brief Set PCNT channel level mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param hctrl_mode Counter mode when control signal is high level + * @param lctrl_mode Counter mode when control signal is low level + */ +static inline void pcnt_ll_set_level_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode) +{ + typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; + if (channel == 0) { + conf0_reg.ch0_hctrl_mode = hctrl_mode; + conf0_reg.ch0_lctrl_mode = lctrl_mode; + } else { + conf0_reg.ch1_hctrl_mode = hctrl_mode; + conf0_reg.ch1_lctrl_mode = lctrl_mode; + } + hw->conf_unit[unit].conf0 = conf0_reg; +} + /** * @brief Set PCNT counter mode * @@ -45,19 +89,8 @@ extern "C" { */ static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode) { - typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; - if (channel == 0) { - conf0_reg.ch0_pos_mode = pos_mode; - conf0_reg.ch0_neg_mode = neg_mode; - conf0_reg.ch0_hctrl_mode = hctrl_mode; - conf0_reg.ch0_lctrl_mode = lctrl_mode; - } else { - conf0_reg.ch1_pos_mode = pos_mode; - conf0_reg.ch1_neg_mode = neg_mode; - conf0_reg.ch1_hctrl_mode = hctrl_mode; - conf0_reg.ch1_lctrl_mode = lctrl_mode; - } - hw->conf_unit[unit].conf0 = conf0_reg; + pcnt_ll_set_edge_mode(hw, unit, channel, pos_mode, neg_mode); + pcnt_ll_set_level_mode(hw, unit, channel, hctrl_mode, lctrl_mode); } /** @@ -247,6 +280,18 @@ static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcn } } +/** + * @brief Get PCNT event status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return event status word + */ +static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, pcnt_unit_t unit) +{ + return hw->status_unit[unit].val; +} + /** * @brief Set PCNT filter value * diff --git a/components/hal/esp32s3/include/hal/pcnt_ll.h b/components/hal/esp32s3/include/hal/pcnt_ll.h index 376f17c268..19a5fc1977 100644 --- a/components/hal/esp32s3/include/hal/pcnt_ll.h +++ b/components/hal/esp32s3/include/hal/pcnt_ll.h @@ -32,6 +32,50 @@ extern "C" { // Get PCNT hardware instance with giving pcnt num #define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL) +/** + * @brief Set PCNT channel edge mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param pos_mode Counter mode when detecting positive edge + * @param neg_mode Counter mode when detecting negative edge + */ +static inline void pcnt_ll_set_edge_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode) +{ + typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; + if (channel == 0) { + conf0_reg.ch0_pos_mode = pos_mode; + conf0_reg.ch0_neg_mode = neg_mode; + } else { + conf0_reg.ch1_pos_mode = pos_mode; + conf0_reg.ch1_neg_mode = neg_mode; + } + hw->conf_unit[unit].conf0 = conf0_reg; +} + +/** + * @brief Set PCNT channel level mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param hctrl_mode Counter mode when control signal is high level + * @param lctrl_mode Counter mode when control signal is low level + */ +static inline void pcnt_ll_set_level_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode) +{ + typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; + if (channel == 0) { + conf0_reg.ch0_hctrl_mode = hctrl_mode; + conf0_reg.ch0_lctrl_mode = lctrl_mode; + } else { + conf0_reg.ch1_hctrl_mode = hctrl_mode; + conf0_reg.ch1_lctrl_mode = lctrl_mode; + } + hw->conf_unit[unit].conf0 = conf0_reg; +} + /** * @brief Set PCNT counter mode * @@ -45,19 +89,8 @@ extern "C" { */ static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode) { - typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0; - if (channel == 0) { - conf0_reg.ch0_pos_mode = pos_mode; - conf0_reg.ch0_neg_mode = neg_mode; - conf0_reg.ch0_hctrl_mode = hctrl_mode; - conf0_reg.ch0_lctrl_mode = lctrl_mode; - } else { - conf0_reg.ch1_pos_mode = pos_mode; - conf0_reg.ch1_neg_mode = neg_mode; - conf0_reg.ch1_hctrl_mode = hctrl_mode; - conf0_reg.ch1_lctrl_mode = lctrl_mode; - } - hw->conf_unit[unit].conf0 = conf0_reg; + pcnt_ll_set_edge_mode(hw, unit, channel, pos_mode, neg_mode); + pcnt_ll_set_level_mode(hw, unit, channel, hctrl_mode, lctrl_mode); } /** @@ -247,6 +280,18 @@ static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcn } } +/** + * @brief Get PCNT event status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return event status word + */ +static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, pcnt_unit_t unit) +{ + return hw->status_unit[unit].val; +} + /** * @brief Set PCNT filter value * diff --git a/components/soc/soc/esp32/CMakeLists.txt b/components/soc/soc/esp32/CMakeLists.txt index 334f189b5e..c423a829bc 100644 --- a/components/soc/soc/esp32/CMakeLists.txt +++ b/components/soc/soc/esp32/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(soc_esp32 STATIC "adc_periph.c" "dac_periph.c" "gpio_periph.c" + "pcnt_periph.c" "rtc_io_periph.c" "rtc_periph.c" "sdio_slave_periph.c" diff --git a/components/soc/soc/esp32/include/soc/soc_caps.h b/components/soc/soc/esp32/include/soc/soc_caps.h index 2be66b43eb..76d778e71c 100644 --- a/components/soc/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/soc/esp32/include/soc/soc_caps.h @@ -63,6 +63,7 @@ #define SOC_MCPWM_SUPPORTED 1 #define SOC_SDMMC_HOST_SUPPORTED 1 #define SOC_BT_SUPPORTED 1 +#define SOC_PCNT_SUPPORTED 1 #define SOC_SDIO_SLAVE_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1 #define SOC_EMAC_SUPPORTED 1 @@ -155,6 +156,7 @@ // ESP32 have 1 PCNT peripheral #define SOC_PCNT_PORT_NUM (1) #define SOC_PCNT_UNIT_NUM (8) +#define SOC_PCNT_UNIT_CHANNEL_NUM (2) /*-------------------------- RMT CAPS ----------------------------------------*/ #define SOC_RMT_CHANNEL_MEM_WORDS (64) /*!< Each channel owns 64 words memory */ diff --git a/components/soc/soc/esp32/pcnt_periph.c b/components/soc/soc/esp32/pcnt_periph.c new file mode 100644 index 0000000000..92d97815c6 --- /dev/null +++ b/components/soc/soc/esp32/pcnt_periph.c @@ -0,0 +1,119 @@ +// Copyright 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. + +#include "soc/pcnt_periph.h" +#include "soc/gpio_sig_map.h" + +const pcnt_signal_conn_t pcnt_periph_signals = { + .module = PERIPH_PCNT_MODULE, + .irq = ETS_PCNT_INTR_SOURCE, + .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 + } + } + }, + [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 + } + } + }, + [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 + } + } + }, + [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 + } + } + }, + [4] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN4_IDX, + .pulse_sig = PCNT_SIG_CH0_IN4_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN4_IDX, + .pulse_sig = PCNT_SIG_CH1_IN4_IDX + } + } + }, + [5] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN5_IDX, + .pulse_sig = PCNT_SIG_CH0_IN5_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN5_IDX, + .pulse_sig = PCNT_SIG_CH1_IN5_IDX + } + } + }, + [6] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN6_IDX, + .pulse_sig = PCNT_SIG_CH0_IN6_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN6_IDX, + .pulse_sig = PCNT_SIG_CH1_IN6_IDX + } + } + }, + [7] = { + .channels = { + [0] = { + .control_sig = PCNT_CTRL_CH0_IN7_IDX, + .pulse_sig = PCNT_SIG_CH0_IN7_IDX + }, + [1] = { + .control_sig = PCNT_CTRL_CH1_IN7_IDX, + .pulse_sig = PCNT_SIG_CH1_IN7_IDX + } + } + } + } +}; diff --git a/components/soc/soc/esp32s2/CMakeLists.txt b/components/soc/soc/esp32s2/CMakeLists.txt index f981736f66..6def90f058 100644 --- a/components/soc/soc/esp32s2/CMakeLists.txt +++ b/components/soc/soc/esp32s2/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(soc_esp32s2 STATIC "adc_periph.c" "dac_periph.c" "gpio_periph.c" + "pcnt_periph.c" "rtc_io_periph.c" "rtc_periph.c" "interrupts.c" diff --git a/components/soc/soc/esp32s2/include/soc/soc_caps.h b/components/soc/soc/esp32s2/include/soc/soc_caps.h index a77899d021..00dd682fd2 100644 --- a/components/soc/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/soc/esp32s2/include/soc/soc_caps.h @@ -43,6 +43,7 @@ #define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_RISCV_COPROC_SUPPORTED 1 #define SOC_USB_SUPPORTED 1 +#define SOC_PCNT_SUPPORTED 1 #define SOC_CACHE_SUPPORT_WRAP 1 @@ -132,6 +133,7 @@ // ESP32-S2 have 1 PCNT peripheral #define SOC_PCNT_PORT_NUM (1) #define SOC_PCNT_UNIT_NUM (4) // ESP32-S2 only have 4 unit +#define SOC_PCNT_UNIT_CHANNEL_NUM (2) /*-------------------------- RMT CAPS ----------------------------------------*/ #define SOC_RMT_CHANNEL_MEM_WORDS (64) /*!< Each channel owns 64 words memory (1 word = 4 Bytes) */ diff --git a/components/soc/soc/esp32s2/pcnt_periph.c b/components/soc/soc/esp32s2/pcnt_periph.c new file mode 100644 index 0000000000..a411187dee --- /dev/null +++ b/components/soc/soc/esp32s2/pcnt_periph.c @@ -0,0 +1,71 @@ +// Copyright 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. + +#include "soc/pcnt_periph.h" +#include "soc/gpio_sig_map.h" + +const pcnt_signal_conn_t pcnt_periph_signals = { + .module = PERIPH_PCNT_MODULE, + .irq = ETS_PCNT_INTR_SOURCE, + .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 + } + } + }, + [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 + } + } + }, + [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 + } + } + }, + [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 + } + } + } + } +}; diff --git a/components/soc/soc/esp32s3/CMakeLists.txt b/components/soc/soc/esp32s3/CMakeLists.txt index f49505994f..0f2d0be691 100644 --- a/components/soc/soc/esp32s3/CMakeLists.txt +++ b/components/soc/soc/esp32s3/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(soc_esp32s3 STATIC "i2s_periph.c" "interrupts.c" "ledc_periph.c" + "pcnt_periph.c" "rtc_io_periph.c" "rtc_periph.c" "sdio_slave_periph.c" diff --git a/components/soc/soc/esp32s3/include/soc/pcnt_caps.h b/components/soc/soc/esp32s3/include/soc/pcnt_caps.h deleted file mode 100644 index b72d302c2e..0000000000 --- a/components/soc/soc/esp32s3/include/soc/pcnt_caps.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015-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_PCNT_PORT_NUM (1) -#define SOC_PCNT_UNIT_NUM (4) - -#ifdef __cplusplus -} -#endif diff --git a/components/soc/soc/esp32s3/include/soc/soc_caps.h b/components/soc/soc/esp32s3/include/soc/soc_caps.h index 44cecec96b..d26e91df3c 100644 --- a/components/soc/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/soc/esp32s3/include/soc/soc_caps.h @@ -6,6 +6,7 @@ #pragma once /*-------------------------- COMMON CAPS ---------------------------------------*/ +#define SOC_PCNT_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1 #define SOC_GDMA_SUPPORTED 1 #define SOC_CPU_CORES_NUM 2 @@ -42,7 +43,9 @@ #include "mpu_caps.h" /*-------------------------- PCNT CAPS ---------------------------------------*/ -#include "pcnt_caps.h" +#define SOC_PCNT_PORT_NUM (1) +#define SOC_PCNT_UNIT_NUM (4) +#define SOC_PCNT_UNIT_CHANNEL_NUM (2) /*-------------------------- RMT CAPS ----------------------------------------*/ #include "rmt_caps.h" diff --git a/components/soc/soc/esp32s3/pcnt_periph.c b/components/soc/soc/esp32s3/pcnt_periph.c new file mode 100644 index 0000000000..a411187dee --- /dev/null +++ b/components/soc/soc/esp32s3/pcnt_periph.c @@ -0,0 +1,71 @@ +// Copyright 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. + +#include "soc/pcnt_periph.h" +#include "soc/gpio_sig_map.h" + +const pcnt_signal_conn_t pcnt_periph_signals = { + .module = PERIPH_PCNT_MODULE, + .irq = ETS_PCNT_INTR_SOURCE, + .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 + } + } + }, + [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 + } + } + }, + [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 + } + } + }, + [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 + } + } + } + } +}; diff --git a/components/soc/soc/include/soc/pcnt_periph.h b/components/soc/soc/include/soc/pcnt_periph.h index d74b175bbf..fa0f58221d 100644 --- a/components/soc/soc/include/soc/pcnt_periph.h +++ b/components/soc/soc/include/soc/pcnt_periph.h @@ -13,5 +13,30 @@ // limitations under the License. #pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" #include "soc/pcnt_reg.h" #include "soc/pcnt_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + struct { + struct { + const uint32_t pulse_sig; + const uint32_t control_sig; + } channels[SOC_PCNT_UNIT_CHANNEL_NUM]; + } units[SOC_PCNT_UNIT_NUM]; + const uint32_t irq; + const periph_module_t module; +} pcnt_signal_conn_t; + +extern const pcnt_signal_conn_t pcnt_periph_signals; + +#ifdef __cplusplus +} +#endif