diff --git a/lib_xua/lib_xua/src/core/user/hid/user_hid.h b/lib_xua/lib_xua/src/core/user/hid/user_hid.h index 9fdf141..ad06b27 100644 --- a/lib_xua/lib_xua/src/core/user/hid/user_hid.h +++ b/lib_xua/lib_xua/src/core/user/hid/user_hid.h @@ -38,6 +38,8 @@ typedef struct hidEvent_t { #endif #define HID_EVENT_INVALID_ID ( 0x100 ) +#define HID_MAX_OUT_BYTES ( 65 ) + /** * \brief Get the data for the next HID Report * diff --git a/lib_xua/lib_xua/src/hid/hid.xc b/lib_xua/lib_xua/src/hid/hid.xc index 52ad0f3..6e84aa8 100644 --- a/lib_xua/lib_xua/src/hid/hid.xc +++ b/lib_xua/lib_xua/src/hid/hid.xc @@ -20,6 +20,8 @@ static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, static XUD_Result_t HidProcessSetIdleRequest( XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &sp ); static unsigned HidTimeDiff( const unsigned earlierTime, const unsigned laterTime ); +extern unsigned char process_send_params(uint8_t data[], uint16_t len); +extern unsigned char process_read_params(uint8_t response[]); XUD_Result_t HidInterfaceClassRequests( XUD_ep c_ep0_out, XUD_ep c_ep0_in, @@ -28,14 +30,37 @@ XUD_Result_t HidInterfaceClassRequests( #endif USB_SetupPacket_t &sp ) { -#if (USE_EX3D == 1) +#if ((USE_EX3D == 1) || (EQ_EN == 1)) unsigned datalength; - unsigned char buffer[64] = {0}; + unsigned char buffer[65] = {0}; #endif XUD_Result_t result = XUD_RES_ERR; switch ( sp.bRequest ) { -#if (USE_EX3D == 1) + case HID_GET_REPORT: + unsigned ret_len = 65; + + buffer[0] = 0x1; + process_read_params(&buffer[1]); +#if 0 + debug_printf("%d:\n", ret_len); + for(int i=0; i < ret_len; i++) + { + printhex((buffer, unsigned char[])[i]); + printstr("-"); + } + printstrln("\n"); +#endif + return XUD_DoGetRequest(c_ep0_out, c_ep0_in, (buffer, unsigned char []), ret_len, sp.wLength); + break; + case HID_GET_IDLE: + /* Do nothing - i.e. STALL */ + break; + case HID_GET_PROTOCOL: + /* Do nothing - i.e. STALL */ + break; + +#if ((USE_EX3D == 1) || (EQ_EN == 1)) case HID_SET_REPORT: result = XUD_GetBuffer(c_ep0_out, (buffer, unsigned char[]), datalength); if(result == XUD_RES_OKAY) { @@ -49,6 +74,11 @@ XUD_Result_t HidInterfaceClassRequests( } } + if (buffer[1] == 0x77 && buffer[2] >= 0x8A) + { + process_send_params(&buffer[1], datalength - 1); + } + result = XUD_DoSetRequestStatus(c_ep0_in); } break; @@ -58,6 +88,9 @@ XUD_Result_t HidInterfaceClassRequests( result = HidProcessSetIdleRequest( c_ep0_out, c_ep0_in, sp ); break; + case HID_SET_PROTOCOL: + break; + default: break; } diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt b/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt index 36c7539..72299d8 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt +++ b/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt @@ -44,6 +44,7 @@ set(SW_USB_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} -O3 -DUSB_TILE=tile[0] -DADAT_TX_USE_SHARED_BUFF=1 -DXUA_QUAD_SPI_FLASH=1 + -DEQ_EN=1 -D${TARGET_BOARD} -D${CODEC_IC} -DWINDOWS_OS_DESCRIPTOR_SUPPORT diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp_core0.xc b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp_core0.xc index 2ea9f8b..463fba1 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp_core0.xc +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp_core0.xc @@ -41,23 +41,17 @@ void dsp_core0(void) static unsigned int usb_to_dsp_ratio = 1; static int buffer_in_active = 0; static int buffer_out_active = 0; - static unsigned int sample_freq; + static unsigned int sample_freq = 48000; unsigned b_fade_in = 0; unsigned u_in_step; unsigned b_fade_out = 0; unsigned u_out_step; - unsigned settings_initialized; // EQ Flash存储初始化标志 delay_milliseconds(100); #if EQ_EN - GET_SHARED_GLOBAL(settings_initialized, g_settings_initialized); - while (settings_initialized == 0) { - GET_SHARED_GLOBAL(settings_initialized, g_settings_initialized); - } - debug_printf("Settings initialized\n"); uint32_t time = get_reference_time(), time2; // EQ Flash存储初始化 - 只在第一次运行时执行 @@ -113,7 +107,6 @@ void dsp_core0(void) } else { - sample_freq = g_samfreq; audio_in_samples[0] = read_from_ring_buffer(0); audio_in_samples[1] = read_from_ring_buffer(1); diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq.c b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq.c index 2ca8dc2..7938a1e 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq.c +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq.c @@ -35,95 +35,6 @@ #include "biquad_standalone.h" #include "eq_flash_storage.h" -// 改动原因:设备参数专用的读取请求标志,使用独立帧头0x77 0x5C,与EQ命令分离 -static struct { - bool is_read_device_params_request; // 设备参数读取请求标志 -} device_params_request = {0}; - -/** - * @brief 处理设备参数设置命令 (帧头: 0x77 0x5C) - * @param data HID数据包 - * @return 处理结果 - * - * 改动原因:将设备参数命令从EQ命令中独立出来,使用专用帧头0x77 0x5C,避免与EQ命令混淆 - */ -unsigned char process_device_params_set(uint8_t data[]) { - // 检查命令码 - if (data[2] != 0x94) { - debug_printf("Error: Invalid device params set command: 0x%02x\n", data[2]); - return false; - } - - debug_printf("Received set device params command (0x77 0x5C 0x94)\n"); - - // 数据格式: - // Byte 0: 0x77 (sync header 1) - // Byte 1: 0x5C (sync header 2 - device params) - // Byte 2: 0x94 (SET_DEVICE_PARAMS command) - // Byte 3: volume_level (0-60) - // Byte 4: gain_mode (0:低阻, 1:高阻) - // Byte 5: filter_mode (0-6) - // Byte 6: game_mode (0-2) - - extern unsigned g_volume_level, g_gain_mode, g_filter_mode, g_game_mode; - - uint8_t volume_level = data[3]; - uint8_t gain_mode = data[4]; - uint8_t filter_mode = data[5]; - uint8_t game_mode = data[6]; - - debug_printf("Setting device params - Volume: %d, Gain: %d, Filter: %d, Game: %d\n", - volume_level, gain_mode, filter_mode, game_mode); - - // 参数验证 - if (volume_level > 60) { - debug_printf("Error: Invalid volume_level %d (must be 0-60)\n", volume_level); - return false; - } - if (gain_mode > 1) { - debug_printf("Error: Invalid gain_mode %d (must be 0-1)\n", gain_mode); - return false; - } - if (filter_mode > 6) { - debug_printf("Error: Invalid filter_mode %d (must be 0-6)\n", filter_mode); - return false; - } - if (game_mode > 2) { - debug_printf("Error: Invalid game_mode %d (must be 0-2)\n", game_mode); - return false; - } - - // 设置全局变量(直接赋值,因为在C文件中) - g_volume_level = volume_level; - g_gain_mode = gain_mode; - g_filter_mode = filter_mode; - g_game_mode = game_mode; - - debug_printf("Device params set successfully\n"); - return true; -} - -/** - * @brief 处理设备参数读取请求 (帧头: 0x77 0x5C) - * @param data HID数据包 - * @return 处理结果 - * - * 改动原因:将设备参数命令从EQ命令中独立出来,使用专用帧头0x77 0x5C - */ -unsigned char process_device_params_get_request(uint8_t data[]) { - // 检查命令码 - if (data[2] != 0x95) { - debug_printf("Error: Invalid device params get command: 0x%02x\n", data[2]); - return false; - } - - debug_printf("Received get device params request (0x77 0x5C 0x95)\n"); - - // 设置读取请求标志 - device_params_request.is_read_device_params_request = true; - return true; -} - #if EQ_EN @@ -1182,7 +1093,6 @@ void get_device_info(unsigned char *response) { -void program_key(unsigned char *, signed int); unsigned char process_send_params(uint8_t data[], uint16_t len) { #if 0 for (int i = 0; i < len; i++) { @@ -1195,30 +1105,6 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) { return false; } - // 改动原因:优先检查设备参数命令帧头 0x77 0x5C,与EQ命令分离 - if (data[0] == 0x77 && data[1] == 0x5C) { - debug_printf("Device params frame detected (0x77 0x5C)\n"); - g_settings_program = 1; - - // 根据命令码分发 - if (data[2] == 0x94) { - // SET_DEVICE_PARAMS - return process_device_params_set(data); - } else if (data[2] == 0x95) { - // GET_DEVICE_PARAMS request - return process_device_params_get_request(data); - } else { - debug_printf("Error: Unknown device params command: 0x%02x\n", data[2]); - return false; - } - } - - if (data[0] == 0x77 && data[1] == 0x5B && key_program == 0) - { - key_program = 1; - program_key(data, len); - } - #if EQ_EN // Check sync header if (data[0] != 0x77) { @@ -2123,64 +2009,10 @@ void init_mode_info(void) { #endif -/** - * @brief 构建设备参数读取响应 - * @param response 响应数据缓冲区 - * @return 处理结果 - * - * 改动原因:独立的设备参数响应构建函数 - */ -unsigned char build_device_params_response(uint8_t response[]) { - if (device_params_request.is_read_device_params_request == false) { - return false; - } - - debug_printf("Building device params response (0x77 0x5C 0x95)\n"); - - // 读取全局变量(直接读取,因为在C文件中) - extern unsigned g_volume_level, g_gain_mode, g_filter_mode, g_game_mode; - unsigned volume_level = g_volume_level; - unsigned gain_mode = g_gain_mode; - unsigned filter_mode = g_filter_mode; - unsigned game_mode = g_game_mode; - - // 填充响应数据 - // 数据格式: - // Byte 0: 0x77 (sync header 1) - // Byte 1: 0x5C (sync header 2 - device params) - // Byte 2: 0x95 (GET_DEVICE_PARAMS response) - // Byte 3: volume_level (0-60) - // Byte 4: gain_mode (0:低阻, 1:高阻) - // Byte 5: filter_mode (0-6) - // Byte 6: game_mode (0-2) - response[0] = 0x77; // Sync header 1 - response[1] = 0x5C; // Sync header 2 (device params) - response[2] = 0x95; // GET_DEVICE_PARAMS response - response[3] = volume_level; - response[4] = gain_mode; - response[5] = filter_mode; - response[6] = game_mode; - - debug_printf("Device params - Volume: %d, Gain: %d, Filter: %d, Game: %d\n", - volume_level, gain_mode, filter_mode, game_mode); - - device_params_request.is_read_device_params_request = false; // Clear request flag - return true; -} - void get_key_ret(uint8_t *buffer); // Process read parameter request - Get bands and coeffs data from eq_hid_params unsigned char process_read_params(uint8_t response[]) { - // 改动原因:优先处理设备参数读取请求,使用独立帧头0x77 0x5C - if (g_settings_program == 1) { - g_settings_program = 0; - - if (build_device_params_response(response)) { - return true; - } - return true; - } - + debug_printf("========================\n"); #if EQ_EN // 处理读取当前EQ模式的请求 (0x8B) - GET_EQ_MODE if (read_request.is_read_mode_request == true) { @@ -2377,14 +2209,11 @@ unsigned char process_read_params(uint8_t response[]) { return true; } #endif -#if 1 - if (key_program == 1) - { - key_program = 0; - debug_printf("Key program completed\n"); - get_key_ret(response); - return true; +#if 0 + for (int i = 0; i < len; i++) { + debug_printf("data[%d]: %02x\n", i, data[i]); } -#endif - return false; + debug_printf("len: %d\n", len); +#endif + return false; } \ No newline at end of file diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq_designer_new.py b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq_designer_new.py index eaf0cb8..3f5dd2c 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq_designer_new.py +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/eq_designer_new.py @@ -711,6 +711,7 @@ class EQDesigner(QMainWindow): import time time.sleep(0.05) # 等待设备响应 reply = h.get_input_report(0x1, 64) # 64字节响应 + print(reply) if reply and len(reply) == 64: # 检查Report ID和同步头 if reply[0] == 0x01 and reply[1] == 0x77 and reply[2] == 0x8B: @@ -1341,7 +1342,9 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{ for device in hid.enumerate(): # 添加usage page信息 usage_page = device.get('usage_page', 0) - if (usage_page == 0xff82 or usage_page == 0xff83): + pid = device.get('product_id', 0) + vid = device.get('vendor_id', 0) + if ((usage_page == 0xff82 or usage_page == 0xff83) or (vid == 0x20b1 and pid == 0x0016)): info = f"{device.get('product_string', 'Unknown')}" self.device_combo.addItem(info, device) self.on_switch_mode() diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/hid_report_descriptor.h b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/hid_report_descriptor.h similarity index 90% rename from sw_usb_audio/app_usb_aud_phaten_golden/src/hid_report_descriptor.h rename to sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/hid_report_descriptor.h index 0556576..f5810d3 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/hid_report_descriptor.h +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/hid_report_descriptor.h @@ -29,6 +29,35 @@ unsigned char hidReportDescriptor[] = }; #endif +static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }}; + +static const USB_HID_Short_Item_t hidUsagePageVendor = { .header = 0x06, .data = { 0x82, 0xff }}; + +static const USB_HID_Short_Item_t hidUsageConsumerVendor = { .header = 0x09, .data = { 0x03, 0x00 }}; + +static const USB_HID_Short_Item_t hidPassReportId = { .header = 0x85, .data = { 0x1, 0x00 }}; +static const USB_HID_Short_Item_t hidButtonReportId = { .header = 0x85, .data = { 0x2, 0x00 }}; + +static const USB_HID_Short_Item_t hidLogicalMaximum2 = { .header = 0x26, .data = { 0xFF, 0x00 }}; + +static const USB_HID_Short_Item_t hidReportSize = { .header = 0x75, .data = { 0x08, 0x00 }}; +#if DEBUG_MEMORY_LOG_ENABLED +static const USB_HID_Short_Item_t hidPassReportCount = { .header = 0x95, .data = { 0x3F, 0x00 }}; +static const USB_HID_Short_Item_t hidPassReportCount2 = { .header = 0x95, .data = { 0x3F, 0x00 }}; +static const USB_HID_Short_Item_t hidPassReportCount3 = { .header = 0x95, .data = { 0x3f, 0x00 }}; +#else +static const USB_HID_Short_Item_t hidPassReportCount = { .header = 0x95, .data = { 0x3f, 0x00 }}; +static const USB_HID_Short_Item_t hidPassReportCount2 = { .header = 0x95, .data = { 0x3f, 0x00 }}; +static const USB_HID_Short_Item_t hidPassReportCount3 = { .header = 0x95, .data = { 0x3f, 0x00 }}; +#endif +static const USB_HID_Short_Item_t hidButtonReportCount = { .header = 0x95, .data = { 0x04, 0x00 }}; +static const USB_HID_Short_Item_t hidUsageVendor = { .header = 0x09, .data = { 0x04, 0x00 }}; +static const USB_HID_Short_Item_t hidUsageVendor2 = { .header = 0x09, .data = { 0x05, 0x00 }}; + +static const USB_HID_Short_Item_t hidInputFeatureVar = { + .header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_FEATURE), + .data = { 0x01, 0x00 } }; + #if 0//AIZIP_DNR == 1 /* * Define non-configurable items in the HID Report descriptor. @@ -396,6 +425,9 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &hidOutputDataVar, &(hidUsageUnassigned.item), &hidInputDataVar, + &(hidUsageUnassigned.item), + &hidInputFeatureVar, + // &hidLogicalMinimum0, // &hidLogicalMaximum1,