2022-07-15 12:52:44 +08:00
/*
2023-08-08 20:45:00 +08:00
* SPDX - FileCopyrightText : 2015 - 2023 Espressif Systems ( Shanghai ) CO LTD
2022-07-15 12:52:44 +08:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
# pragma once
# include <stdint.h>
# include <stdbool.h>
# include "esp_err.h"
# include "sdkconfig.h"
# include "hal/adc_types.h"
# ifdef __cplusplus
extern " C " {
# endif
2023-07-31 10:59:34 +08:00
/*
* Driver Backgrounds
2022-07-15 12:52:44 +08:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | Conversion Frame |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* | Conversion Result | Conversion Result | Conversion Result | Conversion Result | . . . |
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* ADC continuous mode conversion is made up with multiple Conversion Frames .
* - Conversion Frame : One Conversion Frame contains multiple Conversion Results .
* Conversion Frame size is configured in ` adc_continuous_handle_cfg_t : conv_frame_size ` , in bytes .
* Each time driver see an interrupt event , this means one Conversion Frame is generated by the hardware .
* - Conversion Result : One Conversion Result contains multiple bytes ( see ` SOC_ADC_DIGI_RESULT_BYTES ` ) . Its
* structure is ` adc_digi_output_data_t ` , including ADC Unit , ADC Channel and Raw Data .
*
* For example :
2023-07-31 10:59:34 +08:00
* conv_frame_size = 100 indicates one Conversion Frame contains ( 100 / ` SOC_ADC_DIGI_RESULT_BYTES ` ) pieces of Conversion Results .
2022-07-15 12:52:44 +08:00
*/
/**
* @ brief ADC read max timeout value , it may make the ` ` adc_continuous_read ` ` block forever if the OS supports
*/
# define ADC_MAX_DELAY UINT32_MAX
/**
* @ brief Type of adc continuous mode driver handle
*/
typedef struct adc_continuous_ctx_t * adc_continuous_handle_t ;
/**
* @ brief ADC continuous mode driver initial configurations
*/
typedef struct {
2023-08-07 14:37:24 +08:00
uint32_t max_store_buf_size ; ///< Max length of the conversion results that driver can store, in bytes.
2022-07-15 12:52:44 +08:00
uint32_t conv_frame_size ; ///< Conversion frame size, in bytes. This should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`.
2023-05-23 16:11:26 +08:00
struct {
uint32_t flush_pool : 1 ; ///< Flush the internal pool when the pool is full.
} flags ; ///< Driver flags
2022-07-15 12:52:44 +08:00
} adc_continuous_handle_cfg_t ;
/**
* @ brief ADC continuous mode driver configurations
*/
typedef struct {
uint32_t pattern_num ; ///< Number of ADC channels that will be used
adc_digi_pattern_config_t * adc_pattern ; ///< List of configs for each ADC channel that will be used
uint32_t sample_freq_hz ; /*!< The expected ADC sampling frequency in Hz. Please refer to `soc/soc_caps.h` to know available sampling frequency range*/
adc_digi_convert_mode_t conv_mode ; ///< ADC DMA conversion mode, see `adc_digi_convert_mode_t`.
adc_digi_output_format_t format ; ///< ADC DMA conversion output format, see `adc_digi_output_format_t`.
} adc_continuous_config_t ;
/**
* @ brief Event data structure
* @ note The ` conv_frame_buffer ` is maintained by the driver itself , so never free this piece of memory .
*/
typedef struct {
uint8_t * conv_frame_buffer ; ///< Pointer to conversion result buffer for one conversion frame
uint32_t size ; ///< Conversion frame size
} adc_continuous_evt_data_t ;
/**
* @ brief Prototype of ADC continuous mode event callback
*
* @ param [ in ] handle ADC continuous mode driver handle
2023-08-07 14:37:24 +08:00
* @ param [ in ] edata Pointer to ADC continuous mode event data
2022-07-15 12:52:44 +08:00
* @ param [ in ] user_data User registered context , registered when in ` adc_continuous_register_event_callbacks ( ) `
*
* @ return Whether a high priority task is woken up by this function
*/
typedef bool ( * adc_continuous_callback_t ) ( adc_continuous_handle_t handle , const adc_continuous_evt_data_t * edata , void * user_data ) ;
/**
* @ brief Group of ADC continuous mode callbacks
*
* @ note These callbacks are all running in an ISR environment .
* @ note When CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is enabled , the callback itself and functions called by it should be placed in IRAM .
* Involved variables should be in internal RAM as well .
*/
typedef struct {
2023-08-07 14:37:24 +08:00
adc_continuous_callback_t on_conv_done ; ///< Event callback, invoked when one conversion frame is done. See the subsection `Driver Backgrounds` in this header file to learn about the `conversion frame` concept.
2022-07-15 12:52:44 +08:00
adc_continuous_callback_t on_pool_ovf ; ///< Event callback, invoked when the internal pool is full.
} adc_continuous_evt_cbs_t ;
/**
* @ brief Initialize ADC continuous driver and get a handle to it
*
* @ param [ in ] hdl_config Pointer to ADC initilization config . Refer to ` ` adc_continuous_handle_cfg_t ` ` .
* @ param [ out ] ret_handle ADC continuous mode driver handle
*
* @ return
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid .
* - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags
* - ESP_ERR_NO_MEM If out of memory
* - ESP_OK On success
*/
esp_err_t adc_continuous_new_handle ( const adc_continuous_handle_cfg_t * hdl_config , adc_continuous_handle_t * ret_handle ) ;
/**
* @ brief Set ADC continuous mode required configurations
*
* @ param [ in ] handle ADC continuous mode driver handle
* @ param [ in ] config Refer to ` ` adc_digi_config_t ` ` .
*
* @ return
* - ESP_ERR_INVALID_STATE : Driver state is invalid , you shouldn ' t call this API at this moment
* - ESP_ERR_INVALID_ARG : If the combination of arguments is invalid .
* - ESP_OK : On success
*/
esp_err_t adc_continuous_config ( adc_continuous_handle_t handle , const adc_continuous_config_t * config ) ;
/**
* @ brief Register callbacks
*
2023-02-07 16:01:26 +08:00
* @ note User can deregister a previously registered callback by calling this function and setting the to - be - deregistered callback member in
2022-07-15 12:52:44 +08:00
* the ` cbs ` structure to NULL .
* @ note When CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is enabled , the callback itself and functions called by it should be placed in IRAM .
* Involved variables ( including ` user_data ` ) should be in internal RAM as well .
* @ note You should only call this API when the ADC continuous mode driver isn ' t started . Check return value to know this .
*
* @ param [ in ] handle ADC continuous mode driver handle
* @ param [ in ] cbs Group of callback functions
* @ param [ in ] user_data User data , which will be delivered to the callback functions directly
*
* @ return
* - ESP_OK : On success
* - ESP_ERR_INVALID_ARG : Invalid arguments
* - ESP_ERR_INVALID_STATE : Driver state is invalid , you shouldn ' t call this API at this moment
*/
esp_err_t adc_continuous_register_event_callbacks ( adc_continuous_handle_t handle , const adc_continuous_evt_cbs_t * cbs , void * user_data ) ;
/**
* @ brief Start the ADC under continuous mode . After this , the hardware starts working .
*
* @ param [ in ] handle ADC continuous mode driver handle
*
* @ return
* - ESP_ERR_INVALID_STATE Driver state is invalid .
* - ESP_OK On success
*/
esp_err_t adc_continuous_start ( adc_continuous_handle_t handle ) ;
/**
* @ brief Read bytes from ADC under continuous mode .
*
* @ param [ in ] handle ADC continuous mode driver handle
* @ param [ out ] buf Conversion result buffer to read from ADC . Suggest convert to ` adc_digi_output_data_t ` for ` ADC Conversion Results ` .
2023-08-07 14:37:24 +08:00
* See the subsection ` Driver Backgrounds ` in this header file to learn about this concept .
2022-07-15 12:52:44 +08:00
* @ param [ in ] length_max Expected length of the Conversion Results read from the ADC , in bytes .
* @ param [ out ] out_length Real length of the Conversion Results read from the ADC via this API , in bytes .
* @ param [ in ] timeout_ms Time to wait for data via this API , in millisecond .
*
* @ return
* - ESP_ERR_INVALID_STATE Driver state is invalid . Usually it means the ADC sampling rate is faster than the task processing rate .
* - ESP_ERR_TIMEOUT Operation timed out
* - ESP_OK On success
*/
esp_err_t adc_continuous_read ( adc_continuous_handle_t handle , uint8_t * buf , uint32_t length_max , uint32_t * out_length , uint32_t timeout_ms ) ;
/**
* @ brief Stop the ADC . After this , the hardware stops working .
*
* @ param [ in ] handle ADC continuous mode driver handle
*
* @ return
* - ESP_ERR_INVALID_STATE Driver state is invalid .
* - ESP_OK On success
*/
esp_err_t adc_continuous_stop ( adc_continuous_handle_t handle ) ;
/**
* @ brief Deinitialize the ADC continuous driver .
*
* @ param [ in ] handle ADC continuous mode driver handle
*
* @ return
* - ESP_ERR_INVALID_STATE Driver state is invalid .
* - ESP_OK On success
*/
esp_err_t adc_continuous_deinit ( adc_continuous_handle_t handle ) ;
2023-08-08 20:45:00 +08:00
/**
* @ brief Flush the driver internal pool
*
* @ note This API is not supposed to be called in an ISR context
*
* @ param [ in ] handle ADC continuous mode driver handle
*
* @ return
* - ESP_ERR_INVALID_STATE Driver state is invalid , you should call this API when it ' s in init state
* - ESP_ERR_INVALID_ARG : Invalid arguments
* - ESP_OK On success
*/
esp_err_t adc_continuous_flush_pool ( adc_continuous_handle_t handle ) ;
2022-07-15 12:52:44 +08:00
/**
* @ brief Get ADC channel from the given GPIO number
*
* @ param [ in ] io_num GPIO number
* @ param [ out ] unit_id ADC unit
* @ param [ out ] channel ADC channel
*
* @ return
* - ESP_OK : On success
* - ESP_ERR_INVALID_ARG : Invalid argument
* - ESP_ERR_NOT_FOUND : The IO is not a valid ADC pad
*/
2023-07-10 14:29:31 +08:00
esp_err_t adc_continuous_io_to_channel ( int io_num , adc_unit_t * const unit_id , adc_channel_t * const channel ) ;
2022-07-15 12:52:44 +08:00
/**
* @ brief Get GPIO number from the given ADC channel
*
* @ param [ in ] unit_id ADC unit
* @ param [ in ] channel ADC channel
* @ param [ out ] io_num GPIO number
*
* @ param
* - ESP_OK : On success
* - ESP_ERR_INVALID_ARG : Invalid argument
*/
2023-07-10 14:29:31 +08:00
esp_err_t adc_continuous_channel_to_io ( adc_unit_t unit_id , adc_channel_t channel , int * const io_num ) ;
2022-07-15 12:52:44 +08:00
# ifdef __cplusplus
}
# endif