Skip to content

Commit 9633320

Browse files
committed
Merge pull request #3640 from NicoHood/USB-Core-Fixes
Usb core fixes
2 parents fca0c4d + f0b004c commit 9633320

File tree

3 files changed

+68
-14
lines changed

3 files changed

+68
-14
lines changed

hardware/arduino/avr/cores/arduino/CDC.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ const CDCDescriptor _cdcInterface =
4949

5050
// CDC data interface
5151
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
52-
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,0x40,0),
53-
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
52+
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
53+
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
5454
};
5555

5656
int CDC_GetInterface(u8* interfaceNum)
@@ -92,11 +92,24 @@ bool CDC_Setup(USBSetup& setup)
9292
// with a relatively long period so it can finish housekeeping tasks
9393
// like servicing endpoints before the sketch ends
9494

95+
#ifndef MAGIC_KEY
96+
#define MAGIC_KEY 0x7777
97+
#endif
98+
#ifndef MAGIC_KEY_POS
99+
#define MAGIC_KEY_POS 0x0800
100+
#endif
101+
95102
// We check DTR state to determine if host port is open (bit 0 of lineState).
96103
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
97104
{
98-
*(uint16_t *)(RAMEND-1) = *(uint16_t *)0x0800;
99-
*(uint16_t *)0x0800 = 0x7777;
105+
#if MAGIC_KEY_POS != (RAMEND-1)
106+
*(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS;
107+
*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
108+
#else
109+
// for future boards save the key in the inproblematic RAMEND
110+
// which is reserved for the main() return value (which will never return)
111+
*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
112+
#endif
100113
wdt_enable(WDTO_120MS);
101114
}
102115
else
@@ -108,7 +121,11 @@ bool CDC_Setup(USBSetup& setup)
108121

109122
wdt_disable();
110123
wdt_reset();
111-
*(uint16_t *)0x0800 = *(uint16_t *)(RAMEND-1);
124+
#if MAGIC_KEY_POS != (RAMEND-1)
125+
*(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1);
126+
#else
127+
*(uint16_t *)MAGIC_KEY_POS = 0x0000;
128+
#endif
112129
}
113130
}
114131
return true;

hardware/arduino/avr/cores/arduino/USBAPI.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ typedef unsigned long u32;
3232

3333
#include "Arduino.h"
3434

35+
// This definitions is usefull if you want to reduce the EP_SIZE to 16
36+
// at the moment only 64 and 16 as EP_SIZE for all EPs are supported except the control endpoint
37+
#ifndef USB_EP_SIZE
38+
#define USB_EP_SIZE 64
39+
#endif
40+
3541
#if defined(USBCON)
3642

3743
#include "USBDesc.h"
@@ -41,13 +47,13 @@ typedef unsigned long u32;
4147
//================================================================================
4248
// USB
4349

44-
#define EP_TYPE_CONTROL 0x00
45-
#define EP_TYPE_BULK_IN 0x81
46-
#define EP_TYPE_BULK_OUT 0x80
47-
#define EP_TYPE_INTERRUPT_IN 0xC1
48-
#define EP_TYPE_INTERRUPT_OUT 0xC0
49-
#define EP_TYPE_ISOCHRONOUS_IN 0x41
50-
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
50+
#define EP_TYPE_CONTROL (0x00)
51+
#define EP_TYPE_BULK_IN ((1<<EPTYPE1) | (1<<EPDIR))
52+
#define EP_TYPE_BULK_OUT (1<<EPTYPE1)
53+
#define EP_TYPE_INTERRUPT_IN ((1<<EPTYPE1) | (1<<EPTYPE0) | (1<<EPDIR))
54+
#define EP_TYPE_INTERRUPT_OUT ((1<<EPTYPE1) | (1<<EPTYPE0))
55+
#define EP_TYPE_ISOCHRONOUS_IN ((1<<EPTYPE0) | (1<<EPDIR))
56+
#define EP_TYPE_ISOCHRONOUS_OUT (1<<EPTYPE0)
5157

5258
class USBDevice_
5359
{

hardware/arduino/avr/cores/arduino/USBCore.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static inline void ClearOUT(void)
110110
UEINTX = ~(1<<RXOUTI);
111111
}
112112

