From c45ceea5359680567f139acf751ff725844e8c86 Mon Sep 17 00:00:00 2001 From: awalol Date: Sat, 9 May 2026 14:21:21 +0800 Subject: [PATCH] optimize high frequency 0x02 SetStateData --- src/audio.cpp | 31 +++++++++++++++++++++++++------ src/audio.h | 3 +++ src/main.cpp | 34 ++++++++++++++++++++++++++-------- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/audio.cpp b/src/audio.cpp index 0925198..27a9c44 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -40,6 +40,22 @@ struct audio_raw_element { float data[512 * 2]; }; +uint8_t interrupt_out_data[63] = { + 0xfd, 0xf7, 0x0, 0x0, + 0x7f, 0x7f, // Headphones, Speaker + 0xff, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x7, 0x0, 0x0, 0x2, 0x1, + 0x00, + 0xff, 0xd7, 0x00, // RGB LED: R, G, B (Nijika Color!)✨ +}; + +void set_interrupt_out_data(const uint8_t* data, const uint8_t len) { + memcpy(interrupt_out_data, data, len); +} + void set_headset(bool state) { plug_headset = state; } @@ -115,16 +131,19 @@ void audio_loop() { pkt[8] = buf_len; // 这 4 个字节的作用未知,调整没有效果 pkt[9] = buf_len; // audio buffer length 只有调整这个字节生效。 pkt[10] = packetCounter++; - pkt[11] = 0x12 | 0 << 6 | 1 << 7; - pkt[12] = SAMPLE_SIZE; - memcpy(pkt + 13, haptic_buf, SAMPLE_SIZE); - pkt[77] = (plug_headset ? 0x16 : 0x13) | 0 << 6 | 1 << 7; // Speaker: 0x13 + pkt[11] = 0x10 | 0 << 6 | 1 << 7; + pkt[12] = 63; + memcpy(pkt + 13, interrupt_out_data, sizeof(interrupt_out_data)); + pkt[76] = 0x12 | 0 << 6 | 1 << 7; + pkt[77] = SAMPLE_SIZE; + memcpy(pkt + 78, haptic_buf, SAMPLE_SIZE); + pkt[142] = (plug_headset ? 0x16 : 0x13) | 0 << 6 | 1 << 7; // Speaker: 0x13 // L Headset Mono: 0x14 // L Headset R Speaker: 0x15 // Headset: 0x16 - pkt[78] = 200; + pkt[143] = 200; critical_section_enter_blocking(&opus_cs); - memcpy(pkt + 79, opus_buf, 200); + memcpy(pkt + 144, opus_buf, 200); critical_section_exit(&opus_cs); bt_write(pkt, sizeof(pkt)); diff --git a/src/audio.h b/src/audio.h index 38aa1b0..b7afd00 100644 --- a/src/audio.h +++ b/src/audio.h @@ -5,9 +5,12 @@ #ifndef DS5_BRIDGE_AUDIO_H #define DS5_BRIDGE_AUDIO_H +#include + void audio_init(); void audio_loop(); void core1_entry(); void set_headset(bool state); +void set_interrupt_out_data(const uint8_t* data, const uint8_t len); #endif //DS5_BRIDGE_AUDIO_H \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e4171a5..3c807a0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,7 @@ int reportSeqCounter = 0; uint8_t packetCounter = 0; +bool spk_active = false; uint8_t interrupt_in_data[63] = { 0x7f, 0x7d, 0x7f, 0x7e, 0x00, 0x00, 0xa7, @@ -66,7 +67,7 @@ void interrupt_loop() { if (should_send) { if (!tud_hid_report(0x01, safe_report, 63)) { printf("[USBHID] tud_hid_report error\n"); - + // If the report failed to queue, restore the dirty flag // so we try again on the next loop iteration. critical_section_enter_blocking(&report_cs); @@ -113,7 +114,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t (void) reqlen; if (is_pico_cmd(report_id)) { - return pico_cmd_get(report_id,buffer,reqlen); + return pico_cmd_get(report_id, buffer, reqlen); } std::vector feature_data = get_feature_data(report_id, reqlen); @@ -124,6 +125,19 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t return feature_data.empty() ? 0 : feature_data.size() - 1; } +bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void) rhport; + uint8_t const itf = tu_u16_low(p_request->wIndex); // wInterface + uint8_t const alt = tu_u16_low(p_request->wValue); // bAlternateSetting + + if (itf == 1) { + printf("[AUDIO] Set interface Speaker to alternate setting %d\n", alt); + spk_active = alt; + } + + return true; +} + // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, @@ -135,8 +149,8 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep (void) bufsize; if (is_pico_cmd(report_id)) { - printf("[HID] Receive 0xf6 setting config, funcid:0x%02X\n",buffer[0]); - pico_cmd_set(report_id,buffer,bufsize); + printf("[HID] Receive 0xf6 setting config, funcid:0x%02X\n", buffer[0]); + pico_cmd_set(report_id, buffer, bufsize); return; } @@ -144,6 +158,10 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep if (report_id == 0) { switch (buffer[0]) { case 0x02: { + if (spk_active) { + set_interrupt_out_data(buffer + 1, bufsize - 1); + break; + } uint8_t outputData[78]; outputData[0] = 0x31; outputData[1] = reportSeqCounter << 4; @@ -162,7 +180,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep report_id == 0x60 || report_id == 0x62 || report_id == 0x61) { - set_feature_data(report_id,const_cast(buffer),bufsize); + set_feature_data(report_id, const_cast(buffer), bufsize); return; } } @@ -196,10 +214,10 @@ int main() { if (watchdog_caused_reboot()) { printf("Rebooted by Watchdog!\n"); // 当崩溃重启以后,闪三下灯 - for (int i = 0;i < 6;i++) { + for (int i = 0; i < 6; i++) { if (i % 2 == 0) { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true); - }else { + } else { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, false); } sleep_ms(500); @@ -208,7 +226,7 @@ int main() { printf("Clean boot\n"); } #endif - + // Initialize the critical section for the report buffer critical_section_init(&report_cs);