125 lines
3.9 KiB
C
125 lines
3.9 KiB
C
/**
|
|
* @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 <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 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);
|