Skip to content

Commit d54db39

Browse files
committed
rg_input: Add support for new ADC oneshot driver (#260)
1 parent 737a971 commit d54db39

File tree

1 file changed

+104
-43
lines changed

1 file changed

+104
-43
lines changed

components/retro-go/rg_input.c

Lines changed: 104 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,24 @@
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>
2021
static 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
2428
static 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

Comments
 (0)