Files
portersky 8276b7bad5 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.
2026-06-14 19:26:37 +02:00

145 lines
3.4 KiB
Markdown

# STK Library
A C23 library for reading EdgeTX radio joystick (HID) input on Windows.
Reads raw HID input reports to access 4 analog axes and 24 buttons.
Wired for test-driven development using
[Unity](https://github.com/ThrowTheSwitch/Unity) and
[CMock](https://github.com/ThrowTheSwitch/CMock).
All dependencies are fetched automatically via CMake `FetchContent` — no
manual installation required beyond the tools listed below.
## Requirements
| Tool | Purpose |
| ------------- | ----------------------------------------------------- |
| CMake >= 3.21 | Build system |
| Ninja | Build backend |
| C23 compiler | GCC 14+, Clang 18+ |
| Ruby >= 3.0 | CMock mock generation |
| gcovr >= 6.0 | Coverage reports — optional (`uv tool install gcovr`) |
## Build
Configure:
```sh
cmake -S . -B build -G Ninja
```
Build:
```sh
ninja -C build
```
## Test
Full Unity output with colors:
```sh
ninja -C build check
```
CTest summary only:
```sh
ninja -C build test
```
`check` builds all suites and runs CTest with `--output-on-failure`,
so assertion-level detail appears on any failure without running
binaries by hand.
## Coverage
Configure with coverage instrumentation:
```sh
cmake -S . -B build-cov -G Ninja -DENABLE_COVERAGE=ON
```
Generate the HTML report:
```sh
ninja -C build-cov coverage
```
Open `build-cov/coverage/index.html` in a browser to view results.
Only `stk/` source files are measured. Unity, CMock, and generated
mock files are excluded. Requires GCC or Clang with gcov support, and
`gcovr` on `PATH`.
> **Windows note:** requires GCC (e.g. `scoop install gcc`) or a Clang
> build that includes compiler-rt. A custom Clang without compiler-rt
> will fail at link time.
## Run
Windows:
```sh
./build/main.exe
```
## API
```c
#include <stk/stk.h>
// Open with default VID/PID
stk_config_t config = {
.vendor_id = STK_DEFAULT_VID,
.product_id = STK_DEFAULT_PID,
};
if (stk_open(&config) != 0) {
// handle error
}
// Read state (non-blocking)
stk_state_t state;
stk_read(&state);
// Named accessors for the 4 active axes
int16_t rx = stk_right_x(&state);
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/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)) {
// switch 4 is on
}
// Close the device
stk_close();
```
## Radio Profile
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/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)
- [x] Raw HID device enumeration and opening
- [x] Reading 4 axes and 24 buttons
- [ ] Linux support
- [ ] macOS support