27 #define TX_RX_LED_PULSE_MS 100 28 volatile u8 TxLEDPulse;
29 volatile u8 RxLEDPulse;
34 extern const u16 STRING_LANGUAGE[] PROGMEM;
35 extern const u8 STRING_PRODUCT[] PROGMEM;
36 extern const u8 STRING_MANUFACTURER[] PROGMEM;
38 extern bool _updatedLUFAbootloader;
40 const u16 STRING_LANGUAGE[2] = {
47 #define USB_PRODUCT "USB IO Board" 50 const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
53 # if defined(USB_MANUFACTURER) 54 # undef USB_MANUFACTURER 56 # define USB_MANUFACTURER "Arduino LLC" 57 #elif USB_VID == 0x1b4f 58 # if defined(USB_MANUFACTURER) 59 # undef USB_MANUFACTURER 61 # define USB_MANUFACTURER "SparkFun" 62 #elif !defined(USB_MANUFACTURER) 64 # define USB_MANUFACTURER "Unknown" 67 const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER;
70 #define DEVICE_CLASS 0x02 74 D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,
IMANUFACTURER,
IPRODUCT,ISERIAL,1);
79 volatile u8 _usbConfiguration = 0;
80 volatile u8 _usbCurrentStatus = 0;
81 volatile u8 _usbSuspendState = 0;
83 static inline void WaitIN(
void)
85 while (!(UEINTX & (1<<TXINI)))
89 static inline void ClearIN(
void)
94 static inline void WaitOUT(
void)
96 while (!(UEINTX & (1<<RXOUTI)))
100 static inline u8 WaitForINOrOUT()
102 while (!(UEINTX & ((1<<TXINI)|(1<<RXOUTI))))
104 return (UEINTX & (1<<RXOUTI)) == 0;
107 static inline void ClearOUT(
void)
109 UEINTX = ~(1<<RXOUTI);
118 RxLEDPulse = TX_RX_LED_PULSE_MS;
121 static inline u8 Recv8()
124 RxLEDPulse = TX_RX_LED_PULSE_MS;
129 static inline void Send8(
u8 d)
134 static inline void SetEP(
u8 ep)
139 static inline u8 FifoByteCount()
144 static inline u8 ReceivedSetupInt()
146 return UEINTX & (1<<RXSTPI);
149 static inline void ClearSetupInt()
151 UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
154 static inline void Stall()
156 UECONX = (1<<STALLRQ) | (1<<EPEN);
159 static inline u8 ReadWriteAllowed()
161 return UEINTX & (1<<RWAL);
164 static inline u8 Stalled()
166 return UEINTX & (1<<STALLEDI);
169 static inline u8 FifoFree()
171 return UEINTX & (1<<FIFOCON);
174 static inline void ReleaseRX()
179 static inline void ReleaseTX()
184 static inline u8 FrameNumber()
192 u8 USBGetConfiguration(
void)
194 return _usbConfiguration;
197 #define USB_RECV_TIMEOUT 202 LockEP(
u8 ep) : _sreg(SREG)
214 u8 USB_Available(
u8 ep)
217 return FifoByteCount();
222 int USB_Recv(
u8 ep,
void* d,
int len)
224 if (!_usbConfiguration || len < 0)
228 u8 n = FifoByteCount();
234 if (len && !FifoByteCount())
244 if (USB_Recv(ep,&c,1) != 1)
250 u8 USB_SendSpace(
u8 ep)
253 if (!ReadWriteAllowed())
259 int USB_Send(
u8 ep,
const void* d,
int len)
261 if (!_usbConfiguration)
264 if (_usbSuspendState & (1<<SUSPI)) {
266 UDCON |= (1 << RMWKUP);
270 const u8* data = (
const u8*)d;
272 bool sendZlp =
false;
274 while (len || sendZlp)
276 u8 n = USB_SendSpace(ep);
292 if (!ReadWriteAllowed())
296 if (ep & TRANSFER_ZERO)
301 else if (ep & TRANSFER_PGM)
304 Send8(pgm_read_byte(data++));
315 }
else if (!ReadWriteAllowed()) {
317 if (len == 0) sendZlp =
true;
318 }
else if ((len == 0) && (ep & TRANSFER_RELEASE)) {
325 TxLEDPulse = TX_RX_LED_PULSE_MS;
333 EP_TYPE_INTERRUPT_IN,
340 #define EP_SINGLE_64 0x32 // EP0 341 #define EP_DOUBLE_64 0x36 // Other endpoints 342 #define EP_SINGLE_16 0x12 356 for (
u8 i = 1; i <
sizeof(_initEndpoints) && _initEndpoints[i] != 0; i++)
360 UECFG0X = _initEndpoints[i];
361 #if USB_EP_SIZE == 16 362 UECFG1X = EP_SINGLE_16;
363 #elif USB_EP_SIZE == 64 364 UECFG1X = EP_DOUBLE_64;
366 #error Unsupported value for USB_EP_SIZE 375 bool ClassInterfaceRequest(USBSetup&
setup)
380 return CDC_Setup(setup);
382 #ifdef PLUGGABLE_USB_ENABLED 383 return PluggableUSB().setup(setup);
390 void InitControl(
int end)
398 bool SendControl(
u8 d)
402 if (!WaitForINOrOUT())
405 if (!((_cmark + 1) & 0x3F))
413 int USB_SendControl(
u8 flags,
const void* d,
int len)
416 const u8* data = (
const u8*)d;
417 bool pgm = flags & TRANSFER_PGM;
420 u8 c = pgm ? pgm_read_byte(data++) : *data++;
430 static bool USB_SendStringDescriptor(
const u8*string_P,
u8 string_len, uint8_t flags) {
431 SendControl(2 + string_len * 2);
433 bool pgm = flags & TRANSFER_PGM;
434 for(
u8 i = 0; i < string_len; i++) {
435 bool r = SendControl(pgm ? pgm_read_byte(&string_P[i]) : string_P[i]);
445 int USB_RecvControl(
void* d,
int len)
459 Recv((
u8*)d + len -
length, recvLength);
466 static u8 SendInterfaces()
470 CDC_GetInterface(&interfaces);
472 #ifdef PLUGGABLE_USB_ENABLED 473 PluggableUSB().getInterface(&interfaces);
483 bool SendConfiguration(
int maxlen)
487 u8 interfaces = SendInterfaces();
498 bool SendDescriptor(USBSetup& setup)
501 u8 t = setup.wValueH;
503 return SendConfiguration(setup.wLength);
505 InitControl(setup.wLength);
506 #ifdef PLUGGABLE_USB_ENABLED 507 ret = PluggableUSB().getDescriptor(setup);
509 return (ret > 0 ?
true :
false);
513 const u8* desc_addr = 0;
516 desc_addr = (
const u8*)&USB_DeviceDescriptorIAD;
520 if (setup.wValueL == 0) {
521 desc_addr = (
const u8*)&STRING_LANGUAGE;
523 else if (setup.wValueL ==
IPRODUCT) {
524 return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM);
527 return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER), TRANSFER_PGM);
529 else if (setup.wValueL == ISERIAL) {
530 #ifdef PLUGGABLE_USB_ENABLED 532 PluggableUSB().getShortName(name);
533 return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0);
542 u8 desc_length = pgm_read_byte(desc_addr);
544 USB_SendControl(TRANSFER_PGM,desc_addr,desc_length);
552 if (!ReceivedSetupInt())
559 u8 requestType = setup.bmRequestType;
569 u8 r = setup.bRequest;
570 u16 wValue = setup.wValueL | (setup.wValueH << 8);
575 Send8(_usbCurrentStatus);
605 UDADDR = setup.wValueL | (1<<ADDEN);
609 ok = SendDescriptor(setup);
624 _usbConfiguration = setup.wValueL;
637 InitControl(setup.wLength);
638 ok = ClassInterfaceRequest(setup);
649 void USB_Flush(
u8 ep)
656 static inline void USB_ClockDisable()
659 USBCON = (USBCON & ~(1<<OTGPADE)) | (1<<FRZCLK);
661 USBCON = (1 << FRZCLK);
663 PLLCSR &= ~(1<<PLLE);
666 static inline void USB_ClockEnable()
669 UHWCON |= (1<<UVREGE);
671 USBCON = (1<<USBE) | (1<<FRZCLK);
675 #if F_CPU == 16000000UL 676 PLLCSR |= (1<<PINDIV);
677 #elif F_CPU == 8000000UL 678 PLLCSR &= ~(1<<PINDIV);
680 #error "Clock rate of F_CPU not supported" 683 #elif defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) 685 #if F_CPU == 16000000UL 687 PLLCSR |= (1 << PLLP0);
688 #elif F_CPU == 8000000UL 690 PLLCSR &= ~(1 << PLLP0);
695 #if F_CPU == 16000000UL 696 #if defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) 698 PLLCSR = (PLLCSR & ~(1<<PLLP1)) | ((1<<PLLP2) | (1<<PLLP0));
699 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) 701 PLLCSR = (PLLCSR & ~(1<<PLLP0)) | ((1<<PLLP2) | (1<<PLLP1));
703 #error "USB Chip not supported, please defined method of USB PLL initialization" 705 #elif F_CPU == 8000000UL 707 PLLCSR = (PLLCSR & ~(1<<PLLP2)) | ((1<<PLLP1) | (1<<PLLP0));
709 #error "Clock rate of F_CPU not supported" 712 #error "USB Chip not supported, please defined method of USB PLL initialization" 716 while (!(PLLCSR & (1<<PLOCK)))
725 USBCON = (USBCON & ~(1<<FRZCLK)) | (1<<OTGPADE);
727 USBCON &= ~(1 << FRZCLK);
732 UDCON &= ~((1<<RSTCPU) | (1<<LSM) | (1<<RMWKUP) | (1<<DETACH));
734 UDCON &= ~((1 << RSTCPU) | (1 << RMWKUP) | (1 << DETACH));
738 UDCON &= ~((1<<LSM) | (1<<RMWKUP) | (1<<DETACH));
746 UDINT &= ~((1<<EORSTI) | (1<<SOFI));
749 if (udint & (1<<EORSTI))
751 InitEP(0,EP_TYPE_CONTROL,EP_SINGLE_64);
752 _usbConfiguration = 0;
753 UEIENX = 1 << RXSTPE;
757 if (udint & (1<<SOFI))
762 if (TxLEDPulse && !(--TxLEDPulse))
764 if (RxLEDPulse && !(--RxLEDPulse))
771 if (udint & (1<<WAKEUPI))
773 UDIEN = (UDIEN & ~(1<<WAKEUPE)) | (1<<SUSPE);
778 UDINT &= ~(1<<WAKEUPI);
779 _usbSuspendState = (_usbSuspendState & ~(1<<SUSPI)) | (1<<WAKEUPI);
781 else if (udint & (1<<SUSPI))
783 UDIEN = (UDIEN & ~(1<<SUSPE)) | (1<<WAKEUPE);
788 UDINT &= ~((1<<WAKEUPI) | (1<<SUSPI));
789 _usbSuspendState = (_usbSuspendState & ~(1<<WAKEUPI)) | (1<<SUSPI);
805 USBDevice_ USBDevice;
807 USBDevice_::USBDevice_()
811 void USBDevice_::attach()
813 _usbConfiguration = 0;
814 _usbCurrentStatus = 0;
815 _usbSuspendState = 0;
818 UDINT &= ~((1<<WAKEUPI) | (1<<SUSPI));
819 UDIEN = (1<<EORSTE) | (1<<SOFE) | (1<<SUSPE);
823 #if MAGIC_KEY_POS != (RAMEND-1) 825 _updatedLUFAbootloader =
true;
830 void USBDevice_::detach()
836 bool USBDevice_::configured()
838 return _usbConfiguration;
841 void USBDevice_::poll()
845 bool USBDevice_::wakeupHost()
849 UDCON &= ~(1 << RMWKUP);
851 if(!(UDCON & (1 << RMWKUP))
852 && (_usbSuspendState & (1<<SUSPI))
858 UDCON |= (1 << RMWKUP);
GLuint GLsizei GLsizei * length
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
#define USB_DEVICE_DESCRIPTOR_TYPE
#define REQUEST_RECIPIENT
#define D_DEVICE(_class, _subClass, _proto, _packetSize0, _vid, _pid, _version, _im, _ip, _is, _configs)
#define REQUEST_DEVICETOHOST
#define CDC_ACM_INTERFACE
#define DEVICE_REMOTE_WAKEUP
#define D_CONFIG(_totalLength, _interfaces)
#define REQUEST_HOSTTODEVICE
#define NEW_LUFA_SIGNATURE
GLuint const GLchar * name
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
void delay(unsigned long)
#define FEATURE_REMOTE_WAKEUP_ENABLED
#define USB_STRING_DESCRIPTOR_TYPE
#define GET_CONFIGURATION
#define SET_CONFIGURATION
GLdouble GLdouble GLdouble r
GLuint GLuint GLsizei count
GLuint GLuint GLsizei GLenum type
GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble f