From de10af9a5f4b93fb75c9ec716bfc35042ea55f17 Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Mon, 3 Apr 2023 19:10:17 +0200 Subject: [PATCH] Add support for different speed limits on different airplanes --- FlyWithLua/rpi2040_hid.lua | 32 ++++++--- src/main.c | 135 +++++++++++++++++++++++-------------- src/usb_config.c | 17 +++-- 3 files changed, 121 insertions(+), 63 deletions(-) diff --git a/FlyWithLua/rpi2040_hid.lua b/FlyWithLua/rpi2040_hid.lua index b23cb98..46f0614 100644 --- a/FlyWithLua/rpi2040_hid.lua +++ b/FlyWithLua/rpi2040_hid.lua @@ -27,12 +27,24 @@ local led_flc = 0x0400 local led_spd = 0x0800 local led_n1 = 0x1000 +local aircraft_data = { + ["SR22"] = {["min_as"] = 64, ["max_as"] = 205}, + ["DR40"] = {["min_as"] = 49, ["max_as"] = 146}, + ["E55P"] = {["min_as"] = 89, ["max_as"] = 320}, +} + +dataref("ac_icao", "sim/aircraft/view/acf_ICAO") + +print("Aircraft is " .. ac_icao) +local cur_aircraft = aircraft_data[ac_icao] +print("Min AS " .. cur_aircraft.min_as .. ", Max AS " .. cur_aircraft.max_as) + 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), + hid_write(device, 2, 0, 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 @@ -74,6 +86,8 @@ if device == nil then print("No device!") else hid_set_nonblocking(device, 1) + hid_write(device, 2, 1, bit.band(cur_aircraft.min_as, 0xff), bit.arshift(cur_aircraft.min_as, 8), + bit.band(cur_aircraft.max_as, 0xff), bit.arshift(cur_aircraft.max_as, 8), 0, 0, 0, 0, 0, 0) dataref("ap_hdg", "sim/cockpit2/autopilot/heading_dial_deg_mag_pilot", "writable") dataref("mag_hdg", "sim/cockpit2/gauges/indicators/heading_AHARS_deg_mag_copilot") @@ -106,12 +120,12 @@ else 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))} + tmp_cnt, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11] = hid_read(device, 12) + if tmp_cnt >= 11 and tmp[0] == 2 and tmp[1] == 0 then + app_report = {bit.bor(tmp[2], bit.lshift(tmp[3], 8)), + bit.bor(tmp[6], bit.lshift(tmp[7], 8)), + bit.bor(tmp[8], bit.lshift(tmp[9], 8)), + bit.bor(tmp[10], bit.lshift(tmp[11], 8))} app_report_good = true end loops = loops - 1 @@ -147,8 +161,8 @@ else end -- airspeed if status_altmode == 5 and prev_status_altmode ~= 5 then - if cur_ias < 64 then - send_as = 64 + if cur_ias < cur_aircraft.min_as then + send_as = cur_aircraft.min_as else send_as = math.floor(cur_ias + 0.5) end diff --git a/src/main.c b/src/main.c index 3e7e0e5..8f92fa0 100644 --- a/src/main.c +++ b/src/main.c @@ -24,12 +24,25 @@ __attribute__((packed)) struct button_report { uint32_t buttons; }; +#define APP_UPDATE 0 +#define APP_INIT 1 + __attribute__((packed)) struct app_report { - int16_t hdg; - int16_t leds; - int16_t alt; - int16_t vs; - int16_t as; + uint8_t type; + union { + struct __attribute__((packed)) { + int16_t hdg; + int16_t leds; + int16_t alt; + int16_t vs; + int16_t as; + } update; + struct __attribute__((packed)) { + int16_t min_as; + int16_t max_as; + int16_t reserved[3]; + } init; + }; }; static struct light_data the_light_data; @@ -41,6 +54,8 @@ static volatile unsigned alt = 0; static volatile int vs = 0; static volatile unsigned as = 0; +static int min_as = 0, max_as = 999; + #define BUTTON_HDG_SYNC 1 #define BUTTON_ALT_SYNC 7 @@ -133,17 +148,17 @@ void rotary_event(int rot_ch, bool ccw) update_alt_display(); } else if (rot_ch == 1) { if (ccw) { - vs = vs == -5000 ? -5000 : vs - 100; + vs = vs == -5000 ? -5000 : ((vs < 0 ? vs : vs + 99) / 100) * 100 - 100; } else { - vs = vs == 5000 ? 5000 : vs + 100; + vs = vs == 5000 ? 5000 : ((vs > 0 ? vs : vs - 99) / 100) * 100 + 100; } update_vs_display(); } else { // TODO: knots / mach mode switch if (ccw) { - as = as == 64 ? 64 : as - 1; + as = as <= min_as ? min_as : as - 1; } else { - as = as == 205 ? 205 : as + 1; + as = as >= max_as ? max_as : as + 1; } update_as_display(); } @@ -187,15 +202,15 @@ static void hid_task(void) start_ms += interval_ms; if (start_ms % 10 == 0 && send_heading_reports) { - struct app_report report = { .hdg = -1, .alt = -1, .vs = -1, .as = -1 }; + struct app_report report = { .type = APP_UPDATE, .update = { .hdg = -1, .alt = -1, .vs = -1, .as = -1 } }; if (send_heading_reports) - report.hdg = hdg; + report.update.hdg = hdg; if (send_alt_reports) - report.alt = alt; + report.update.alt = alt; if (send_vs_reports) - report.vs = vs; + report.update.vs = vs; if (send_as_reports) - report.as = as; + report.update.as = as; if (tud_hid_ready()) tud_hid_n_report(ITF_NUM_HID, HID_REPORT_APP, &report, sizeof(report)); } else { @@ -222,6 +237,54 @@ static void hid_task(void) } } +static void app_update_report(struct app_report const *report) +{ + if (report->update.hdg >= 0) { + hdg = report->update.hdg; + update_hdg_display(); + send_heading_reports = true; + } + if (report->update.alt >= 0) { + alt = report->update.alt; + update_alt_display(); + send_alt_reports = true; + } + if (report->update.vs != -1) { + if (report->update.vs == -2) { + // disable vs mode + show_vs = false; + send_vs_reports = false; + } else { + vs = report->update.vs; + show_vs = true; + send_vs_reports = true; + } + update_vs_display(); + } + if (report->update.as != -1) { + if (report->update.as == -2) { + show_as = false; + send_as_reports = false; + } else { + as = report->update.as; + show_as = true; + send_as_reports = true; + } + update_as_display(); + } + if (report->update.leds >= 0) { + statusleds_set(report->update.leds); + } +} + +static void app_init_report(struct app_report const *report) +{ + min_as = report->init.min_as; + max_as = report->init.max_as; + show_vs = false; + show_as = false; +} + void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { @@ -229,41 +292,15 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ 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); + switch (report.type) { + case APP_UPDATE: + app_update_report(&report); + break; + case APP_INIT: + app_init_report(&report); + break; + default: + break; } } diff --git a/src/usb_config.c b/src/usb_config.c index f5f8ce5..5e9f0b7 100644 --- a/src/usb_config.c +++ b/src/usb_config.c @@ -25,19 +25,27 @@ HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ HID_COLLECTION_END -#define RP2040_HID_REPORT_DESC_APP(...) \ +#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(5), \ - HID_REPORT_SIZE(16), \ + HID_REPORT_COUNT(1), \ + HID_REPORT_SIZE(8), \ 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_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ + 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(2), \ + HID_USAGE_MAX(6), \ + HID_INPUT(HID_DATA | HID_VARIABLE | HID_ABSOLUTE), \ HID_COLLECTION_END /* HID_REPORT_COUNT(16), /\*16 button lights *\/ \ */ @@ -52,7 +60,6 @@ /* HID_USAGE_MAX(1), \ */ /* HID_INPUT(HID_CONSTANT | HID_VARIABLE | HID_ABSOLUTE), \ */ - /* clang-format on */ static char const *string_desc_arr[] = {