diff --git a/CMakeLists.txt b/CMakeLists.txt index c4cd9a3..4ee574c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,13 @@ set(PICO_BOARD pico2_w CACHE STRING "Board type") #set(PICO_CYW43_SUPPORTED 1) #set(PICO_CYW43_ARCH_THREADSAFE_BACKGROUND 1) +option(ENABLE_SERIAL "Enable USB CDC serial printf output" OFF) +if (ENABLE_SERIAL) + set(ENABLE_SERIAL_VALUE 1) +else () + set(ENABLE_SERIAL_VALUE 0) +endif () + # Pull in Raspberry Pi Pico SDK (must be before project) include(pico_sdk_import.cmake) @@ -67,9 +74,13 @@ target_compile_definitions(wdl_resampler PRIVATE ) target_compile_definitions(ds5-bridge PRIVATE CYW43_LWIP=0 + ENABLE_SERIAL=${ENABLE_SERIAL_VALUE} PICO_FLASH_ASSUME_CORE1_SAFE=1 WDL_RESAMPLE_TYPE=float CYW43_PIO_CLOCK_DIV_INT=5 + PICO_STDIO_USB_USE_DEFAULT_DESCRIPTORS=0 + PICO_STDIO_USB_ENABLE_RESET_VIA_BAUD_RATE=0 + PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE=0 ) pico_set_program_name(ds5-bridge "ds5-bridge") @@ -77,7 +88,7 @@ pico_set_program_version(ds5-bridge "0.5.3") # Modify the below lines to enable/disable output over UART/USB pico_enable_stdio_uart(ds5-bridge 1) -pico_enable_stdio_usb(ds5-bridge 0) +pico_enable_stdio_usb(ds5-bridge ${ENABLE_SERIAL_VALUE}) # Add the standard include files to the build #target_include_directories(ds5-bridge PRIVATE diff --git a/src/bt.cpp b/src/bt.cpp index eb14abd..2954e75 100644 --- a/src/bt.cpp +++ b/src/bt.cpp @@ -298,7 +298,9 @@ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p } case HCI_EVENT_DISCONNECTION_COMPLETE: { +#ifndef ENABLE_SERIAL tud_disconnect(); +#endif gap_connectable_control(1); gap_discoverable_control(1); const uint8_t reason = hci_event_disconnection_complete_get_reason(packet); @@ -345,7 +347,9 @@ static void l2cap_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t }else if (size > 1){ is_dse = true; } +#ifndef ENABLE_SERIAL tud_connect(); +#endif } if (packet[0] == 0xA3) { uint8_t report_id = packet[1]; diff --git a/src/main.cpp b/src/main.cpp index cd46262..34d574a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,9 @@ #include "hardware/vreg.h" #include "hardware/watchdog.h" #include "pico/cyw43_arch.h" +#if ENABLE_SERIAL +#include "pico/stdio_usb.h" +#endif #include "config.h" #include "cmd.h" @@ -175,8 +178,13 @@ int main() { .speed = TUSB_SPEED_FULL }; tusb_init(BOARD_TUD_RHPORT, &dev_init); +#ifndef ENABLE_SERIAL tud_disconnect(); +#endif board_init_after_tusb(); +#if ENABLE_SERIAL + stdio_usb_init(); +#endif if (cyw43_arch_init()) { printf("Failed to initialize CYW43\n"); diff --git a/src/tusb_config.h b/src/tusb_config.h index c36e201..875d63a 100644 --- a/src/tusb_config.h +++ b/src/tusb_config.h @@ -30,6 +30,10 @@ extern "C" { #endif +#ifndef ENABLE_SERIAL +#define ENABLE_SERIAL 0 +#endif + //--------------------------------------------------------------------+ // Board Specific Configuration //--------------------------------------------------------------------+ @@ -93,7 +97,7 @@ //------------- CLASS -------------// #define CFG_TUD_AUDIO 1 #define CFG_TUD_HID 1 -#define CFG_TUD_CDC 1 +#define CFG_TUD_CDC ENABLE_SERIAL #define CFG_TUD_MSC 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 @@ -143,4 +147,4 @@ } #endif -#endif /* TUSB_CONFIG_H_ */ \ No newline at end of file +#endif /* TUSB_CONFIG_H_ */ diff --git a/src/usb_descriptors.cpp b/src/usb_descriptors.cpp index c41be18..2d32ff4 100644 --- a/src/usb_descriptors.cpp +++ b/src/usb_descriptors.cpp @@ -27,6 +27,10 @@ #include "tusb.h" #include "config.h" +#ifndef ENABLE_SERIAL +#define ENABLE_SERIAL 0 +#endif + bool ds_mode() { if (get_config().controller_mode == 2) { return !is_dse; @@ -34,6 +38,41 @@ bool ds_mode() { return get_config().controller_mode == 0; } +enum { + ITF_NUM_AUDIO_CONTROL = 0, + ITF_NUM_AUDIO_STREAMING_OUT, + ITF_NUM_AUDIO_STREAMING_IN, + ITF_NUM_HID, +#if ENABLE_SERIAL + ITF_NUM_CDC, + ITF_NUM_CDC_DATA, +#endif + ITF_NUM_TOTAL, + + CONFIG_DESC_LEN_AUDIO_IAD = +#if ENABLE_SERIAL + 8, +#else + 0, +#endif + CONFIG_DESC_LEN_BASE = 0x00E3 + CONFIG_DESC_LEN_AUDIO_IAD, + CONFIG_DESC_LEN_TOTAL = CONFIG_DESC_LEN_BASE +#if ENABLE_SERIAL + + TUD_CDC_DESC_LEN +#endif +}; + +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +#if ENABLE_SERIAL + STRID_CDC, +#endif +}; + //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ @@ -45,12 +84,15 @@ tusb_desc_device_t desc_device = // Use Interface Association Descriptor (IAD) for Audio // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) - /*.bDeviceClass = TUSB_CLASS_MISC, +#if ENABLE_SERIAL + .bDeviceClass = TUSB_CLASS_MISC, .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD,*/ + .bDeviceProtocol = MISC_PROTOCOL_IAD, +#else .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, +#endif .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = 0x054C, @@ -79,13 +121,25 @@ uint8_t descriptor_configuration[] = { // --- CONFIGURATION DESCRIPTOR --- 0x09, // bLength 0x02, // bDescriptorType (CONFIGURATION) - 0xE3, 0x00, // wTotalLength: 227 - 0x04, // bNumInterfaces: 4 + U16_TO_U8S_LE(CONFIG_DESC_LEN_TOTAL), // wTotalLength + ITF_NUM_TOTAL, // bNumInterfaces 0x01, // bConfigurationValue: 1 0x00, // iConfiguration: 0 0xC0, // bmAttributes: SELF-POWERED, NO REMOTE-WAKEUP 0xFA, // bMaxPower: 500mA (250 * 2mA) +#if ENABLE_SERIAL + // --- INTERFACE ASSOCIATION DESCRIPTOR: Audio function (interfaces 0-2) --- + 0x08, // bLength + TUSB_DESC_INTERFACE_ASSOCIATION, // bDescriptorType + ITF_NUM_AUDIO_CONTROL, // bFirstInterface + 0x03, // bInterfaceCount + 0x01, // bFunctionClass: Audio + 0x01, // bFunctionSubClass: Audio Control + 0x00, // bFunctionProtocol + 0x00, // iFunction + +#endif // --- INTERFACE DESCRIPTOR (0.0): Audio Control --- 0x09, // bLength 0x04, // bDescriptorType (INTERFACE) @@ -326,6 +380,11 @@ uint8_t descriptor_configuration[] = { 0x03, // bmAttributes: Interrupt 0x40, 0x00, // wMaxPacketSize: 64 0x01, // bInterval: 1 (polling every 4ms -> 1ms) + +#if ENABLE_SERIAL + // --- CDC ACM (USB Serial) --- + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, STRID_CDC, 0x85, 0x08, 0x06, 0x86, 0x40), +#endif }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -345,7 +404,7 @@ uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { bInterval = 0x01; break; } - constexpr auto offset = sizeof(descriptor_configuration); + constexpr auto offset = CONFIG_DESC_LEN_BASE; descriptor_configuration[offset - 1] = bInterval; descriptor_configuration[offset - 8] = bInterval; if (ds_mode()) { @@ -741,14 +800,6 @@ uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) { // String Descriptors //--------------------------------------------------------------------+ -// String Descriptor Index -enum { - STRID_LANGID = 0, - STRID_MANUFACTURER, - STRID_PRODUCT, - STRID_SERIAL, -}; - // array of pointer to string descriptors static char const *string_desc_arr[] = { @@ -756,6 +807,9 @@ static char const *string_desc_arr[] = "Sony Interactive Entertainment", // 1: Manufacturer NULL, // 2: Product NULL, // 3: Serials will use unique ID if possible +#if ENABLE_SERIAL + "USB Serial", // 4: CDC interface +#endif }; static uint16_t _desc_str[60 + 1];