Added u2 Series support

This commit is contained in:
Nico 2014-12-09 16:46:05 +01:00
parent 9f26da32e6
commit cdc7471ddb
5 changed files with 99 additions and 10 deletions

34
CDC.cpp
View file

@ -50,8 +50,9 @@ 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)
// edit by NicoHood
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 WEAK CDC_GetInterface(u8* interfaceNum)
@ -96,8 +97,28 @@ bool WEAK CDC_Setup(Setup& setup)
// We check DTR state to determine if host port is open (bit 0 of lineState).
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
{
// edit by NicoHood
// change ram pointer to fit the 16u2's ram size and only use an 8bit value
#if defined(__AVR_ATmega32U4__)
*(uint16_t *)0x0800 = 0x7777;
wdt_enable(WDTO_120MS);
#else
// workaround for this issue:
// https://github.com/arduino/Arduino/issues/2474
// I didn't change this for the 32u4 to simply not touch their code
// the correct way would be to add a compiler flag like this:
// -Wl,--section-start=.blkey=0x280
//volatile uint8_t MagicBootKey __attribute__((section(".blkey")));
cli();
//MagicBootKey = 0x77;
*(uint8_t *)0x0280 = 0x77;
wdt_enable(WDTO_120MS);
// wait for reset
for (;;);
#endif
}
else
{
@ -106,9 +127,18 @@ bool WEAK CDC_Setup(Setup& setup)
// To avoid spurious resets we set the watchdog to 250ms and eventually
// cancel if DTR goes back high.
// edit by NicoHood
#if defined(__AVR_ATmega32U4__)
wdt_disable();
wdt_reset();
*(uint16_t *)0x0800 = 0x0;
#else
// not used because of the workaround above
//wdt_disable();
//wdt_reset();
//MagicBootKey = 0x00;
//*(uint8_t *)0x0280 = 0x00;
#endif
}
}
return true;

View file

@ -131,7 +131,8 @@ const HIDDescriptor _hidInterface =
{
D_INTERFACE(HID_INTERFACE, 1, 3, 0, 0),
D_HIDREPORT(sizeof(_hidReportDescriptor)),
D_ENDPOINT(USB_ENDPOINT_IN(HID_ENDPOINT_INT), USB_ENDPOINT_TYPE_INTERRUPT, 0x40, 0x01)
// edit by NicoHood
D_ENDPOINT(USB_ENDPOINT_IN(HID_ENDPOINT_INT), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
};
//================================================================================

View file

@ -271,7 +271,8 @@ u8 USB_SendSpace(u8 ep)
LockEP lock(ep);
if (!ReadWriteAllowed())
return 0;
return 64 - FifoByteCount();
// edit by NicoHood
return USB_EP_SIZE - FifoByteCount();
}
// Blocking Send of data to an endpoint
@ -344,6 +345,8 @@ const u8 _initEndpoints[] =
#define EP_SINGLE_64 0x32 // EP0
#define EP_DOUBLE_64 0x36 // Other endpoints
// edit by NicoHood
#define EP_SINGLE_16 0x12
static
void InitEP(u8 index, u8 type, u8 size)
@ -362,7 +365,14 @@ void InitEndpoints()
UENUM = i;
UECONX = (1 << EPEN);
UECFG0X = pgm_read_byte(_initEndpoints + i);
// edit by NicoHood
#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;
@ -666,16 +676,55 @@ USBDevice_::USBDevice_()
{
}
// edit by NicoHood
// added from teensy definition by paul stoffregen
#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)
#define HW_CONFIG()
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
#define USB_CONFIG() (USBCON = (1<<USBE))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
#define HW_CONFIG() (UHWCON = 0x01)
#define PLL_CONFIG() (PLLCSR = 0x12)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB646__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x1A)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB1286__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x16)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#endif
void USBDevice_::attach()
{
// edit by NicoHood
// added support for u2 and u4 Series. Other MCUs not tested, but they could work.
_usbConfiguration = 0;
UHWCON = 0x01; // power internal reg
USBCON = (1 << USBE) | (1 << FRZCLK); // clock frozen, usb enabled
HW_CONFIG(); // power internal reg
// from Paul Brook source, TODO needed? (we might change this in a future commit with the USB wakeup)
//USBCON = 0; // Reset controller
USB_FREEZE(); // clock frozen, usb enabled
#if F_CPU == 16000000UL
PLLCSR = 0x12; // Need 16 MHz xtal
// Need 16 MHz xtal
#ifdef PINDIV
PLLCSR = (1 << PINDIV) | (1 << PLLE);
#else
// added from Paul Brook source, no idea for what board this is used for
PLLCSR = (1 << PLLP0) | (1 << PLLE);
#endif
#elif F_CPU == 8000000UL
PLLCSR = 0x02; // Need 8 MHz xtal
// Need 8 MHz xtal
PLLCSR = (1 << PLLE);
#endif
while (!(PLLCSR & (1 << PLOCK))) // wait for lock pll
;
@ -684,7 +733,7 @@ void USBDevice_::attach()
// port touch at 1200 bps. This delay fixes this behaviour.
delay(1);
USBCON = ((1 << USBE) | (1 << OTGPADE)); // start USB clock
USB_CONFIG(); // start USB clock
UDIEN = (1 << EORSTE) | (1 << SOFE); // Enable interrupts for EOR (End of Reset) and SOF (start of frame)
UDCON = 0; // enable attach resistor

View file

@ -58,6 +58,13 @@
#define HID_TX HID_ENDPOINT_INT
#endif
// edit by NicoHood
// 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
#define IMANUFACTURER 1
#define IPRODUCT 2

View file

@ -52,7 +52,9 @@ extern "C"{
#define EXTERNAL_INT_6 6
#define EXTERNAL_INT_7 7
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__)
// edit by NicoHood
#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) \
|| defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__)
#define EXTERNAL_NUM_INTERRUPTS 8
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
#define EXTERNAL_NUM_INTERRUPTS 3