1 /* 2 * SPDX-FileCopyrightText: 2015-2022 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 "sdkconfig.h" 13 #include "hal/adc_types.h" 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 20 /** 21 * @brief Driver Backgrounds 22 * 23 * -------------------------------------------------------------------------------------------------------- 24 * | Conversion Frame | 25 * -------------------------------------------------------------------------------------------------------- 26 * | Conversion Result | Conversion Result | Conversion Result | Conversion Result | ... | 27 * -------------------------------------------------------------------------------------------------------- 28 * 29 * ADC continuous mode conversion is made up with multiple Conversion Frames. 30 * - Conversion Frame: One Conversion Frame contains multiple Conversion Results. 31 * Conversion Frame size is configured in `adc_continuous_handle_cfg_t:conv_frame_size`, in bytes. 32 * Each time driver see an interrupt event, this means one Conversion Frame is generated by the hardware. 33 * - Conversion Result: One Conversion Result contains multiple bytes (see `SOC_ADC_DIGI_RESULT_BYTES`). Its 34 * structure is `adc_digi_output_data_t`, including ADC Unit, ADC Channel and Raw Data. 35 * 36 * For example: 37 * conv_frame_size = 100, 38 * then one Conversion Frame contains (100 / `SOC_ADC_DIGI_RESULT_BYTES`) pieces of Conversion Results 39 */ 40 41 /** 42 * @brief ADC read max timeout value, it may make the ``adc_continuous_read`` block forever if the OS supports 43 */ 44 #define ADC_MAX_DELAY UINT32_MAX 45 46 /** 47 * @brief Type of adc continuous mode driver handle 48 */ 49 typedef struct adc_continuous_ctx_t *adc_continuous_handle_t; 50 51 /** 52 * @brief ADC continuous mode driver initial configurations 53 */ 54 typedef struct { 55 uint32_t max_store_buf_size; ///< Max length of the conversion Results that driver can store, in bytes. 56 uint32_t conv_frame_size; ///< Conversion frame size, in bytes. This should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`. 57 } adc_continuous_handle_cfg_t; 58 59 /** 60 * @brief ADC continuous mode driver configurations 61 */ 62 typedef struct { 63 uint32_t pattern_num; ///< Number of ADC channels that will be used 64 adc_digi_pattern_config_t *adc_pattern; ///< List of configs for each ADC channel that will be used 65 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*/ 66 adc_digi_convert_mode_t conv_mode; ///< ADC DMA conversion mode, see `adc_digi_convert_mode_t`. 67 adc_digi_output_format_t format; ///< ADC DMA conversion output format, see `adc_digi_output_format_t`. 68 } adc_continuous_config_t; 69 70 /** 71 * @brief Event data structure 72 * @note The `conv_frame_buffer` is maintained by the driver itself, so never free this piece of memory. 73 */ 74 typedef struct { 75 uint8_t *conv_frame_buffer; ///< Pointer to conversion result buffer for one conversion frame 76 uint32_t size; ///< Conversion frame size 77 } adc_continuous_evt_data_t; 78 79 /** 80 * @brief Prototype of ADC continuous mode event callback 81 * 82 * @param[in] handle ADC continuous mode driver handle 83 * @param[in] edata Pointer to ADC contunuous mode event data 84 * @param[in] user_data User registered context, registered when in `adc_continuous_register_event_callbacks()` 85 * 86 * @return Whether a high priority task is woken up by this function 87 */ 88 typedef bool (*adc_continuous_callback_t)(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data); 89 90 /** 91 * @brief Group of ADC continuous mode callbacks 92 * 93 * @note These callbacks are all running in an ISR environment. 94 * @note When CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. 95 * Involved variables should be in internal RAM as well. 96 */ 97 typedef struct { 98 adc_continuous_callback_t on_conv_done; ///< Event callback, invoked when one conversion frame is done. See `@brief Driver Backgrounds` to konw `conversion frame` concept. 99 adc_continuous_callback_t on_pool_ovf; ///< Event callback, invoked when the internal pool is full. 100 } adc_continuous_evt_cbs_t; 101 102 /** 103 * @brief Initialize ADC continuous driver and get a handle to it 104 * 105 * @param[in] hdl_config Pointer to ADC initilization config. Refer to ``adc_continuous_handle_cfg_t``. 106 * @param[out] ret_handle ADC continuous mode driver handle 107 * 108 * @return 109 * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. 110 * - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags 111 * - ESP_ERR_NO_MEM If out of memory 112 * - ESP_OK On success 113 */ 114 esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_config, adc_continuous_handle_t *ret_handle); 115 116 /** 117 * @brief Set ADC continuous mode required configurations 118 * 119 * @param[in] handle ADC continuous mode driver handle 120 * @param[in] config Refer to ``adc_digi_config_t``. 121 * 122 * @return 123 * - ESP_ERR_INVALID_STATE: Driver state is invalid, you shouldn't call this API at this moment 124 * - ESP_ERR_INVALID_ARG: If the combination of arguments is invalid. 125 * - ESP_OK: On success 126 */ 127 esp_err_t adc_continuous_config(adc_continuous_handle_t handle, const adc_continuous_config_t *config); 128 129 /** 130 * @brief Register callbacks 131 * 132 * @note User can deregister a previously registered callback by calling this function and setting the to-be-deregistered callback member in 133 * the `cbs` structure to NULL. 134 * @note When CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. 135 * Involved variables (including `user_data`) should be in internal RAM as well. 136 * @note You should only call this API when the ADC continuous mode driver isn't started. Check return value to know this. 137 * 138 * @param[in] handle ADC continuous mode driver handle 139 * @param[in] cbs Group of callback functions 140 * @param[in] user_data User data, which will be delivered to the callback functions directly 141 * 142 * @return 143 * - ESP_OK: On success 144 * - ESP_ERR_INVALID_ARG: Invalid arguments 145 * - ESP_ERR_INVALID_STATE: Driver state is invalid, you shouldn't call this API at this moment 146 */ 147 esp_err_t adc_continuous_register_event_callbacks(adc_continuous_handle_t handle, const adc_continuous_evt_cbs_t *cbs, void *user_data); 148 149 /** 150 * @brief Start the ADC under continuous mode. After this, the hardware starts working. 151 * 152 * @param[in] handle ADC continuous mode driver handle 153 * 154 * @return 155 * - ESP_ERR_INVALID_STATE Driver state is invalid. 156 * - ESP_OK On success 157 */ 158 esp_err_t adc_continuous_start(adc_continuous_handle_t handle); 159 160 /** 161 * @brief Read bytes from ADC under continuous mode. 162 * 163 * @param[in] handle ADC continuous mode driver handle 164 * @param[out] buf Conversion result buffer to read from ADC. Suggest convert to `adc_digi_output_data_t` for `ADC Conversion Results`. 165 * See `@brief Driver Backgrounds` to know this concept. 166 * @param[in] length_max Expected length of the Conversion Results read from the ADC, in bytes. 167 * @param[out] out_length Real length of the Conversion Results read from the ADC via this API, in bytes. 168 * @param[in] timeout_ms Time to wait for data via this API, in millisecond. 169 * 170 * @return 171 * - ESP_ERR_INVALID_STATE Driver state is invalid. Usually it means the ADC sampling rate is faster than the task processing rate. 172 * - ESP_ERR_TIMEOUT Operation timed out 173 * - ESP_OK On success 174 */ 175 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); 176 177 /** 178 * @brief Stop the ADC. After this, the hardware stops working. 179 * 180 * @param[in] handle ADC continuous mode driver handle 181 * 182 * @return 183 * - ESP_ERR_INVALID_STATE Driver state is invalid. 184 * - ESP_OK On success 185 */ 186 esp_err_t adc_continuous_stop(adc_continuous_handle_t handle); 187 188 /** 189 * @brief Deinitialize the ADC continuous driver. 190 * 191 * @param[in] handle ADC continuous mode driver handle 192 * 193 * @return 194 * - ESP_ERR_INVALID_STATE Driver state is invalid. 195 * - ESP_OK On success 196 */ 197 esp_err_t adc_continuous_deinit(adc_continuous_handle_t handle); 198 199 /** 200 * @brief Get ADC channel from the given GPIO number 201 * 202 * @param[in] io_num GPIO number 203 * @param[out] unit_id ADC unit 204 * @param[out] channel ADC channel 205 * 206 * @return 207 * - ESP_OK: On success 208 * - ESP_ERR_INVALID_ARG: Invalid argument 209 * - ESP_ERR_NOT_FOUND: The IO is not a valid ADC pad 210 */ 211 esp_err_t adc_continuous_io_to_channel(int io_num, adc_unit_t *unit_id, adc_channel_t *channel); 212 213 /** 214 * @brief Get GPIO number from the given ADC channel 215 * 216 * @param[in] unit_id ADC unit 217 * @param[in] channel ADC channel 218 * @param[out] io_num GPIO number 219 * 220 * @param 221 * - ESP_OK: On success 222 * - ESP_ERR_INVALID_ARG: Invalid argument 223 */ 224 esp_err_t adc_continuous_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int *io_num); 225 226 227 #ifdef __cplusplus 228 } 229 #endif 230