113-
void Recv(volatile u8* data, u8 count)
113+
static inline void Recv(volatile u8* data, u8 count)
114114
{
115115
while (count--)
116116
*data++ = UEDATX;
@@ -253,7 +253,7 @@ u8 USB_SendSpace(u8 ep)
253253
LockEP lock(ep);
254254
if (!ReadWriteAllowed())
255255
return 0;
256-
return 64 - FifoByteCount();
256+
return USB_EP_SIZE - FifoByteCount();
257257
}
258258

259259
// Blocking Send of data to an endpoint
@@ -326,6 +326,7 @@ u8 _initEndpoints[] =
326326

327327
#define EP_SINGLE_64 0x32 // EP0
328328
#define EP_DOUBLE_64 0x36 // Other endpoints
329+
#define EP_SINGLE_16 0x12
329330

330331
static
331332
void InitEP(u8 index, u8 type, u8 size)
@@ -344,7 +345,13 @@ void InitEndpoints()
344345
UENUM = i;
345346
UECONX = (1<<EPEN);
346347
UECFG0X = _initEndpoints[i];
348+
#if USB_EP_SIZE == 16
349+
UECFG1X = EP_SINGLE_16;
350+
#elif USB_EP_SIZE == 64
347351
UECFG1X = EP_DOUBLE_64;
352+
#else
353+
#error Unsupported value for USB_EP_SIZE
354+
#endif
348355
}
349356
UERST = 0x7E; // And reset them
350357
UERST = 0;
@@ -620,13 +627,19 @@ void USB_Flush(u8 ep)
620627

621628
static inline void USB_ClockDisable()
622629
{
630+
#if defined(OTGPADE)
623631
USBCON = (USBCON & ~(1<<OTGPADE)) | (1<<FRZCLK); // freeze clock and disable VBUS Pad
632+
#else // u2 Series
633+
USBCON = (1 << FRZCLK); // freeze clock
634+
#endif
624635
PLLCSR &= ~(1<<PLLE); // stop PLL
625636
}
626637

627638
static inline void USB_ClockEnable()
628639
{
640+
#if defined(UHWCON)
629641
UHWCON |= (1<<UVREGE); // power internal reg
642+
#endif
630643
USBCON = (1<<USBE) | (1<<FRZCLK); // clock frozen, usb enabled
631644

632645
// ATmega32U4
@@ -639,6 +652,16 @@ static inline void USB_ClockEnable()
639652
#error "Clock rate of F_CPU not supported"
640653
#endif
641654

655+
#elif defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)
656+
// for the u2 Series the datasheet is confusing. On page 40 its called PINDIV and on page 290 its called PLLP0
657+
#if F_CPU == 16000000UL
658+
// Need 16 MHz xtal
659+
PLLCSR |= (1 << PLLP0);
660+
#elif F_CPU == 8000000UL
661+
// Need 8 MHz xtal
662+
PLLCSR &= ~(1 << PLLP0);
663+
#endif
664+
642665
// AT90USB646, AT90USB647, AT90USB1286, AT90USB1287
643666
#elif defined(PLLP2)
644667
#if F_CPU == 16000000UL
@@ -670,10 +693,18 @@ static inline void USB_ClockEnable()
670693
// strange behaviors when the board is reset using the serial
671694
// port touch at 1200 bps. This delay fixes this behavior.
672695
delay(1);
696+
#if defined(OTGPADE)
673697
USBCON = (USBCON & ~(1<<FRZCLK)) | (1<<OTGPADE); // start USB clock, enable VBUS Pad
698+
#else
699+
USBCON &= ~(1 << FRZCLK); // start USB clock
700+
#endif
674701

675702
#if defined(RSTCPU)
703+
#if defined(LSM)
676704
UDCON &= ~((1<<RSTCPU) | (1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode
705+
#else // u2 Series
706+
UDCON &= ~((1 << RSTCPU) | (1 << RMWKUP) | (1 << DETACH)); // enable attach resistor, set full speed mode
707+
#endif
677708
#else
678709
// AT90USB64x and AT90USB128x don't have RSTCPU
679710
UDCON &= ~((1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode

0 commit comments

Comments
 (0)