Files
LoraTestSystemRX_TX/components/input/input.c
2026-01-17 09:53:08 +02:00

95 lines
2.5 KiB
C

#include "input.h"
#include <limits.h>
#include "esp_log.h"
#include "sdkconfig.h"
#include "esp_adc/adc_oneshot.h"
static const char *TAG = "input";
static adc_oneshot_unit_handle_t s_adc_handle;
static adc_channel_t s_channel;
static void log_levels(void)
{
ESP_LOGI(TAG, "Joystick ladder on ADC1_CH%d, levels L=%d U=%d P=%d D=%d R=%d tol=%d",
CONFIG_JOYSTICK_ADC_CHANNEL,
CONFIG_JOYSTICK_ADC_LEVEL_LEFT,
CONFIG_JOYSTICK_ADC_LEVEL_UP,
CONFIG_JOYSTICK_ADC_LEVEL_PRESS,
CONFIG_JOYSTICK_ADC_LEVEL_DOWN,
CONFIG_JOYSTICK_ADC_LEVEL_RIGHT,
CONFIG_JOYSTICK_ADC_TOLERANCE);
}
void input_init(void)
{
adc_oneshot_unit_init_cfg_t unit_cfg = {
.unit_id = ADC_UNIT_1,
.ulp_mode = ADC_ULP_MODE_DISABLE,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&unit_cfg, &s_adc_handle));
s_channel = (adc_channel_t)CONFIG_JOYSTICK_ADC_CHANNEL;
adc_oneshot_chan_cfg_t chan_cfg = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB_11,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(s_adc_handle, s_channel, &chan_cfg));
log_levels();
}
adc_channel_t input_get_channel(void)
{
return s_channel;
}
esp_err_t input_read_raw(int *out_raw)
{
int raw = 0;
esp_err_t err = adc_oneshot_read(s_adc_handle, s_channel, &raw);
if (err != ESP_OK) {
return err;
}
if (out_raw) {
*out_raw = raw;
}
return ESP_OK;
}
input_event_t input_poll(void)
{
int raw = 0;
if (input_read_raw(&raw) != ESP_OK) {
return INPUT_NONE;
}
struct level_map {
input_event_t evt;
int expected;
} map[] = {
{INPUT_LEFT, CONFIG_JOYSTICK_ADC_LEVEL_LEFT},
// Вертикаль інвертована (UP читається ближче до рівня DOWN) на цій платі
{INPUT_UP, CONFIG_JOYSTICK_ADC_LEVEL_DOWN},
{INPUT_CENTER, CONFIG_JOYSTICK_ADC_LEVEL_PRESS},
{INPUT_DOWN, CONFIG_JOYSTICK_ADC_LEVEL_UP},
{INPUT_RIGHT, CONFIG_JOYSTICK_ADC_LEVEL_RIGHT},
};
int best_diff = INT_MAX;
input_event_t best_evt = INPUT_NONE;
for (size_t i = 0; i < sizeof(map) / sizeof(map[0]); i++) {
int diff = map[i].expected - raw;
if (diff < 0) {
diff = -diff;
}
if (diff < best_diff) {
best_diff = diff;
best_evt = map[i].evt;
}
}
if (best_diff <= CONFIG_JOYSTICK_ADC_TOLERANCE) {
return best_evt;
}
return INPUT_NONE;
}