| 
									
										
										
										
											2021-05-24 02:02:15 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: Apache-2.0 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-21 13:07:34 +08:00
										 |  |  | #include "sdkconfig.h"
 | 
					
						
							|  |  |  | #include "esp_types.h"
 | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  | #include "esp_log.h"
 | 
					
						
							|  |  |  | #include "sys/lock.h"
 | 
					
						
							|  |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "hal/adc_types.h"
 | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  | #include "hal/adc_ll.h"
 | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
 | 
					
						
							|  |  |  | #define ADC_ENTER_CRITICAL()  portENTER_CRITICAL(&rtc_spinlock)
 | 
					
						
							|  |  |  | #define ADC_EXIT_CRITICAL()  portEXIT_CRITICAL(&rtc_spinlock)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |  * Config monitor of adc digital controller. | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |  * @note The monitor will monitor all the enabled channel data of the each ADC unit at the same time. | 
					
						
							|  |  |  |  * @param adc_n ADC unit. | 
					
						
							|  |  |  |  * @param config Refer to ``adc_digi_monitor_t``. | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  | static void adc_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config) | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |     adc_ll_digi_monitor_set_mode(adc_n, config->mode); | 
					
						
							|  |  |  |     adc_ll_digi_monitor_set_thres(adc_n, config->threshold); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*************************************/ | 
					
						
							|  |  |  | /* Digital controller filter setting */ | 
					
						
							|  |  |  | /*************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADC_ENTER_CRITICAL(); | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_FILTER_IDX0) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_reset(ADC_NUM_1); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_FILTER_IDX1) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_reset(ADC_NUM_2); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ADC_EXIT_CRITICAL(); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADC_ENTER_CRITICAL(); | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_FILTER_IDX0) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_set_factor(ADC_NUM_1, config->mode); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_FILTER_IDX1) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_set_factor(ADC_NUM_2, config->mode); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ADC_EXIT_CRITICAL(); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADC_ENTER_CRITICAL(); | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_FILTER_IDX0) { | 
					
						
							|  |  |  |         config->adc_unit = ADC_UNIT_1; | 
					
						
							|  |  |  |         config->channel = ADC_CHANNEL_MAX; | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_get_factor(ADC_NUM_1, &config->mode); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_FILTER_IDX1) { | 
					
						
							|  |  |  |         config->adc_unit = ADC_UNIT_2; | 
					
						
							|  |  |  |         config->channel = ADC_CHANNEL_MAX; | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_get_factor(ADC_NUM_2, &config->mode); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ADC_EXIT_CRITICAL(); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADC_ENTER_CRITICAL(); | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_FILTER_IDX0) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_enable(ADC_NUM_1, enable); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_FILTER_IDX1) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_filter_enable(ADC_NUM_2, enable); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ADC_EXIT_CRITICAL(); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief Get the filtered data of adc digital controller filter. For debug. | 
					
						
							|  |  |  |  *        The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @note For ESP32S2, The filter will filter all the enabled channel data of the each ADC unit at the same time. | 
					
						
							|  |  |  |  * @param idx Filter index. | 
					
						
							|  |  |  |  * @return Filtered data. if <0, the read data invalid. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int adc_digi_filter_read_data(adc_digi_filter_idx_t idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_FILTER_IDX0) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         return adc_ll_digi_filter_read_data(ADC_NUM_1); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_FILTER_IDX1) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         return adc_ll_digi_filter_read_data(ADC_NUM_2); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************/ | 
					
						
							|  |  |  | /* Digital controller monitor setting */ | 
					
						
							|  |  |  | /**************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADC_ENTER_CRITICAL(); | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_MONITOR_IDX0) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_digi_monitor_config(ADC_NUM_1, config); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_MONITOR_IDX1) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_digi_monitor_config(ADC_NUM_2, config); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ADC_EXIT_CRITICAL(); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ADC_ENTER_CRITICAL(); | 
					
						
							|  |  |  |     if (idx == ADC_DIGI_MONITOR_IDX0) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_monitor_enable(ADC_NUM_1, enable); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } else if (idx == ADC_DIGI_MONITOR_IDX1) { | 
					
						
							| 
									
										
										
										
											2021-12-15 14:15:32 +08:00
										 |  |  |         adc_ll_digi_monitor_enable(ADC_NUM_2, enable); | 
					
						
							| 
									
										
										
										
											2020-02-25 22:19:48 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     ADC_EXIT_CRITICAL(); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } |