55#include <string.h>
66#include <math.h>
77
8+ // #define USE_ADC_DRIVER_NG
9+
810#ifdef ESP_PLATFORM
911#include <driver/gpio.h>
10- #include <driver/adc.h>
11- // This is a lazy way to silence deprecation notices on some esp-idf versions...
12- // This hardcoded value is the first thing to check if something stops working!
13- #define ADC_ATTEN_DB_11 3
12+ #ifdef USE_ADC_DRIVER_NG
13+ #include <esp_adc/adc_oneshot.h>
14+ #include <esp_adc/adc_cali.h>
15+ #include <esp_adc/adc_cali_scheme.h>
16+ static adc_oneshot_unit_handle_t adc_handles [4 ];
17+ static adc_cali_handle_t adc_cali_handles [4 ];
1418#else
15- #include <SDL2/SDL.h>
16- #endif
17-
18- #if RG_BATTERY_DRIVER == 1
19+ #include <driver/adc.h>
1920#include <esp_adc_cal.h>
2021static esp_adc_cal_characteristics_t adc_chars ;
2122#endif
23+ #else
24+ #include <SDL2/SDL.h>
25+ #endif
2226
2327#ifdef RG_GAMEPAD_ADC_MAP
2428static rg_keymap_adc_t keymap_adc [] = RG_GAMEPAD_ADC_MAP ;
@@ -48,21 +52,98 @@ static rg_battery_t battery_state = {0};
4852 gamepad_mapped |= keymap[i].key; \
4953
5054#ifdef ESP_PLATFORM
51- static inline int adc_get_raw (adc_unit_t unit , adc_channel_t channel )
55+ static inline bool _adc_setup_channel (adc_unit_t unit , adc_channel_t channel , adc_atten_t atten , adc_bitwidth_t width , bool calibrate )
5256{
53- if (unit == ADC_UNIT_1 )
57+ RG_ASSERT (unit == ADC_UNIT_1 || unit == ADC_UNIT_2 , "Invalid ADC unit" );
58+ #ifdef USE_ADC_DRIVER_NG
59+ if (!adc_handles [unit ])
5460 {
55- return adc1_get_raw (channel );
61+ const adc_oneshot_unit_init_cfg_t config = {
62+ .unit_id = unit ,
63+ .clk_src = 0 ,
64+ .ulp_mode = ADC_ULP_MODE_DISABLE ,
65+ };
66+ if (adc_oneshot_new_unit (& config , & adc_handles [unit ]) != ESP_OK )
67+ {
68+ RG_LOGE ("Failed to initialize ADC unit:%d" , (int )unit );
69+ return false;
70+ }
71+ }
72+ const adc_oneshot_chan_cfg_t config = {.atten = atten , .bitwidth = ADC_BITWIDTH_DEFAULT };
73+ if (adc_oneshot_config_channel (adc_handles [unit ], channel , & config ) != ESP_OK )
74+ {
75+ RG_LOGE ("Failed to configure ADC unit:%d channel:%d atten:%d width:%d" ,
76+ (int )unit , (int )channel , (int )atten , (int )width );
77+ return false;
78+ }
79+ if (calibrate )
80+ {
81+ #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
82+ adc_cali_curve_fitting_config_t config = {
83+ .unit_id = unit ,
84+ .atten = atten ,
85+ .bitwidth = width ,
86+ };
87+ adc_cali_create_scheme_curve_fitting (& config , & adc_cali_handles [unit ]);
88+ #elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED
89+ adc_cali_line_fitting_config_t config = {
90+ .unit_id = unit ,
91+ .atten = atten ,
92+ .bitwidth = width ,
93+ #if CONFIG_IDF_TARGET_ESP32
94+ .default_vref = 1100 ,
95+ #endif
96+ };
97+ adc_cali_create_scheme_line_fitting (& config , & adc_cali_handles [unit ]);
98+ #else
99+ RG_LOGW ("Calibration not supported!" );
100+ #endif
56101 }
57- else if (unit == ADC_UNIT_2 )
102+ #else
103+ if (RG_BATTERY_ADC_UNIT == ADC_UNIT_1 )
104+ {
105+ adc1_config_width (ADC_WIDTH_MAX - 1 );
106+ adc1_config_channel_atten (channel , atten );
107+ }
108+ else if (RG_BATTERY_ADC_UNIT == ADC_UNIT_2 )
58109 {
59- int adc_raw_value = -1 ;
60- if (adc2_get_raw (channel , ADC_WIDTH_MAX - 1 , & adc_raw_value ) != ESP_OK )
61- RG_LOGE ("ADC2 reading failed, this can happen while wifi is active." );
62- return adc_raw_value ;
110+ adc2_config_channel_atten (channel , atten );
63111 }
64- RG_LOGE ("Invalid ADC unit %d" , (int )unit );
65- return -1 ;
112+ if (calibrate )
113+ esp_adc_cal_characterize (unit , atten , ADC_WIDTH_MAX - 1 , 1100 , & adc_chars );
114+ #endif
115+ return true;
116+ }
117+
118+ static inline int _adc_get_raw (adc_unit_t unit , adc_channel_t channel )
119+ {
120+ RG_ASSERT (unit == ADC_UNIT_1 || unit == ADC_UNIT_2 , "Invalid ADC unit" );
121+ int adc_raw_value = -1 ;
122+ #ifdef USE_ADC_DRIVER_NG
123+ if (adc_oneshot_read (adc_handles [unit ], channel , & adc_raw_value ) != ESP_OK )
124+ RG_LOGE ("ADC reading failed, this can happen while wifi is active." );
125+ #else
126+ if (unit == ADC_UNIT_1 )
127+ adc_raw_value = adc1_get_raw (channel );
128+ else if (adc2_get_raw (channel , ADC_WIDTH_MAX - 1 , & adc_raw_value ) != ESP_OK )
129+ RG_LOGE ("ADC2 reading failed, this can happen while wifi is active." );
130+ #endif
131+ return adc_raw_value ;
132+ }
133+
134+ static inline int _adc_get_voltage (adc_unit_t unit , adc_channel_t channel )
135+ {
136+ int raw_value = _adc_get_raw (unit , channel );
137+ if (raw_value < 0 )
138+ return -1 ;
139+ #ifdef USE_ADC_DRIVER_NG
140+ int voltage ;
141+ if (adc_cali_raw_to_voltage (adc_cali_handles [unit ], raw_value , & voltage ) != ESP_OK )
142+ return -1 ;
143+ return voltage ;
144+ #else
145+ return esp_adc_cal_raw_to_voltage (raw_value , & adc_chars );
146+ #endif
66147}
67148#endif
68149
@@ -75,10 +156,10 @@ bool rg_input_read_battery_raw(rg_battery_t *out)
75156#if RG_BATTERY_DRIVER == 1 /* ADC */
76157 for (int i = 0 ; i < 4 ; ++ i )
77158 {
78- int value = adc_get_raw (RG_BATTERY_ADC_UNIT , RG_BATTERY_ADC_CHANNEL );
159+ int value = _adc_get_voltage (RG_BATTERY_ADC_UNIT , RG_BATTERY_ADC_CHANNEL );
79160 if (value < 0 )
80161 return false;
81- raw_value += esp_adc_cal_raw_to_voltage ( value , & adc_chars ) ;
162+ raw_value += value ;
82163 }
83164 raw_value /= 4 ;
84165#elif RG_BATTERY_DRIVER == 2 /* I2C */
@@ -112,7 +193,7 @@ bool rg_input_read_gamepad_raw(uint32_t *out)
112193 for (size_t i = 0 ; i < RG_COUNT (keymap_adc ); ++ i )
113194 {
114195 const rg_keymap_adc_t * mapping = & keymap_adc [i ];
115- int value = adc_get_raw (mapping -> unit , mapping -> channel );
196+ int value = _adc_get_raw (mapping -> unit , mapping -> channel );
116197 if (value >= mapping -> min && value <= mapping -> max )
117198 {
118199 if (abs (old_adc_values [i ] - value ) < RG_GAMEPAD_ADC_FILTER_WINDOW )
@@ -271,16 +352,10 @@ void rg_input_init(void)
271352
272353#if defined(RG_GAMEPAD_ADC_MAP )
273354 RG_LOGI ("Initializing ADC gamepad driver..." );
274- adc1_config_width (ADC_WIDTH_MAX - 1 );
275355 for (size_t i = 0 ; i < RG_COUNT (keymap_adc ); ++ i )
276356 {
277357 const rg_keymap_adc_t * mapping = & keymap_adc [i ];
278- if (mapping -> unit == ADC_UNIT_1 )
279- adc1_config_channel_atten (mapping -> channel , mapping -> atten );
280- else if (mapping -> unit == ADC_UNIT_2 )
281- adc2_config_channel_atten (mapping -> channel , mapping -> atten );
282- else
283- RG_LOGE ("Invalid ADC unit %d!" , (int )mapping -> unit );
358+ _adc_setup_channel (mapping -> unit , mapping -> channel , mapping -> atten , ADC_BITWIDTH_DEFAULT , false);
284359 }
285360 UPDATE_GLOBAL_MAP (keymap_adc );
286361#endif
@@ -337,21 +412,7 @@ void rg_input_init(void)
337412
338413#if RG_BATTERY_DRIVER == 1 /* ADC */
339414 RG_LOGI ("Initializing ADC battery driver..." );
340- if (RG_BATTERY_ADC_UNIT == ADC_UNIT_1 )
341- {
342- adc1_config_width (ADC_WIDTH_MAX - 1 ); // there is no adc2_config_width
343- adc1_config_channel_atten (RG_BATTERY_ADC_CHANNEL , ADC_ATTEN_DB_11 );
344- esp_adc_cal_characterize (ADC_UNIT_1 , ADC_ATTEN_DB_11 , ADC_WIDTH_MAX - 1 , 1100 , & adc_chars );
345- }
346- else if (RG_BATTERY_ADC_UNIT == ADC_UNIT_2 )
347- {
348- adc2_config_channel_atten (RG_BATTERY_ADC_CHANNEL , ADC_ATTEN_DB_11 );
349- esp_adc_cal_characterize (ADC_UNIT_2 , ADC_ATTEN_DB_11 , ADC_WIDTH_MAX - 1 , 1100 , & adc_chars );
350- }
351- else
352- {
353- RG_LOGE ("Only ADC1 and ADC2 are supported for ADC battery driver!" );
354- }
415+ _adc_setup_channel (RG_BATTERY_ADC_UNIT , RG_BATTERY_ADC_CHANNEL , ADC_ATTEN_DB_11 , ADC_BITWIDTH_DEFAULT , true);
355416#endif
356417
357418 // The first read returns bogus data in some drivers, waste it.
0 commit comments