commit
b3197c6ef8
|
@ -49,8 +49,8 @@ const CDCDescriptor _cdcInterface =
|
||||||
|
|
||||||
// CDC data interface
|
// CDC data interface
|
||||||
D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
|
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_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0)
|
D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
|
||||||
};
|
};
|
||||||
|
|
||||||
int CDC_GetInterface(u8* interfaceNum)
|
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
|
// with a relatively long period so it can finish housekeeping tasks
|
||||||
// like servicing endpoints before the sketch ends
|
// 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).
|
// We check DTR state to determine if host port is open (bit 0 of lineState).
|
||||||
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
|
if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
|
||||||
{
|
{
|
||||||
*(uint16_t *)(RAMEND-1) = *(uint16_t *)0x0800;
|
#if MAGIC_KEY_POS != (RAMEND-1)
|
||||||
*(uint16_t *)0x0800 = 0x7777;
|
*(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);
|
wdt_enable(WDTO_120MS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -108,7 +121,11 @@ bool CDC_Setup(USBSetup& setup)
|
||||||
|
|
||||||
wdt_disable();
|
wdt_disable();
|
||||||
wdt_reset();
|
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;
|
return true;
|
||||||
|
|
|
@ -32,6 +32,12 @@ typedef unsigned long u32;
|
||||||
|
|
||||||
#include "Arduino.h"
|
#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)
|
#if defined(USBCON)
|
||||||
|
|
||||||
#include "USBDesc.h"
|
#include "USBDesc.h"
|
||||||
|
@ -41,13 +47,13 @@ typedef unsigned long u32;
|
||||||
//================================================================================
|
//================================================================================
|
||||||
// USB
|
// USB
|
||||||
|
|
||||||
#define EP_TYPE_CONTROL 0x00
|
#define EP_TYPE_CONTROL (0x00)
|
||||||
#define EP_TYPE_BULK_IN 0x81
|
#define EP_TYPE_BULK_IN ((1<<EPTYPE1) | (1<<EPDIR))
|
||||||
#define EP_TYPE_BULK_OUT 0x80
|
#define EP_TYPE_BULK_OUT (1<<EPTYPE1)
|
||||||
#define EP_TYPE_INTERRUPT_IN 0xC1
|
#define EP_TYPE_INTERRUPT_IN ((1<<EPTYPE1) | (1<<EPTYPE0) | (1<<EPDIR))
|
||||||
#define EP_TYPE_INTERRUPT_OUT 0xC0
|
#define EP_TYPE_INTERRUPT_OUT ((1<<EPTYPE1) | (1<<EPTYPE0))
|
||||||
#define EP_TYPE_ISOCHRONOUS_IN 0x41
|
#define EP_TYPE_ISOCHRONOUS_IN ((1<<EPTYPE0) | (1<<EPDIR))
|
||||||
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
|
#define EP_TYPE_ISOCHRONOUS_OUT (1<<EPTYPE0)
|
||||||
|
|
||||||
class USBDevice_
|
class USBDevice_
|
||||||
{
|
{
|
||||||
|
|
|
@ -110,7 +110,7 @@ static inline void ClearOUT(void)
|
||||||
UEINTX = ~(1<<RXOUTI);
|
UEINTX = ~(1<<RXOUTI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Recv(volatile u8* data, u8 count)
|
static inline void Recv(volatile u8* data, u8 count)
|
||||||
{
|
{
|
||||||
while (count--)
|
while (count--)
|
||||||
*data++ = UEDATX;
|
*data++ = UEDATX;
|
||||||
|
@ -253,7 +253,7 @@ u8 USB_SendSpace(u8 ep)
|
||||||
LockEP lock(ep);
|
LockEP lock(ep);
|
||||||
if (!ReadWriteAllowed())
|
if (!ReadWriteAllowed())
|
||||||
return 0;
|
return 0;
|
||||||
return 64 - FifoByteCount();
|
return USB_EP_SIZE - FifoByteCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blocking Send of data to an endpoint
|
// Blocking Send of data to an endpoint
|
||||||
|
@ -326,6 +326,7 @@ u8 _initEndpoints[] =
|
||||||
|
|
||||||
#define EP_SINGLE_64 0x32 // EP0
|
#define EP_SINGLE_64 0x32 // EP0
|
||||||
#define EP_DOUBLE_64 0x36 // Other endpoints
|
#define EP_DOUBLE_64 0x36 // Other endpoints
|
||||||
|
#define EP_SINGLE_16 0x12
|
||||||
|
|
||||||
static
|
static
|
||||||
void InitEP(u8 index, u8 type, u8 size)
|
void InitEP(u8 index, u8 type, u8 size)
|
||||||
|
@ -344,7 +345,13 @@ void InitEndpoints()
|
||||||
UENUM = i;
|
UENUM = i;
|
||||||
UECONX = (1<<EPEN);
|
UECONX = (1<<EPEN);
|
||||||
UECFG0X = _initEndpoints[i];
|
UECFG0X = _initEndpoints[i];
|
||||||
|
#if USB_EP_SIZE == 16
|
||||||
|
UECFG1X = EP_SINGLE_16;
|
||||||
|
#elif USB_EP_SIZE == 64
|
||||||
UECFG1X = EP_DOUBLE_64;
|
UECFG1X = EP_DOUBLE_64;
|
||||||
|
#else
|
||||||
|
#error Unsupported value for USB_EP_SIZE
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
UERST = 0x7E; // And reset them
|
UERST = 0x7E; // And reset them
|
||||||
UERST = 0;
|
UERST = 0;
|
||||||
|
@ -620,13 +627,19 @@ void USB_Flush(u8 ep)
|
||||||
|
|
||||||
static inline void USB_ClockDisable()
|
static inline void USB_ClockDisable()
|
||||||
{
|
{
|
||||||
|
#if defined(OTGPADE)
|
||||||
USBCON = (USBCON & ~(1<<OTGPADE)) | (1<<FRZCLK); // freeze clock and disable VBUS Pad
|
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
|
PLLCSR &= ~(1<<PLLE); // stop PLL
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void USB_ClockEnable()
|
static inline void USB_ClockEnable()
|
||||||
{
|
{
|
||||||
|
#if defined(UHWCON)
|
||||||
UHWCON |= (1<<UVREGE); // power internal reg
|
UHWCON |= (1<<UVREGE); // power internal reg
|
||||||
|
#endif
|
||||||
USBCON = (1<<USBE) | (1<<FRZCLK); // clock frozen, usb enabled
|
USBCON = (1<<USBE) | (1<<FRZCLK); // clock frozen, usb enabled
|
||||||
|
|
||||||
// ATmega32U4
|
// ATmega32U4
|
||||||
|
@ -639,6 +652,16 @@ static inline void USB_ClockEnable()
|
||||||
#error "Clock rate of F_CPU not supported"
|
#error "Clock rate of F_CPU not supported"
|
||||||
#endif
|
#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
|
// AT90USB646, AT90USB647, AT90USB1286, AT90USB1287
|
||||||
#elif defined(PLLP2)
|
#elif defined(PLLP2)
|
||||||
#if F_CPU == 16000000UL
|
#if F_CPU == 16000000UL
|
||||||
|
@ -670,10 +693,18 @@ static inline void USB_ClockEnable()
|
||||||
// strange behaviors when the board is reset using the serial
|
// strange behaviors when the board is reset using the serial
|
||||||
// port touch at 1200 bps. This delay fixes this behavior.
|
// port touch at 1200 bps. This delay fixes this behavior.
|
||||||
delay(1);
|
delay(1);
|
||||||
|
#if defined(OTGPADE)
|
||||||
USBCON = (USBCON & ~(1<<FRZCLK)) | (1<<OTGPADE); // start USB clock, enable VBUS Pad
|
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(RSTCPU)
|
||||||
|
#if defined(LSM)
|
||||||
UDCON &= ~((1<<RSTCPU) | (1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode
|
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
|
#else
|
||||||
// AT90USB64x and AT90USB128x don't have RSTCPU
|
// AT90USB64x and AT90USB128x don't have RSTCPU
|
||||||
UDCON &= ~((1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode
|
UDCON &= ~((1<<LSM) | (1<<RMWKUP) | (1<<DETACH)); // enable attach resistor, set full speed mode
|
||||||
|
|
|
@ -43,7 +43,7 @@ static u8 HID_INTERFACE;
|
||||||
HIDDescriptor _hidInterface;
|
HIDDescriptor _hidInterface;
|
||||||
|
|
||||||
static HIDDescriptorListNode* rootNode = NULL;
|
static HIDDescriptorListNode* rootNode = NULL;
|
||||||
static uint8_t sizeof_hidReportDescriptor = 0;
|
static uint16_t sizeof_hidReportDescriptor = 0;
|
||||||
static uint8_t modules_count = 0;
|
static uint8_t modules_count = 0;
|
||||||
//================================================================================
|
//================================================================================
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
@ -59,7 +59,7 @@ int HID_GetInterface(u8* interfaceNum)
|
||||||
{
|
{
|
||||||
D_INTERFACE(HID_INTERFACE,1,3,0,0),
|
D_INTERFACE(HID_INTERFACE,1,3,0,0),
|
||||||
D_HIDREPORT(sizeof_hidReportDescriptor),
|
D_HIDREPORT(sizeof_hidReportDescriptor),
|
||||||
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)
|
D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,USB_EP_SIZE,0x01)
|
||||||
};
|
};
|
||||||
return USB_SendControl(0,&_hidInterface,sizeof(_hidInterface));
|
return USB_SendControl(0,&_hidInterface,sizeof(_hidInterface));
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ void HID_::AppendDescriptor(HIDDescriptorListNode *node)
|
||||||
current->next = node;
|
current->next = node;
|
||||||
}
|
}
|
||||||
modules_count++;
|
modules_count++;
|
||||||
sizeof_hidReportDescriptor += node->cb->length;
|
sizeof_hidReportDescriptor += (uint16_t)node->cb->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HID_::SendReport(u8 id, const void* data, int len)
|
void HID_::SendReport(u8 id, const void* data, int len)
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
|
#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
|
||||||
|
|
||||||
typedef struct __attribute__((packed)) {
|
typedef struct __attribute__((packed)) {
|
||||||
u8 length;
|
uint16_t length;
|
||||||
const void* descriptor;
|
const void* descriptor;
|
||||||
} HID_Descriptor;
|
} HID_Descriptor;
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ typedef struct
|
||||||
#define HID_TX HID_ENDPOINT_INT
|
#define HID_TX HID_ENDPOINT_INT
|
||||||
|
|
||||||
#define D_HIDREPORT(_descriptorLength) \
|
#define D_HIDREPORT(_descriptorLength) \
|
||||||
{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 }
|
{ 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength & 0xFF, _descriptorLength >> 8 }
|
||||||
|
|
||||||
#define WEAK __attribute__ ((weak))
|
#define WEAK __attribute__ ((weak))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue