1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include "esp_err.h"
12 #include "hal/adc_types.h"
13 #include "adc_cali.h"
14 #include "adc_cali_scheme.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 /**
21  * @brief Type of ADC unit handle for oneshot mode
22  */
23 typedef struct adc_oneshot_unit_ctx_t *adc_oneshot_unit_handle_t;
24 
25 /**
26  * @brief ADC oneshot driver initial configurations
27  */
28 typedef struct {
29     adc_unit_t unit_id;             ///< ADC unit
30     adc_oneshot_clk_src_t clk_src;  ///< Clock source
31     adc_ulp_mode_t ulp_mode;        ///< ADC controlled by ULP, see `adc_ulp_mode_t`
32 } adc_oneshot_unit_init_cfg_t;
33 
34 /**
35  * @brief ADC channel configurations
36  */
37 typedef struct {
38     adc_atten_t atten;              ///< ADC attenuation
39     adc_bitwidth_t bitwidth;        ///< ADC conversion result bits
40 } adc_oneshot_chan_cfg_t;
41 
42 /**
43  * @brief Create a handle to a specific ADC unit
44  *
45  * @note This API is thread-safe. For more details, see ADC programming guide
46  *
47  * @param[in]  init_config    Driver initial configurations
48  * @param[out] ret_unit       ADC unit handle
49  *
50  * @return
51  *        - ESP_OK:              On success
52  *        - ESP_ERR_INVALID_ARG: Invalid arguments
53  *        - ESP_ERR_NO_MEM:      No memory
54  *        - ESP_ERR_NOT_FOUND:   The ADC peripheral to be claimed is already in use
55  *        - ESP_FAIL:            Clock source isn't initialised correctly
56  */
57 esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, adc_oneshot_unit_handle_t *ret_unit);
58 
59 /**
60  * @brief Set ADC oneshot mode required configurations
61  *
62  * @note This API is thread-safe. For more details, see ADC programming guide
63  *
64  * @param[in] handle    ADC handle
65  * @param[in] channel   ADC channel to be configured
66  * @param[in] config    ADC configurations
67  *
68  * @return
69  *        - ESP_OK:              On success
70  *        - ESP_ERR_INVALID_ARG: Invalid arguments
71  */
72 esp_err_t adc_oneshot_config_channel(adc_oneshot_unit_handle_t handle, adc_channel_t channel, const adc_oneshot_chan_cfg_t *config);
73 
74 /**
75  * @brief Get one ADC conversion raw result
76  *
77  * @note This API is thread-safe. For more details, see ADC programming guide
78  * @note This API should NOT be called in an ISR context
79  *
80  * @param[in] handle    ADC handle
81  * @param[in] chan      ADC channel
82  * @param[out] out_raw  ADC conversion raw result
83  *
84  * @return
85  *        - ESP_OK:                On success
86  *        - ESP_ERR_INVALID_ARG:   Invalid arguments
87  *        - ESP_ERR_TIMEOUT:       Timeout, the ADC result is invalid
88  */
89 esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, int *out_raw);
90 
91 /**
92  * @brief Delete the ADC unit handle
93  *
94  * @note This API is thread-safe. For more details, see ADC programming guide
95  *
96  * @param[in] handle    ADC handle
97  *
98  * @return
99  *        - ESP_OK:              On success
100  *        - ESP_ERR_INVALID_ARG: Invalid arguments
101  *        - ESP_ERR_NOT_FOUND:   The ADC peripheral to be disclaimed isn't in use
102  */
103 esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle);
104 
105 /**
106  * @brief Get ADC channel from the given GPIO number
107  *
108  * @param[in]  io_num     GPIO number
109  * @param[out] unit_id    ADC unit
110  * @param[out] channel    ADC channel
111  *
112  * @return
113  *        - ESP_OK:              On success
114  *        - ESP_ERR_INVALID_ARG: Invalid argument
115  *        - ESP_ERR_NOT_FOUND:   The IO is not a valid ADC pad
116  */
117 esp_err_t adc_oneshot_io_to_channel(int io_num, adc_unit_t *unit_id, adc_channel_t *channel);
118 
119 /**
120  * @brief Get GPIO number from the given ADC channel
121  *
122  * @param[in]  unit_id    ADC unit
123  * @param[in]  channel    ADC channel
124  * @param[out] io_num     GPIO number
125  *
126  * @param
127  *       - ESP_OK:              On success
128  *       - ESP_ERR_INVALID_ARG: Invalid argument
129  */
130 esp_err_t adc_oneshot_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int *io_num);
131 
132 /**
133  * @brief Convenience function to get ADC calibrated result
134  *
135  * This is an all-in-one function which does:
136  * - oneshot read ADC raw result
137  * - calibrate the raw result and convert it into calibrated result (in mV)
138  *
139  * @param[in]  handle       ADC oneshot handle, you should call adc_oneshot_new_unit() to get this handle
140  * @param[in]  cali_handle  ADC calibration handle, you should call adc_cali_create_scheme_x() in adc_cali_scheme.h to create a handle
141  * @param[in]  chan         ADC channel
142  * @param[out] cali_result  Calibrated ADC result (in mV)
143  *
144  * @return
145  *        - ESP_OK
146  *        Other return errors from adc_oneshot_read() and adc_cali_raw_to_voltage()
147  */
148 esp_err_t adc_oneshot_get_calibrated_result(adc_oneshot_unit_handle_t handle, adc_cali_handle_t cali_handle, adc_channel_t chan, int *cali_result);
149 
150 #ifdef __cplusplus
151 }
152 #endif
153