diff options
author | Martino Facchin <m.facchin@arduino.cc> | 2015-08-13 09:39:21 +0200 |
---|---|---|
committer | Martino Facchin <m.facchin@arduino.cc> | 2015-08-13 09:39:21 +0200 |
commit | b3197c6ef83253d712f4b7b30a0763f18f6d3ddc (patch) | |
tree | c1c11380a35613e3ab8e9264bfb84251a91d5db8 /cores/arduino | |
parent | 98f7ab15884119b1c9f1f58f96a8302200c1e2a3 (diff) | |
parent | 98301ba23a1f7c60b4590330da2ee1c260da7aa6 (diff) |
Merge pull request #3640 from NicoHood/USB-Core-Fixes
Usb core fixes
Diffstat (limited to 'cores/arduino')
-rw-r--r-- | cores/arduino/CDC.cpp | 27 | ||||
-rw-r--r-- | cores/arduino/USBAPI.h | 20 | ||||
-rw-r--r-- | cores/arduino/USBCore.cpp | 35 |
3 files changed, 68 insertions, 14 deletions
diff --git a/cores/arduino/CDC.cpp b/cores/arduino/CDC.cpp index d694a2d..7c7eacf 100644 --- a/cores/arduino/CDC.cpp +++ b/cores/arduino/CDC.cpp @@ -49,8 +49,8 @@ const CDCDescriptor _cdcInterface = // 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,0x40,0), - D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) + D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0), + D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0) }; int CDC_GetInterface(u8* interfaceNum) @@ -92,11 +92,24 @@ bool CDC_Setup(USBSetup& setup) // with a relatively long period so it can finish housekeeping tasks // like servicing endpoints before the sketch ends +#ifndef MAGIC_KEY +#define MAGIC_KEY 0x7777 +#endif +#ifndef MAGIC_KEY_POS +#define MAGIC_KEY_POS 0x0800 +#endif + // We check DTR state to determine if host port is open (bit 0 of lineState). if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { - *(uint16_t *)(RAMEND-1) = *(uint16_t *)0x0800; - *(uint16_t *)0x0800 = 0x7777; +#if MAGIC_KEY_POS != (RAMEND-1) + *(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS; + *(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY; +#else + // for future boards save the key in the inproblematic RAMEND + // which is reserved for the main() return value (which will never return) + *(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY; +#endif wdt_enable(WDTO_120MS); } else @@ -108,7 +121,11 @@ bool CDC_Setup(USBSetup& setup) wdt_disable(); wdt_reset(); - *(uint16_t *)0x0800 = *(uint16_t *)(RAMEND-1); +#if MAGIC_KEY_POS != (RAMEND-1) + *(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1); +#else + *(uint16_t *)MAGIC_KEY_POS = 0x0000; +#endif } } return true; diff --git a/cores/arduino/USBAPI.h b/cores/arduino/USBAPI.h index 4abd961..7f468a6 100644 --- a/cores/arduino/USBAPI.h +++ b/cores/arduino/USBAPI.h @@ -32,6 +32,12 @@ typedef unsigned long u32; #include "Arduino.h" +// This definitions is usefull if you want to reduce the EP_SIZE to 16 +// at the moment only 64 and 16 as EP_SIZE for all EPs are supported except the control endpoint +#ifndef USB_EP_SIZE +#define USB_EP_SIZE 64 +#endif + #if defined(USBCON) #include "USBDesc.h" @@ -41,13 +47,13 @@ typedef unsigned long u32; //================================================================================ // USB -#define EP_TYPE_CONTROL 0x00 -#define EP_TYPE_BULK_IN 0x81 -#define EP_TYPE_BULK_OUT 0x80 -#define EP_TYPE_INTERRUPT_IN 0xC1 -#define EP_TYPE_INTERRUPT_OUT 0xC0 -#define EP_TYPE_ISOCHRONOUS_IN 0x41 -#define EP_TYPE_ISOCHRONOUS_OUT 0x40 +#define EP_TYPE_CONTROL (0x00) +#define EP_TYPE_BULK_IN ((1<<EPTYPE1) | (1<<EPDIR)) +#define EP_TYPE_BULK_OUT (1<<EPTYPE1) +#define EP_TYPE_INTERRUPT_IN ((1<<EPTYPE1) | (1<<EPTYPE0) | (1<<EPDIR)) +#define EP_TYPE_INTERRUPT_OUT ((1<<EPTYPE1) | (1<<EPTYPE0)) +#define EP_TYPE_ISOCHRONOUS_IN ((1<<EPTYPE0) | (1<<EPDIR)) +#define EP_TYPE_ISOCHRONOUS_OUT (1<<EPTYPE0) class USBDevice_ { diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 8237ccb..f12d326 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -110,7 +110,7 @@ static inline void ClearOUT(void) UEINTX = ~(1<<RXOUTI); } -void Recv(volatile u8* data, u8 count) +static inline void Recv(volatile u8* data, u8 count) { while (count--) *data++ = UEDATX; @@ -253,7 +253,7 @@ u8 USB_SendSpace(u8 ep) LockEP lock(ep); if (!ReadWriteAllowed()) return 0; - return 64 - FifoByteCount(); + return USB_EP_SIZE - FifoByteCount(); } // Blocking Send of data to an endpoint @@ -326,6 +326,7 @@ u8 _initEndpoints[] = #define EP_SINGLE_64 0x32 // EP0 #define EP_DOUBLE_64 0x36 // Other endpoints +#define EP_SINGLE_16 0x12 static void InitEP(u8 index, u8 type, u8 size) @@ -344,7 +345,13 @@ void InitEndpoints() UENUM = i; UECONX = (1<<EPEN); UECFG0X = _initEndpoints[i]; +#if USB_EP_SIZE == 16 + UECFG1X = EP_SINGLE_16; +#elif USB_EP_SIZE == 64 UECFG1X = EP_DOUBLE_64; +#else +#error Unsupported value for USB_EP_SIZE +#endif } UERST = 0x7E; // And reset them UERST = 0; @@ -620,13 +627,19 @@ void USB_Flush(u8 ep) static inline void USB_ClockDisable() { +#if defined(OTGPADE) USBCON = (USBCON & ~(1<<OTGPADE)) | (1<<FRZCLK); // freeze clock and disable VBUS Pad +#else // u2 Series + USBCON = (1 << FRZCLK); // freeze clock +#endif PLLCSR &= ~(1<<PLLE); // stop PLL } static inline void USB_ClockEnable() { +#if defined(UHWCON) UHWCON |= (1<<UVREGE); // power internal reg +#endif USBCON = (1<<USBE) | (1<<FRZCLK); // clock frozen, usb enabled // ATmega32U4 @@ -639,6 +652,16 @@ static inline void USB_ClockEnable() #error "Clock rate of F_CPU not supported" #endif +#elif defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) + // for the u2 Series the datasheet is confusing. On page 40 its called PINDIV and on page 290 its called PLLP0 +#if F_CPU == 16000000UL + // Need 16 MHz xtal + PLLCSR |= (1 << PLLP0); +#elif F_CPU == 8000000UL + // Need 8 MHz xtal + PLLCSR &= ~(1 << PLLP0); +#endif + // AT90USB646, AT90USB647, AT90USB1286, AT90USB1287 #elif defined(PLLP2) #if F_CPU == 16000000UL @@ -670,10 +693,18 @@ static inline void USB_ClockEnable() // strange behaviors when the board is reset using the serial // port touch at 1200 bps. This delay fixes this behavior. delay(1); +#if defined(OTGPADE) USBCON = (USBCON & ~(1<<FRZCLK)) | (1<<OTGPADE); // start USB clock, enable VBUS Pad +#else + USBCON &= ~(1 << FRZCLK); // start USB clock +#endif #if defined(RSTCPU) +#if defined(LSM) UDCON &= ~((1<<RSTCPU) | (1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode +#else // u2 Series + UDCON &= ~((1 << RSTCPU) | (1 << RMWKUP) | (1 << DETACH)); // enable attach resistor, set full speed mode +#endif #else // AT90USB64x and AT90USB128x don't have RSTCPU UDCON &= ~((1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode |