From eb7ccbd174b53b7ba1079f40ab10b19b6e7d1e98 Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 13 Feb 2023 16:52:10 +0800 Subject: [PATCH] hal: added analog comparator's LL driver --- components/hal/CMakeLists.txt | 4 + components/hal/analog_cmpr_hal.c | 13 ++ .../hal/esp32h2/include/hal/analog_cmpr_ll.h | 172 ++++++++++++++++++ components/hal/include/hal/analog_cmpr_hal.h | 37 ++++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 + .../soc/esp32h2/include/soc/gpio_ext_struct.h | 5 + components/soc/esp32h2/include/soc/soc_caps.h | 1 + .../soc/esp32h2/ld/esp32h2.peripherals.ld | 1 + 8 files changed, 237 insertions(+) create mode 100644 components/hal/analog_cmpr_hal.c create mode 100644 components/hal/esp32h2/include/hal/analog_cmpr_ll.h create mode 100644 components/hal/include/hal/analog_cmpr_hal.h diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index a944c360b3..6fdfa36008 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -97,6 +97,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sdm_hal.c") endif() + if(CONFIG_SOC_ANALOG_CMPR_SUPPORTED) + list(APPEND srcs "analog_cmpr_hal.c") + endif() + if(CONFIG_ETH_USE_ESP32_EMAC) list(APPEND srcs "emac_hal.c") endif() diff --git a/components/hal/analog_cmpr_hal.c b/components/hal/analog_cmpr_hal.c new file mode 100644 index 0000000000..a9c4cc8e79 --- /dev/null +++ b/components/hal/analog_cmpr_hal.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/analog_cmpr_ll.h" +#include "hal/analog_cmpr_hal.h" + +void analog_cmpr_hal_init(analog_cmpr_hal_context_t *hal) +{ + hal->dev = ANALOG_CMPR_LL_GET_HW(); +} diff --git a/components/hal/esp32h2/include/hal/analog_cmpr_ll.h b/components/hal/esp32h2/include/hal/analog_cmpr_ll.h new file mode 100644 index 0000000000..e60a03961c --- /dev/null +++ b/components/hal/esp32h2/include/hal/analog_cmpr_ll.h @@ -0,0 +1,172 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/misc.h" +#include "hal/assert.h" +#include "soc/gpio_ext_struct.h" + +#define ANALOG_CMPR_LL_GET_HW() (&ANALOG_CMPR) +#define ANALOG_CMPR_LL_EVENT_CROSS (1 << 0) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable analog comparator + * + * @param hw Analog comparator register base address + * @param en True to enable, False to disable + */ +static inline void analog_cmpr_ll_enable(analog_cmpr_dev_t *hw, bool en) +{ + hw->pad_comp_config.xpd_comp = en; +} + +/** + * @brief Set the voltage of the internal reference + * + * @param hw Analog comparator register base address + * @param voltage The voltage of the internal reference, range [0.0V, 0.7VDD], step 0.1VDD + */ +static inline void analog_cmpr_ll_set_internal_ref_voltage(analog_cmpr_dev_t *hw, float voltage) +{ + hw->pad_comp_config.mode_comp = 0; + uint32_t volt_reg_val = (uint32_t)((voltage + 0.05F) / 0.1F); + HAL_ASSERT(volt_reg_val <= 7); + hw->pad_comp_config.dref_comp = volt_reg_val; +} + +/** + * @brief Get the voltage of the internal reference + * + * @param hw Analog comparator register base address + * @return The voltage of the internal reference + */ +static inline float analog_cmpr_ll_get_internal_ref_voltage(analog_cmpr_dev_t *hw) +{ + return hw->pad_comp_config.dref_comp * 0.1F; +} + +/** + * @brief The reference voltage comes from GPIO pad (GPIO10) + * + * @note Also see `analog_cmpr_ll_set_internal_ref_voltage` to use the internal reference voltage + * + * @param hw Analog comparator register base address + */ +static inline void analog_cmpr_ll_ref_voltage_from_external(analog_cmpr_dev_t *hw) +{ + hw->pad_comp_config.mode_comp = 1; +} + +/** + * @brief Disable the cross detection + * + * @param hw Analog comparator register base address + */ +static inline void analog_cmpr_ll_disable_cross_detection(analog_cmpr_dev_t *hw) +{ + hw->pad_comp_config.zero_det_mode = 0; +} + +/** + * @brief Enable to detect the positive cross (input analog goes from low to high and across the reference voltage) + * + * @param hw Analog comparator register base address + * @param enable True to enable, False to disable + */ +static inline void analog_cmpr_ll_enable_pos_cross_detection(analog_cmpr_dev_t *hw, bool enable) +{ + if (enable) { + hw->pad_comp_config.zero_det_mode |= (1 << 0); + } else { + hw->pad_comp_config.zero_det_mode &= ~(1 << 0); + } +} + +/** + * @brief Enable to detect the negative cross (input analog goes from high to low and across the reference voltage) + * + * @param hw Analog comparator register base address + * @param enable True to enable, False to disable + */ +static inline void analog_cmpr_ll_enable_neg_cross_detection(analog_cmpr_dev_t *hw, bool enable) +{ + if (enable) { + hw->pad_comp_config.zero_det_mode |= (1 << 1); + } else { + hw->pad_comp_config.zero_det_mode &= ~(1 << 1); + } +} + +/** + * @brief Set the debounce cycle for the cross detection + * + * @note When the comparator detects a cross, it will wait for the debounce cycle to make sure the cross is stable. + * + * @param hw Analog comparator register base address + * @param cycle The debounce cycle + */ +static inline void analog_cmpr_ll_set_debounce_cycle(analog_cmpr_dev_t *hw, uint32_t cycle) +{ + hw->pad_comp_filter.zero_det_filter_cnt = cycle; +} + +/** + * @brief Enable comparator interrupt + * + * @param hw Analog comparator register base address + * @param mask Interrupt mask + * @param enable True to enable, False to disable + */ +static inline void analog_cmpr_ll_enable_intr(analog_cmpr_dev_t *hw, uint32_t mask, bool enable) +{ + if (enable) { + hw->int_ena.val |= mask; + } else { + hw->int_ena.val &= ~mask; + } +} + +/** + * @brief Get comparator interrupt status + * + * @param hw Analog comparator register base address + */ +static inline void analog_cmpr_ll_get_intr_status(analog_cmpr_dev_t *hw) +{ + hw->int_st.val; +} + +/** + * @brief Clear comparator interrupt status + * + * @param hw Analog comparator register base address + * @param mask Interrupt status word + */ +static inline void analog_cmpr_ll_clear_intr(analog_cmpr_dev_t *hw, uint32_t mask) +{ + hw->int_clr.val = mask; +} + +/** + * @brief Get the interrupt status register address + * + * @param hw Analog comparator register base address + * @return The interrupt status register address + */ +static inline volatile void *analog_cmpr_ll_get_intr_status_reg(analog_cmpr_dev_t *hw) +{ + return &hw->int_st; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/analog_cmpr_hal.h b/components/hal/include/hal/analog_cmpr_hal.h new file mode 100644 index 0000000000..01d81ff1c0 --- /dev/null +++ b/components/hal/include/hal/analog_cmpr_hal.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct analog_cmpr_dev_t *analog_cmpr_handle_t; // Analog comparator SOC layer handle + +/** + * HAL context type of analog comparator driver + */ +typedef struct { + analog_cmpr_handle_t dev; +} analog_cmpr_hal_context_t; + +/** + * @brief Initialize Analog comparator hal driver + * + * @param hal Context of the HAL layer + */ +void analog_cmpr_hal_init(analog_cmpr_hal_context_t *hal); + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index d342077dd8..25095ba7d5 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -83,6 +83,10 @@ config SOC_SDM_SUPPORTED bool default y +config SOC_ANALOG_CMPR_SUPPORTED + bool + default y + config SOC_ETM_SUPPORTED bool default y diff --git a/components/soc/esp32h2/include/soc/gpio_ext_struct.h b/components/soc/esp32h2/include/soc/gpio_ext_struct.h index 10786e703c..815d6d9e5e 100644 --- a/components/soc/esp32h2/include/soc/gpio_ext_struct.h +++ b/components/soc/esp32h2/include/soc/gpio_ext_struct.h @@ -305,10 +305,15 @@ typedef struct { volatile gpio_ext_version_reg_t version; } gpio_ext_dev_t; +// analog comparator is a stand alone peripheral, but it is connected to GPIO +// so we rename it to analog_cmpr_dev_t from user's perspective +typedef gpio_ext_dev_t analog_cmpr_dev_t; + extern gpio_sd_dev_t SDM; extern gpio_glitch_filter_dev_t GLITCH_FILTER; extern gpio_etm_dev_t GPIO_ETM; extern gpio_ext_dev_t GPIO_EXT; +extern analog_cmpr_dev_t ANALOG_CMPR; #ifndef __cplusplus _Static_assert(sizeof(gpio_ext_dev_t) == 0x100, "Invalid size of gpio_ext_dev_t structure"); diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index abb72b6a14..2614da02ae 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -45,6 +45,7 @@ #define SOC_RTC_MEM_SUPPORTED 1 #define SOC_I2S_SUPPORTED 1 #define SOC_SDM_SUPPORTED 1 +#define SOC_ANALOG_CMPR_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 #define SOC_RMT_SUPPORTED 1 #define SOC_PARLIO_SUPPORTED 1 diff --git a/components/soc/esp32h2/ld/esp32h2.peripherals.ld b/components/soc/esp32h2/ld/esp32h2.peripherals.ld index c6927ba776..4d24b46d2c 100644 --- a/components/soc/esp32h2/ld/esp32h2.peripherals.ld +++ b/components/soc/esp32h2/ld/esp32h2.peripherals.ld @@ -44,6 +44,7 @@ PROVIDE ( HMAC = 0x6008D000 ); PROVIDE ( IO_MUX = 0x60090000 ); PROVIDE ( GPIO = 0x60091000 ); PROVIDE ( GPIO_EXT = 0x60091f00 ); +PROVIDE ( ANALOG_CMPR = 0x60091f00 ); PROVIDE ( SDM = 0x60091f00 ); PROVIDE ( GLITCH_FILTER = 0x60091f30 ); PROVIDE ( GPIO_ETM = 0x60091f60 );