Skip to content

Commit cb4c0a5

Browse files
Nicoobra
authored andcommitted
Added u2 Series support
1 parent 85f04a3 commit cb4c0a5

File tree

5 files changed

+99
-10
lines changed

5 files changed

+99
-10
lines changed

plugins/KeyboardioHID/CDC.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ const CDCDescriptor _cdcInterface =
5050

5151
// CDC data interface
5252
D_INTERFACE(CDC_DATA_INTERFACE, 2, CDC_DATA_INTERFACE_CLASS, 0, 0),
53-
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK, 0x40, 0),
54-
D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_IN), USB_ENDPOINT_TYPE_BULK, 0x40, 0)
53+
// edit by NicoHood
54+
D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0),
55+
D_ENDPOINT(USB_ENDPOINT_IN(CDC_ENDPOINT_IN), USB_ENDPOINT_TYPE_BULK, USB_EP_SIZE, 0)
5556
};
5657

5758
int WEAK CDC_GetInterface(u8* interfaceNum)
@@ -96,8 +97,28 @@ bool WEAK CDC_Setup(Setup& setup)
9697
// We check DTR state to determine if host port is open (bit 0 of lineState).
9798
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
9899
{
100+
// edit by NicoHood
101+
// change ram pointer to fit the 16u2's ram size and only use an 8bit value
102+
#if defined(__AVR_ATmega32U4__)
99103
*(uint16_t *)0x0800 = 0x7777;
100104
wdt_enable(WDTO_120MS);
105+
#else
106+
// workaround for this issue:
107+
// https://github.com/arduino/Arduino/issues/2474
108+
// I didn't change this for the 32u4 to simply not touch their code
109+
// the correct way would be to add a compiler flag like this:
110+
// -Wl,--section-start=.blkey=0x280
111+
//volatile uint8_t MagicBootKey __attribute__((section(".blkey")));
112+
cli();
113+
114+
//MagicBootKey = 0x77;
115+
*(uint8_t *)0x0280 = 0x77;
116+
117+
wdt_enable(WDTO_120MS);
118+
119+
// wait for reset
120+
for (;;);
121+
#endif
101122
}
102123
else
103124
{
@@ -106,9 +127,18 @@ bool WEAK CDC_Setup(Setup& setup)
106127
// To avoid spurious resets we set the watchdog to 250ms and eventually
107128
// cancel if DTR goes back high.
108129

130+
// edit by NicoHood
131+
#if defined(__AVR_ATmega32U4__)
109132
wdt_disable();
110133
wdt_reset();
111134
*(uint16_t *)0x0800 = 0x0;
135+
#else
136+
// not used because of the workaround above
137+
//wdt_disable();
138+
//wdt_reset();
139+
//MagicBootKey = 0x00;
140+
//*(uint8_t *)0x0280 = 0x00;
141+
#endif
112142
}
113143
}
114144
return true;

plugins/KeyboardioHID/HID.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ const HIDDescriptor _hidInterface =
131131
{
132132
D_INTERFACE(HID_INTERFACE, 1, 3, 0, 0),
133133
D_HIDREPORT(sizeof(_hidReportDescriptor)),
134-
D_ENDPOINT(USB_ENDPOINT_IN(HID_ENDPOINT_INT), USB_ENDPOINT_TYPE_INTERRUPT, 0x40, 0x01)
134+
// edit by NicoHood
135+
D_ENDPOINT(USB_ENDPOINT_IN(HID_ENDPOINT_INT), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
135136
};
136137

137138
//================================================================================

plugins/KeyboardioHID/USBCore.cpp

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ u8 USB_SendSpace(u8 ep)
271271
LockEP lock(ep);
272272
if (!ReadWriteAllowed())
273273
return 0;
274-
return 64 - FifoByteCount();
274+
// edit by NicoHood
275+
return USB_EP_SIZE - FifoByteCount();
275276
}
276277

277278
// Blocking Send of data to an endpoint
@@ -344,6 +345,8 @@ const u8 _initEndpoints[] =
344345

345346
#define EP_SINGLE_64 0x32 // EP0
346347
#define EP_DOUBLE_64 0x36 // Other endpoints
348+
// edit by NicoHood
349+
#define EP_SINGLE_16 0x12
347350

