Initial working setup for SR22
This commit is contained in:
@@ -10,12 +10,18 @@ project(rp2040_hid)
|
||||
pico_sdk_init()
|
||||
|
||||
add_executable(rp2040_hid
|
||||
src/buttons.c
|
||||
src/main.c
|
||||
src/rotary.c
|
||||
src/sevenseg.c
|
||||
src/statusleds.c
|
||||
src/usb_config.c
|
||||
)
|
||||
|
||||
# Add pico_stdlib library which aggregates commonly used features
|
||||
target_link_libraries(rp2040_hid pico_stdlib pico_unique_id tinyusb_device tinyusb_board)
|
||||
pico_generate_pio_header(rp2040_hid ${CMAKE_CURRENT_LIST_DIR}/src/sevenseg.pio)
|
||||
pico_generate_pio_header(rp2040_hid ${CMAKE_CURRENT_LIST_DIR}/src/shift_in.pio)
|
||||
pico_generate_pio_header(rp2040_hid ${CMAKE_CURRENT_LIST_DIR}/src/statusleds.pio)
|
||||
target_link_libraries(rp2040_hid pico_stdlib pico_unique_id tinyusb_device tinyusb_board hardware_pio)
|
||||
target_include_directories(rp2040_hid PRIVATE src)
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,165 @@
|
||||
device = hid_open(0x1209, 1)
|
||||
local bit = require("bit")
|
||||
|
||||
all_devs, number = create_HID_table()
|
||||
local the_index
|
||||
for k, v in pairs(all_devs) do
|
||||
if v.vendor_id == 0x1209 and v.usage == 0 then
|
||||
the_path = v.path
|
||||
--print(v.path)
|
||||
--print(v.usage)
|
||||
end
|
||||
end
|
||||
|
||||
local button_offset = 320
|
||||
local button_hdg_sync = 1
|
||||
local button_alt_sync = 7
|
||||
local led_hdg = 0x0001
|
||||
local led_apr = 0x0002
|
||||
local led_nav = 0x0004
|
||||
local led_lvl = 0x0008
|
||||
local led_alt = 0x0010
|
||||
local led_fd = 0x0020
|
||||
local led_vnav = 0x0040
|
||||
local led_ap = 0x0080
|
||||
local led_vs = 0x0100
|
||||
local led_at = 0x0200
|
||||
local led_flc = 0x0400
|
||||
local led_spd = 0x0800
|
||||
local led_n1 = 0x1000
|
||||
|
||||
function table.clone(org)
|
||||
return {table.unpack(org)}
|
||||
end
|
||||
|
||||
function send_app_report(device, hdg, leds, alt, vs, as)
|
||||
hid_write(device, 2, bit.band(hdg, 0xff), bit.arshift(hdg, 8), bit.band(leds, 0xff), bit.arshift(leds, 8),
|
||||
bit.band(alt, 0xff), bit.arshift(alt, 8), bit.band(vs, 0xff), bit.arshift(vs, 8),
|
||||
bit.band(as, 0xff), bit.arshift(as, 8))
|
||||
end
|
||||
|
||||
function build_leds()
|
||||
local val = 0
|
||||
if status_hdg == 1 then
|
||||
val = val + led_hdg
|
||||
elseif status_hdg == 2 then
|
||||
val = val + led_nav
|
||||
end
|
||||
if status_apr > 0 then
|
||||
val = val + led_apr
|
||||
end
|
||||
if status_alt > 1 then
|
||||
val = val + led_alt
|
||||
end
|
||||
if status_fd == 1 then
|
||||
val = val + led_fd
|
||||
elseif status_fd == 2 then
|
||||
val = val + led_fd + led_ap
|
||||
end
|
||||
if status_vnav > 1 then
|
||||
val = val + led_vnav
|
||||
end
|
||||
if status_altmode == 4 then
|
||||
val = val + led_vs
|
||||
elseif status_altmode == 5 then
|
||||
val = val + led_flc
|
||||
end
|
||||
|
||||
return val
|
||||
end
|
||||
|
||||
if the_path ~= nil then
|
||||
device = hid_open_path(the_path)
|
||||
end
|
||||
if device == nil then
|
||||
print("No device!")
|
||||
else
|
||||
dataref("low_vac", "sim/cockpit2/annunciators/low_vacuum", "readable")
|
||||
local prev_low_vac
|
||||
function low_vac_indicator()
|
||||
if low_vac ~= prev_low_vac then
|
||||
if low_vac > 0 then
|
||||
hid_write(device, 2, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
else
|
||||
hid_write(device, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
hid_set_nonblocking(device, 1)
|
||||
dataref("ap_hdg", "sim/cockpit2/autopilot/heading_dial_deg_mag_pilot", "writable")
|
||||
dataref("mag_hdg", "sim/cockpit2/gauges/indicators/heading_AHARS_deg_mag_copilot")
|
||||
|
||||
dataref("ap_alt", "sim/cockpit2/autopilot/altitude_dial_ft", "writable")
|
||||
dataref("cur_alt", "sim/cockpit2/gauges/indicators/altitude_ft_pilot")
|
||||
|
||||
dataref("ap_vs", "sim/cockpit2/autopilot/vvi_dial_fpm", "writable")
|
||||
dataref("cur_vvi", "sim/cockpit2/gauges/indicators/vvi_fpm_pilot")
|
||||
|
||||
dataref("ap_as", "sim/cockpit2/autopilot/airspeed_dial_kts", "writable")
|
||||
dataref("cur_ias", "sim/cockpit2/gauges/indicators/airspeed_kts_pilot")
|
||||
|
||||
dataref("status_alt", "sim/cockpit2/autopilot/altitude_hold_status")
|
||||
dataref("status_apr", "sim/cockpit2/autopilot/approach_status")
|
||||
dataref("status_hdg", "sim/cockpit2/autopilot/heading_mode")
|
||||
dataref("status_fd", "sim/cockpit2/autopilot/flight_director_mode")
|
||||
dataref("status_vnav", "sim/cockpit2/autopilot/vnav_status")
|
||||
dataref("status_altmode", "sim/cockpit2/autopilot/altitude_mode")
|
||||
send_app_report(device, math.floor(ap_hdg + 0.5), build_leds(), math.floor(ap_alt + 0.5), -2, -2)
|
||||
local prev_status_altmode = 0
|
||||
function usb_app()
|
||||
local send_hdg = -1
|
||||
local send_alt = -1
|
||||
local send_vs = -1
|
||||
local send_as = -1
|
||||
local app_report = {0xffff, 0xffff, 0xffff, 0xffff}
|
||||
local app_report_good = false
|
||||
local loops = 100
|
||||
-- read app report from hid device, discarding all reports except the latest one to prevent input lag
|
||||
repeat
|
||||
local tmp_cnt
|
||||
local tmp = {}
|
||||
tmp_cnt, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10] = hid_read(device, 11)
|
||||
if tmp_cnt >= 11 and tmp[0] == 2 then
|
||||
app_report = {bit.bor(tmp[1], bit.lshift(tmp[2], 8)),
|
||||
bit.bor(tmp[5], bit.lshift(tmp[6], 8)),
|
||||
bit.bor(tmp[7], bit.lshift(tmp[8], 8)),
|
||||
bit.bor(tmp[9], bit.lshift(tmp[10], 8))}
|
||||
app_report_good = true
|
||||
end
|
||||
prev_low_vac = low_vac
|
||||
loops = loops - 1
|
||||
until tmp_cnt == 0 or tmp_cnt == nil or loops == 0
|
||||
-- autopilot heading
|
||||
if button(button_offset + button_hdg_sync) and not last_button(button_offset + button_hdg_sync) then
|
||||
mag_hdg_int = math.floor(mag_hdg + 0.5)
|
||||
ap_hdg = mag_hdg_int
|
||||
send_hdg = mag_hdg_int
|
||||
elseif app_report_good and app_report[1] ~= 0xffff then
|
||||
ap_hdg = app_report[1]
|
||||
end
|
||||
-- autopilot altitude
|
||||
if button(button_offset + button_alt_sync) and not last_button(button_offset + button_alt_sync) then
|
||||
cur_alt_int = math.floor(cur_alt + 0.5)
|
||||
ap_alt = cur_alt_int
|
||||
send_alt = cur_alt_int
|
||||
end
|
||||
if app_report_good and app_report[2] ~= 0xffff then
|
||||
ap_alt = app_report[2]
|
||||
end
|
||||
-- vertical speed
|
||||
if status_altmode == 4 and prev_status_altmode ~= 4 then
|
||||
send_vs = math.floor(cur_vvi + 0.5)
|
||||
elseif status_altmode ~= 4 and prev_status_altmode == 4 then
|
||||
send_vs = -2
|
||||
elseif app_report_good and app_report[3] ~= 0xffff then
|
||||
if bit.band(app_report[3], 0x8000) ~= 0 then
|
||||
ap_vs = -bit.band(bit.bnot(app_report[3]), 0x7fff) - 1
|
||||
else
|
||||
ap_vs = app_report[3]
|
||||
end
|
||||
end
|
||||
-- airspeed
|
||||
if status_altmode == 5 and prev_status_altmode ~= 5 then
|
||||
if cur_ias < 64 then
|
||||
send_as = 64
|
||||
else
|
||||
send_as = math.floor(cur_ias + 0.5)
|
||||
end
|
||||
elseif status_altmode ~= 5 and prev_status_altmode == 5 then
|
||||
send_as = -2
|
||||
elseif app_report_good and app_report[4] ~= 0xffff then
|
||||
ap_as = app_report[4]
|
||||
end
|
||||
send_app_report(device, send_hdg, build_leds(), send_alt, send_vs, send_as)
|
||||
prev_status_altmode = status_altmode
|
||||
end
|
||||
|
||||
do_every_frame("low_vac_indicator()")
|
||||
do_every_frame("usb_app()")
|
||||
end
|
||||
|
||||
254
src/main.c
254
src/main.c
@@ -1,11 +1,17 @@
|
||||
#include "buttons.h"
|
||||
#include "pinmap.h"
|
||||
#include "rotary.h"
|
||||
#include "sevenseg.h"
|
||||
#include "statusleds.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <bsp/board.h>
|
||||
#include <hardware/pio.h>
|
||||
#include <pico/stdlib.h>
|
||||
#include <tusb.h>
|
||||
#include "usb_config.h"
|
||||
|
||||
#define BUTTON1_GPIO 2
|
||||
#define LED1_GPIO 22
|
||||
PIO pio = pio0;
|
||||
|
||||
static void hid_task(void);
|
||||
|
||||
@@ -18,20 +24,147 @@ __attribute__((packed)) struct button_report {
|
||||
uint32_t buttons;
|
||||
};
|
||||
|
||||
__attribute__((packed)) struct app_report {
|
||||
int16_t hdg;
|
||||
int16_t leds;
|
||||
int16_t alt;
|
||||
int16_t vs;
|
||||
int16_t as;
|
||||
};
|
||||
|
||||
static struct light_data the_light_data;
|
||||
|
||||
static bool show_vs = false, show_as = false;
|
||||
|
||||
static volatile unsigned hdg = 0;
|
||||
static volatile unsigned alt = 0;
|
||||
static volatile int vs = 0;
|
||||
static volatile unsigned as = 0;
|
||||
|
||||
#define BUTTON_HDG_SYNC 1
|
||||
#define BUTTON_ALT_SYNC 7
|
||||
|
||||
static void update_hdg_display(void)
|
||||
{
|
||||
sevenseg_set_digit(0, hdg / 100);
|
||||
sevenseg_set_digit(1, hdg / 10 % 10);
|
||||
sevenseg_set_digit(2, hdg % 10);
|
||||
}
|
||||
|
||||
static void update_alt_display(void)
|
||||
{
|
||||
int val = alt;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (val || i == 0)
|
||||
sevenseg_set_digit(7 - i, val % 10);
|
||||
else
|
||||
sevenseg_set_digit(7 - i, LED_BLANK);
|
||||
val /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_vs_display(void)
|
||||
{
|
||||
if (show_vs) {
|
||||
int val = vs;
|
||||
unsigned val_abs = val < 0 ? -val : val;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (val_abs || i == 0) {
|
||||
sevenseg_set_digit(11 - i, val_abs % 10);
|
||||
} else {
|
||||
sevenseg_set_digit(11 - i, LED_BLANK);
|
||||
}
|
||||
val_abs /= 10;
|
||||
}
|
||||
if (val >= 1000 || val <= -1000) {
|
||||
sevenseg_set_digit(8, (val_abs % 10) | (val < 0 ? LED_DECIMAL : 0));
|
||||
} else if (val < 0) {
|
||||
sevenseg_set_digit(8, LED_MINUS);
|
||||
} else {
|
||||
sevenseg_set_digit(8, LED_BLANK);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
sevenseg_set_digit(11 - i, LED_BLANK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_as_display(void)
|
||||
{
|
||||
if (show_as) {
|
||||
int val = as;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (val || i == 0)
|
||||
sevenseg_set_digit(15 - i, val % 10);
|
||||
else
|
||||
sevenseg_set_digit(15 - i, LED_BLANK);
|
||||
val /= 10;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
sevenseg_set_digit(15 - i, LED_BLANK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rotary_event(int rot_ch, bool ccw)
|
||||
{
|
||||
/* if (ccw) */
|
||||
/* rotary_events = (rotary_events & ~(0x3<<(rot_ch*2))) | (0x1<<(rot_ch*2)); */
|
||||
/* else */
|
||||
/* rotary_events = (rotary_events & ~(0x3<<(rot_ch*2))) | (0x3<<(rot_ch*2)); */
|
||||
/* rotary_events |= 1<<(rot_ch*2 + ccw); */
|
||||
/* sevenseg_set_digit(0, rot_ch); */
|
||||
/* sevenseg_set_digit(1, ccw); */
|
||||
if (rot_ch == 3) {
|
||||
if (ccw) {
|
||||
hdg = hdg == 0 ? 359 : hdg - 1;
|
||||
} else {
|
||||
hdg = hdg == 359 ? 0 : hdg + 1;
|
||||
}
|
||||
update_hdg_display();
|
||||
} else if (rot_ch == 2) {
|
||||
if (ccw) {
|
||||
alt = alt == 0 ? 0 : ((alt + 99) / 100) * 100 - 100;
|
||||
} else {
|
||||
alt = alt == 50000 ? 50000 : (alt / 100) * 100 + 100;
|
||||
}
|
||||
update_alt_display();
|
||||
} else if (rot_ch == 1) {
|
||||
if (ccw) {
|
||||
vs = vs == -5000 ? -5000 : vs - 100;
|
||||
} else {
|
||||
vs = vs == 5000 ? 5000 : vs + 100;
|
||||
}
|
||||
update_vs_display();
|
||||
} else {
|
||||
// TODO: knots / mach mode switch
|
||||
if (ccw) {
|
||||
as = as == 64 ? 64 : as - 1;
|
||||
} else {
|
||||
as = as == 205 ? 205 : as + 1;
|
||||
}
|
||||
update_as_display();
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
setup_default_uart();
|
||||
tusb_init();
|
||||
|
||||
gpio_init(BUTTON1_GPIO);
|
||||
gpio_set_dir(BUTTON1_GPIO, GPIO_IN);
|
||||
gpio_pull_up(BUTTON1_GPIO);
|
||||
rotary_init();
|
||||
sevenseg_init();
|
||||
buttons_init();
|
||||
statusleds_init();
|
||||
|
||||
gpio_init(LED1_GPIO);
|
||||
gpio_set_dir(LED1_GPIO, GPIO_OUT);
|
||||
gpio_put(LED1_GPIO, true);
|
||||
update_hdg_display();
|
||||
update_alt_display();
|
||||
update_vs_display();
|
||||
update_as_display();
|
||||
|
||||
irq_set_enabled(PIO0_IRQ_1, true);
|
||||
|
||||
printf("Hello, world!\n");
|
||||
while (1) {
|
||||
@@ -41,6 +174,8 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool send_heading_reports = true, send_alt_reports = true, send_vs_reports = false, send_as_reports = false;
|
||||
|
||||
static void hid_task(void)
|
||||
{
|
||||
// Poll every 1ms
|
||||
@@ -51,18 +186,39 @@ static void hid_task(void)
|
||||
return; // poll interval not elapsed
|
||||
start_ms += interval_ms;
|
||||
|
||||
bool btn = !gpio_get(BUTTON1_GPIO);
|
||||
if (start_ms % 10 == 0 && send_heading_reports) {
|
||||
struct app_report report = { .hdg = -1, .alt = -1, .vs = -1, .as = -1 };
|
||||
if (send_heading_reports)
|
||||
report.hdg = hdg;
|
||||
if (send_alt_reports)
|
||||
report.alt = alt;
|
||||
if (send_vs_reports)
|
||||
report.vs = vs;
|
||||
if (send_as_reports)
|
||||
report.as = as;
|
||||
if (tud_hid_ready())
|
||||
tud_hid_n_report(ITF_NUM_HID, HID_REPORT_APP, &report, sizeof(report));
|
||||
} else {
|
||||
static int btns_prev = 0;
|
||||
unsigned btns = buttons_read() & 0xfffff;
|
||||
|
||||
// Remote wakeup
|
||||
if (tud_suspended() && btn) {
|
||||
// Wake up host if we are in suspend mode
|
||||
// and REMOTE_WAKEUP feature is enabled by host
|
||||
tud_remote_wakeup();
|
||||
}
|
||||
if ((btns >> BUTTON_HDG_SYNC) & 1 && !((btns_prev >> BUTTON_HDG_SYNC) & 1))
|
||||
send_heading_reports = false;
|
||||
if ((btns >> BUTTON_ALT_SYNC) & 1 && !((btns_prev >> BUTTON_ALT_SYNC) & 1))
|
||||
send_alt_reports = false;
|
||||
|
||||
if (tud_hid_ready()) {
|
||||
struct button_report report = { .buttons = btn ? GAMEPAD_BUTTON_0 : 0 };
|
||||
tud_hid_n_report(ITF_NUM_HID, HID_REPORT_GAMEPAD, &report, sizeof(report));
|
||||
btns_prev = btns;
|
||||
// Remote wakeup
|
||||
if (tud_suspended() && btns) {
|
||||
// Wake up host if we are in suspend mode
|
||||
// and REMOTE_WAKEUP feature is enabled by host
|
||||
tud_remote_wakeup();
|
||||
}
|
||||
|
||||
if (tud_hid_ready()) {
|
||||
struct button_report report = { .buttons = btns };
|
||||
tud_hid_n_report(ITF_NUM_HID, HID_REPORT_GAMEPAD, &report, sizeof(report));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,11 +226,45 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_
|
||||
uint16_t bufsize)
|
||||
{
|
||||
//printf("REPORT id %hhu type %d [0] %hhu size %hu\n", report_id, report_type, buffer[0], bufsize);
|
||||
if (report_id == HID_REPORT_LIGHTS && report_type == HID_REPORT_TYPE_OUTPUT &&
|
||||
bufsize >= sizeof(struct light_data)) {
|
||||
size_t i = 0;
|
||||
memcpy(&the_light_data, buffer, sizeof(the_light_data));
|
||||
gpio_put(LED1_GPIO, the_light_data.leds[0] > 0x7f ? false : true);
|
||||
if (report_id == HID_REPORT_APP && report_type == HID_REPORT_TYPE_OUTPUT && bufsize >= 2) {
|
||||
struct app_report report;
|
||||
memcpy(&report, buffer, sizeof(report));
|
||||
if (report.hdg >= 0) {
|
||||
hdg = report.hdg;
|
||||
update_hdg_display();
|
||||
send_heading_reports = true;
|
||||
}
|
||||
if (report.alt >= 0) {
|
||||
alt = report.alt;
|
||||
update_alt_display();
|
||||
send_alt_reports = true;
|
||||
}
|
||||
if (report.vs != -1) {
|
||||
if (report.vs == -2) {
|
||||
// disable vs mode
|
||||
show_vs = false;
|
||||
send_vs_reports = false;
|
||||
} else {
|
||||
vs = report.vs;
|
||||
show_vs = true;
|
||||
send_vs_reports = true;
|
||||
}
|
||||
update_vs_display();
|
||||
}
|
||||
if (report.as != -1) {
|
||||
if (report.as == -2) {
|
||||
show_as = false;
|
||||
send_as_reports = false;
|
||||
} else {
|
||||
as = report.as;
|
||||
show_as = true;
|
||||
send_as_reports = true;
|
||||
}
|
||||
update_as_display();
|
||||
}
|
||||
if (report.leds >= 0) {
|
||||
statusleds_set(report.leds);
|
||||
}
|
||||
}
|
||||
|
||||
// echo back anything we received from host
|
||||
@@ -111,17 +301,13 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t
|
||||
if (report_type != HID_REPORT_TYPE_INPUT)
|
||||
return 0;
|
||||
switch (report_id) {
|
||||
case HID_REPORT_LIGHTS:
|
||||
act_len = sizeof(the_light_data) > reqlen ? reqlen : sizeof(the_light_data);
|
||||
memcpy(buffer, &the_light_data, act_len);
|
||||
return act_len;
|
||||
case HID_REPORT_GAMEPAD: {
|
||||
const bool btn = !gpio_get(BUTTON1_GPIO);
|
||||
const struct button_report report = { .buttons = btn ? GAMEPAD_BUTTON_0 : 0 };
|
||||
act_len = sizeof(report) > reqlen ? reqlen : sizeof(report);
|
||||
memcpy(buffer, &report, act_len);
|
||||
return act_len;
|
||||
}
|
||||
/* case HID_REPORT_GAMEPAD: { */
|
||||
/* const bool btn = !gpio_get(BUTTON1_GPIO); */
|
||||
/* const struct button_report report = { .buttons = btn ? GAMEPAD_BUTTON_0 : 0 }; */
|
||||
/* act_len = sizeof(report) > reqlen ? reqlen : sizeof(report); */
|
||||
/* memcpy(buffer, &report, act_len); */
|
||||
/* return act_len; */
|
||||
/* } */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ static void rotary_timer_event(uint alarm_num)
|
||||
state[i] = rotary_state_idle;
|
||||
if (rot_gpio[i * 2] && !rot_gpio[i * 2 + 1]) {
|
||||
state[i] = rotary_state_A;
|
||||
rotary_event(i, true);
|
||||
rotary_event(i, false);
|
||||
}
|
||||
break;
|
||||
case rotary_state_A:
|
||||
@@ -47,7 +47,7 @@ static void rotary_timer_event(uint alarm_num)
|
||||
state[i] = rotary_state_idle;
|
||||
if (!rot_gpio[i * 2] && rot_gpio[i * 2 + 1]) {
|
||||
state[i] = rotary_state_B;
|
||||
rotary_event(i, false);
|
||||
rotary_event(i, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <tusb.h>
|
||||
|
||||
/* clang-format off */
|
||||
// Gamepad Report Descriptor Template with 32 buttons with following layout
|
||||
// Gamepad Report Descriptor Template with 28 buttons with following layout
|
||||
// | Button Map (4 bytes) |
|
||||
#define RP2040_HID_REPORT_DESC_GAMEPAD(...) \
|
||||
HID_USAGE_PAGE (HID_USAGE_PAGE_DESKTOP), \
|
||||
@@ -14,10 +14,10 @@
|
||||
HID_COLLECTION (HID_COLLECTION_APPLICATION), \
|
||||
/* Report ID if any */ \
|
||||
__VA_ARGS__ \
|
||||
/* 32 bit Button Map */ \
|
||||
/* 20 bit Button Map */ \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_BUTTON), \
|
||||
HID_USAGE_MIN(1), \
|
||||
HID_USAGE_MAX(32), \
|
||||
HID_USAGE_MAX(20), \
|
||||
HID_LOGICAL_MIN(0), \
|
||||
HID_LOGICAL_MAX(1), \
|
||||
HID_REPORT_COUNT(32), \
|
||||
@@ -25,23 +25,33 @@
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END
|
||||
|
||||
#define RP2040_HID_REPORT_DESC_LIGHTS(...) \
|
||||
#define RP2040_HID_REPORT_DESC_APP(...) \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_DESKTOP), \
|
||||
HID_USAGE(0x00), \
|
||||
HID_COLLECTION(HID_COLLECTION_APPLICATION), \
|
||||
__VA_ARGS__ \
|
||||
HID_REPORT_COUNT(16), /*16 button lights */ \
|
||||
HID_REPORT_SIZE(8), \
|
||||
HID_LOGICAL_MIN(0x00), \
|
||||
HID_LOGICAL_MAX_N(0x00ff, 2), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \
|
||||
HID_USAGE_MIN(1), \
|
||||
HID_USAGE_MAX(16), \
|
||||
HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_USAGE_MIN(1), \
|
||||
HID_USAGE_MAX(1), \
|
||||
HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END
|
||||
HID_REPORT_COUNT(5), \
|
||||
HID_REPORT_SIZE(16), \
|
||||
HID_LOGICAL_MIN(-1), \
|
||||
HID_LOGICAL_MAX(127), \
|
||||
HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \
|
||||
HID_USAGE_MIN(1), \
|
||||
HID_USAGE_MAX(1), \
|
||||
HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \
|
||||
HID_COLLECTION_END
|
||||
|
||||
/* HID_REPORT_COUNT(16), /\*16 button lights *\/ \ */
|
||||
/* HID_REPORT_SIZE(8), \ */
|
||||
/* HID_LOGICAL_MIN(0x00), \ */
|
||||
/* HID_LOGICAL_MAX_N(0x00ff, 2), \ */
|
||||
/* HID_USAGE_PAGE(HID_USAGE_PAGE_ORDINAL), \ */
|
||||
/* HID_USAGE_MIN(1), \ */
|
||||
/* HID_USAGE_MAX(16), \ */
|
||||
/* HID_OUTPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ */
|
||||
/* HID_USAGE_MIN(1), \ */
|
||||
/* HID_USAGE_MAX(1), \ */
|
||||
/* HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE), \ */
|
||||
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
@@ -129,7 +139,7 @@ uint8_t const *tud_descriptor_device_cb(void)
|
||||
}
|
||||
|
||||
static uint8_t const desc_hid_report[] = { RP2040_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(HID_REPORT_GAMEPAD)),
|
||||
RP2040_HID_REPORT_DESC_LIGHTS(HID_REPORT_ID(HID_REPORT_LIGHTS)) };
|
||||
RP2040_HID_REPORT_DESC_APP(HID_REPORT_ID(HID_REPORT_APP)) };
|
||||
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN)
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
|
||||
enum { ITF_NUM_HID, ITF_NUM_TOTAL };
|
||||
|
||||
enum { HID_REPORT_GAMEPAD = 1, HID_REPORT_LIGHTS };
|
||||
enum { HID_REPORT_GAMEPAD = 1, HID_REPORT_APP };
|
||||
|
||||
Reference in New Issue
Block a user