mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/esp32: port periph/adc to ESP-IDF interface API
This commit is contained in:
parent
9e011b653f
commit
11c9703675
@ -17,7 +17,6 @@ config CPU_FAM_ESP32
|
||||
select HAS_CPU_ESP32
|
||||
select HAS_ESP_HW_COUNTER
|
||||
select HAS_ESP_WIFI_ENTERPRISE
|
||||
select HAS_PERIPH_ADC_CTRL
|
||||
select HAS_PUF_SRAM
|
||||
|
||||
select PACKAGE_ESP32_SDK if TEST_KCONFIG
|
||||
@ -81,11 +80,6 @@ config HAS_ESP_SPI_RAM
|
||||
Indicates that an external RAM is connected via the FSPI interface in
|
||||
the board.
|
||||
|
||||
config HAS_PERIPH_ADC_CTRL
|
||||
bool
|
||||
help
|
||||
Indicates that an ESP32 ADC controller peripheral is present.
|
||||
|
||||
## Common CPU symbols
|
||||
config CPU_CORE
|
||||
default "xtensa-lx6" if CPU_CORE_XTENSA_LX6
|
||||
|
@ -60,16 +60,17 @@ ifneq (,$(filter esp_idf_nvs_flash,$(USEMODULE)))
|
||||
USEMODULE += mtd
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_idf_wifi,$(USEMODULE)))
|
||||
# add additional modules required by esp_idf_wifi
|
||||
USEMODULE += esp_idf_adc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_rtc,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += esp_rtc_timer_32k
|
||||
FEATURES_OPTIONAL += esp_rtc_timer_32k
|
||||
endif
|
||||
|
||||
ifneq (,$(filter esp_rtc_timer_32k,$(FEATURES_USED)))
|
||||
USEMODULE += esp_rtc_timer_32k
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_adc periph_dac,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_adc_ctrl
|
||||
USEMODULE += esp_rtc_timer_32k
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_gpio,$(USEMODULE)))
|
||||
@ -113,6 +114,10 @@ ifneq (,$(filter mtd,$(USEMODULE)))
|
||||
USEMODULE += esp_idf_spi_flash
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_adc,$(USEMODULE)))
|
||||
USEMODULE += esp_idf_adc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_rtc,$(USEMODULE)))
|
||||
USEMODULE += rtt_rtc
|
||||
endif
|
||||
|
@ -7,7 +7,6 @@ include $(RIOTCPU)/esp_common/Makefile.features
|
||||
FEATURES_PROVIDED += arch_esp32
|
||||
FEATURES_PROVIDED += esp_wifi_enterprise
|
||||
FEATURES_PROVIDED += esp_hw_counter
|
||||
FEATURES_PROVIDED += periph_adc_ctrl
|
||||
FEATURES_PROVIDED += puf_sram
|
||||
|
||||
ifneq (,$(filter esp32-wrover%,$(CPU_MODEL)))
|
||||
|
@ -704,15 +704,15 @@ Attenuation | Voltage Range | Symbol
|
||||
</center><br>
|
||||
|
||||
@note The reference voltage Vref can vary from device to device in the range of 1.0V and 1.2V. The
|
||||
Vref of a device can be read with the `#adc_vref_to_gpio25` function at GPIO 25.<br>
|
||||
Vref of a device can be read with the `#adc_line_vref_to_gpio` function at GPIO 25.<br>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
|
||||
extern int adc_vref_to_gpio25 (void);
|
||||
extern int adc_line_vref_to_gpio(adc_t line, gpio_t gpio);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For that purpose GPIO25 is initialized automatically as ADC channel and is connected internally to
|
||||
Vref to measure the current voltage. Once the initialization is finished and the function returns
|
||||
with success, the current voltage can be read from GPIO25. The results of the ADC input can then be
|
||||
adjusted accordingly. The `#adc_vref_to_gpio25` function can be used to determine the current
|
||||
adjusted accordingly. The `#adc_line_vref_to_gpio` function can be used to determine the current
|
||||
voltage at ESP32.
|
||||
|
||||
[Back to table of contents](#esp32_toc)
|
||||
|
@ -17,6 +17,7 @@ config MODULE_ESP_IDF
|
||||
help
|
||||
Espressif IoT Development Framework.
|
||||
|
||||
rsource "adc/Kconfig"
|
||||
rsource "common/Kconfig"
|
||||
rsource "efuse/Kconfig"
|
||||
rsource "eth/Kconfig"
|
||||
|
@ -9,5 +9,8 @@ config MODULE_ESP_IDF_WIFI
|
||||
bool
|
||||
depends on TEST_KCONFIG
|
||||
depends on MODULE_ESP_IDF
|
||||
|
||||
select MODULE_ESP_IDF_ADC
|
||||
|
||||
help
|
||||
ESP-IDF code required for accessing the WiFi interface.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2022 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -11,7 +11,14 @@
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture specific ADC functions for ESP32
|
||||
* @brief Architecture specific ADC definitions and functions for ESP32
|
||||
*
|
||||
* All ESP32x SoCs have two SAR ADC units each. However, these have
|
||||
* functionalities as well as specific properties that vary between the
|
||||
* ESP32x SoC and therefore require different handling for each ESP32x SoC.
|
||||
* This is already taken into account in the high-level API of the ESP-IDF.
|
||||
* To avoid having to reimplement these specifics and the different handling,
|
||||
* the high-level API of the ESP-IDF is used directly for the ADC peripherals.
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
@ -24,17 +31,25 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "periph/gpio.h"
|
||||
#include "periph/adc.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#include "hal/adc_types.h"
|
||||
|
||||
#include "esp_idf_api/adc.h"
|
||||
|
||||
/**
|
||||
* @brief Attenuations that can be set for ADC lines
|
||||
*
|
||||
* Event though ESP-IDF type `adc_atten_t` and `ADC_ATTEN_DB_*` are used
|
||||
* now, the `adc_attenuation_t` type with constants `ADC_ATTENUATION_*_DB` are
|
||||
* kept for compatibility.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ATTENUATION_0_DB = 0, /**< full-range is about 1.1 V (Vref) */
|
||||
ADC_ATTENUATION_3_DB, /**< full-range is about 1.5 V */
|
||||
ADC_ATTENUATION_6_DB, /**< full-range is about 2.2 V */
|
||||
ADC_ATTENUATION_11_DB /**< full-range is about 3.3 V */
|
||||
ADC_ATTENUATION_0_DB = ADC_ATTEN_DB_0, /**< full-range is about 1.1 V (Vref) */
|
||||
ADC_ATTENUATION_3_DB = ADC_ATTEN_DB_2_5, /**< full-range is about 1.5 V */
|
||||
ADC_ATTENUATION_6_DB = ADC_ATTEN_DB_6, /**< full-range is about 2.2 V */
|
||||
ADC_ATTENUATION_11_DB = ADC_ATTEN_DB_11, /**< full-range is about 3.3 V */
|
||||
} adc_attenuation_t;
|
||||
|
||||
/**
|
||||
@ -51,32 +66,57 @@ typedef enum {
|
||||
*
|
||||
* Attenuation | Voltage Range | Symbol
|
||||
* ----------------|-------------------|----------------------
|
||||
* 0 dB | 0 ... 1.1V (Vref) | ADC_ATTENUATION_0_DB
|
||||
* 3 dB | 0 ... 1.5V | ADC_ATTENUATION_3_DB
|
||||
* 6 dB | 0 ... 2.2V | ADC_ATTENUATION_6_DB
|
||||
* 11 dB (default) | 0 ... 3.3V | ADC_ATTENUATION_11_DB
|
||||
* 0 dB | 0 ... 1.1V (Vref) | ADC_ATTEN_DB_0
|
||||
* 2.5 dB | 0 ... 1.5V | ADC_ATTEN_DB_2_5
|
||||
* 6 dB | 0 ... 2.2V | ADC_ATTEN_DB_6
|
||||
* 11 dB (default) | 0 ... 3.3V | ADC_ATTEN_DB_11
|
||||
*
|
||||
* </center>
|
||||
*
|
||||
* Please note: The reference voltage Vref can vary from device to device in
|
||||
* the range of 1.0V and 1.2V. The Vref of a device can be read with the
|
||||
* function *adc_vref_to_gpio25* at the pin GPIO 25. The results of the ADC
|
||||
* input can then be adjusted accordingly.
|
||||
* @note: The reference voltage Vref can vary from ADC unit to ADC unit in
|
||||
* the range of 1.0V and 1.2V. The Vref of a unit can be routed with
|
||||
* function *adc_vref_to_gpio* to a GPIO pin.
|
||||
*
|
||||
* @param line ADC line for which the attenuation is set
|
||||
* @param atten Attenuation, see type definition of *adc_attenuation_t
|
||||
* @return 0 on success
|
||||
* @return -1 on invalid ADC line
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int adc_set_attenuation(adc_t line, adc_attenuation_t atten);
|
||||
int adc_set_attenuation(adc_t line, adc_atten_t atten);
|
||||
|
||||
/**
|
||||
* @brief Output reference voltage of a ADC line to GPIO n
|
||||
*
|
||||
* The Vref of the ADC unit of the given ADC line is routed to a GPIO pin n.
|
||||
* This allows to measure the Vref used by the ADC unit to adjusted the
|
||||
* results of the conversions accordingly.
|
||||
*
|
||||
* @note
|
||||
* - The given GPIO must be a valid ADC channel of ADC2 unit.
|
||||
* - For ESP32 and ESP32C3, the given ADC line has to be a channel of ADC2 unit.
|
||||
*
|
||||
* @param line ADC line for which Vref of its ADC unit is routed to the GPIO
|
||||
* @param gpio GPIO to which Vref is routed (ADC2 channel GPIOs only)
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int adc_line_vref_to_gpio(adc_t line, gpio_t gpio);
|
||||
|
||||
#if defined(MCU_ESP32)
|
||||
/**
|
||||
* @brief Output ADC reference voltage to GPIO25
|
||||
*
|
||||
* This function is deprecated and will be removed in future versions.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on invalid ADC line
|
||||
*/
|
||||
int adc_vref_to_gpio25 (void);
|
||||
static inline int adc_vref_to_gpio25 (void)
|
||||
{
|
||||
return esp_idf_adc_vref_to_gpio(ADC_UNIT_2, GPIO25);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
65
cpu/esp32/include/adc_arch_private.h
Normal file
65
cpu/esp32/include/adc_arch_private.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture specific internal ADC functions for ESP32
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef ADC_ARCH_PRIVATE_H
|
||||
#define ADC_ARCH_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hal/adc_types.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#ifndef DOXYGEN /* hide implementation details from doxygen */
|
||||
|
||||
#define RTCIO_GPIO(n) n /* n-th RTCIO GPIO */
|
||||
#define RTCIO_NA UINT8_MAX /* RTCIO pin not available */
|
||||
|
||||
/**
|
||||
* @brief ADC hardware descriptor (for internal use only)
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t rtc_gpio; /**< RTC GPIO number */
|
||||
gpio_t gpio; /**< GPIO */
|
||||
adc_unit_t adc_ctrl; /**< ADC controller */
|
||||
adc_channel_t adc_channel; /**< channel of ADC controller */
|
||||
char* pad_name; /**< symbolic name of pad */
|
||||
} _adc_hw_desc_t;
|
||||
|
||||
/**
|
||||
* @brief ADC hardware descriptor table (for internal use only)
|
||||
*
|
||||
* @note The index of entries in the table MUST correspond to the
|
||||
* RTCIO GPIO number.
|
||||
*/
|
||||
extern const _adc_hw_desc_t _adc_hw[];
|
||||
|
||||
/**
|
||||
* @brief GPIO to RTC IO map (for internal use only)
|
||||
*/
|
||||
extern const gpio_t _gpio_rtcio_map[];
|
||||
|
||||
#endif /* !DOXYGEN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ADC_ARCH_PRIVATE_H */
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ADC controller functions used by ADC and DAC peripherals
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef ADC_CTRL_H
|
||||
#define ADC_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "periph/gpio.h"
|
||||
|
||||
/**
|
||||
* @brief ADC controllers
|
||||
*/
|
||||
enum {
|
||||
ADC1_CTRL, /**< ADC1 controller */
|
||||
ADC2_CTRL /**< ADC2 controller */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RTC IO pin type (does not correspond to RTC gpio num order)
|
||||
*/
|
||||
enum {
|
||||
|
||||
RTCIO_TOUCH0 = 0, /**< touch sensor 0 */
|
||||
RTCIO_TOUCH1, /**< touch sensor 1 */
|
||||
RTCIO_TOUCH2, /**< touch sensor 2 */
|
||||
RTCIO_TOUCH3, /**< touch sensor 3 */
|
||||
RTCIO_TOUCH4, /**< touch sensor 4 */
|
||||
RTCIO_TOUCH5, /**< touch sensor 5 */
|
||||
RTCIO_TOUCH6, /**< touch sensor 6 */
|
||||
RTCIO_TOUCH7, /**< touch sensor 7 */
|
||||
RTCIO_TOUCH8, /**< touch sensor 8, 32K_XP */
|
||||
RTCIO_TOUCH9, /**< touch sensor 9, 32K_XN */
|
||||
|
||||
RTCIO_ADC_ADC1, /**< VDET_1 */
|
||||
RTCIO_ADC_ADC2, /**< VDET_2 */
|
||||
|
||||
RTCIO_SENSOR_SENSE1, /**< SENSOR_VP */
|
||||
RTCIO_SENSOR_SENSE2, /**< SENSOR_CAPP */
|
||||
RTCIO_SENSOR_SENSE3, /**< SENSOR_CAPN */
|
||||
RTCIO_SENSOR_SENSE4, /**< SENSOR_VN */
|
||||
|
||||
RTCIO_DAC1, /**< DAC output */
|
||||
RTCIO_DAC2, /**< DAC output */
|
||||
|
||||
RTCIO_NA, /**< RTC pad not available */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief ADC pin hardware information type (for internal use only)
|
||||
*/
|
||||
struct _adc_hw_t {
|
||||
gpio_t gpio; /**< GPIO */
|
||||
uint8_t rtc_gpio; /**< corresponding RTC GPIO */
|
||||
uint8_t adc_ctrl; /**< ADC controller */
|
||||
uint8_t adc_channel; /**< channel of ADC controller */
|
||||
char* pad_name; /**< symbolic name of pad */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RTC hardware map
|
||||
*
|
||||
* The index corresponds to RTC pin type _rtcio_pin_t (Table 19 in Technical
|
||||
* Reference)
|
||||
*/
|
||||
extern const struct _adc_hw_t _adc_hw[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ADC_CTRL_H */
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2022 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -243,24 +243,6 @@ typedef enum {
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Possible ADC resolution settings
|
||||
*/
|
||||
#define HAVE_ADC_RES_T
|
||||
typedef enum {
|
||||
ADC_RES_6BIT = 0xf0, /**< ADC resolution: 6 bit is not supported */
|
||||
ADC_RES_8BIT = 0xf1, /**< ADC resolution: 8 bit is not supported */
|
||||
ADC_RES_9BIT = 0, /**< ADC resolution: 9 bit */
|
||||
ADC_RES_10BIT = 1, /**< ADC resolution: 10 bit */
|
||||
ADC_RES_11BIT = 2, /**< ADC resolution: 11 bit */
|
||||
ADC_RES_12BIT = 3, /**< ADC resolution: 12 bit */
|
||||
ADC_RES_14BIT = 0xf2, /**< ADC resolution: 14 bit is not supported */
|
||||
ADC_RES_16BIT = 0xf3, /**< ADC resolution: 16 bit is not supported */
|
||||
} adc_res_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Number of ADC channels that could be used at maximum
|
||||
*
|
||||
@ -268,7 +250,7 @@ typedef enum {
|
||||
* therefore not usable. The maximum number of ADC channels (ADC_NUMOF_MAX)
|
||||
* is therefore set to 16.
|
||||
*/
|
||||
#define ADC_NUMOF_MAX 16
|
||||
#define ADC_NUMOF_MAX (SOC_ADC_CHANNEL_NUM(0) + SOC_ADC_CHANNEL_NUM(1))
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -14,11 +14,6 @@ config MODULE_ESP_RTC_TIMER_32K
|
||||
help
|
||||
Use RTC timer with external 32.768 kHz crystal as RTT.
|
||||
|
||||
config MODULE_PERIPH_ADC_CTRL
|
||||
bool
|
||||
depends on HAS_PERIPH_ADC_CTRL
|
||||
default y if MODULE_PERIPH_ADC || MODULE_PERIPH_DAC
|
||||
|
||||
config MODULE_PERIPH_RTT_HW_SYS
|
||||
bool
|
||||
default y if MODULE_PERIPH_RTT
|
||||
|
@ -1,5 +1,9 @@
|
||||
MODULE = periph
|
||||
|
||||
ifneq (,$(filter periph_adc periph_dac,$(USEMODULE)))
|
||||
SRC += adc_arch.c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_gpio,$(USEMODULE)))
|
||||
SRC += gpio_arch.c
|
||||
endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Gunar Schorcht
|
||||
* Copyright (C) 2022 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
@ -14,61 +14,115 @@
|
||||
* @file
|
||||
* @brief Low-level ADC driver implementation
|
||||
*
|
||||
* All ESP32x SoCs have two SAR ADC units each. However, these have
|
||||
* functionalities as well as specific properties that vary between the
|
||||
* ESP32x SoC and therefore require different handling for each ESP32x SoC.
|
||||
* This is already taken into account in the high-level API of the ESP-IDF.
|
||||
* To avoid having to reimplement these specifics and the different handling,
|
||||
* the high-level API of the ESP-IDF is used directly for the ADC peripherals.
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "periph/adc.h"
|
||||
|
||||
#include "adc_arch.h"
|
||||
#include "adc_ctrl.h"
|
||||
#include "adc_arch_private.h"
|
||||
#include "esp_common.h"
|
||||
#include "gpio_arch.h"
|
||||
#include "soc/rtc_io_struct.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
|
||||
#include "esp_idf_api/adc.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/* declaration of external functions */
|
||||
extern void _adc1_ctrl_init(void);
|
||||
extern void _adc2_ctrl_init(void);
|
||||
|
||||
/* forward declarations of internal functions */
|
||||
static bool _adc_conf_check(void);
|
||||
static void _adc_module_init(void);
|
||||
static bool _adc_module_initialized = false;
|
||||
static void _adc1_ctrl_init(void);
|
||||
static void _adc2_ctrl_init(void);
|
||||
|
||||
/* external variable declarations */
|
||||
extern const gpio_t _gpio_rtcio_map[];
|
||||
|
||||
/*
|
||||
* Structure for mapping RIOT's ADC resolutions to ESP-IDF resolutions
|
||||
* of the according ESP32x SoC.
|
||||
*/
|
||||
typedef struct {
|
||||
adc_bits_width_t res; /* used ESP-IDF resolution */
|
||||
unsigned shift; /* bit shift number for results */
|
||||
} _adc_esp_res_map_t;
|
||||
|
||||
/*
|
||||
* Table for resolution mapping
|
||||
*/
|
||||
_adc_esp_res_map_t _adc_esp_res_map[] = {
|
||||
#if defined(MCU_ESP32)
|
||||
{ .res = ADC_WIDTH_BIT_9, .shift = 3 }, /* ADC_RES_6BIT */
|
||||
{ .res = ADC_WIDTH_BIT_9, .shift = 1 }, /* ADC_RES_8BIT */
|
||||
{ .res = ADC_WIDTH_BIT_10, .shift = 0 }, /* ADC_RES_10BIT */
|
||||
{ .res = ADC_WIDTH_BIT_12, .shift = 0 }, /* ADC_RES_12BIT */
|
||||
{ .res = ADC_WIDTH_MAX }, /* ADC_RES_14BIT */
|
||||
{ .res = ADC_WIDTH_MAX }, /* ADC_RES_16BIT */
|
||||
#elif SOC_ADC_MAX_BITWIDTH == 12
|
||||
{ .res = ADC_WIDTH_BIT_12, .shift = 6 }, /* ADC_RES_6BIT */
|
||||
{ .res = ADC_WIDTH_BIT_12, .shift = 4 }, /* ADC_RES_8BIT */
|
||||
{ .res = ADC_WIDTH_BIT_12, .shift = 2 }, /* ADC_RES_10BIT */
|
||||
{ .res = ADC_WIDTH_BIT_12, .shift = 0 }, /* ADC_RES_12BIT */
|
||||
{ .res = ADC_WIDTH_MAX }, /* ADC_RES_14BIT */
|
||||
{ .res = ADC_WIDTH_MAX }, /* ADC_RES_16BIT */
|
||||
#elif SOC_ADC_MAX_BITWIDTH == 13
|
||||
{ .res = ADC_WIDTH_BIT_13, .shift = 7 }, /* ADC_RES_6BIT */
|
||||
{ .res = ADC_WIDTH_BIT_13, .shift = 5 }, /* ADC_RES_8BIT */
|
||||
{ .res = ADC_WIDTH_BIT_13, .shift = 3 }, /* ADC_RES_10BIT */
|
||||
{ .res = ADC_WIDTH_BIT_13, .shift = 1 }, /* ADC_RES_12BIT */
|
||||
{ .res = ADC_WIDTH_MAX }, /* ADC_RES_14BIT */
|
||||
{ .res = ADC_WIDTH_MAX }, /* ADC_RES_16BIT */
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool _adc_module_initialized = false;
|
||||
|
||||
static inline void _adc1_ctrl_init(void)
|
||||
{
|
||||
/* nothing to do for the moment */
|
||||
}
|
||||
|
||||
static inline void _adc2_ctrl_init(void)
|
||||
{
|
||||
/* nothing to do for the moment */
|
||||
}
|
||||
|
||||
int adc_init(adc_t line)
|
||||
{
|
||||
CHECK_PARAM_RET (line < ADC_NUMOF, -1)
|
||||
DEBUG("[adc] line=%u\n", line);
|
||||
|
||||
if (line >= ADC_NUMOF) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!_adc_module_initialized) {
|
||||
/* do some configuration checks */
|
||||
if (!_adc_conf_check()) {
|
||||
return -1;
|
||||
}
|
||||
_adc_module_init();
|
||||
_adc_module_initialized = true;
|
||||
}
|
||||
|
||||
/* get the RTCIO pin number for the given GPIO defined as ADC channel */
|
||||
uint8_t rtcio = _gpio_rtcio_map[adc_channels[line]];
|
||||
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC1_CTRL) {
|
||||
_adc1_ctrl_init();
|
||||
}
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC2_CTRL) {
|
||||
_adc2_ctrl_init();
|
||||
/* check whether the GPIO is avalid ADC channel pin */
|
||||
if (rtcio == RTCIO_NA) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* try to initialize the pin as ADC input */
|
||||
/* check whether the pin is not used for other purposes */
|
||||
if (gpio_get_pin_usage(_adc_hw[rtcio].gpio) != _GPIO) {
|
||||
LOG_TAG_ERROR("adc", "GPIO%d is used for %s and cannot be used as "
|
||||
"ADC input\n", _adc_hw[rtcio].gpio,
|
||||
@ -76,73 +130,25 @@ int adc_init(adc_t line)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t idx;
|
||||
|
||||
/* disable the pad output */
|
||||
RTCIO.enable_w1tc.val = BIT(_adc_hw[rtcio].rtc_gpio);
|
||||
|
||||
/* route pads to RTC and if possible, disable input, pull-up/pull-down */
|
||||
switch (rtcio) {
|
||||
case RTCIO_SENSOR_SENSE1: /* GPIO36, RTC0 */
|
||||
RTCIO.sensor_pads.sense1_mux_sel = 1; /* route to RTC */
|
||||
RTCIO.sensor_pads.sense1_fun_sel = 0; /* function ADC1_CH0 */
|
||||
break;
|
||||
case RTCIO_SENSOR_SENSE2: /* GPIO37, RTC1 */
|
||||
RTCIO.sensor_pads.sense2_mux_sel = 1; /* route to RTC */
|
||||
RTCIO.sensor_pads.sense2_fun_sel = 0; /* function ADC1_CH1 */
|
||||
break;
|
||||
case RTCIO_SENSOR_SENSE3: /* GPIO38, RTC2 */
|
||||
RTCIO.sensor_pads.sense3_mux_sel = 1; /* route to RTC */
|
||||
RTCIO.sensor_pads.sense3_fun_sel = 0; /* function ADC1_CH2 */
|
||||
break;
|
||||
case RTCIO_SENSOR_SENSE4: /* GPIO39, RTC3 */
|
||||
RTCIO.sensor_pads.sense4_mux_sel = 1; /* route to RTC */
|
||||
RTCIO.sensor_pads.sense4_fun_sel = 0; /* function ADC1_CH3 */
|
||||
break;
|
||||
|
||||
case RTCIO_TOUCH0: /* GPIO4, RTC10 */
|
||||
case RTCIO_TOUCH1: /* GPIO0, RTC11 */
|
||||
case RTCIO_TOUCH2: /* GPIO2, RTC12 */
|
||||
case RTCIO_TOUCH3: /* GPIO15, RTC13 */
|
||||
case RTCIO_TOUCH4: /* GPIO13, RTC14 */
|
||||
case RTCIO_TOUCH5: /* GPIO12, RTC15 */
|
||||
case RTCIO_TOUCH6: /* GPIO14, RTC16 */
|
||||
case RTCIO_TOUCH7: /* GPIO27, RTC17 */
|
||||
case RTCIO_TOUCH8: /* GPIO33, RTC8 */
|
||||
case RTCIO_TOUCH9: /* GPIO32, RTC9 */
|
||||
idx = rtcio - RTCIO_TOUCH0;
|
||||
RTCIO.touch_pad[idx].mux_sel = 1; /* route to RTC */
|
||||
RTCIO.touch_pad[idx].fun_sel = 0; /* function ADC2_CH0..ADC2_CH9 */
|
||||
RTCIO.touch_pad[idx].fun_ie = 0; /* input disabled */
|
||||
RTCIO.touch_pad[idx].rue = 0; /* pull-up disabled */
|
||||
RTCIO.touch_pad[idx].rde = 0; /* pull-down disabled */
|
||||
RTCIO.touch_pad[idx].xpd = 0; /* touch sensor powered off */
|
||||
break;
|
||||
|
||||
case RTCIO_ADC_ADC1: /* GPIO34, RTC4 */
|
||||
RTCIO.adc_pad.adc1_mux_sel = 1; /* route to RTC */
|
||||
RTCIO.adc_pad.adc1_fun_sel = 0; /* function ADC1_CH6 */
|
||||
break;
|
||||
case RTCIO_ADC_ADC2: /* GPIO35, RTC5 */
|
||||
RTCIO.adc_pad.adc2_mux_sel = 1; /* route to RTC */
|
||||
RTCIO.adc_pad.adc2_fun_sel = 0; /* function ADC1_CH7 */
|
||||
break;
|
||||
|
||||
case RTCIO_DAC1: /* GPIO25, RTC6 */
|
||||
case RTCIO_DAC2: /* GPIO26, RTC7 */
|
||||
idx = rtcio - RTCIO_DAC1;
|
||||
RTCIO.pad_dac[idx].mux_sel = 1; /* route to RTC */
|
||||
RTCIO.pad_dac[idx].fun_sel = 0; /* function ADC2_CH8, ADC2_CH9 */
|
||||
RTCIO.pad_dac[idx].fun_ie = 0; /* input disabled */
|
||||
RTCIO.pad_dac[idx].rue = 0; /* pull-up disabled */
|
||||
RTCIO.pad_dac[idx].rde = 0; /* pull-down disabled */
|
||||
RTCIO.pad_dac[idx].xpd_dac = 0; /* DAC powered off */
|
||||
break;
|
||||
|
||||
default: return -1;
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC_UNIT_1) {
|
||||
/* initialize the ADC1 unit if needed */
|
||||
_adc1_ctrl_init();
|
||||
/* set the attenuation and configure its associated GPIO pin mux */
|
||||
esp_idf_adc1_config_channel_atten(_adc_hw[rtcio].adc_channel,
|
||||
ADC_ATTEN_DB_11);
|
||||
}
|
||||
else if (_adc_hw[rtcio].adc_ctrl == ADC_UNIT_2) {
|
||||
/* initialize the ADC2 unit if needed */
|
||||
_adc2_ctrl_init();
|
||||
/* set the attenuation and configure its associated GPIO pin mux */
|
||||
esp_idf_adc2_config_channel_atten(_adc_hw[rtcio].adc_channel,
|
||||
ADC_ATTEN_DB_11);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set pin usage type */
|
||||
/* set pin usage type */
|
||||
gpio_set_pin_usage(_adc_hw[rtcio].gpio, _ADC);
|
||||
|
||||
return 0;
|
||||
@ -150,95 +156,83 @@ int adc_init(adc_t line)
|
||||
|
||||
int32_t adc_sample(adc_t line, adc_res_t res)
|
||||
{
|
||||
CHECK_PARAM_RET (line < ADC_NUMOF, -1)
|
||||
CHECK_PARAM_RET (res <= ADC_RES_12BIT, -1)
|
||||
DEBUG("[adc] line=%u res=%u\n", line, res);
|
||||
|
||||
if (_adc_esp_res_map[res].res == ADC_WIDTH_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t rtcio = _gpio_rtcio_map[adc_channels[line]];
|
||||
int raw;
|
||||
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC1_CTRL) {
|
||||
/* set the resolution for the measurement */
|
||||
SENS.sar_start_force.sar1_bit_width = res;
|
||||
SENS.sar_read_ctrl.sar1_sample_bit = res;
|
||||
|
||||
/* enable the pad in the pad enable bitmap */
|
||||
SENS.sar_meas_start1.sar1_en_pad = (1 << _adc_hw[rtcio].adc_channel);
|
||||
while (SENS.sar_slave_addr1.meas_status != 0) {}
|
||||
|
||||
/* start measurement by toggling the start bit and wait until the
|
||||
measurement has been finished */
|
||||
SENS.sar_meas_start1.meas1_start_sar = 0;
|
||||
SENS.sar_meas_start1.meas1_start_sar = 1;
|
||||
while (SENS.sar_meas_start1.meas1_done_sar == 0) {}
|
||||
|
||||
/* read out the result and return */
|
||||
return SENS.sar_meas_start1.meas1_data_sar;
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC_UNIT_1) {
|
||||
esp_idf_adc1_config_width(_adc_esp_res_map[res].res);
|
||||
raw = esp_idf_adc1_get_raw(_adc_hw[rtcio].adc_channel);
|
||||
if (raw < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* set the resolution for the measurement */
|
||||
SENS.sar_start_force.sar2_bit_width = res;
|
||||
SENS.sar_read_ctrl2.sar2_sample_bit = res;
|
||||
|
||||
/* enable the pad in the pad enable bitmap */
|
||||
SENS.sar_meas_start2.sar2_en_pad = (1 << _adc_hw[rtcio].adc_channel);
|
||||
|
||||
/* start measurement by toggling the start bit and wait until the
|
||||
measurement has been finished */
|
||||
SENS.sar_meas_start2.meas2_start_sar = 0;
|
||||
SENS.sar_meas_start2.meas2_start_sar = 1;
|
||||
while (SENS.sar_meas_start2.meas2_done_sar == 0) {}
|
||||
|
||||
/* read out the result and return */
|
||||
return SENS.sar_meas_start2.meas2_data_sar;
|
||||
}
|
||||
}
|
||||
|
||||
int adc_set_attenuation(adc_t line, adc_attenuation_t atten)
|
||||
{
|
||||
CHECK_PARAM_RET (line < ADC_NUMOF, -1)
|
||||
|
||||
uint8_t rtcio = _gpio_rtcio_map[adc_channels[line]];
|
||||
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC1_CTRL) {
|
||||
SENS.sar_atten1 &= ~(0x3 << (_adc_hw[rtcio].adc_channel << 1));
|
||||
SENS.sar_atten1 |= (atten << (_adc_hw[rtcio].adc_channel << 1));
|
||||
}
|
||||
else {
|
||||
SENS.sar_atten2 &= ~(0x3 << (_adc_hw[rtcio].adc_channel << 1));
|
||||
SENS.sar_atten2 |= (atten << (_adc_hw[rtcio].adc_channel << 1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adc_vref_to_gpio25 (void)
|
||||
{
|
||||
/* determine ADC line for GPIO25 */
|
||||
adc_t line = ADC_UNDEF;
|
||||
for (unsigned i = 0; i < ADC_NUMOF; i++) { \
|
||||
if (adc_channels[i] == GPIO25) { \
|
||||
line = i;
|
||||
break;
|
||||
else if (_adc_hw[rtcio].adc_ctrl == ADC_UNIT_2) {
|
||||
if (esp_idf_adc2_get_raw(_adc_hw[rtcio].adc_channel,
|
||||
_adc_esp_res_map[res].res, &raw) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (line == ADC_UNDEF) {
|
||||
LOG_TAG_ERROR("adc", "Have no ADC line for GPIO25\n");
|
||||
return -1;
|
||||
return raw >> _adc_esp_res_map[res].shift;
|
||||
}
|
||||
|
||||
int adc_set_attenuation(adc_t line, adc_atten_t atten)
|
||||
{
|
||||
DEBUG("[adc] line=%u atten=%u\n", line, atten);
|
||||
|
||||
uint8_t rtcio = _gpio_rtcio_map[adc_channels[line]];
|
||||
|
||||
assert(rtcio != RTCIO_NA);
|
||||
|
||||
if (_adc_hw[rtcio].adc_ctrl == ADC_UNIT_1) {
|
||||
return esp_idf_adc1_config_channel_atten(_adc_hw[rtcio].adc_channel,
|
||||
atten);
|
||||
}
|
||||
else if (_adc_hw[rtcio].adc_ctrl == ADC_UNIT_2) {
|
||||
return esp_idf_adc2_config_channel_atten(_adc_hw[rtcio].adc_channel,
|
||||
atten);
|
||||
}
|
||||
|
||||
if (adc_init(line) == 0)
|
||||
{
|
||||
uint8_t rtcio = _gpio_rtcio_map[adc_channels[line]];
|
||||
RTCCNTL.bias_conf.dbg_atten = 0;
|
||||
RTCCNTL.test_mux.dtest_rtc = 1;
|
||||
RTCCNTL.test_mux.ent_rtc = 1;
|
||||
SENS.sar_start_force.sar2_en_test = 1;
|
||||
SENS.sar_meas_start2.sar2_en_pad = (1 << _adc_hw[rtcio].adc_channel);
|
||||
LOG_TAG_INFO("adc", "You can now measure Vref at GPIO25\n");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int adc_line_vref_to_gpio(adc_t line, gpio_t gpio)
|
||||
{
|
||||
uint8_t rtcio_vref = _gpio_rtcio_map[adc_channels[line]];
|
||||
uint8_t rtcio_out = _gpio_rtcio_map[gpio];
|
||||
|
||||
/* both the ADC line and the GPIO for the output must be ADC channels */
|
||||
assert(rtcio_vref != RTCIO_NA);
|
||||
assert(rtcio_out != RTCIO_NA);
|
||||
/* avoid compilation problems with NDEBUG defined */
|
||||
(void)rtcio_out;
|
||||
|
||||
/* the GPIO for the output must be a channel of ADC2 */
|
||||
assert(_adc_hw[rtcio_out].adc_ctrl == ADC_UNIT_2);
|
||||
|
||||
esp_err_t res = ESP_OK;
|
||||
|
||||
if (_adc_hw[rtcio_vref].adc_ctrl == ADC_UNIT_1) {
|
||||
res = esp_idf_adc_vref_to_gpio(ADC_UNIT_1, gpio);
|
||||
}
|
||||
else if (_adc_hw[rtcio_vref].adc_ctrl == ADC_UNIT_2) {
|
||||
res = esp_idf_adc_vref_to_gpio(ADC_UNIT_2, gpio);
|
||||
}
|
||||
if (res != ESP_OK) {
|
||||
LOG_TAG_ERROR("adc", "Could not route Vref of ADC line %d to GPIO%d\n",
|
||||
line, gpio);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
LOG_TAG_ERROR("adc", "Could not init GPIO25 as Vref output\n");
|
||||
return -1;
|
||||
LOG_TAG_ERROR("adc", "Vref of ADC%d can now be measured at GPIO %d\n",
|
||||
_adc_hw[rtcio_vref].adc_ctrl, gpio);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,18 +249,6 @@ static bool _adc_conf_check(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _adc_module_init(void)
|
||||
{
|
||||
RTCIO.enable_w1tc.val = ~0x0;
|
||||
|
||||
/* always power on */
|
||||
SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
|
||||
|
||||
/* disable temperature sensor */
|
||||
SENS.sar_tctrl.tsens_power_up_force = 1; /* controlled by SW */
|
||||
SENS.sar_tctrl.tsens_power_up = 0; /* power down */
|
||||
}
|
||||
|
||||
void adc_print_config(void)
|
||||
{
|
||||
printf("\tADC\t\tpins=[ ");
|
||||
|
109
cpu/esp32/periph/adc_arch.c
Normal file
109
cpu/esp32/periph/adc_arch.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture-specific ADC/DAC definitions for ESP32 variant (family)
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include "adc_arch_private.h"
|
||||
#include "esp_common.h"
|
||||
#include "soc/adc_channel.h"
|
||||
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief ADC hardware descriptor table (for internal use only)
|
||||
*
|
||||
* Reference: Technical Reference Manual, Section 4.11 Table 19
|
||||
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
|
||||
*
|
||||
* @note The index of entries in the table MUST correspond to the
|
||||
* RTCIO GPIO number.
|
||||
*/
|
||||
const _adc_hw_desc_t _adc_hw[] = {
|
||||
/* rtcio, gpio, adc_ctrl, adc_channel, pad_name */
|
||||
{ RTCIO_GPIO(0), ADC1_CHANNEL_0_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_0, "SENSOR_VP" },
|
||||
{ RTCIO_GPIO(1), ADC1_CHANNEL_1_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_1, "SENSOR_CAPP" },
|
||||
{ RTCIO_GPIO(2), ADC1_CHANNEL_2_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_2, "SENSOR_CAPN" },
|
||||
{ RTCIO_GPIO(3), ADC1_CHANNEL_3_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_3, "SENSOR_VN" },
|
||||
{ RTCIO_GPIO(4), ADC1_CHANNEL_6_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_6, "VDET_1" },
|
||||
{ RTCIO_GPIO(5), ADC1_CHANNEL_7_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_7, "VDET_2" },
|
||||
{ RTCIO_GPIO(6), ADC2_CHANNEL_8_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_8, "GPIO25" },
|
||||
{ RTCIO_GPIO(7), ADC2_CHANNEL_9_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_9, "GPIO26" },
|
||||
{ RTCIO_GPIO(8), ADC1_CHANNEL_5_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_5, "32K_XN" },
|
||||
{ RTCIO_GPIO(9), ADC1_CHANNEL_4_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_4, "32K_XP" },
|
||||
{ RTCIO_GPIO(10), ADC2_CHANNEL_0_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_0, "GPIO4" },
|
||||
{ RTCIO_GPIO(11), ADC2_CHANNEL_1_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_1, "GPIO0" },
|
||||
{ RTCIO_GPIO(12), ADC2_CHANNEL_2_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_2, "GPIO2" },
|
||||
{ RTCIO_GPIO(13), ADC2_CHANNEL_3_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_3, "MTDO" },
|
||||
{ RTCIO_GPIO(14), ADC2_CHANNEL_4_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_4, "MTCK" },
|
||||
{ RTCIO_GPIO(15), ADC2_CHANNEL_5_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_5, "MTDI" },
|
||||
{ RTCIO_GPIO(16), ADC2_CHANNEL_6_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_6, "MTMS" },
|
||||
{ RTCIO_GPIO(17), ADC2_CHANNEL_7_GPIO_NUM, ADC_UNIT_2, ADC_CHANNEL_7, "GPIO27" },
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief GPIO to RTC IO map (for internal use only)
|
||||
*
|
||||
* Reference: Technical Reference Manual, Section 4.11 Table 19
|
||||
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
|
||||
*/
|
||||
const gpio_t _gpio_rtcio_map[] = {
|
||||
RTCIO_GPIO(11), /* GPIO0 */
|
||||
RTCIO_NA, /* GPIO1 */
|
||||
RTCIO_GPIO(12), /* GPIO2 */
|
||||
RTCIO_NA, /* GPIO3 */
|
||||
RTCIO_GPIO(10), /* GPIO4 */
|
||||
RTCIO_NA, /* GPIO5 */
|
||||
RTCIO_NA, /* GPIO6 */
|
||||
RTCIO_NA, /* GPIO7 */
|
||||
RTCIO_NA, /* GPIO8 */
|
||||
RTCIO_NA, /* GPIO9 */
|
||||
RTCIO_NA, /* GPIO10 */
|
||||
RTCIO_NA, /* GPIO11 */
|
||||
RTCIO_GPIO(15), /* GPIO12 MTDI */
|
||||
RTCIO_GPIO(14), /* GPIO13 MTCK */
|
||||
RTCIO_GPIO(16), /* GPIO14 MTMS */
|
||||
RTCIO_GPIO(13), /* GPIO15 MTDO */
|
||||
RTCIO_NA, /* GPIO16 */
|
||||
RTCIO_NA, /* GPIO17 */
|
||||
RTCIO_NA, /* GPIO18 */
|
||||
RTCIO_NA, /* GPIO19 */
|
||||
RTCIO_NA, /* GPIO20 */
|
||||
RTCIO_NA, /* GPIO21 */
|
||||
RTCIO_NA, /* GPIO22 */
|
||||
RTCIO_NA, /* GPIO23 */
|
||||
RTCIO_NA, /* GPIO24 */
|
||||
RTCIO_GPIO(6), /* GPIO25 */
|
||||
RTCIO_GPIO(7), /* GPIO26 */
|
||||
RTCIO_GPIO(17), /* GPIO27 */
|
||||
RTCIO_NA, /* GPIO28 */
|
||||
RTCIO_NA, /* GPIO29 */
|
||||
RTCIO_NA, /* GPIO30 */
|
||||
RTCIO_NA, /* GPIO31 */
|
||||
RTCIO_GPIO(9), /* GPIO32 32K_XP */
|
||||
RTCIO_GPIO(8), /* GPIO33 32K_XN */
|
||||
RTCIO_GPIO(4), /* GPIO34 VDET_1 */
|
||||
RTCIO_GPIO(5), /* GPIO35 VDET_2 */
|
||||
RTCIO_GPIO(0), /* GPIO36 SENSOR_VP */
|
||||
RTCIO_GPIO(1), /* GPIO37 SENSOR_CAPP */
|
||||
RTCIO_GPIO(2), /* GPIO38 SENSOR_CAPN */
|
||||
RTCIO_GPIO(3), /* GPIO39 SENSOR_VN */
|
||||
};
|
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief ADC controller functions used by ADC and DAC peripherals
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include "adc_ctrl.h"
|
||||
#include "esp_common.h"
|
||||
#include "soc/rtc_io_struct.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief RTC hardware map
|
||||
*
|
||||
* The index corresponds to RTC pin type _rtcio_pin_t (Table 19 in Technical
|
||||
* Reference)
|
||||
*/
|
||||
const struct _adc_hw_t _adc_hw[] =
|
||||
{
|
||||
/* gpio rtc_gpio adc_ctrl adc_channel, pad_name */
|
||||
{ GPIO4, 10, ADC2_CTRL, 0, "GPIO4" }, /* RTCIO_TOUCH0 */
|
||||
{ GPIO0, 11, ADC2_CTRL, 1, "GPIO0" }, /* RTCIO_TOUCH1 */
|
||||
{ GPIO2, 12, ADC2_CTRL, 2, "GPIO2" }, /* RTCIO_TOUCH2 */
|
||||
{ GPIO15, 13, ADC2_CTRL, 3, "MTDO" }, /* RTCIO_TOUCH3 */
|
||||
{ GPIO13, 14, ADC2_CTRL, 4, "MTCK" }, /* RTCIO_TOUCH4 */
|
||||
{ GPIO12, 15, ADC2_CTRL, 5, "MTDI" }, /* RTCIO_TOUCH5 */
|
||||
{ GPIO14, 16, ADC2_CTRL, 6, "MTMS" }, /* RTCIO_TOUCH6 */
|
||||
{ GPIO27, 17, ADC2_CTRL, 7, "GPIO27" }, /* RTCIO_TOUCH7 */
|
||||
{ GPIO33, 8, ADC1_CTRL, 5, "32K_XN" }, /* RTCIO_TOUCH8 */
|
||||
{ GPIO32, 9, ADC1_CTRL, 4, "32K_XP" }, /* RTCIO_TOUCH9 */
|
||||
{ GPIO34, 4, ADC1_CTRL, 6, "VDET_1" }, /* RTCIO_ADC_ADC1 */
|
||||
{ GPIO35, 5, ADC1_CTRL, 7, "VDET_2" }, /* RTCIO_ADC_ADC2 */
|
||||
{ GPIO36, 0, ADC1_CTRL, 0, "SENSOR_VP" }, /* RTCIO_SENSOR_SENSE1 */
|
||||
{ GPIO37, 1, ADC1_CTRL, 1, "SENSOR_CAPP" }, /* RTCIO_SENSOR_SENSE2 */
|
||||
{ GPIO38, 2, ADC1_CTRL, 2, "SENSOR_CAPN" }, /* RTCIO_SENSOR_SENSE3 */
|
||||
{ GPIO39, 3, ADC1_CTRL, 3, "SENSOR_VN" }, /* RTCIO_SENSOR_SENSE4 */
|
||||
{ GPIO25, 6, ADC2_CTRL, 8, "GPIO25" }, /* RTCIO_DAC1 */
|
||||
{ GPIO26, 7, ADC2_CTRL, 9, "GPIO26" } /* RTCIO_DAC2 */
|
||||
};
|
||||
|
||||
/* maps GPIO pin to RTC pin, this index is used to access ADC hardware table
|
||||
(Table 19 in Technical Reference) */
|
||||
const gpio_t _gpio_rtcio_map[] = {
|
||||
RTCIO_TOUCH1, /* GPIO0 */
|
||||
RTCIO_NA , /* GPIO1 */
|
||||
RTCIO_TOUCH2, /* GPIO2 */
|
||||
RTCIO_NA, /* GPIO3 */
|
||||
RTCIO_TOUCH0, /* GPIO4 */
|
||||
RTCIO_NA, /* GPIO5 */
|
||||
RTCIO_NA, /* GPIO6 */
|
||||
RTCIO_NA, /* GPIO7 */
|
||||
RTCIO_NA, /* GPIO8 */
|
||||
RTCIO_NA, /* GPIO9 */
|
||||
RTCIO_NA, /* GPIO10 */
|
||||
RTCIO_NA, /* GPIO11 */
|
||||
RTCIO_TOUCH5, /* GPIO12 MTDI */
|
||||
RTCIO_TOUCH4, /* GPIO13 MTCK */
|
||||
RTCIO_TOUCH6, /* GPIO14 MTMS */
|
||||
RTCIO_TOUCH3, /* GPIO15 MTDO */
|
||||
RTCIO_NA, /* GPIO16 */
|
||||
RTCIO_NA, /* GPIO17 */
|
||||
RTCIO_NA, /* GPIO18 */
|
||||
RTCIO_NA, /* GPIO19 */
|
||||
RTCIO_NA, /* GPIO20 */
|
||||
RTCIO_NA, /* GPIO21 */
|
||||
RTCIO_NA, /* GPIO22 */
|
||||
RTCIO_NA, /* GPIO23 */
|
||||
RTCIO_NA, /* GPIO24 */
|
||||
RTCIO_DAC1, /* GPIO25 */
|
||||
RTCIO_DAC2, /* GPIO26 */
|
||||
RTCIO_TOUCH7, /* GPIO27 */
|
||||
RTCIO_NA, /* GPIO28 */
|
||||
RTCIO_NA, /* GPIO29 */
|
||||
RTCIO_NA, /* GPIO30 */
|
||||
RTCIO_NA, /* GPIO31 */
|
||||
RTCIO_TOUCH9, /* GPIO32 32K_XP */
|
||||
RTCIO_TOUCH8, /* GPIO33 32K_XN */
|
||||
RTCIO_ADC_ADC1, /* GPIO34 VDET_1 */
|
||||
RTCIO_ADC_ADC2, /* GPIO35 VDET_2 */
|
||||
RTCIO_SENSOR_SENSE1, /* GPIO36 SENSOR_VP */
|
||||
RTCIO_SENSOR_SENSE2, /* GPIO37 SENSOR_CAPP */
|
||||
RTCIO_SENSOR_SENSE3, /* GPIO38 SENSOR_CAPN */
|
||||
RTCIO_SENSOR_SENSE4, /* GPIO39 SENSOR_VN */
|
||||
};
|
||||
|
||||
/* flags to indicate whether the according controller is already initialized */
|
||||
static bool _adc1_ctrl_initialized = false;
|
||||
static bool _adc2_ctrl_initialized = false;
|
||||
|
||||
void _adc1_ctrl_init(void)
|
||||
{
|
||||
/* return if already initialized */
|
||||
if (_adc1_ctrl_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* always power on */
|
||||
SENS.sar_meas_wait2.force_xpd_sar = SENS_FORCE_XPD_SAR_PU;
|
||||
|
||||
/* power off LN amp */
|
||||
SENS.sar_meas_wait2.sar2_rstb_wait = 2;
|
||||
SENS.sar_meas_ctrl.amp_rst_fb_fsm = 0;
|
||||
SENS.sar_meas_ctrl.amp_short_ref_fsm = 0;
|
||||
SENS.sar_meas_ctrl.amp_short_ref_gnd_fsm = 0;
|
||||
SENS.sar_meas_wait1.sar_amp_wait1 = 1;
|
||||
SENS.sar_meas_wait1.sar_amp_wait2 = 1;
|
||||
SENS.sar_meas_wait2.sar_amp_wait3 = 1;
|
||||
SENS.sar_meas_wait2.force_xpd_amp = SENS_FORCE_XPD_AMP_PD;
|
||||
|
||||
/* SAR ADC1 controller configuration */
|
||||
SENS.sar_read_ctrl.sar1_dig_force = 0; /* SAR ADC1 controlled by RTC */
|
||||
SENS.sar_meas_start1.meas1_start_force = 1; /* SAR ADC1 started by SW */
|
||||
SENS.sar_meas_start1.sar1_en_pad_force = 1; /* pad enable bitmap controlled by SW */
|
||||
SENS.sar_touch_ctrl1.xpd_hall_force = 1; /* XPD HALL is controlled by SW */
|
||||
SENS.sar_touch_ctrl1.hall_phase_force = 1; /* HALL PHASE is controlled by SW */
|
||||
SENS.sar_read_ctrl.sar1_data_inv = 1; /* invert data */
|
||||
SENS.sar_atten1 = 0xffffffff; /* set attenuation to 11 dB for all pads
|
||||
(input range 0 ... 3,3 V) */
|
||||
/* power off built-in hall sensor */
|
||||
RTCIO.hall_sens.xpd_hall = 0;
|
||||
|
||||
/* set default resolution */
|
||||
SENS.sar_start_force.sar1_bit_width = ADC_RES_12BIT;
|
||||
SENS.sar_read_ctrl.sar1_sample_bit = ADC_RES_12BIT;
|
||||
|
||||
_adc1_ctrl_initialized = true;
|
||||
}
|
||||
|
||||
void _adc2_ctrl_init(void)
|
||||
{
|
||||
/* return if already initialized */
|
||||
if (_adc2_ctrl_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* SAR ADC2 controller configuration */
|
||||
SENS.sar_read_ctrl2.sar2_dig_force = 0; /* SAR ADC2 controlled by RTC not DIG*/
|
||||
SENS.sar_meas_start2.meas2_start_force = 1; /* SAR ADC2 started by SW */
|
||||
SENS.sar_meas_start2.sar2_en_pad_force = 1; /* pad enable bitmap controlled by SW */
|
||||
SENS.sar_read_ctrl2.sar2_data_inv = 1; /* invert data */
|
||||
SENS.sar_atten2 = 0xffffffff; /* set attenuation to 11 dB for all pads
|
||||
(input range 0 ... 3,3 V) */
|
||||
/* set default resolution */
|
||||
SENS.sar_start_force.sar2_bit_width = ADC_RES_12BIT;
|
||||
SENS.sar_read_ctrl2.sar2_sample_bit = ADC_RES_12BIT;
|
||||
|
||||
_adc2_ctrl_initialized = true;
|
||||
}
|
Loading…
Reference in New Issue
Block a user