@@ -34,7 +34,6 @@ volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
3434extern const u16 STRING_LANGUAGE[] PROGMEM;
3535extern const u8 STRING_PRODUCT[] PROGMEM;
3636extern const u8 STRING_MANUFACTURER[] PROGMEM;
37- extern const DeviceDescriptor USB_DeviceDescriptorIAD PROGMEM;
3837
3938const u16 STRING_LANGUAGE[2 ] = {
4039 (3 <<8 ) | (2 +2 ),
@@ -66,22 +65,6 @@ const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
6665const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER;
6766
6867
69- #define DEVICE_CLASS 0x02
70-
71- // DEVICE DESCRIPTOR
72-
73- #ifdef CDC_ENABLED
74- const DeviceDescriptor USB_DeviceDescriptorIAD =
75- D_DEVICE (0xEF ,0x02 ,0x01 ,64 ,USB_VID,USB_PID,0x100 ,IMANUFACTURER,IPRODUCT,ISERIAL,1 );
76- #else // CDC_DISABLED
77- // The default descriptor uses USB class OxEF, subclass 0x02 with protocol 1
78- // which means "Interface Association Descriptor" - that's needed for the CDC,
79- // but doesn't make much sense as a default for custom devices when CDC is disabled.
80- // (0x00 means "Use class information in the Interface Descriptors" which should be generally ok)
81- const DeviceDescriptor USB_DeviceDescriptorIAD =
82- D_DEVICE (0x00 ,0x00 ,0x00 ,64 ,USB_VID,USB_PID,0x100 ,IMANUFACTURER,IPRODUCT,ISERIAL,1 );
83- #endif
84-
8568// ==================================================================
8669// ==================================================================
8770
@@ -335,24 +318,21 @@ int USB_Send(u8 ep, const void* d, int len)
335318 return r;
336319}
337320
338- u8 _initEndpoints[USB_ENDPOINTS] =
339- {
340- 0 , // Control Endpoint
341-
342- #ifdef CDC_ENABLED
343- EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
344- EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
345- EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
346- #endif
347-
348- // Following endpoints are automatically initialized to 0
349- };
350-
351321#define EP_SINGLE_64 0x32 // EP0
352322#define EP_DOUBLE_64 0x36 // Other endpoints
353323#define EP_SINGLE_16 0x12
354324
355- static
325+ static inline
326+ u8 BankSizeMask (const uint8_t nbytes) {
327+ uint8_t mask = 0 ;
328+ for (uint8_t size = 8 ; size < 64 ; size <<= 1 ) {
329+ if (nbytes <= size) break ;
330+ mask++;
331+ }
332+ return (mask << EPSIZE0);
333+ }
334+ static inline
335+
356336void InitEP (u8 index, u8 type, u8 size)
357337{
358338 UENUM = index;
@@ -361,41 +341,24 @@ void InitEP(u8 index, u8 type, u8 size)
361341 UECFG1X = size;
362342}
363343
364- static
365- void InitEndpoints ()
366- {
367- for (u8 i = 1 ; i < sizeof (_initEndpoints) && _initEndpoints[i] != 0 ; i++)
368- {
369- UENUM = i;
370- UECONX = (1 <<EPEN);
371- UECFG0X = _initEndpoints[i];
372- #if USB_EP_SIZE == 16
373- UECFG1X = EP_SINGLE_16;
374- #elif USB_EP_SIZE == 64
375- UECFG1X = EP_DOUBLE_64;
376- #else
377- #error Unsupported value for USB_EP_SIZE
378- #endif
379- }
380- UERST = 0x7E ; // And reset them
381- UERST = 0 ;
344+ static inline
345+ bool InitEPSize (const u8 index, const u8 type, const u8 nbanks, const u8 banksize){
346+ if (index >= USB_ENDPOINTS) return false ;
347+ uint8_t size = ((1 << ALLOC) | ((nbanks > 1 ) ? (1 << EPBK0) : 0 ) | BankSizeMask (banksize));
348+ InitEP (index, type, size);
349+ return UESTA0X & (1 << CFGOK); // Success
382350}
383-
384- // Handle CLASS_INTERFACE requests
385351static
386- bool ClassInterfaceRequest (USBSetup& setup)
387- {
388- # ifdef CDC_ENABLED
389- u8 i = setup. wIndex ;
352+ void InitEndpoints () {
353+ InitEPSize (ARDUINODS4_TX_ENDPOINT, EP_TYPE_INTERRUPT_IN, 1 , 32 ); // Control Data Send
354+ InitEPSize (ARDUINODS4_RX_ENDPOINT, EP_TYPE_INTERRUPT_OUT, 2 , 32 ); // Control Data Receive
355+ InitEPSize ( 5 , EP_TYPE_INTERRUPT_IN, 1 , 32 ); // Expansion Interface NACK (avoid config reset)
390356
391- if (CDC_ACM_INTERFACE == i)
392- return CDC_Setup (setup);
393- #endif
357+ UERST = 0x7E ; // Reset endpoints
358+ UERST = 0 ; // End reset
394359
395- #ifdef PLUGGABLE_USB_ENABLED
396- return PluggableUSB ().setup (setup);
397- #endif
398- return false ;
360+ SetEP (ARDUINODS4_RX_ENDPOINT); // Select XInput RX endpoint (OUT)
361+ UEIENX |= (1 << RXOUTE); // Enable received "OUT" interrupt
399362}
400363
401364static int _cmark;
@@ -476,36 +439,14 @@ int USB_RecvControl(void* d, int len)
476439 return len;
477440}
478441
479- static u8 SendInterfaces ()
480- {
481- u8 interfaces = 0 ;
482-
483- #ifdef CDC_ENABLED
484- CDC_GetInterface (&interfaces);
485- #endif
486-
487- #ifdef PLUGGABLE_USB_ENABLED
488- PluggableUSB ().getInterface (&interfaces);
489- #endif
490-
491- return interfaces;
492- }
493-
494442// Construct a dynamic configuration descriptor
495443// This really needs dynamic endpoint allocation etc
496444// TODO
497445static
498446bool SendConfiguration (int maxlen)
499447{
500- // Count and measure interfaces
501- InitControl (0 );
502- u8 interfaces = SendInterfaces ();
503- ConfigDescriptor config = D_CONFIG (_cmark + sizeof (ConfigDescriptor),interfaces);
504-
505- // Now send them
506448 InitControl (maxlen);
507- USB_SendControl (0 ,&config,sizeof (ConfigDescriptor));
508- SendInterfaces ();
449+ USB_SendControl (TRANSFER_PGM, &USB_ConfigDescriptor, USB_ConfigDescriptorSize);
509450 return true ;
510451}
511452
@@ -527,7 +468,7 @@ bool SendDescriptor(USBSetup& setup)
527468 const u8 * desc_addr = 0 ;
528469 if (USB_DEVICE_DESCRIPTOR_TYPE == t)
529470 {
530- desc_addr = (const u8 *)&USB_DeviceDescriptorIAD ;
471+ desc_addr = (const u8 *) &USB_DeviceDescriptor ;
531472 }
532473 else if (USB_STRING_DESCRIPTOR_TYPE == t)
533474 {
@@ -545,8 +486,13 @@ bool SendDescriptor(USBSetup& setup)
545486 char name[ISERIAL_MAX_LEN];
546487 PluggableUSB ().getShortName (name);
547488 return USB_SendStringDescriptor ((uint8_t *)name, strlen (name), 0 );
489+ #else
490+ return USB_SendStringDescriptor (STRING_SERIAL, strlen ((char *)STRING_SERIAL), TRANSFER_PGM);
548491#endif
549492 }
493+ else if (setup.wValueL == ISECURITY) {
494+ return USB_SendStringDescriptor (STRING_SECURITY, strlen ((char *)STRING_SECURITY), TRANSFER_PGM);
495+ }
550496 else
551497 return false ;
552498 }
@@ -559,9 +505,16 @@ bool SendDescriptor(USBSetup& setup)
559505 return true ;
560506}
561507
562- // Endpoint 0 interrupt
508+ // Endpoint interrupt
563509ISR (USB_COM_vect)
564510{
511+ SetEP (ARDUINODS4_RX_ENDPOINT); // Select XInput RX endpoint (OUT)
512+ if (UEINTX & (1 << RXOUTI)) { // If data received...
513+ UEINTX &= ~(1 << RXOUTI); // Clear interrupt flag
514+ if (ArduinoDS4USB::RecvCallback != nullptr ) {
515+ ArduinoDS4USB::RecvCallback (); // Call callback function if it exists
516+ }
517+ }
565518 SetEP (0 );
566519 if (!ReceivedSetupInt ())
567520 return ;
@@ -648,8 +601,7 @@ ISR(USB_COM_vect)
648601 }
649602 else
650603 {
651- InitControl (setup.wLength ); // Max length of transfer
652- ok = ClassInterfaceRequest (setup);
604+ ok = true ;
653605 }
654606
655607 if (ok)
@@ -770,7 +722,6 @@ ISR(USB_GEN_vect)
770722 // Start of Frame - happens every millisecond so we use it for TX and RX LED one-shot timing, too
771723 if (udint & (1 <<SOFI))
772724 {
773- USB_Flush (CDC_TX); // Send a tx frame if found
774725
775726 // check whether the one-shot period has elapsed. if so, turn off the LED
776727 if (TxLEDPulse && !(--TxLEDPulse))
0 commit comments