1 /*
2  * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * ADC is shared by multiple components, including:
9  * - esp_phy
10  * - esp_wifi
11  * - driver
12  *
13  * However, usages of above components are different.
14  * Therefore, we put the common used parts into `esp_hw_support`, including:
15  * - adc power maintainance
16  * - adc hw calibration settings
17  * - adc locks, to prevent concurrently using adc hw
18  */
19 
20 #pragma once
21 #include "esp_err.h"
22 #include "hal/adc_types.h"
23 #include "soc/soc_caps.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #if SOC_ADC_CALIBRATION_V1_SUPPORTED
30 /*---------------------------------------------------------------
31             ADC Hardware Calibration
32 ---------------------------------------------------------------*/
33 /**
34  * @brief Calculate the ADC HW calibration code. (Based on the pre-stored efuse or actual calibration)
35  *
36  * @param adc_n ADC unit to calibrate
37  * @param atten Attenuation to use
38  */
39 void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten);
40 
41 /**
42  * @brief Set the ADC HW calibration code.
43  *
44  * @param adc_n ADC unit to calibrate
45  * @param atten Attenuation to use
46  */
47 void adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten);
48 
49 #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED
50 /**
51  * @brief Load the channel compensation of the ADC HW calibration from eFuse to a static array
52  *
53  * @param adc_n ADC unit to compensation
54  * @param chan  ADC channel to compensation
55  * @param atten Attenuation to use
56  */
57 void adc_load_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten);
58 
59 /**
60  * @brief Get the channel compensation of the ADC HW calibration from the static array
61  *        that have been loaded from eFuse
62  *
63  * @param adc_n ADC unit to compensation
64  * @param chan  ADC channel to compensation
65  * @param atten Attenuation to use
66  * @return The channel compensation
67  */
68 int adc_get_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten);
69 #endif  // SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED
70 #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED
71 
72 
73 /*---------------------------------------------------------------
74             ADC Cross Peripheral Locks
75 ---------------------------------------------------------------*/
76 /**
77  * @brief Acquire ADC lock by unit
78  *
79  * The lock acquiring sequence will be: ADC1, ADC2, ...
80  *
81  * @note If any of the locks are taken, this API will wait until the lock is successfully acquired.
82  *
83  * @param[in] adc_unit    ADC unit ID
84  *
85  * @return
86  *        - ESP_OK: On success
87  */
88 esp_err_t adc_lock_acquire(adc_unit_t adc_unit);
89 
90 /**
91  * @brief Release ADC lock by unit
92  *
93  * The lock releasing sequence will be: ..., ADC2, ADC1
94  *
95  * @param[in] adc_unit    ADC unit ID
96  *
97  * @return
98  *        - ESP_OK:                On success
99  *        - ESP_ERR_INVALID_STATE: The lock(s) isn't acquired yet
100  */
101 esp_err_t adc_lock_release(adc_unit_t adc_unit);
102 
103 /**
104  * @brief Try to acquire ADC lock by unit
105  *
106  * The lock acquiring sequence will be: ADC1, ADC2, ...
107  *
108  * @note If any of the locks are taken, this API will return immediately with an error `ESP_ERR_TIMEOUT`
109  *
110  * @param[in] adc_unit    ADC unit ID
111  *
112  * @return
113  *        - ESP_OK:          On success
114  *        - ESP_ERR_TIMEOUT: Lock(s) is taken already
115  */
116 esp_err_t adc_lock_try_acquire(adc_unit_t adc_unit);
117 
118 /**
119  * @brief For WIFI module to claim the usage of ADC2.
120  *
121  * Other tasks will be forbidden to use ADC2 between ``adc2_wifi_acquire`` and ``adc2_wifi_release``.
122  * The WIFI module may have to wait for a short time for the current conversion (if exist) to finish.
123  *
124  * @return
125  *        - ESP_OK success
126  *        - ESP_ERR_TIMEOUT reserved for future use. Currently the function will wait until success.
127  */
128 esp_err_t adc2_wifi_acquire(void);
129 
130 /**
131  * @brief For WIFI module to let other tasks use the ADC2 when WIFI is not work.
132  *
133  * Other tasks will be forbidden to use ADC2 between ``adc2_wifi_acquire`` and ``adc2_wifi_release``.
134  * Call this function to release the occupation of ADC2 by WIFI.
135  *
136  * @return
137  *        - ESP_OK:                On success
138  *        - ESP_ERR_INVALID_STATE: The lock(s) isn't acquired yet
139  */
140 esp_err_t adc2_wifi_release(void);
141 
142 
143 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
144 /**
145  * @brief This API help ADC2 calibration constructor be linked.
146  *
147  * @note  This is a private function, Don't call `adc2_cal_include` in user code.
148  */
149 void adc2_cal_include(void);
150 
151 /**
152  * @brief Set initial code to ADC2 after calibration. ADC2 RTC and ADC2 PWDET controller share the initial code.
153  *        This API be called in before `app_main()`.
154  */
155 void adc2_init_code_calibration(void);
156 #else
157 /**
158  * @brief There's no calibration involved on this chip.
159  *
160  * @note  This is a private function, Don't call `adc2_cal_include` in user code.
161  */
162 #define adc2_cal_include()
163 #endif //CONFIG_IDF_TARGET_*
164 
165 /*------------------------------------------------------------------------------
166 * For those who use APB_SARADC periph
167 *----------------------------------------------------------------------------*/
168 /**
169  * @brief Claim the usage of the APB_SARADC periph
170  *
171  * Reference count inside
172  */
173 void adc_apb_periph_claim(void);
174 
175 /**
176  * @brief Free the usage of the APB_SARADC periph
177  *
178  * Reference count inside
179  */
180 void adc_apb_periph_free(void);
181 
182 
183 #ifdef __cplusplus
184 }
185 #endif
186