348351
static
349352
void InitEP(u8 index, u8 type, u8 size)
@@ -362,7 +365,14 @@ void InitEndpoints()
362365
UENUM = i;
363366
UECONX = (1 << EPEN);
364367
UECFG0X = pgm_read_byte(_initEndpoints + i);
368+
// edit by NicoHood
369+
#if USB_EP_SIZE == 16
370+
UECFG1X = EP_SINGLE_16;
371+
#elif USB_EP_SIZE == 64
365372
UECFG1X = EP_DOUBLE_64;
373+
#else
374+
#error Unsupported value for USB_EP_SIZE
375+
#endif
366376
}
367377
UERST = 0x7E; // And reset them
368378
UERST = 0;
@@ -666,16 +676,55 @@ USBDevice_::USBDevice_()
666676
{
667677
}
668678

679+
// edit by NicoHood
680+
// added from teensy definition by paul stoffregen
681+
#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)
682+
#define HW_CONFIG()
683+
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
684+
#define USB_CONFIG() (USBCON = (1<<USBE))
685+
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
686+
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
687+
#define HW_CONFIG() (UHWCON = 0x01)
688+
#define PLL_CONFIG() (PLLCSR = 0x12)
689+
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
690+
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
691+
#elif defined(__AVR_AT90USB646__)
692+
#define HW_CONFIG() (UHWCON = 0x81)
693+
#define PLL_CONFIG() (PLLCSR = 0x1A)
694+
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
695+
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
696+
#elif defined(__AVR_AT90USB1286__)
697+
#define HW_CONFIG() (UHWCON = 0x81)
698+
#define PLL_CONFIG() (PLLCSR = 0x16)
699+
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
700+
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
701+
#endif
702+
669703
void USBDevice_::attach()
670704
{
705+
// edit by NicoHood
706+
// added support for u2 and u4 Series. Other MCUs not tested, but they could work.
671707
_usbConfiguration = 0;
672-
UHWCON = 0x01; // power internal reg
673-
USBCON = (1 << USBE) | (1 << FRZCLK); // clock frozen, usb enabled
708+
HW_CONFIG(); // power internal reg
709+
710+
// from Paul Brook source, TODO needed? (we might change this in a future commit with the USB wakeup)
711+
//USBCON = 0; // Reset controller
712+
USB_FREEZE(); // clock frozen, usb enabled
713+
674714
#if F_CPU == 16000000UL
675-
PLLCSR = 0x12; // Need 16 MHz xtal
715+
// Need 16 MHz xtal
716+
#ifdef PINDIV
717+
PLLCSR = (1 << PINDIV) | (1 << PLLE);
718+
#else
719+
// added from Paul Brook source, no idea for what board this is used for
720+
PLLCSR = (1 << PLLP0) | (1 << PLLE);
721+
#endif
722+
676723
#elif F_CPU == 8000000UL
677-
PLLCSR = 0x02; // Need 8 MHz xtal
724+
// Need 8 MHz xtal
725+
PLLCSR = (1 << PLLE);
678726
#endif
727+
679728
while (!(PLLCSR & (1 << PLOCK))) // wait for lock pll
680729
;
681730

@@ -684,7 +733,7 @@ void USBDevice_::attach()
684733
// port touch at 1200 bps. This delay fixes this behaviour.
685734
delay(1);
686735

687-
USBCON = ((1 << USBE) | (1 << OTGPADE)); // start USB clock
736+
USB_CONFIG(); // start USB clock
688737
UDIEN = (1 << EORSTE) | (1 << SOFE); // Enable interrupts for EOR (End of Reset) and SOF (start of frame)
689738
UDCON = 0; // enable attach resistor
690739

plugins/KeyboardioHID/USBDesc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@
5858
#define HID_TX HID_ENDPOINT_INT
5959
#endif
6060

61+
// edit by NicoHood
62+
// this definitions is usefull if you want to reduce the EP_SIZE to 16
63+
// at the moment only 64 and 16 as EP_SIZE for all EPs are supported except the control endpoint
64+
#ifndef USB_EP_SIZE
65+
#define USB_EP_SIZE 64
66+
#endif
67+
6168
#define IMANUFACTURER 1
6269
#define IPRODUCT 2
6370

plugins/KeyboardioHID/wiring_private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ extern "C"{
5252
#define EXTERNAL_INT_6 6
5353
#define EXTERNAL_INT_7 7
5454

55-
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__)
55+
// edit by NicoHood
56+
#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) \
57+
|| defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega128RFA1__) || defined(__AVR_ATmega256RFR2__)
5658
#define EXTERNAL_NUM_INTERRUPTS 8
5759
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
5860
#define EXTERNAL_NUM_INTERRUPTS 3

0 commit comments

Comments
 (0)