/** * @file stk.h * @brief EdgeTX RC library interface for HID joystick mode. * * Reads raw HID input reports from the EdgeTX radio and exposes * 4 analog axes (sticks + throttle) and 24 digital buttons * (switches, rockers, paddles). * * @par Report layout (20 bytes): * @code * byte 0 : report ID (0x00) * byte 1 : buttons bits 0..7 * bytes 2..17 : 8 axes x 16-bit LE (HID usage 0x30..0x37) * bytes 18..19 : buttons bits 8..23 * @endcode * * @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 #include #include // --------------------------------------------------------------------------- // Axis range (10-bit ADC on the radio) // --------------------------------------------------------------------------- #define STK_AXIS_MIN 0 #define STK_AXIS_MAX 2047 #define STK_AXIS_MID 1024 // --------------------------------------------------------------------------- // Default device IDs (EdgeTX radio in HID joystick mode) // --------------------------------------------------------------------------- #define STK_DEFAULT_VID 0x1209 #define STK_DEFAULT_PID 0x4F54 // --------------------------------------------------------------------------- // Configuration // --------------------------------------------------------------------------- typedef struct { uint16_t vendor_id; uint16_t product_id; } stk_config_t; // --------------------------------------------------------------------------- // Radio state // // 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. // --------------------------------------------------------------------------- #define STK_NUM_AXES 8 #define STK_NUM_BUTTONS 24 typedef struct { int16_t axes[STK_NUM_AXES]; uint32_t buttons; } stk_state_t; // --------------------------------------------------------------------------- // Convenience accessors for the 4 active axes // --------------------------------------------------------------------------- static inline int16_t stk_right_x(stk_state_t const* s) { return s->axes[1]; } static inline int16_t stk_right_y(stk_state_t const* s) { return s->axes[2]; } static inline int16_t stk_throttle(stk_state_t const* s) { return s->axes[3]; } static inline int16_t stk_left_x(stk_state_t const* s) { return s->axes[4]; } // --------------------------------------------------------------------------- // Button bitmask helpers (bit 0 = first switch, bit 23 = last) // --------------------------------------------------------------------------- static inline bool stk_button_pressed(stk_state_t const* s, uint8_t index) { if (index >= STK_NUM_BUTTONS) return false; return (s->buttons >> index) & 1; } // --------------------------------------------------------------------------- // API // --------------------------------------------------------------------------- /** * Open the HID radio device. * config must remain valid for the lifetime of the open session. * Returns 0 on success, -1 on failure. */ int stk_open(stk_config_t const* config); /** * Read the current radio state (non-blocking). * Returns 0 on success, -1 on failure or no new data. */ int stk_read(stk_state_t* state); /** * Close the radio device. Safe to call multiple times. */ void stk_close(void);