From 8276b7bad55a8b11497ff0751a04c9a8ec1f2940 Mon Sep 17 00:00:00 2001 From: portersky <24420859+portersky@users.noreply.github.com> Date: Sun, 14 Jun 2026 19:26:37 +0200 Subject: [PATCH] fix: map throttle to axis 3 (AETR layout) Verified via hid_discover caps and live data dump. Throttle responds on axis 3 (HID usage 0x33 = Rx), not axis 5 or 6. --- README.md | 8 ++++++-- stk/stk.h | 27 +++++++++++++-------------- tests/test_stk.c | 4 ++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index dfbd7e6..251c235 100644 --- a/README.md +++ b/README.md @@ -109,8 +109,9 @@ int16_t ry = stk_right_y(&state); int16_t throttle = stk_throttle(&state); int16_t lx = stk_left_x(&state); -// Raw axes array (indices 0-7, only 1/2/4/5 active) +// Raw axes array (indices 0-7, only 1/2/3/4 active) // state.axes[0..7] — values in range STK_AXIS_MIN..MAX (0..2047) +// AETR layout: axes 1/2 = right stick, 3 = throttle, 4 = left X (rudder) // Button check if (stk_button_pressed(&state, 3)) { @@ -127,10 +128,13 @@ EdgeTX radio (VID:PID 1209:4F54) HID input report: | Field | Size | Details | | ------- | ---------- | --------------------------------------------------- | -| Axes | 4 x 16-bit | Range 0-2047 (HID usage 0x30-0x37, indices 1/2/4/5) | +| Axes | 4 x 16-bit | Range 0-2047 (HID usage 0x30-0x37, indices 1/2/3/4) | | Buttons | 24 bits | Switches, rockers, paddles | | Total | 20 bytes | No report ID | +Axis 1 = right X (aileron), 2 = right Y (elevator), 3 = throttle, +4 = left X (rudder). This matches the AETR stick layout. + ## Current Status - [x] Build system (CMake + Ninja) diff --git a/stk/stk.h b/stk/stk.h index 3d132d4..bea06d7 100644 --- a/stk/stk.h +++ b/stk/stk.h @@ -14,16 +14,15 @@ * bytes 18..19 : buttons bits 8..23 * @endcode * - * @par Active axes: - * | Index | Usage | Physical control | Rest value | - * |-------|-------|-----------------|------------| - * | 0 | — | unused | always 0 | - * | 1 | RX | right stick X | ~1024 | - * | 2 | RY | right stick Y | ~1024 | - * | 3 | — | unused | always 0 | - * | 4 | Z | left stick Y | 0..2047 | - * | 5 | VR | left stick X | ~1024 | - * | 6..7 | — | unused | always 0 | + * @par Active axes (AETR stick mapping): + * | Index | Usage | HID name | Physical control | Rest value | + * |-------|-------|----------|-----------------|------------| + * | 0 | 0x30 | X | unused | always 0 | + * | 1 | 0x31 | Y | right stick X | ~1024 | + * | 2 | 0x32 | Z | right stick Y | ~1024 | + * | 3 | 0x33 | Rx | throttle | ~0 | + * | 4 | 0x34 | Ry | left stick X | ~1024 | + * | 5..7 | — | unused | always 0 | always 0 | */ #pragma once @@ -56,8 +55,8 @@ typedef struct { // --------------------------------------------------------------------------- // Radio state // -// axes[] holds all 8 HID axes (indices 0-7). Only indices 1, 2, 4, 5 -// are wired to physical controls. The rest stay at 0. +// axes[] holds all 8 HID axes (indices 0-7). Only indices 1, 2, 3, 4 +// are wired to physical controls (AETR layout). The rest stay at 0. // // buttons is a 24-bit bitmask: bit N set = switch/button N+1 pressed. // --------------------------------------------------------------------------- @@ -83,11 +82,11 @@ static inline int16_t stk_right_y(stk_state_t const* s) { } static inline int16_t stk_throttle(stk_state_t const* s) { - return s->axes[4]; + return s->axes[3]; } static inline int16_t stk_left_x(stk_state_t const* s) { - return s->axes[5]; + return s->axes[4]; } // --------------------------------------------------------------------------- diff --git a/tests/test_stk.c b/tests/test_stk.c index ebfd147..b702857 100644 --- a/tests/test_stk.c +++ b/tests/test_stk.c @@ -75,8 +75,8 @@ void test_named_accessors_map_correct_indices(void) { stk_state_t state = { 0 }; state.axes[1] = 111; state.axes[2] = 222; - state.axes[4] = 333; - state.axes[5] = 444; + state.axes[3] = 333; + state.axes[4] = 444; TEST_ASSERT_EQUAL_INT16(111, stk_right_x(&state)); TEST_ASSERT_EQUAL_INT16(222, stk_right_y(&state));