diff --git a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp index 4ceca33f6..83e70f55f 100644 --- a/hardware/arduino/sam/cores/arduino/USB/CDC.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/CDC.cpp @@ -64,13 +64,30 @@ static const CDCDescriptor _cdcInterface = D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 - D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x10/*0x40*/), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10), // CDC data interface D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,512,0), D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,512,0) }; +static const CDCDescriptor _cdcOtherInterface = +{ + D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1), + + // CDC communication interface + D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0), + D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd) + D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not) + D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported + D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0 + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10, 0x10), + + // CDC data interface + D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0), + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,64,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,64,0) +}; _Pragma("pack()") int WEAK CDC_GetInterface(uint8_t* interfaceNum) @@ -79,6 +96,12 @@ int WEAK CDC_GetInterface(uint8_t* interfaceNum) return USBD_SendControl(0,&_cdcInterface,sizeof(_cdcInterface)); } +int WEAK CDC_GetOtherInterface(uint8_t* interfaceNum) +{ + interfaceNum[0] += 2; // uses 2 + return USBD_SendControl(0,&_cdcOtherInterface,sizeof(_cdcOtherInterface)); +} + __attribute__ ((long_call, section (".ramfunc"))) void banzai() { // Disable all interrupts diff --git a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h index 7ccd1e219..8f10cff99 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBAPI.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBAPI.h @@ -191,6 +191,7 @@ bool MSC_Data(uint8_t rx,uint8_t tx); // CSC 'Driver' int CDC_GetInterface(uint8_t* interfaceNum); +int CDC_GetOtherInterface(uint8_t* interfaceNum); int CDC_GetDescriptor(int i); bool CDC_Setup(Setup& setup); diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp index f255f19d3..d5f0f9e0c 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.cpp @@ -96,6 +96,7 @@ const DeviceDescriptor USB_DeviceQualifier = volatile uint32_t _usbConfiguration = 0; volatile uint32_t _usbInitialized = 0; +uint32_t _usbSetInterface = 0; uint32_t _cdcComposite = 0; //================================================================== @@ -283,6 +284,24 @@ int USBD_SendInterfaces(void) return interfaces; } +int USBD_SendOtherInterfaces(void) +{ + int total = 0; + uint8_t interfaces = 0; + +#ifdef CDC_ENABLED + total = CDC_GetOtherInterface(&interfaces); +#endif + +#ifdef HID_ENABLED + total += HID_GetInterface(&interfaces); +#endif + + total = total; // Get rid of compiler warning + TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);) + return interfaces; +} + // Construct a dynamic configuration descriptor // This really needs dynamic endpoint allocation etc // TODO @@ -309,6 +328,29 @@ _Pragma("pack()") return true; } +static bool USBD_SendOtherConfiguration(int maxlen) +{ + // Count and measure interfaces + USBD_InitControl(0); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);) + int interfaces = USBD_SendOtherInterfaces(); + //TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);) + //TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));) + +_Pragma("pack(1)") + ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces); +_Pragma("pack()") + //TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);) + + //TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);) + + // Now send them + USBD_InitControl(maxlen); + USBD_SendControl(0,&config,sizeof(ConfigDescriptor)); + USBD_SendOtherInterfaces(); + return true; +} + static bool USBD_SendDescriptor(Setup& setup) { uint8_t t = setup.wValueH; @@ -344,15 +386,12 @@ static bool USBD_SendDescriptor(Setup& setup) TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");) if (setup.wValueL == 0) { desc_addr = (const uint8_t*)&STRING_LANGUAGE; - printf("St1=%d\n\r", *desc_addr); } else if (setup.wValueL == IPRODUCT) { desc_addr = (const uint8_t*)&STRING_IPRODUCT; - printf("St2=%d\n\r", *desc_addr); } else if (setup.wValueL == IMANUFACTURER) { desc_addr = (const uint8_t*)&STRING_IMANUFACTURER; - printf("St3=%d\n\r", *desc_addr); } else { return false; @@ -365,11 +404,14 @@ static bool USBD_SendDescriptor(Setup& setup) { // Device qualifier descriptor requested desc_addr = (const uint8_t*)&USB_DeviceQualifier; + if( *desc_addr > setup.wLength ) { + desc_length = setup.wLength; + } } else if (USB_OTHER_SPEED_CONFIGURATION == t) { - // TODO // Other configuration descriptor requested + return USBD_SendOtherConfiguration(setup.wLength); } else { @@ -575,13 +617,12 @@ static void USB_ISR(void) } else if (GET_INTERFACE == r) { - // TODO TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");) - UDD_Send8(EP0, setup.wIndex); + UDD_Send8(EP0, _usbSetInterface); } else if (SET_INTERFACE == r) { - // TODO + _usbSetInterface = setup.wValueL; TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");) } } diff --git a/hardware/arduino/sam/cores/arduino/USB/USBCore.h b/hardware/arduino/sam/cores/arduino/USB/USBCore.h index 36d044a3e..b01d7576a 100644 --- a/hardware/arduino/sam/cores/arduino/USB/USBCore.h +++ b/hardware/arduino/sam/cores/arduino/USB/USBCore.h @@ -287,6 +287,9 @@ _Pragma("pack()") #define D_CONFIG(_totalLength,_interfaces) \ { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } +#define D_OTHERCONFIG(_totalLength,_interfaces) \ + { 9, 7, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) } + #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }