Skip to content

Commit 4a71669

Browse files
authored
Update USBCore.cpp
1 parent b4110d5 commit 4a71669

File tree

1 file changed

+41
-90
lines changed

1 file changed

+41
-90
lines changed

cores/arduino/USBCore.cpp

Lines changed: 41 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ volatile u8 RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
3434
extern const u16 STRING_LANGUAGE[] PROGMEM;
3535
extern const u8 STRING_PRODUCT[] PROGMEM;
3636
extern const u8 STRING_MANUFACTURER[] PROGMEM;
37-
extern const DeviceDescriptor USB_DeviceDescriptorIAD PROGMEM;
3837

3938
const u16 STRING_LANGUAGE[2] = {
4039
(3<<8) | (2+2),
@@ -66,22 +65,6 @@ const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
6665
const 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+
356336
void 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
385351
static
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

401364
static 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
497445
static
498446
bool 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
563509
ISR(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

Comments
 (0)