/* * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include "esp_err.h" #include "soc/soc_caps.h" #include "hal/dma_types.h" #include "hal/adc_types.h" #include "hal/adc_ll.h" #include "hal/adc_hal_common.h" #include "esp_err.h" #if SOC_GDMA_SUPPORTED #include "soc/gdma_struct.h" #include "hal/gdma_ll.h" #endif #if CONFIG_IDF_TARGET_ESP32S2 //ADC utilises SPI3 DMA on ESP32S2 #include "hal/spi_ll.h" #endif #if CONFIG_IDF_TARGET_ESP32 //ADC utilises I2S0 DMA on ESP32 #include "hal/i2s_ll.h" #endif #ifdef __cplusplus extern "C" { #endif #if SOC_GDMA_SUPPORTED #define ADC_HAL_DMA_INTR_MASK GDMA_LL_EVENT_RX_SUC_EOF #elif CONFIG_IDF_TARGET_ESP32S2 #define ADC_HAL_DMA_INTR_MASK SPI_LL_INTR_IN_SUC_EOF #else //CONFIG_IDF_TARGET_ESP32 #define ADC_HAL_DMA_INTR_MASK BIT(9) #endif /** * @brief Enum for DMA descriptor status */ typedef enum adc_hal_dma_desc_status_t { ADC_HAL_DMA_DESC_VALID = 0, ///< This DMA descriptor is written by HW already ADC_HAL_DMA_DESC_WAITING = 1, ///< This DMA descriptor is not written by HW yet ADC_HAL_DMA_DESC_NULL = 2 ///< This DMA descriptor is NULL } adc_hal_dma_desc_status_t; /** * @brief Configuration of the HAL */ typedef struct adc_hal_dma_config_t { void *dev; ///< DMA peripheral address uint32_t desc_max_num; ///< Number of the descriptors linked once uint32_t dma_chan; ///< DMA channel to be used uint32_t eof_num; ///< Bytes between 2 in_suc_eof interrupts } adc_hal_dma_config_t; /** * @brief Context of the HAL */ typedef struct adc_hal_dma_ctx_t { /**< this needs to be malloced by the driver layer first */ dma_descriptor_t *rx_desc; ///< DMA descriptors /**< these will be assigned by hal layer itself */ dma_descriptor_t desc_dummy_head; ///< Dummy DMA descriptor for ``cur_desc_ptr`` to start dma_descriptor_t *cur_desc_ptr; ///< Pointer to the current descriptor /**< these need to be configured by `adc_hal_dma_config_t` via driver layer*/ void *dev; ///< DMA address uint32_t desc_max_num; ///< Number of the descriptors linked once uint32_t dma_chan; ///< DMA channel to be used uint32_t eof_num; ///< Words between 2 in_suc_eof interrupts } adc_hal_dma_ctx_t; typedef struct adc_hal_digi_ctrlr_cfg_t { uint32_t adc_pattern_len; //total pattern item number, including ADC1 and ADC2 adc_digi_pattern_config_t *adc_pattern; //pattern item uint32_t sample_freq_hz; //ADC sample frequency adc_digi_convert_mode_t conv_mode; //controller work mode uint32_t bit_width; //output data width } adc_hal_digi_ctrlr_cfg_t; /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ /** * Set ADC module power management. * * @prarm manage Set ADC power status. */ #define adc_hal_set_power_manage(manage) adc_ll_set_power_manage(manage) /*--------------------------------------------------------------- PWDET(Power detect) controller setting ---------------------------------------------------------------*/ /** * Set adc cct for PWDET controller. * * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. * @prarm cct Range: 0 ~ 7. */ #define adc_hal_pwdet_set_cct(cct) adc_ll_pwdet_set_cct(cct) /** * Get adc cct for PWDET controller. * * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. * @return cct Range: 0 ~ 7. */ #define adc_hal_pwdet_get_cct() adc_ll_pwdet_get_cct() /** * Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels. * * This function routes the internal reference voltage of ADCn to one of * ADC2's channels. This reference voltage can then be manually measured * for calibration purposes. * * @note ESP32 only supports output of ADC2's internal reference voltage. * @param[in] adc ADC unit select * @param[in] channel ADC2 channel number * @param[in] en Enable/disable the reference voltage output */ #define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en) /*--------------------------------------------------------------- Digital controller setting ---------------------------------------------------------------*/ /** * @brief Initialize the HW * * @param hal Context of the HAL */ void adc_hal_digi_init(adc_hal_dma_ctx_t *hal); /** * Digital controller deinitialization. * * @param hal Context of the HAL */ void adc_hal_digi_deinit(adc_hal_dma_ctx_t *hal); /** * @brief Initialize the hal context * * @param hal Context of the HAL * @param config Configuration of the HAL */ void adc_hal_dma_ctx_config(adc_hal_dma_ctx_t *hal, const adc_hal_dma_config_t *config); /** * Setting the digital controller. * * @param hal Context of the HAL * @param cfg Pointer to digital controller paramter. */ void adc_hal_digi_controller_config(adc_hal_dma_ctx_t *hal, const adc_hal_digi_ctrlr_cfg_t *cfg); /** * @brief Start Conversion * * @param hal Context of the HAL * @param data_buf Pointer to the data buffer, the length should be multiple of ``desc_max_num`` and ``eof_num`` in ``adc_hal_dma_ctx_t`` */ void adc_hal_digi_start(adc_hal_dma_ctx_t *hal, uint8_t *data_buf); #if !SOC_GDMA_SUPPORTED /** * @brief Get the DMA descriptor that Hardware has finished processing. * * @param hal Context of the HAL * * @return DMA descriptor address */ intptr_t adc_hal_get_desc_addr(adc_hal_dma_ctx_t *hal); /** * @brief Check the hardware interrupt event * * @param hal Context of the HAL * @param mask Event mask * * @return True: the event is triggered. False: the event is not triggered yet. */ bool adc_hal_check_event(adc_hal_dma_ctx_t *hal, uint32_t mask); #endif /** * @brief Get the ADC reading result * * @param hal Context of the HAL * @param eof_desc_addr The last descriptor that is finished by HW. Should be got from DMA * @param[out] cur_desc The descriptor with ADC reading result (from the 1st one to the last one (``eof_desc_addr``)) * * @return See ``adc_hal_dma_desc_status_t`` */ adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_dma_ctx_t *hal, const intptr_t eof_desc_addr, dma_descriptor_t **cur_desc); /** * @brief Clear interrupt * * @param hal Context of the HAL * @param mask mask of the interrupt */ void adc_hal_digi_clr_intr(adc_hal_dma_ctx_t *hal, uint32_t mask); /** * @brief Enable interrupt * * @param hal Context of the HAL * @param mask mask of the interrupt */ void adc_hal_digi_dis_intr(adc_hal_dma_ctx_t *hal, uint32_t mask); /** * @brief Stop conversion * * @param hal Context of the HAL */ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal); #ifdef __cplusplus } #endif