From 9526491fe8d8d0e4030b25d9f12ee4696503684e Mon Sep 17 00:00:00 2001 From: Jacki Date: Sun, 22 Dec 2024 12:47:16 +0100 Subject: [PATCH] Implement MCU support for Xreal Air 2 Ultra --- examples/debug_mcu/src/debug.c | 28 +++++++++- interface_lib/include/device_mcu.h | 20 +++++++ interface_lib/src/device_mcu.c | 89 +++++++++++++++++++++++++++++- interface_lib/src/hid_ids.c | 2 +- 4 files changed, 134 insertions(+), 5 deletions(-) diff --git a/examples/debug_mcu/src/debug.c b/examples/debug_mcu/src/debug.c index e8bea0c..6597ae1 100644 --- a/examples/debug_mcu/src/debug.c +++ b/examples/debug_mcu/src/debug.c @@ -31,8 +31,11 @@ void test(uint64_t timestamp, uint8_t brightness, const char* msg) { switch (event) { - case DEVICE_MCU_EVENT_MESSAGE: - printf("Message: `%s`\n", msg); + case DEVICE_MCU_EVENT_SCREEN_OFF: + printf("Toggle Screen OFF!\n"); + break; + case DEVICE_MCU_EVENT_SCREEN_ON: + printf("Toggle Screen ON!\n"); break; case DEVICE_MCU_EVENT_BRIGHTNESS_UP: printf("Increase Brightness: %u\n", brightness); @@ -40,6 +43,27 @@ void test(uint64_t timestamp, case DEVICE_MCU_EVENT_BRIGHTNESS_DOWN: printf("Decrease Brightness: %u\n", brightness); break; + case DEVICE_MCU_EVENT_MESSAGE: + printf("Message: `%s`\n", msg); + break; + case DEVICE_MCU_EVENT_DISPLAY_MODE_2D: + printf("Toggle Display Mode 2D!\n"); + break; + case DEVICE_MCU_EVENT_DISPLAY_MODE_3D: + printf("Toggle Display Mode 3D!\n"); + break; + case DEVICE_MCU_EVENT_BLEND_CYCLE: + printf("Cycle Screen Blending!\n"); + break; + case DEVICE_MCU_EVENT_CONTROL_TOGGLE: + printf("Toggle Control Mode!\n"); + break; + case DEVICE_MCU_EVENT_VOLUME_UP: + printf("Increase Volume!\n"); + break; + case DEVICE_MCU_EVENT_VOLUME_DOWN: + printf("Decrease Volume!\n"); + break; default: break; } diff --git a/interface_lib/include/device_mcu.h b/interface_lib/include/device_mcu.h index 2d9448c..a253317 100644 --- a/interface_lib/include/device_mcu.h +++ b/interface_lib/include/device_mcu.h @@ -75,6 +75,7 @@ #define DEVICE_MCU_MSG_W_BOOT_UPDATE_FINISH 0x1105 #define DEVICE_MCU_MSG_P_START_HEARTBEAT 0x6c02 +#define DEVICE_MCU_MSG_P_DISPLAY_TOGGLED 0x6C04 #define DEVICE_MCU_MSG_P_BUTTON_PRESSED 0x6C05 #define DEVICE_MCU_MSG_P_END_HEARTBEAT 0x6c12 #define DEVICE_MCU_MSG_P_ASYNC_TEXT_LOG 0x6c09 @@ -101,6 +102,17 @@ #define DEVICE_MCU_BUTTON_VIRT_BRIGHTNESS_DOWN 0x7 #define DEVICE_MCU_BUTTON_VIRT_UP 0x8 #define DEVICE_MCU_BUTTON_VIRT_DOWN 0x9 +#define DEVICE_MCU_BUTTON_VIRT_MODE_2D 0xA +#define DEVICE_MCU_BUTTON_VIRT_MODE_3D 0xB +#define DEVICE_MCU_BUTTON_VIRT_BLEND_CYCLE 0xC +#define DEVICE_MCU_BUTTON_VIRT_CONTROL_TOGGLE 0xF + +#define DEVICE_MCU_BLEND_STATE_LOW 0x0 +#define DEVICE_MCU_BLEND_STATE_MEDIUM 0x2 +#define DEVICE_MCU_BLEND_STATE_FULL 0x3 + +#define DEVICE_MCU_CONTROL_MODE_BRIGHTNESS 0x0 +#define DEVICE_MCU_CONTROL_MODE_VOLUME 0x1 #ifdef __cplusplus extern "C" { @@ -141,6 +153,12 @@ enum device_mcu_event_t { DEVICE_MCU_EVENT_BRIGHTNESS_UP = 3, DEVICE_MCU_EVENT_BRIGHTNESS_DOWN = 4, DEVICE_MCU_EVENT_MESSAGE = 5, + DEVICE_MCU_EVENT_DISPLAY_MODE_2D = 6, + DEVICE_MCU_EVENT_DISPLAY_MODE_3D = 7, + DEVICE_MCU_EVENT_BLEND_CYCLE = 8, + DEVICE_MCU_EVENT_CONTROL_TOGGLE = 9, + DEVICE_MCU_EVENT_VOLUME_UP = 10, + DEVICE_MCU_EVENT_VOLUME_DOWN = 11, }; typedef enum device_mcu_error_t device_mcu_error_type; @@ -167,6 +185,8 @@ struct device_mcu_t { bool active; uint8_t brightness; uint8_t disp_mode; + uint8_t blend_state; + uint8_t control_mode; device_mcu_event_callback callback; }; diff --git a/interface_lib/src/device_mcu.c b/interface_lib/src/device_mcu.c index 9e76f0a..551617d 100644 --- a/interface_lib/src/device_mcu.c +++ b/interface_lib/src/device_mcu.c @@ -43,6 +43,8 @@ #define device_mcu_error(msg) (0) #endif +#define device_mcu_warning(msg) device_mcu_error(msg) + #define MAX_PACKET_SIZE 64 #define PACKET_HEAD 0xFD @@ -231,8 +233,7 @@ device_mcu_error_type device_mcu_open(device_mcu_type* device, device_mcu_event_ device->activated = (activated != 0); if (!device->activated) { - device_mcu_error("Device is not activated"); - return DEVICE_MCU_ERROR_NO_ACTIVATION; + device_mcu_warning("Device is not activated"); } if (!send_payload_action(device, DEVICE_MCU_MSG_R_MCU_APP_FW_VERSION, 0, NULL)) { @@ -382,6 +383,30 @@ device_mcu_error_type device_mcu_read(device_mcu_type* device, int timeout) { case DEVICE_MCU_MSG_P_START_HEARTBEAT: { break; } + case DEVICE_MCU_MSG_P_DISPLAY_TOGGLED: { + const uint8_t value = packet.data[0]; + + device->active = value; + + if (device->active) { + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_SCREEN_ON, + device->brightness, + NULL + ); + } else { + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_SCREEN_OFF, + device->brightness, + NULL + ); + } + break; + } case DEVICE_MCU_MSG_P_BUTTON_PRESSED: { const uint8_t phys_button = packet.data[0]; const uint8_t virt_button = packet.data[4]; @@ -431,6 +456,66 @@ device_mcu_error_type device_mcu_read(device_mcu_type* device, int timeout) { NULL ); break; + case DEVICE_MCU_BUTTON_VIRT_UP: + if (device->control_mode == DEVICE_MCU_CONTROL_MODE_VOLUME) + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_VOLUME_UP, + device->brightness, + NULL + ); + break; + case DEVICE_MCU_BUTTON_VIRT_DOWN: + if (device->control_mode == DEVICE_MCU_CONTROL_MODE_VOLUME) + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_VOLUME_DOWN, + device->brightness, + NULL + ); + break; + case DEVICE_MCU_BUTTON_VIRT_MODE_2D: + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_DISPLAY_MODE_2D, + device->brightness, + NULL + ); + break; + case DEVICE_MCU_BUTTON_VIRT_MODE_3D: + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_DISPLAY_MODE_3D, + device->brightness, + NULL + ); + break; + case DEVICE_MCU_BUTTON_VIRT_BLEND_CYCLE: + device->blend_state = value; + + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_BLEND_CYCLE, + device->brightness, + NULL + ); + break; + case DEVICE_MCU_BUTTON_VIRT_CONTROL_TOGGLE: + device->control_mode = value; + + device_mcu_callback( + device, + timestamp, + DEVICE_MCU_EVENT_CONTROL_TOGGLE, + device->brightness, + NULL + ); + break; default: break; } diff --git a/interface_lib/src/hid_ids.c b/interface_lib/src/hid_ids.c index 25799b3..c86bbcd 100644 --- a/interface_lib/src/hid_ids.c +++ b/interface_lib/src/hid_ids.c @@ -53,7 +53,7 @@ const int xreal_mcu_interface_ids[NUM_SUPPORTED_PRODUCTS] = { 4, // XREAL Air 4, // XREAL Air 2 4, // XREAL Air 2 Pro - -1 // TODO - XREAL Air 2 Ultra MCU support via interface 0 + 0 // XREAL Air 2 Ultra MCU }; static int xreal_product_index(uint16_t product_id) {