#include "input.h" #include #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; }