Preparing from initial AVR USB NKRO support.
- Refactored pjrc USB (definitions to the .h file)
This commit is contained in:
		
							parent
							
								
									111475c86d
								
							
						
					
					
						commit
						8a66563622
					
				
					 5 changed files with 723 additions and 559 deletions
				
			
		| 
						 | 
					@ -43,7 +43,7 @@ include( Lib/CMake/initialize.cmake )
 | 
				
			||||||
#| All of the modules must be specified, as they generate the sources list of files to compile
 | 
					#| All of the modules must be specified, as they generate the sources list of files to compile
 | 
				
			||||||
#| Any modifications to this file will cause a complete rebuild of the project
 | 
					#| Any modifications to this file will cause a complete rebuild of the project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#| Please look at the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones
 | 
					#| Please look at the {Scan,Macro,Output,Debug} for information on the modules and how to create new ones
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##| Deals with acquiring the keypress information and turning it into a key index
 | 
					##| Deals with acquiring the keypress information and turning it into a key index
 | 
				
			||||||
set(   ScanModule "DPH" )
 | 
					set(   ScanModule "DPH" )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,433 +26,109 @@
 | 
				
			||||||
#include "usb_keyboard_serial.h"
 | 
					#include "usb_keyboard_serial.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----- Functions -----
 | 
					// ----- Variables -----
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set the avr into firmware reload mode
 | 
					 | 
				
			||||||
void usb_debug_reload()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	cli();
 | 
					 | 
				
			||||||
	// Disable watchdog, if enabled
 | 
					 | 
				
			||||||
	// Disable all peripherals
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	UDCON = 1;
 | 
					 | 
				
			||||||
	USBCON = (1 << FRZCLK);  // Disable USB
 | 
					 | 
				
			||||||
	UCSR1B = 0;
 | 
					 | 
				
			||||||
	_delay_ms( 5 );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(__AVR_AT90USB162__)                // Teensy 1.0
 | 
					 | 
				
			||||||
	EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
 | 
					 | 
				
			||||||
	TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
 | 
					 | 
				
			||||||
	DDRB = 0; DDRC = 0; DDRD = 0;
 | 
					 | 
				
			||||||
	PORTB = 0; PORTC = 0; PORTD = 0;
 | 
					 | 
				
			||||||
	asm volatile("jmp 0x3E00");
 | 
					 | 
				
			||||||
#elif defined(__AVR_ATmega32U4__)              // Teensy 2.0
 | 
					 | 
				
			||||||
	EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
 | 
					 | 
				
			||||||
	TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
 | 
					 | 
				
			||||||
	DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
 | 
					 | 
				
			||||||
	PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
 | 
					 | 
				
			||||||
	asm volatile("jmp 0x7E00");
 | 
					 | 
				
			||||||
#elif defined(__AVR_AT90USB646__)              // Teensy++ 1.0
 | 
					 | 
				
			||||||
	EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
 | 
					 | 
				
			||||||
	TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
 | 
					 | 
				
			||||||
	DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
 | 
					 | 
				
			||||||
	PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
 | 
					 | 
				
			||||||
	asm volatile("jmp 0xFC00");
 | 
					 | 
				
			||||||
#elif defined(__AVR_AT90USB1286__)             // Teensy++ 2.0
 | 
					 | 
				
			||||||
	EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
 | 
					 | 
				
			||||||
	TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
 | 
					 | 
				
			||||||
	DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
 | 
					 | 
				
			||||||
	PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
 | 
					 | 
				
			||||||
	asm volatile("jmp 0x1FC00");
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WDT Setup for software reset the chip
 | 
					 | 
				
			||||||
void wdt_init(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	MCUSR = 0;
 | 
					 | 
				
			||||||
	wdt_disable();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**************************************************************************
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  Configurable Options
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 **************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// When you write data, it goes into a USB endpoint buffer, which
 | 
					 | 
				
			||||||
// is transmitted to the PC when it becomes full, or after a timeout
 | 
					 | 
				
			||||||
// with no more writes.  Even if you write in exactly packet-size
 | 
					 | 
				
			||||||
// increments, this timeout is used to send a "zero length packet"
 | 
					 | 
				
			||||||
// that tells the PC no more data is expected and it should pass
 | 
					 | 
				
			||||||
// any buffered data to the application that may be waiting.  If
 | 
					 | 
				
			||||||
// you want data sent immediately, call usb_serial_flush_output().
 | 
					 | 
				
			||||||
#define TRANSMIT_FLUSH_TIMEOUT	5   /* in milliseconds */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// If the PC is connected but not "listening", this is the length
 | 
					 | 
				
			||||||
// of time before usb_serial_getchar() returns with an error.  This
 | 
					 | 
				
			||||||
// is roughly equivilant to a real UART simply transmitting the
 | 
					 | 
				
			||||||
// bits on a wire where nobody is listening, except you get an error
 | 
					 | 
				
			||||||
// code which you can ignore for serial-like discard of data, or
 | 
					 | 
				
			||||||
// use to know your data wasn't sent.
 | 
					 | 
				
			||||||
#define TRANSMIT_TIMEOUT	25   /* in milliseconds */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// USB devices are supposed to implment a halt feature, which is
 | 
					 | 
				
			||||||
// rarely (if ever) used.  If you comment this line out, the halt
 | 
					 | 
				
			||||||
// code will be removed, saving 116 bytes of space (gcc 4.3.0).
 | 
					 | 
				
			||||||
// This is not strictly USB compliant, but works with all major
 | 
					 | 
				
			||||||
// operating systems.
 | 
					 | 
				
			||||||
#define SUPPORT_ENDPOINT_HALT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**************************************************************************
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  Descriptor Data
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 **************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Descriptors are the data that your computer reads when it auto-detects
 | 
					 | 
				
			||||||
// this USB device (called "enumeration" in USB lingo).  The most commonly
 | 
					 | 
				
			||||||
// changed items are editable at the top of this file.  Changing things
 | 
					 | 
				
			||||||
// in here should only be done by those who've read chapter 9 of the USB
 | 
					 | 
				
			||||||
// spec and relevant portions of any USB class specifications!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const uint8_t PROGMEM device_descriptor[] = {
 | 
					 | 
				
			||||||
	18,					// bLength
 | 
					 | 
				
			||||||
	1,					// bDescriptorType
 | 
					 | 
				
			||||||
	0x00, 0x02,				// bcdUSB
 | 
					 | 
				
			||||||
	0,					// bDeviceClass
 | 
					 | 
				
			||||||
	0,					// bDeviceSubClass
 | 
					 | 
				
			||||||
	0,					// bDeviceProtocol
 | 
					 | 
				
			||||||
	ENDPOINT0_SIZE,				// bMaxPacketSize0
 | 
					 | 
				
			||||||
	LSB(VENDOR_ID), MSB(VENDOR_ID),		// idVendor
 | 
					 | 
				
			||||||
	LSB(PRODUCT_ID), MSB(PRODUCT_ID),	// idProduct
 | 
					 | 
				
			||||||
	0x00, 0x01,				// bcdDevice
 | 
					 | 
				
			||||||
	1,					// iManufacturer
 | 
					 | 
				
			||||||
	2,					// iProduct
 | 
					 | 
				
			||||||
	3,					// iSerialNumber
 | 
					 | 
				
			||||||
	1					// bNumConfigurations
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
 | 
					 | 
				
			||||||
static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
 | 
					 | 
				
			||||||
        0x05, 0x01,          // Usage Page (Generic Desktop),
 | 
					 | 
				
			||||||
        0x09, 0x06,          // Usage (Keyboard),
 | 
					 | 
				
			||||||
        0xA1, 0x01,          // Collection (Application),
 | 
					 | 
				
			||||||
        0x75, 0x01,          //   Report Size (1),
 | 
					 | 
				
			||||||
        0x95, 0x08,          //   Report Count (8),
 | 
					 | 
				
			||||||
        0x05, 0x07,          //   Usage Page (Key Codes),
 | 
					 | 
				
			||||||
        0x19, 0xE0,          //   Usage Minimum (224),
 | 
					 | 
				
			||||||
        0x29, 0xE7,          //   Usage Maximum (231),
 | 
					 | 
				
			||||||
        0x15, 0x00,          //   Logical Minimum (0),
 | 
					 | 
				
			||||||
        0x25, 0x01,          //   Logical Maximum (1),
 | 
					 | 
				
			||||||
        0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
 | 
					 | 
				
			||||||
        0x95, 0x08,          //  Report Count (8),
 | 
					 | 
				
			||||||
        0x75, 0x01,          //  Report Size (1),
 | 
					 | 
				
			||||||
        0x15, 0x00,          //  Logical Minimum (0),
 | 
					 | 
				
			||||||
        0x25, 0x01,          //  Logical Maximum (1),
 | 
					 | 
				
			||||||
        0x05, 0x0C,          //  Usage Page (Consumer),
 | 
					 | 
				
			||||||
        0x09, 0xE9,          //  Usage (Volume Increment),
 | 
					 | 
				
			||||||
        0x09, 0xEA,          //  Usage (Volume Decrement),
 | 
					 | 
				
			||||||
        0x09, 0xE2,          //  Usage (Mute),
 | 
					 | 
				
			||||||
        0x09, 0xCD,          //  Usage (Play/Pause),
 | 
					 | 
				
			||||||
        0x09, 0xB5,          //  Usage (Scan Next Track),
 | 
					 | 
				
			||||||
        0x09, 0xB6,          //  Usage (Scan Previous Track),
 | 
					 | 
				
			||||||
        0x09, 0xB7,          //  Usage (Stop),
 | 
					 | 
				
			||||||
        0x09, 0xB8,          //  Usage (Eject),
 | 
					 | 
				
			||||||
        0x81, 0x02,          //  Input (Data, Variable, Absolute), ;Media keys
 | 
					 | 
				
			||||||
        0x95, 0x05,          //  Report Count (5),
 | 
					 | 
				
			||||||
        0x75, 0x01,          //  Report Size (1),
 | 
					 | 
				
			||||||
        0x05, 0x08,          //  Usage Page (LEDs),
 | 
					 | 
				
			||||||
        0x19, 0x01,          //  Usage Minimum (1),
 | 
					 | 
				
			||||||
        0x29, 0x05,          //  Usage Maximum (5),
 | 
					 | 
				
			||||||
        0x91, 0x02,          //  Output (Data, Variable, Absolute), ;LED report
 | 
					 | 
				
			||||||
        0x95, 0x01,          //  Report Count (1),
 | 
					 | 
				
			||||||
        0x75, 0x03,          //  Report Size (3),
 | 
					 | 
				
			||||||
        0x91, 0x03,          //  Output (Constant),                 ;LED report padding
 | 
					 | 
				
			||||||
        0x95, 0x06,          //  Report Count (6),
 | 
					 | 
				
			||||||
        0x75, 0x08,          //  Report Size (8),
 | 
					 | 
				
			||||||
        0x15, 0x00,          //  Logical Minimum (0),
 | 
					 | 
				
			||||||
        0x25, 0x7F,          //  Logical Maximum(104),
 | 
					 | 
				
			||||||
        0x05, 0x07,          //  Usage Page (Key Codes),
 | 
					 | 
				
			||||||
        0x19, 0x00,          //  Usage Minimum (0),
 | 
					 | 
				
			||||||
        0x29, 0x7F,          //  Usage Maximum (104),
 | 
					 | 
				
			||||||
        0x81, 0x00,          //  Input (Data, Array),                ;Normal keys
 | 
					 | 
				
			||||||
        0xc0                 // End Collection
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// <Configuration> + <Keyboard HID> + <Serial CDC>
 | 
					 | 
				
			||||||
#define CONFIG1_DESC_SIZE        (9 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7)
 | 
					 | 
				
			||||||
#define KEYBOARD_HID_DESC_OFFSET (9 + 9)
 | 
					 | 
				
			||||||
#define SERIAL_CDC_DESC_OFFSET   (9 + 9+9+7)
 | 
					 | 
				
			||||||
static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
 | 
					 | 
				
			||||||
// --- Configuration ---
 | 
					 | 
				
			||||||
// - 9 bytes -
 | 
					 | 
				
			||||||
	// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
 | 
					 | 
				
			||||||
	9, 					// bLength;
 | 
					 | 
				
			||||||
	2,					// bDescriptorType;
 | 
					 | 
				
			||||||
	LSB(CONFIG1_DESC_SIZE),			// wTotalLength
 | 
					 | 
				
			||||||
	MSB(CONFIG1_DESC_SIZE),
 | 
					 | 
				
			||||||
	3,					// bNumInterfaces
 | 
					 | 
				
			||||||
	1,					// bConfigurationValue
 | 
					 | 
				
			||||||
	0,					// iConfiguration
 | 
					 | 
				
			||||||
	0xC0,					// bmAttributes
 | 
					 | 
				
			||||||
	50,					// bMaxPower
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// --- Keyboard HID ---
 | 
					 | 
				
			||||||
// - 9 bytes -
 | 
					 | 
				
			||||||
	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
					 | 
				
			||||||
	9,					// bLength
 | 
					 | 
				
			||||||
	4,					// bDescriptorType
 | 
					 | 
				
			||||||
	KEYBOARD_INTERFACE,			// bInterfaceNumber
 | 
					 | 
				
			||||||
	0,					// bAlternateSetting
 | 
					 | 
				
			||||||
	1,					// bNumEndpoints
 | 
					 | 
				
			||||||
	0x03,					// bInterfaceClass (0x03 = HID)
 | 
					 | 
				
			||||||
	0x01,					// bInterfaceSubClass (0x01 = Boot)
 | 
					 | 
				
			||||||
	0x01,					// bInterfaceProtocol (0x01 = Keyboard)
 | 
					 | 
				
			||||||
	0,					// iInterface
 | 
					 | 
				
			||||||
// - 9 bytes -
 | 
					 | 
				
			||||||
	// HID interface descriptor, HID 1.11 spec, section 6.2.1
 | 
					 | 
				
			||||||
	9,					// bLength
 | 
					 | 
				
			||||||
	0x21,					// bDescriptorType
 | 
					 | 
				
			||||||
	0x11, 0x01,				// bcdHID
 | 
					 | 
				
			||||||
	0,					// bCountryCode
 | 
					 | 
				
			||||||
	1,					// bNumDescriptors
 | 
					 | 
				
			||||||
	0x22,					// bDescriptorType
 | 
					 | 
				
			||||||
	LSB(sizeof(keyboard_hid_report_desc)),	// wDescriptorLength
 | 
					 | 
				
			||||||
	MSB(sizeof(keyboard_hid_report_desc)),
 | 
					 | 
				
			||||||
// - 7 bytes -
 | 
					 | 
				
			||||||
	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
					 | 
				
			||||||
	7,					// bLength
 | 
					 | 
				
			||||||
	5,					// bDescriptorType
 | 
					 | 
				
			||||||
	KEYBOARD_ENDPOINT | 0x80,		// bEndpointAddress
 | 
					 | 
				
			||||||
	0x03,					// bmAttributes (0x03=intr)
 | 
					 | 
				
			||||||
	KEYBOARD_SIZE, 0,			// wMaxPacketSize
 | 
					 | 
				
			||||||
	KEYBOARD_INTERVAL,			// bInterval
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// --- Serial CDC ---
 | 
					 | 
				
			||||||
// - 8 bytes -
 | 
					 | 
				
			||||||
        // interface association descriptor, USB ECN, Table 9-Z
 | 
					 | 
				
			||||||
        8,                                      // bLength
 | 
					 | 
				
			||||||
        11,                                     // bDescriptorType
 | 
					 | 
				
			||||||
        CDC_STATUS_INTERFACE,                   // bFirstInterface
 | 
					 | 
				
			||||||
        2,                                      // bInterfaceCount
 | 
					 | 
				
			||||||
        0x02,                                   // bFunctionClass
 | 
					 | 
				
			||||||
        0x02,                                   // bFunctionSubClass
 | 
					 | 
				
			||||||
        0x01,                                   // bFunctionProtocol
 | 
					 | 
				
			||||||
        4,                                      // iFunction
 | 
					 | 
				
			||||||
// - 9 bytes -
 | 
					 | 
				
			||||||
	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
					 | 
				
			||||||
	9,					// bLength
 | 
					 | 
				
			||||||
	4,					// bDescriptorType
 | 
					 | 
				
			||||||
	CDC_STATUS_INTERFACE,			// bInterfaceNumber
 | 
					 | 
				
			||||||
	0,					// bAlternateSetting
 | 
					 | 
				
			||||||
	1,					// bNumEndpoints
 | 
					 | 
				
			||||||
	0x02,					// bInterfaceClass
 | 
					 | 
				
			||||||
	0x02,					// bInterfaceSubClass
 | 
					 | 
				
			||||||
	0x01,					// bInterfaceProtocol
 | 
					 | 
				
			||||||
	0,					// iInterface
 | 
					 | 
				
			||||||
// - 5 bytes -
 | 
					 | 
				
			||||||
	// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
 | 
					 | 
				
			||||||
	5,					// bFunctionLength
 | 
					 | 
				
			||||||
	0x24,					// bDescriptorType
 | 
					 | 
				
			||||||
	0x00,					// bDescriptorSubtype
 | 
					 | 
				
			||||||
	0x10, 0x01,				// bcdCDC
 | 
					 | 
				
			||||||
// - 5 bytes -
 | 
					 | 
				
			||||||
	// Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
 | 
					 | 
				
			||||||
	5,					// bFunctionLength
 | 
					 | 
				
			||||||
	0x24,					// bDescriptorType
 | 
					 | 
				
			||||||
	0x01,					// bDescriptorSubtype
 | 
					 | 
				
			||||||
	0x01,					// bmCapabilities
 | 
					 | 
				
			||||||
	1,					// bDataInterface
 | 
					 | 
				
			||||||
// - 4 bytes -
 | 
					 | 
				
			||||||
	// Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
 | 
					 | 
				
			||||||
	4,					// bFunctionLength
 | 
					 | 
				
			||||||
	0x24,					// bDescriptorType
 | 
					 | 
				
			||||||
	0x02,					// bDescriptorSubtype
 | 
					 | 
				
			||||||
	0x06,					// bmCapabilities
 | 
					 | 
				
			||||||
// - 5 bytes -
 | 
					 | 
				
			||||||
	// Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
 | 
					 | 
				
			||||||
	5,					// bFunctionLength
 | 
					 | 
				
			||||||
	0x24,					// bDescriptorType
 | 
					 | 
				
			||||||
	0x06,					// bDescriptorSubtype
 | 
					 | 
				
			||||||
	CDC_STATUS_INTERFACE,			// bMasterInterface
 | 
					 | 
				
			||||||
	CDC_DATA_INTERFACE,			// bSlaveInterface0
 | 
					 | 
				
			||||||
// - 7 bytes -
 | 
					 | 
				
			||||||
	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
					 | 
				
			||||||
	7,					// bLength
 | 
					 | 
				
			||||||
	5,					// bDescriptorType
 | 
					 | 
				
			||||||
	CDC_ACM_ENDPOINT | 0x80,		// bEndpointAddress
 | 
					 | 
				
			||||||
	0x03,					// bmAttributes (0x03=intr)
 | 
					 | 
				
			||||||
	CDC_ACM_SIZE, 0,			// wMaxPacketSize
 | 
					 | 
				
			||||||
	64,					// bInterval
 | 
					 | 
				
			||||||
// - 9 bytes -
 | 
					 | 
				
			||||||
	// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
					 | 
				
			||||||
	9,					// bLength
 | 
					 | 
				
			||||||
	4,					// bDescriptorType
 | 
					 | 
				
			||||||
	CDC_DATA_INTERFACE,			// bInterfaceNumber
 | 
					 | 
				
			||||||
	0,					// bAlternateSetting
 | 
					 | 
				
			||||||
	2,					// bNumEndpoints
 | 
					 | 
				
			||||||
	0x0A,					// bInterfaceClass
 | 
					 | 
				
			||||||
	0x00,					// bInterfaceSubClass
 | 
					 | 
				
			||||||
	0x00,					// bInterfaceProtocol
 | 
					 | 
				
			||||||
	0,					// iInterface
 | 
					 | 
				
			||||||
// - 7 bytes -
 | 
					 | 
				
			||||||
	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
					 | 
				
			||||||
	7,					// bLength
 | 
					 | 
				
			||||||
	5,					// bDescriptorType
 | 
					 | 
				
			||||||
	CDC_RX_ENDPOINT,			// bEndpointAddress
 | 
					 | 
				
			||||||
	0x02,					// bmAttributes (0x02=bulk)
 | 
					 | 
				
			||||||
	CDC_RX_SIZE, 0,				// wMaxPacketSize
 | 
					 | 
				
			||||||
	0,					// bInterval
 | 
					 | 
				
			||||||
// - 7 bytes -
 | 
					 | 
				
			||||||
	// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
					 | 
				
			||||||
	7,					// bLength
 | 
					 | 
				
			||||||
	5,					// bDescriptorType
 | 
					 | 
				
			||||||
	CDC_TX_ENDPOINT | 0x80,			// bEndpointAddress
 | 
					 | 
				
			||||||
	0x02,					// bmAttributes (0x02=bulk)
 | 
					 | 
				
			||||||
	CDC_TX_SIZE, 0,				// wMaxPacketSize
 | 
					 | 
				
			||||||
	0,					// bInterval
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// If you're desperate for a little extra code memory, these strings
 | 
					 | 
				
			||||||
// can be completely removed if iManufacturer, iProduct, iSerialNumber
 | 
					 | 
				
			||||||
// in the device desciptor are changed to zeros.
 | 
					 | 
				
			||||||
struct usb_string_descriptor_struct {
 | 
					 | 
				
			||||||
	uint8_t bLength;
 | 
					 | 
				
			||||||
	uint8_t bDescriptorType;
 | 
					 | 
				
			||||||
	int16_t wString[];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const struct usb_string_descriptor_struct PROGMEM string0 = {
 | 
					 | 
				
			||||||
	4,
 | 
					 | 
				
			||||||
	3,
 | 
					 | 
				
			||||||
	{0x0409}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const struct usb_string_descriptor_struct PROGMEM string1 = {
 | 
					 | 
				
			||||||
	sizeof(STR_MANUFACTURER),
 | 
					 | 
				
			||||||
	3,
 | 
					 | 
				
			||||||
	STR_MANUFACTURER
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const struct usb_string_descriptor_struct PROGMEM string2 = {
 | 
					 | 
				
			||||||
	sizeof(STR_PRODUCT),
 | 
					 | 
				
			||||||
	3,
 | 
					 | 
				
			||||||
	STR_PRODUCT
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const struct usb_string_descriptor_struct PROGMEM string3 = {
 | 
					 | 
				
			||||||
	sizeof(STR_SERIAL),
 | 
					 | 
				
			||||||
	3,
 | 
					 | 
				
			||||||
	STR_SERIAL
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// This table defines which descriptor data is sent for each specific
 | 
					 | 
				
			||||||
// request from the host (in wValue and wIndex).
 | 
					 | 
				
			||||||
static const struct descriptor_list_struct {
 | 
					 | 
				
			||||||
	uint16_t	wValue;
 | 
					 | 
				
			||||||
	uint16_t	wIndex;
 | 
					 | 
				
			||||||
	const uint8_t	*addr;
 | 
					 | 
				
			||||||
	uint8_t		length;
 | 
					 | 
				
			||||||
} PROGMEM descriptor_list[] = {
 | 
					 | 
				
			||||||
	{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
 | 
					 | 
				
			||||||
	{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
 | 
					 | 
				
			||||||
	{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
 | 
					 | 
				
			||||||
	{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
 | 
					 | 
				
			||||||
	{0x0300, 0x0000, (const uint8_t *)&string0, 4},
 | 
					 | 
				
			||||||
	{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
 | 
					 | 
				
			||||||
	{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)},
 | 
					 | 
				
			||||||
	{0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL)}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**************************************************************************
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  Variables - these are the only non-stack RAM usage
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 **************************************************************************/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// zero when we are not configured, non-zero when enumerated
 | 
					// zero when we are not configured, non-zero when enumerated
 | 
				
			||||||
static volatile uint8_t usb_configuration=0;
 | 
					static volatile uint8_t usb_configuration = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// the time remaining before we transmit any partially full
 | 
					// the time remaining before we transmit any partially full
 | 
				
			||||||
// packet, or send a zero length packet.
 | 
					// packet, or send a zero length packet.
 | 
				
			||||||
static volatile uint8_t transmit_flush_timer=0;
 | 
					static volatile uint8_t transmit_flush_timer = 0;
 | 
				
			||||||
static uint8_t transmit_previous_timeout=0;
 | 
					static uint8_t transmit_previous_timeout = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// serial port settings (baud rate, control signals, etc) set
 | 
					// serial port settings (baud rate, control signals, etc) set
 | 
				
			||||||
// by the PC.  These are ignored, but kept in RAM.
 | 
					// by the PC.  These are ignored, but kept in RAM.
 | 
				
			||||||
static uint8_t cdc_line_coding[7]={0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08};
 | 
					static uint8_t cdc_line_coding[7] = {0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08};
 | 
				
			||||||
static uint8_t cdc_line_rtsdtr=0;
 | 
					static uint8_t cdc_line_rtsdtr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**************************************************************************
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *  Public Functions - these are the API intended for the user
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 **************************************************************************/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----- USB Keyboard Functions -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// initialize USB
 | 
					// Sends normal keyboard out to host
 | 
				
			||||||
void usb_init(void)
 | 
					// NOTE: Make sure to match the descriptor
 | 
				
			||||||
 | 
					void usb_keyboard_toHost()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	HW_CONFIG();
 | 
						uint8_t i;
 | 
				
			||||||
	USB_FREEZE();				// enable USB
 | 
					 | 
				
			||||||
	PLL_CONFIG();				// config PLL
 | 
					 | 
				
			||||||
        while (!(PLLCSR & (1<<PLOCK))) ;	// wait for PLL lock
 | 
					 | 
				
			||||||
        USB_CONFIG();				// start USB clock
 | 
					 | 
				
			||||||
        UDCON = 0;				// enable attach resistor
 | 
					 | 
				
			||||||
	usb_configuration = 0;
 | 
					 | 
				
			||||||
        UDIEN = (1<<EORSTE)|(1<<SOFE);
 | 
					 | 
				
			||||||
	sei();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Disable watchdog timer after possible software reset
 | 
						// Modifiers
 | 
				
			||||||
	//wdt_init(); // XXX Not working...seems to be ok without this, not sure though
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// return 0 if the USB is not configured, or the configuration
 | 
					 | 
				
			||||||
// number selected by the HOST
 | 
					 | 
				
			||||||
uint8_t usb_configured(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return usb_configuration;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// send the contents of USBKeys_Array and USBKeys_Modifiers
 | 
					 | 
				
			||||||
int8_t usb_keyboard_send(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint8_t i, intr_state, timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!usb_configuration) return -1;
 | 
					 | 
				
			||||||
	intr_state = SREG;
 | 
					 | 
				
			||||||
	cli();
 | 
					 | 
				
			||||||
	UENUM = KEYBOARD_ENDPOINT;
 | 
					 | 
				
			||||||
	timeout = UDFNUML + 50;
 | 
					 | 
				
			||||||
	while (1) {
 | 
					 | 
				
			||||||
		// are we ready to transmit?
 | 
					 | 
				
			||||||
		if (UEINTX & (1<<RWAL)) break;
 | 
					 | 
				
			||||||
		SREG = intr_state;
 | 
					 | 
				
			||||||
		// has the USB gone offline?
 | 
					 | 
				
			||||||
		if (!usb_configuration) return -1;
 | 
					 | 
				
			||||||
		// have we waited too long?
 | 
					 | 
				
			||||||
		if (UDFNUML == timeout) return -1;
 | 
					 | 
				
			||||||
		// get ready to try checking again
 | 
					 | 
				
			||||||
		intr_state = SREG;
 | 
					 | 
				
			||||||
		cli();
 | 
					 | 
				
			||||||
		UENUM = KEYBOARD_ENDPOINT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	UEDATX = USBKeys_Modifiers;
 | 
						UEDATX = USBKeys_Modifiers;
 | 
				
			||||||
	UEDATX = 0;
 | 
					
 | 
				
			||||||
	for (i=0; i<6; i++) {
 | 
						// Normal Keys
 | 
				
			||||||
 | 
						for ( i = 0; i < 6; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		UEDATX = USBKeys_Array[i];
 | 
							UEDATX = USBKeys_Array[i];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	UEINTX = 0x3A;
 | 
						UEINTX = 0x3A;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sends NKRO keyboard out to host
 | 
				
			||||||
 | 
					// NOTE: Make sure to match the descriptor
 | 
				
			||||||
 | 
					void usb_nkrokeyboard_toHost()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Modifiers
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						UEDATX = 0x02;
 | 
				
			||||||
 | 
						UEDATX = USBKeys_Modifiers;
 | 
				
			||||||
 | 
						UEINTX = 0x3A;
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Media Keys
 | 
				
			||||||
 | 
						UEDATX = 0x03;
 | 
				
			||||||
 | 
						UEDATX = 0;
 | 
				
			||||||
 | 
						UEINTX = 0x3A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Normal Keys
 | 
				
			||||||
 | 
						UEDATX = 0x04;
 | 
				
			||||||
 | 
						for ( i = 0; i < 6; i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							UEDATX = USBKeys_Array[i];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						UEINTX = 0x3A;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// send the contents of USBKeys_Array and USBKeys_Modifiers
 | 
				
			||||||
 | 
					int8_t usb_keyboard_send()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t intr_state, timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						intr_state = SREG;
 | 
				
			||||||
 | 
						timeout = UDFNUML + 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ready to transmit keypresses?
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SREG = intr_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// has the USB gone offline? or exceeded timeout?
 | 
				
			||||||
 | 
							if ( !usb_configuration || UDFNUML == timeout )
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// get ready to try checking again
 | 
				
			||||||
 | 
							intr_state = SREG;
 | 
				
			||||||
 | 
							cli();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If not using Boot protocol, send NKRO
 | 
				
			||||||
 | 
							UENUM = USBKeys_Protocol ? KEYBOARD_NKRO_ENDPOINT : KEYBOARD_ENDPOINT;
 | 
				
			||||||
 | 
						} while ( !( UEINTX & (1 << RWAL) ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Send normal keyboard interrupt packet(s)
 | 
				
			||||||
 | 
						switch ( USBKeys_Protocol )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						usb_keyboard_toHost();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	USBKeys_Idle_Count = 0;
 | 
						USBKeys_Idle_Count = 0;
 | 
				
			||||||
	SREG = intr_state;
 | 
						SREG = intr_state;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----- USB Virtual Serial Port (CDC) Functions -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// get the next character, or -1 if nothing received
 | 
					// get the next character, or -1 if nothing received
 | 
				
			||||||
int16_t usb_serial_getchar(void)
 | 
					int16_t usb_serial_getchar(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -827,55 +503,121 @@ int8_t usb_serial_set_control(uint8_t signals)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**************************************************************************
 | 
					// ----- General USB Functions -----
 | 
				
			||||||
 *
 | 
					
 | 
				
			||||||
 *  Private Functions - not intended for general user consumption....
 | 
					// Set the avr into firmware reload mode
 | 
				
			||||||
 *
 | 
					void usb_debug_reload()
 | 
				
			||||||
 **************************************************************************/
 | 
					{
 | 
				
			||||||
 | 
						cli();
 | 
				
			||||||
 | 
						// Disable watchdog, if enabled
 | 
				
			||||||
 | 
						// Disable all peripherals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UDCON = 1;
 | 
				
			||||||
 | 
						USBCON = (1 << FRZCLK);  // Disable USB
 | 
				
			||||||
 | 
						UCSR1B = 0;
 | 
				
			||||||
 | 
						_delay_ms( 5 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__AVR_AT90USB162__)                // Teensy 1.0
 | 
				
			||||||
 | 
						EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
 | 
				
			||||||
 | 
						TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
 | 
				
			||||||
 | 
						DDRB = 0; DDRC = 0; DDRD = 0;
 | 
				
			||||||
 | 
						PORTB = 0; PORTC = 0; PORTD = 0;
 | 
				
			||||||
 | 
						asm volatile("jmp 0x3E00");
 | 
				
			||||||
 | 
					#elif defined(__AVR_ATmega32U4__)              // Teensy 2.0
 | 
				
			||||||
 | 
						EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
 | 
				
			||||||
 | 
						TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
 | 
				
			||||||
 | 
						DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
 | 
				
			||||||
 | 
						PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
 | 
				
			||||||
 | 
						asm volatile("jmp 0x7E00");
 | 
				
			||||||
 | 
					#elif defined(__AVR_AT90USB646__)              // Teensy++ 1.0
 | 
				
			||||||
 | 
						EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
 | 
				
			||||||
 | 
						TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
 | 
				
			||||||
 | 
						DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
 | 
				
			||||||
 | 
						PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
 | 
				
			||||||
 | 
						asm volatile("jmp 0xFC00");
 | 
				
			||||||
 | 
					#elif defined(__AVR_AT90USB1286__)             // Teensy++ 2.0
 | 
				
			||||||
 | 
						EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
 | 
				
			||||||
 | 
						TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
 | 
				
			||||||
 | 
						DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
 | 
				
			||||||
 | 
						PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
 | 
				
			||||||
 | 
						asm volatile("jmp 0x1FC00");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WDT Setup for software reset the chip
 | 
				
			||||||
 | 
					void wdt_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						MCUSR = 0;
 | 
				
			||||||
 | 
						wdt_disable();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// initialize USB
 | 
				
			||||||
 | 
					void usb_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						HW_CONFIG();
 | 
				
			||||||
 | 
						USB_FREEZE();				// enable USB
 | 
				
			||||||
 | 
						PLL_CONFIG();				// config PLL
 | 
				
			||||||
 | 
					        while (!(PLLCSR & (1<<PLOCK))) ;	// wait for PLL lock
 | 
				
			||||||
 | 
					        USB_CONFIG();				// start USB clock
 | 
				
			||||||
 | 
					        UDCON = 0;				// enable attach resistor
 | 
				
			||||||
 | 
						usb_configuration = 0;
 | 
				
			||||||
 | 
					        UDIEN = (1<<EORSTE) | (1<<SOFE);
 | 
				
			||||||
 | 
						sei();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Disable watchdog timer after possible software reset
 | 
				
			||||||
 | 
						//wdt_init(); // XXX Not working...seems to be ok without this, not sure though
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// return 0 if the USB is not configured, or the configuration
 | 
				
			||||||
 | 
					// number selected by the HOST
 | 
				
			||||||
 | 
					uint8_t usb_configured()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return usb_configuration;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// USB Device Interrupt - handle all device-level events
 | 
					// USB Device Interrupt - handle all device-level events
 | 
				
			||||||
// the transmit buffer flushing is triggered by the start of frame
 | 
					// the transmit buffer flushing is triggered by the start of frame
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
ISR(USB_GEN_vect)
 | 
					ISR( USB_GEN_vect )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t intbits, t_cdc, i;
 | 
						uint8_t intbits, t_cdc;
 | 
				
			||||||
	static uint8_t div4=0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        intbits = UDINT;
 | 
					        intbits = UDINT;
 | 
				
			||||||
        UDINT = 0;
 | 
					        UDINT = 0;
 | 
				
			||||||
        if (intbits & (1<<EORSTI)) {
 | 
					        if ( intbits & (1 << EORSTI) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		UENUM = 0;
 | 
							UENUM = 0;
 | 
				
			||||||
		UECONX = 1;
 | 
							UECONX = 1;
 | 
				
			||||||
		UECFG0X = EP_TYPE_CONTROL;
 | 
							UECFG0X = EP_TYPE_CONTROL;
 | 
				
			||||||
		UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
 | 
							UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
 | 
				
			||||||
		UEIENX = (1<<RXSTPE);
 | 
							UEIENX = (1 << RXSTPE);
 | 
				
			||||||
		usb_configuration = 0;
 | 
							usb_configuration = 0;
 | 
				
			||||||
		cdc_line_rtsdtr = 0;
 | 
							cdc_line_rtsdtr = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
	if ((intbits & (1<<SOFI)) && usb_configuration) {
 | 
						if ( (intbits & (1 << SOFI)) && usb_configuration )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		t_cdc = transmit_flush_timer;
 | 
							t_cdc = transmit_flush_timer;
 | 
				
			||||||
		if (t_cdc) {
 | 
							if ( t_cdc )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			transmit_flush_timer = --t_cdc;
 | 
								transmit_flush_timer = --t_cdc;
 | 
				
			||||||
			if (!t_cdc) {
 | 
								if ( !t_cdc )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
				UENUM = CDC_TX_ENDPOINT;
 | 
									UENUM = CDC_TX_ENDPOINT;
 | 
				
			||||||
				UEINTX = 0x3A;
 | 
									UEINTX = 0x3A;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (USBKeys_Idle_Config && (++div4 & 3) == 0) {
 | 
							static uint8_t div4 = 0;
 | 
				
			||||||
			UENUM = KEYBOARD_ENDPOINT;
 | 
							if ( USBKeys_Idle_Config && (++div4 & 3) == 0 )
 | 
				
			||||||
			if (UEINTX & (1<<RWAL)) {
 | 
							{
 | 
				
			||||||
				USBKeys_Idle_Count++;
 | 
								USBKeys_Idle_Count++;
 | 
				
			||||||
				if (USBKeys_Idle_Count == USBKeys_Idle_Config) {
 | 
								if ( USBKeys_Idle_Count == USBKeys_Idle_Config )
 | 
				
			||||||
					USBKeys_Idle_Count = 0;
 | 
								{
 | 
				
			||||||
					UEDATX = USBKeys_Modifiers;
 | 
									// XXX TODO Is this even used? If so, when? -Jacob
 | 
				
			||||||
					UEDATX = 0;
 | 
									// From hasu's code, this section looks like it could fix the Mac SET_IDLE problem
 | 
				
			||||||
					for (i=0; i<6; i++) {
 | 
									// Send normal keyboard interrupt packet(s)
 | 
				
			||||||
						UEDATX = USBKeys_Array[i];
 | 
									//usb_keyboard_toHost();
 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					UEINTX = 0x3A;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -935,22 +677,28 @@ ISR(USB_COM_vect)
 | 
				
			||||||
                wLength = UEDATX;
 | 
					                wLength = UEDATX;
 | 
				
			||||||
                wLength |= (UEDATX << 8);
 | 
					                wLength |= (UEDATX << 8);
 | 
				
			||||||
                UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
 | 
					                UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
 | 
				
			||||||
                if (bRequest == GET_DESCRIPTOR) {
 | 
					
 | 
				
			||||||
 | 
					                if ( bRequest == GET_DESCRIPTOR )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			list = (const uint8_t *)descriptor_list;
 | 
								list = (const uint8_t *)descriptor_list;
 | 
				
			||||||
			for (i=0; ; i++) {
 | 
								for ( i = 0; ; i++ )
 | 
				
			||||||
				if (i >= NUM_DESC_LIST) {
 | 
								{
 | 
				
			||||||
					UECONX = (1<<STALLRQ)|(1<<EPEN);  //stall
 | 
									if ( i >= NUM_DESC_LIST )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										UECONX = (1 << STALLRQ) | (1 << EPEN);  //stall
 | 
				
			||||||
					return;
 | 
										return;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				desc_val = pgm_read_word(list);
 | 
									desc_val = pgm_read_word(list);
 | 
				
			||||||
				if (desc_val != wValue) {
 | 
									if ( desc_val != wValue )
 | 
				
			||||||
					list += sizeof(struct descriptor_list_struct);
 | 
									{
 | 
				
			||||||
 | 
										list += sizeof( struct descriptor_list_struct );
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				list += 2;
 | 
									list += 2;
 | 
				
			||||||
				desc_val = pgm_read_word(list);
 | 
									desc_val = pgm_read_word(list);
 | 
				
			||||||
				if (desc_val != wIndex) {
 | 
									if ( desc_val != wIndex )
 | 
				
			||||||
					list += sizeof(struct descriptor_list_struct)-2;
 | 
									{
 | 
				
			||||||
 | 
										list += sizeof(struct descriptor_list_struct) - 2;
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				list += 2;
 | 
									list += 2;
 | 
				
			||||||
| 
						 | 
					@ -977,31 +725,38 @@ ISR(USB_COM_vect)
 | 
				
			||||||
			} while (len || n == ENDPOINT0_SIZE);
 | 
								} while (len || n == ENDPOINT0_SIZE);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (bRequest == SET_ADDRESS) {
 | 
							if (bRequest == SET_ADDRESS) {
 | 
				
			||||||
			usb_send_in();
 | 
								usb_send_in();
 | 
				
			||||||
			usb_wait_in_ready();
 | 
								usb_wait_in_ready();
 | 
				
			||||||
			UDADDR = wValue | (1<<ADDEN);
 | 
								UDADDR = wValue | (1<<ADDEN);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
 | 
					
 | 
				
			||||||
 | 
							if ( bRequest == SET_CONFIGURATION && bmRequestType == 0 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			usb_configuration = wValue;
 | 
								usb_configuration = wValue;
 | 
				
			||||||
			cdc_line_rtsdtr = 0;
 | 
								cdc_line_rtsdtr = 0;
 | 
				
			||||||
			transmit_flush_timer = 0;
 | 
								transmit_flush_timer = 0;
 | 
				
			||||||
			usb_send_in();
 | 
								usb_send_in();
 | 
				
			||||||
			cfg = endpoint_config_table;
 | 
								cfg = endpoint_config_table;
 | 
				
			||||||
			for (i=1; i<6; i++) { // 4+1 of 7 endpoints are used // XXX Important to change if more endpoints are used
 | 
								// Setup each of the 6 additional endpoints (0th already configured)
 | 
				
			||||||
 | 
								for ( i = 1; i < 6; i++ )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
				UENUM = i;
 | 
									UENUM = i;
 | 
				
			||||||
				en = pgm_read_byte(cfg++);
 | 
									en = pgm_read_byte(cfg++);
 | 
				
			||||||
				UECONX = en;
 | 
									UECONX = en;
 | 
				
			||||||
				if (en) {
 | 
									if (en)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
					UECFG0X = pgm_read_byte(cfg++);
 | 
										UECFG0X = pgm_read_byte(cfg++);
 | 
				
			||||||
					UECFG1X = pgm_read_byte(cfg++);
 | 
										UECFG1X = pgm_read_byte(cfg++);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
        		UERST = 0x1E;
 | 
					        		UERST = 0x7E;
 | 
				
			||||||
        		UERST = 0;
 | 
					        		UERST = 0;
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
 | 
							if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
 | 
				
			||||||
			usb_wait_in_ready();
 | 
								usb_wait_in_ready();
 | 
				
			||||||
			UEDATX = usb_configuration;
 | 
								UEDATX = usb_configuration;
 | 
				
			||||||
| 
						 | 
					@ -1009,6 +764,66 @@ ISR(USB_COM_vect)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//if ( wIndex == KEYBOARD_INTERFACE )
 | 
				
			||||||
 | 
							if ( wIndex == KEYBOARD_INTERFACE || wIndex == KEYBOARD_NKRO_INTERFACE )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( bmRequestType == 0xA1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ( bRequest == HID_GET_REPORT )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										usb_wait_in_ready();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// XXX TODO Is this even used? If so, when? -Jacob
 | 
				
			||||||
 | 
										// Send normal keyboard interrupt packet(s)
 | 
				
			||||||
 | 
										//usb_keyboard_toHost();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										usb_send_in();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if ( bRequest == HID_GET_IDLE )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										usb_wait_in_ready();
 | 
				
			||||||
 | 
										UEDATX = USBKeys_Idle_Config;
 | 
				
			||||||
 | 
										usb_send_in();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if ( bRequest == HID_GET_PROTOCOL )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										usb_wait_in_ready();
 | 
				
			||||||
 | 
										UEDATX = USBKeys_Protocol;
 | 
				
			||||||
 | 
										usb_send_in();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								USBKeys_Protocol = bRequest;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if ( bmRequestType == 0x21 )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ( bRequest == HID_SET_REPORT )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										usb_wait_receive_out();
 | 
				
			||||||
 | 
										USBKeys_LEDs = UEDATX;
 | 
				
			||||||
 | 
										usb_ack_out();
 | 
				
			||||||
 | 
										usb_send_in();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if ( bRequest == HID_SET_IDLE )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										USBKeys_Idle_Config = (wValue >> 8);
 | 
				
			||||||
 | 
										USBKeys_Idle_Count = 0;
 | 
				
			||||||
 | 
										//usb_wait_in_ready();
 | 
				
			||||||
 | 
										usb_send_in();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if ( bRequest == HID_SET_PROTOCOL )
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										USBKeys_Protocol = wValue; // 0 - Boot Mode, 1 - NKRO Mode
 | 
				
			||||||
 | 
										//usb_wait_in_ready();
 | 
				
			||||||
 | 
										usb_send_in();
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (bRequest == CDC_GET_LINE_CODING && bmRequestType == 0xA1) {
 | 
							if (bRequest == CDC_GET_LINE_CODING && bmRequestType == 0xA1) {
 | 
				
			||||||
			usb_wait_in_ready();
 | 
								usb_wait_in_ready();
 | 
				
			||||||
			p = cdc_line_coding;
 | 
								p = cdc_line_coding;
 | 
				
			||||||
| 
						 | 
					@ -1040,20 +855,17 @@ ISR(USB_COM_vect)
 | 
				
			||||||
		if (bRequest == GET_STATUS) {
 | 
							if (bRequest == GET_STATUS) {
 | 
				
			||||||
			usb_wait_in_ready();
 | 
								usb_wait_in_ready();
 | 
				
			||||||
			i = 0;
 | 
								i = 0;
 | 
				
			||||||
			#ifdef SUPPORT_ENDPOINT_HALT
 | 
					 | 
				
			||||||
			if (bmRequestType == 0x82) {
 | 
								if (bmRequestType == 0x82) {
 | 
				
			||||||
				UENUM = wIndex;
 | 
									UENUM = wIndex;
 | 
				
			||||||
				if (UECONX & (1<<STALLRQ)) i = 1;
 | 
									if (UECONX & (1<<STALLRQ)) i = 1;
 | 
				
			||||||
				UENUM = 0;
 | 
									UENUM = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			#endif
 | 
					 | 
				
			||||||
			UEDATX = i;
 | 
								UEDATX = i;
 | 
				
			||||||
			UEDATX = 0;
 | 
								UEDATX = 0;
 | 
				
			||||||
			usb_send_in();
 | 
								usb_send_in();
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#ifdef SUPPORT_ENDPOINT_HALT
 | 
					 | 
				
			||||||
		if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
 | 
							if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
 | 
				
			||||||
		  && bmRequestType == 0x02 && wValue == 0) {
 | 
							  && bmRequestType == 0x02 && wValue == 0) {
 | 
				
			||||||
			i = wIndex & 0x7F;
 | 
								i = wIndex & 0x7F;
 | 
				
			||||||
| 
						 | 
					@ -1070,57 +882,7 @@ ISR(USB_COM_vect)
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (wIndex == KEYBOARD_INTERFACE) {
 | 
					 | 
				
			||||||
			if (bmRequestType == 0xA1) {
 | 
					 | 
				
			||||||
				if (bRequest == HID_GET_REPORT) {
 | 
					 | 
				
			||||||
					usb_wait_in_ready();
 | 
					 | 
				
			||||||
					UEDATX = USBKeys_Modifiers;
 | 
					 | 
				
			||||||
					UEDATX = 0;
 | 
					 | 
				
			||||||
					for (i=0; i<6; i++) {
 | 
					 | 
				
			||||||
						UEDATX = USBKeys_Array[i];
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					usb_send_in();
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (bRequest == HID_GET_IDLE) {
 | 
					 | 
				
			||||||
					usb_wait_in_ready();
 | 
					 | 
				
			||||||
					UEDATX = USBKeys_Idle_Config;
 | 
					 | 
				
			||||||
					usb_send_in();
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (bRequest == HID_GET_PROTOCOL) {
 | 
					 | 
				
			||||||
					usb_wait_in_ready();
 | 
					 | 
				
			||||||
					UEDATX = USBKeys_Protocol;
 | 
					 | 
				
			||||||
					usb_send_in();
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (bmRequestType == 0x21) {
 | 
					 | 
				
			||||||
				if (bRequest == HID_SET_REPORT) {
 | 
					 | 
				
			||||||
					usb_wait_receive_out();
 | 
					 | 
				
			||||||
					USBKeys_LEDs = UEDATX;
 | 
					 | 
				
			||||||
					usb_ack_out();
 | 
					 | 
				
			||||||
					usb_send_in();
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (bRequest == HID_SET_IDLE) {
 | 
					 | 
				
			||||||
					USBKeys_Idle_Config = (wValue >> 8);
 | 
					 | 
				
			||||||
					USBKeys_Idle_Count = 0;
 | 
					 | 
				
			||||||
					//usb_wait_in_ready();
 | 
					 | 
				
			||||||
					usb_send_in();
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (bRequest == HID_SET_PROTOCOL) {
 | 
					 | 
				
			||||||
					USBKeys_Protocol = wValue;
 | 
					 | 
				
			||||||
					//usb_wait_in_ready();
 | 
					 | 
				
			||||||
					usb_send_in();
 | 
					 | 
				
			||||||
					return;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	UECONX = (1<<STALLRQ) | (1<<EPEN);	// stall
 | 
						UECONX = (1 << STALLRQ) | (1 << EPEN);	// stall
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,10 +79,13 @@ int8_t usb_serial_set_control(uint8_t signals); // set DSR, DCD, RI, etc
 | 
				
			||||||
// Software reset the chip
 | 
					// Software reset the chip
 | 
				
			||||||
#define usb_debug_software_reset() do { wdt_enable( WDTO_15MS ); for(;;); } while(0)
 | 
					#define usb_debug_software_reset() do { wdt_enable( WDTO_15MS ); for(;;); } while(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EP_SIZE(s)	((s) == 64 ? 0x30 :	\
 | 
					// See EPSIZE -> UECFG1X - 128 and 256 bytes are for endpoint 1 only
 | 
				
			||||||
			((s) == 32 ? 0x20 :	\
 | 
					#define EP_SIZE(s)	((s) == 256 ? 0x50 : \
 | 
				
			||||||
			((s) == 16 ? 0x10 :	\
 | 
								((s) == 128 ? 0x40 : \
 | 
				
			||||||
			             0x00)))
 | 
								((s) ==  64 ? 0x30 : \
 | 
				
			||||||
 | 
								((s) ==  32 ? 0x20 : \
 | 
				
			||||||
 | 
								((s) ==  16 ? 0x10 : \
 | 
				
			||||||
 | 
								              0x00)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LSB(n) (n & 255)
 | 
					#define LSB(n) (n & 255)
 | 
				
			||||||
#define MSB(n) ((n >> 8) & 255)
 | 
					#define MSB(n) ((n >> 8) & 255)
 | 
				
			||||||
| 
						 | 
					@ -172,50 +175,453 @@ int8_t usb_serial_set_control(uint8_t signals); // set DSR, DCD, RI, etc
 | 
				
			||||||
#define CDC_GET_LINE_CODING		0x21
 | 
					#define CDC_GET_LINE_CODING		0x21
 | 
				
			||||||
#define CDC_SET_CONTROL_LINE_STATE	0x22
 | 
					#define CDC_SET_CONTROL_LINE_STATE	0x22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CDC Configuration
 | 
				
			||||||
 | 
					// When you write data, it goes into a USB endpoint buffer, which
 | 
				
			||||||
 | 
					// is transmitted to the PC when it becomes full, or after a timeout
 | 
				
			||||||
 | 
					// with no more writes.  Even if you write in exactly packet-size
 | 
				
			||||||
 | 
					// increments, this timeout is used to send a "zero length packet"
 | 
				
			||||||
 | 
					// that tells the PC no more data is expected and it should pass
 | 
				
			||||||
 | 
					// any buffered data to the application that may be waiting.  If
 | 
				
			||||||
 | 
					// you want data sent immediately, call usb_serial_flush_output().
 | 
				
			||||||
 | 
					#define TRANSMIT_FLUSH_TIMEOUT	5   /* in milliseconds */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If the PC is connected but not "listening", this is the length
 | 
				
			||||||
 | 
					// of time before usb_serial_getchar() returns with an error.  This
 | 
				
			||||||
 | 
					// is roughly equivilant to a real UART simply transmitting the
 | 
				
			||||||
 | 
					// bits on a wire where nobody is listening, except you get an error
 | 
				
			||||||
 | 
					// code which you can ignore for serial-like discard of data, or
 | 
				
			||||||
 | 
					// use to know your data wasn't sent.
 | 
				
			||||||
 | 
					#define TRANSMIT_TIMEOUT	25   /* in milliseconds */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----- Endpoint Configuration -----
 | 
					// ----- Endpoint Configuration -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ENDPOINT0_SIZE		32
 | 
					#define ENDPOINT0_SIZE        	 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define KEYBOARD_INTERFACE	0
 | 
					#define KEYBOARD_NKRO_INTERFACE  0
 | 
				
			||||||
#define KEYBOARD_ENDPOINT	2
 | 
					#define KEYBOARD_NKRO_ENDPOINT   1
 | 
				
			||||||
#define KEYBOARD_SIZE		8
 | 
					#define KEYBOARD_NKRO_SIZE       16
 | 
				
			||||||
#define KEYBOARD_INTERVAL	1
 | 
					#define KEYBOARD_NKRO_HID_BUFFER EP_DOUBLE_BUFFER
 | 
				
			||||||
#define KEYBOARD_HID_BUFFER	EP_DOUBLE_BUFFER
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CDC_IAD_DESCRIPTOR	1
 | 
					#define KEYBOARD_INTERFACE       1
 | 
				
			||||||
#define CDC_STATUS_INTERFACE	1
 | 
					#define KEYBOARD_ENDPOINT        2
 | 
				
			||||||
#define CDC_DATA_INTERFACE	2
 | 
					#define KEYBOARD_SIZE        	 8
 | 
				
			||||||
#define CDC_ACM_ENDPOINT	3
 | 
					#define KEYBOARD_HID_BUFFER      EP_DOUBLE_BUFFER
 | 
				
			||||||
#define CDC_RX_ENDPOINT		4
 | 
					
 | 
				
			||||||
#define CDC_TX_ENDPOINT		5
 | 
					#define CDC_IAD_DESCRIPTOR       1
 | 
				
			||||||
 | 
					#define CDC_STATUS_INTERFACE     2
 | 
				
			||||||
 | 
					#define CDC_DATA_INTERFACE       3
 | 
				
			||||||
 | 
					#define CDC_ACM_ENDPOINT         3
 | 
				
			||||||
 | 
					#define CDC_RX_ENDPOINT        	 4
 | 
				
			||||||
 | 
					#define CDC_TX_ENDPOINT        	 5
 | 
				
			||||||
#if defined(__AVR_AT90USB162__)
 | 
					#if defined(__AVR_AT90USB162__)
 | 
				
			||||||
#define CDC_ACM_SIZE		16
 | 
					#define CDC_ACM_SIZE        	 16
 | 
				
			||||||
#define CDC_ACM_BUFFER		EP_SINGLE_BUFFER
 | 
					#define CDC_ACM_BUFFER        	 EP_SINGLE_BUFFER
 | 
				
			||||||
#define CDC_RX_SIZE		32
 | 
					#define CDC_RX_SIZE        	 32
 | 
				
			||||||
#define CDC_RX_BUFFER 		EP_DOUBLE_BUFFER
 | 
					#define CDC_RX_BUFFER         	 EP_DOUBLE_BUFFER
 | 
				
			||||||
#define CDC_TX_SIZE		32
 | 
					#define CDC_TX_SIZE        	 32
 | 
				
			||||||
#define CDC_TX_BUFFER		EP_DOUBLE_BUFFER
 | 
					#define CDC_TX_BUFFER        	 EP_DOUBLE_BUFFER
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define CDC_ACM_SIZE		16
 | 
					#define CDC_ACM_SIZE        	 16
 | 
				
			||||||
#define CDC_ACM_BUFFER		EP_SINGLE_BUFFER
 | 
					#define CDC_ACM_BUFFER        	 EP_SINGLE_BUFFER
 | 
				
			||||||
#define CDC_RX_SIZE		64
 | 
					#define CDC_RX_SIZE        	 64
 | 
				
			||||||
#define CDC_RX_BUFFER 		EP_DOUBLE_BUFFER
 | 
					#define CDC_RX_BUFFER         	 EP_DOUBLE_BUFFER
 | 
				
			||||||
#define CDC_TX_SIZE		64
 | 
					#define CDC_TX_SIZE        	 64
 | 
				
			||||||
#define CDC_TX_BUFFER		EP_DOUBLE_BUFFER
 | 
					#define CDC_TX_BUFFER        	 EP_DOUBLE_BUFFER
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Endpoint 0 is reserved for the control endpoint
 | 
					// Endpoint 0 is reserved for the control endpoint
 | 
				
			||||||
// Endpoint 1 has a 256 byte buffer
 | 
					// Endpoint 1 has a 256 byte buffer
 | 
				
			||||||
// Endpoints 2-6 have 64 byte buffers
 | 
					// Endpoints 2-6 have 64 byte buffers
 | 
				
			||||||
static const uint8_t PROGMEM endpoint_config_table[] = {
 | 
					static const uint8_t PROGMEM endpoint_config_table[] = {
 | 
				
			||||||
	0, // 256 byte
 | 
						1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_NKRO_SIZE) | KEYBOARD_NKRO_HID_BUFFER, // 256 byte
 | 
				
			||||||
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_HID_BUFFER, // 64 byte
 | 
						1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(KEYBOARD_SIZE)      | KEYBOARD_HID_BUFFER,      // 64 byte
 | 
				
			||||||
	1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(CDC_ACM_SIZE)  | CDC_ACM_BUFFER,      // 64 byte
 | 
						1, EP_TYPE_INTERRUPT_IN,  EP_SIZE(CDC_ACM_SIZE)       | CDC_ACM_BUFFER,           // 64 byte
 | 
				
			||||||
	1, EP_TYPE_BULK_OUT,      EP_SIZE(CDC_RX_SIZE)   | CDC_RX_BUFFER,       // 64 byte
 | 
						1, EP_TYPE_BULK_OUT,      EP_SIZE(CDC_RX_SIZE)        | CDC_RX_BUFFER,            // 64 byte
 | 
				
			||||||
	1, EP_TYPE_BULK_IN,       EP_SIZE(CDC_TX_SIZE)   | CDC_TX_BUFFER,       // 64 byte
 | 
						1, EP_TYPE_BULK_IN,       EP_SIZE(CDC_TX_SIZE)        | CDC_TX_BUFFER,            // 64 byte
 | 
				
			||||||
 | 
						0,                                                                                // 64 byte
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ----- Descriptor Configuration -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Descriptors are the data that your computer reads when it auto-detects
 | 
				
			||||||
 | 
					// this USB device (called "enumeration" in USB lingo).  The most commonly
 | 
				
			||||||
 | 
					// changed items are editable at the top of this file.  Changing things
 | 
				
			||||||
 | 
					// in here should only be done by those who've read chapter 9 of the USB
 | 
				
			||||||
 | 
					// spec and relevant portions of any USB class specifications!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t PROGMEM device_descriptor[] = {
 | 
				
			||||||
 | 
						18,					// bLength
 | 
				
			||||||
 | 
						1,					// bDescriptorType
 | 
				
			||||||
 | 
						0x00, 0x02,				// bcdUSB
 | 
				
			||||||
 | 
						0,					// bDeviceClass
 | 
				
			||||||
 | 
						0,					// bDeviceSubClass
 | 
				
			||||||
 | 
						0,					// bDeviceProtocol
 | 
				
			||||||
 | 
						ENDPOINT0_SIZE,				// bMaxPacketSize0
 | 
				
			||||||
 | 
						LSB(VENDOR_ID), MSB(VENDOR_ID),		// idVendor
 | 
				
			||||||
 | 
						LSB(PRODUCT_ID), MSB(PRODUCT_ID),	// idProduct
 | 
				
			||||||
 | 
						0x00, 0x01,				// bcdDevice
 | 
				
			||||||
 | 
						1,					// iManufacturer
 | 
				
			||||||
 | 
						2,					// iProduct
 | 
				
			||||||
 | 
						3,					// iSerialNumber
 | 
				
			||||||
 | 
						1					// bNumConfigurations
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
 | 
				
			||||||
 | 
					static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
 | 
				
			||||||
 | 
						// Keyboard Collection
 | 
				
			||||||
 | 
					        0x05, 0x01,          // Usage Page (Generic Desktop),
 | 
				
			||||||
 | 
					        0x09, 0x06,          // Usage (Keyboard),
 | 
				
			||||||
 | 
					        0xA1, 0x01,          // Collection (Application) - Keyboard,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Modifier Byte
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x95, 0x08,          //   Report Count (8),
 | 
				
			||||||
 | 
					        0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					        0x19, 0xE0,          //   Usage Minimum (224),
 | 
				
			||||||
 | 
					        0x29, 0xE7,          //   Usage Maximum (231),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x01,          //   Logical Maximum (1),
 | 
				
			||||||
 | 
					        0x81, 0x02,          //   Input (Data, Variable, Absolute),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// LED Report
 | 
				
			||||||
 | 
					        0x95, 0x05,          //   Report Count (5),
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x05, 0x08,          //   Usage Page (LEDs),
 | 
				
			||||||
 | 
					        0x19, 0x01,          //   Usage Minimum (1),
 | 
				
			||||||
 | 
					        0x29, 0x05,          //   Usage Maximum (5),
 | 
				
			||||||
 | 
					        0x91, 0x02,          //   Output (Data, Variable, Absolute),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// LED Report Padding
 | 
				
			||||||
 | 
					        0x95, 0x01,          //   Report Count (1),
 | 
				
			||||||
 | 
					        0x75, 0x03,          //   Report Size (3),
 | 
				
			||||||
 | 
					        0x91, 0x03,          //   Output (Constant),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Normal Keys
 | 
				
			||||||
 | 
					        0x95, 0x06,          //   Report Count (6),
 | 
				
			||||||
 | 
					        0x75, 0x08,          //   Report Size (8),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x7F,          //   Logical Maximum(104),
 | 
				
			||||||
 | 
					        0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					        0x19, 0x00,          //   Usage Minimum (0),
 | 
				
			||||||
 | 
					        0x29, 0x7F,          //   Usage Maximum (104),
 | 
				
			||||||
 | 
					        0x81, 0x00,          //   Input (Data, Array),
 | 
				
			||||||
 | 
					        0xc0,                // End Collection - Keyboard
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
 | 
				
			||||||
 | 
					static const uint8_t PROGMEM keyboard_nkro_hid_report_desc[] = {
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						// System Control Collection
 | 
				
			||||||
 | 
					        0x05, 0x01,          // Usage Page (Generic Desktop),
 | 
				
			||||||
 | 
					        0x09, 0x80,          // Usage (System Control),
 | 
				
			||||||
 | 
					        0xA1, 0x01,          // Collection (Application),
 | 
				
			||||||
 | 
					        0x85, 0x01,          //   Report ID (1),
 | 
				
			||||||
 | 
					        0x95, 0x06,          //   Report Count (6),
 | 
				
			||||||
 | 
					        0x75, 0x08,          //   Report Size (8),
 | 
				
			||||||
 | 
					        0x19, 0x81,          //   Usage Minimum (129),
 | 
				
			||||||
 | 
					        0x29, 0x83,          //   Usage Maximum (131),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x01,          //   Logical Maximum (1),
 | 
				
			||||||
 | 
					        0x81, 0x02,          //   Input (Data, Variable, Absolute),
 | 
				
			||||||
 | 
					        0x95, 0x05,          //   Report Count (5),
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x81, 0x03,          //   Input (Constant, Data, Variable, Absolute),
 | 
				
			||||||
 | 
					        0xc0, 0x00,          // End Collection - System Control
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Keyboard Collection
 | 
				
			||||||
 | 
					        0x05, 0x01,          // Usage Page (Generic Desktop),
 | 
				
			||||||
 | 
					        0x09, 0x06,          // Usage (Keyboard),
 | 
				
			||||||
 | 
					        0xA1, 0x01,          // Collection (Application) - Keyboard,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Modifier Byte
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x85, 0x02,          //   Report ID (2),
 | 
				
			||||||
 | 
					        0x95, 0x08,          //   Report Count (8),
 | 
				
			||||||
 | 
					        0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					        0x19, 0xE0,          //   Usage Minimum (224),
 | 
				
			||||||
 | 
					        0x29, 0xE7,          //   Usage Maximum (231),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x01,          //   Logical Maximum (1),
 | 
				
			||||||
 | 
					        0x81, 0x02,          //   Input (Data, Variable, Absolute),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Media Keys
 | 
				
			||||||
 | 
					        0x95, 0x08,          //   Report Count (8),
 | 
				
			||||||
 | 
					        0x85, 0x03,          //   Report ID (3),
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x01,          //   Logical Maximum (1),
 | 
				
			||||||
 | 
					        0x05, 0x0C,          //   Usage Page (Consumer),
 | 
				
			||||||
 | 
					        0x09, 0xE9,          //   Usage (Volume Increment),
 | 
				
			||||||
 | 
					        0x09, 0xEA,          //   Usage (Volume Decrement),
 | 
				
			||||||
 | 
					        0x09, 0xE2,          //   Usage (Mute),
 | 
				
			||||||
 | 
					        0x09, 0xCD,          //   Usage (Play/Pause),
 | 
				
			||||||
 | 
					        0x09, 0xB5,          //   Usage (Scan Next Track),
 | 
				
			||||||
 | 
					        0x09, 0xB6,          //   Usage (Scan Previous Track),
 | 
				
			||||||
 | 
					        0x09, 0xB7,          //   Usage (Stop),
 | 
				
			||||||
 | 
					        0x09, 0xB8,          //   Usage (Eject),
 | 
				
			||||||
 | 
					        0x81, 0x02,          //   Input (Data, Variable, Absolute),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// LED Report
 | 
				
			||||||
 | 
					        0x95, 0x05,          //   Report Count (5),
 | 
				
			||||||
 | 
					        0x85, 0x01,          //   Report ID (1),
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x05, 0x08,          //   Usage Page (LEDs),
 | 
				
			||||||
 | 
					        0x19, 0x01,          //   Usage Minimum (1),
 | 
				
			||||||
 | 
					        0x29, 0x05,          //   Usage Maximum (5),
 | 
				
			||||||
 | 
					        0x91, 0x02,          //   Output (Data, Variable, Absolute),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// LED Report Padding
 | 
				
			||||||
 | 
					        0x95, 0x01,          //   Report Count (1),
 | 
				
			||||||
 | 
					        0x75, 0x03,          //   Report Size (3),
 | 
				
			||||||
 | 
					        0x91, 0x03,          //   Output (Constant),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						// Misc Keys
 | 
				
			||||||
 | 
					        0x95, 0x06,          //   Report Count (6),
 | 
				
			||||||
 | 
					        0x75, 0x01,          //   Report Size (1),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x7F,          //   Logical Maximum(104),
 | 
				
			||||||
 | 
					        0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					        0x19, 0x00,          //   Usage Minimum (0),
 | 
				
			||||||
 | 
					        0x29, 0x7F,          //   Usage Maximum (104),
 | 
				
			||||||
 | 
					        0x81, 0x00,          //   Input (Data, Array),
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Normal Keys
 | 
				
			||||||
 | 
					        0x95, 0x06,          //   Report Count (6),
 | 
				
			||||||
 | 
					        0x85, 0x04,          //   Report ID (4),
 | 
				
			||||||
 | 
					        0x75, 0x08,          //   Report Size (8),
 | 
				
			||||||
 | 
					        0x15, 0x00,          //   Logical Minimum (0),
 | 
				
			||||||
 | 
					        0x25, 0x7F,          //   Logical Maximum(104),
 | 
				
			||||||
 | 
					        0x05, 0x07,          //   Usage Page (Key Codes),
 | 
				
			||||||
 | 
					        0x19, 0x00,          //   Usage Minimum (0),
 | 
				
			||||||
 | 
					        0x29, 0x7F,          //   Usage Maximum (104),
 | 
				
			||||||
 | 
					        0x81, 0x00,          //   Input (Data, Array),
 | 
				
			||||||
 | 
					        0xc0,                // End Collection - Keyboard
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// <Configuration> + <Keyboard HID> + <NKRO Keyboard HID> + <Serial CDC>
 | 
				
			||||||
 | 
					#define CONFIG1_DESC_SIZE             (9 + 9+9+7 + 9+9+7 + 8+9+5+5+4+5+7+9+7+7)
 | 
				
			||||||
 | 
					#define KEYBOARD_HID_DESC_OFFSET      (9 + 9)
 | 
				
			||||||
 | 
					#define KEYBOARD_NKRO_HID_DESC_OFFSET (9 + 9+9+7 + 9)
 | 
				
			||||||
 | 
					#define SERIAL_CDC_DESC_OFFSET        (9 + 9+9+7 + 9+9+7)
 | 
				
			||||||
 | 
					static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
 | 
				
			||||||
 | 
					// --- Configuration ---
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
 | 
				
			||||||
 | 
						9, 					// bLength;
 | 
				
			||||||
 | 
						2,					// bDescriptorType;
 | 
				
			||||||
 | 
						LSB(CONFIG1_DESC_SIZE),			// wTotalLength
 | 
				
			||||||
 | 
						MSB(CONFIG1_DESC_SIZE),
 | 
				
			||||||
 | 
						4,					// bNumInterfaces
 | 
				
			||||||
 | 
						1,					// bConfigurationValue
 | 
				
			||||||
 | 
						0,					// iConfiguration
 | 
				
			||||||
 | 
						0x80,					// bmAttributes
 | 
				
			||||||
 | 
						250,					// bMaxPower
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- Keyboard HID ---
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
				
			||||||
 | 
						9,					// bLength
 | 
				
			||||||
 | 
						4,					// bDescriptorType
 | 
				
			||||||
 | 
						KEYBOARD_INTERFACE,			// bInterfaceNumber
 | 
				
			||||||
 | 
						0,					// bAlternateSetting
 | 
				
			||||||
 | 
						1,					// bNumEndpoints
 | 
				
			||||||
 | 
						0x03,					// bInterfaceClass (0x03 = HID)
 | 
				
			||||||
 | 
						0x01,					// bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot)
 | 
				
			||||||
 | 
						0x01,					// bInterfaceProtocol (0x01 = Keyboard)
 | 
				
			||||||
 | 
						0,					// iInterface
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// HID interface descriptor, HID 1.11 spec, section 6.2.1
 | 
				
			||||||
 | 
						9,					// bLength
 | 
				
			||||||
 | 
						0x21,					// bDescriptorType
 | 
				
			||||||
 | 
						0x11, 0x01,				// bcdHID
 | 
				
			||||||
 | 
						33,					// bCountryCode - Defaulting to US for now. TODO
 | 
				
			||||||
 | 
						1,					// bNumDescriptors
 | 
				
			||||||
 | 
						0x22,					// bDescriptorType
 | 
				
			||||||
 | 
						LSB(sizeof(keyboard_hid_report_desc)),	// wDescriptorLength
 | 
				
			||||||
 | 
						MSB(sizeof(keyboard_hid_report_desc)),
 | 
				
			||||||
 | 
					// - 7 bytes -
 | 
				
			||||||
 | 
						// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
				
			||||||
 | 
						7,					// bLength
 | 
				
			||||||
 | 
						5,					// bDescriptorType
 | 
				
			||||||
 | 
						KEYBOARD_ENDPOINT | 0x80,		// bEndpointAddress
 | 
				
			||||||
 | 
						0x03,					// bmAttributes (0x03=intr)
 | 
				
			||||||
 | 
						KEYBOARD_SIZE, 0,			// wMaxPacketSize
 | 
				
			||||||
 | 
						1,                                      // bInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- NKRO Keyboard HID ---
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
				
			||||||
 | 
						9,					// bLength
 | 
				
			||||||
 | 
						4,					// bDescriptorType
 | 
				
			||||||
 | 
						KEYBOARD_NKRO_INTERFACE,		// bInterfaceNumber
 | 
				
			||||||
 | 
						0,					// bAlternateSetting
 | 
				
			||||||
 | 
						1,					// bNumEndpoints
 | 
				
			||||||
 | 
						0x03,					// bInterfaceClass (0x03 = HID)
 | 
				
			||||||
 | 
						0x00,					// bInterfaceSubClass (0x00 = Non-Boot, 0x01 = Boot)
 | 
				
			||||||
 | 
						0x01,					// bInterfaceProtocol (0x01 = Keyboard)
 | 
				
			||||||
 | 
						0,					// iInterface
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// HID interface descriptor, HID 1.11 spec, section 6.2.1
 | 
				
			||||||
 | 
						9,					// bLength
 | 
				
			||||||
 | 
						0x21,					// bDescriptorType
 | 
				
			||||||
 | 
						0x11, 0x01,				// bcdHID
 | 
				
			||||||
 | 
						33,					// bCountryCode - Defaulting to US for now. TODO
 | 
				
			||||||
 | 
						1,					// bNumDescriptors
 | 
				
			||||||
 | 
						0x22,					// bDescriptorType
 | 
				
			||||||
 | 
						                                        // wDescriptorLength
 | 
				
			||||||
 | 
						LSB(sizeof(keyboard_nkro_hid_report_desc)),
 | 
				
			||||||
 | 
						MSB(sizeof(keyboard_nkro_hid_report_desc)),
 | 
				
			||||||
 | 
					// - 7 bytes -
 | 
				
			||||||
 | 
						// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
				
			||||||
 | 
						7,					// bLength
 | 
				
			||||||
 | 
						5,					// bDescriptorType
 | 
				
			||||||
 | 
						KEYBOARD_NKRO_ENDPOINT | 0x80,		// bEndpointAddress
 | 
				
			||||||
 | 
						0x03,					// bmAttributes (0x03=intr)
 | 
				
			||||||
 | 
						KEYBOARD_NKRO_SIZE, 0,			// wMaxPacketSize
 | 
				
			||||||
 | 
						1,                                      // bInterval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- Serial CDC ---
 | 
				
			||||||
 | 
					// - 8 bytes -
 | 
				
			||||||
 | 
					        // interface association descriptor, USB ECN, Table 9-Z
 | 
				
			||||||
 | 
					        8,                                      // bLength
 | 
				
			||||||
 | 
					        11,                                     // bDescriptorType
 | 
				
			||||||
 | 
					        CDC_STATUS_INTERFACE,                   // bFirstInterface
 | 
				
			||||||
 | 
					        2,                                      // bInterfaceCount
 | 
				
			||||||
 | 
					        0x02,                                   // bFunctionClass
 | 
				
			||||||
 | 
					        0x02,                                   // bFunctionSubClass
 | 
				
			||||||
 | 
					        0x01,                                   // bFunctionProtocol
 | 
				
			||||||
 | 
					        4,                                      // iFunction
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
				
			||||||
 | 
						9,					// bLength
 | 
				
			||||||
 | 
						4,					// bDescriptorType
 | 
				
			||||||
 | 
						CDC_STATUS_INTERFACE,			// bInterfaceNumber
 | 
				
			||||||
 | 
						0,					// bAlternateSetting
 | 
				
			||||||
 | 
						1,					// bNumEndpoints
 | 
				
			||||||
 | 
						0x02,					// bInterfaceClass
 | 
				
			||||||
 | 
						0x02,					// bInterfaceSubClass
 | 
				
			||||||
 | 
						0x01,					// bInterfaceProtocol
 | 
				
			||||||
 | 
						0,					// iInterface
 | 
				
			||||||
 | 
					// - 5 bytes -
 | 
				
			||||||
 | 
						// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
 | 
				
			||||||
 | 
						5,					// bFunctionLength
 | 
				
			||||||
 | 
						0x24,					// bDescriptorType
 | 
				
			||||||
 | 
						0x00,					// bDescriptorSubtype
 | 
				
			||||||
 | 
						0x10, 0x01,				// bcdCDC
 | 
				
			||||||
 | 
					// - 5 bytes -
 | 
				
			||||||
 | 
						// Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
 | 
				
			||||||
 | 
						5,					// bFunctionLength
 | 
				
			||||||
 | 
						0x24,					// bDescriptorType
 | 
				
			||||||
 | 
						0x01,					// bDescriptorSubtype
 | 
				
			||||||
 | 
						0x01,					// bmCapabilities
 | 
				
			||||||
 | 
						1,					// bDataInterface
 | 
				
			||||||
 | 
					// - 4 bytes -
 | 
				
			||||||
 | 
						// Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
 | 
				
			||||||
 | 
						4,					// bFunctionLength
 | 
				
			||||||
 | 
						0x24,					// bDescriptorType
 | 
				
			||||||
 | 
						0x02,					// bDescriptorSubtype
 | 
				
			||||||
 | 
						0x06,					// bmCapabilities
 | 
				
			||||||
 | 
					// - 5 bytes -
 | 
				
			||||||
 | 
						// Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
 | 
				
			||||||
 | 
						5,					// bFunctionLength
 | 
				
			||||||
 | 
						0x24,					// bDescriptorType
 | 
				
			||||||
 | 
						0x06,					// bDescriptorSubtype
 | 
				
			||||||
 | 
						CDC_STATUS_INTERFACE,			// bMasterInterface
 | 
				
			||||||
 | 
						CDC_DATA_INTERFACE,			// bSlaveInterface0
 | 
				
			||||||
 | 
					// - 7 bytes -
 | 
				
			||||||
 | 
						// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
				
			||||||
 | 
						7,					// bLength
 | 
				
			||||||
 | 
						5,					// bDescriptorType
 | 
				
			||||||
 | 
						CDC_ACM_ENDPOINT | 0x80,		// bEndpointAddress
 | 
				
			||||||
 | 
						0x03,					// bmAttributes (0x03=intr)
 | 
				
			||||||
 | 
						CDC_ACM_SIZE, 0,			// wMaxPacketSize
 | 
				
			||||||
 | 
						64,					// bInterval
 | 
				
			||||||
 | 
					// - 9 bytes -
 | 
				
			||||||
 | 
						// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
				
			||||||
 | 
						9,					// bLength
 | 
				
			||||||
 | 
						4,					// bDescriptorType
 | 
				
			||||||
 | 
						CDC_DATA_INTERFACE,			// bInterfaceNumber
 | 
				
			||||||
 | 
						0,					// bAlternateSetting
 | 
				
			||||||
 | 
						2,					// bNumEndpoints
 | 
				
			||||||
 | 
						0x0A,					// bInterfaceClass
 | 
				
			||||||
 | 
						0x00,					// bInterfaceSubClass
 | 
				
			||||||
 | 
						0x00,					// bInterfaceProtocol
 | 
				
			||||||
 | 
						0,					// iInterface
 | 
				
			||||||
 | 
					// - 7 bytes -
 | 
				
			||||||
 | 
						// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
				
			||||||
 | 
						7,					// bLength
 | 
				
			||||||
 | 
						5,					// bDescriptorType
 | 
				
			||||||
 | 
						CDC_RX_ENDPOINT,			// bEndpointAddress
 | 
				
			||||||
 | 
						0x02,					// bmAttributes (0x02=bulk)
 | 
				
			||||||
 | 
						CDC_RX_SIZE, 0,				// wMaxPacketSize
 | 
				
			||||||
 | 
						0,					// bInterval
 | 
				
			||||||
 | 
					// - 7 bytes -
 | 
				
			||||||
 | 
						// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
				
			||||||
 | 
						7,					// bLength
 | 
				
			||||||
 | 
						5,					// bDescriptorType
 | 
				
			||||||
 | 
						CDC_TX_ENDPOINT | 0x80,			// bEndpointAddress
 | 
				
			||||||
 | 
						0x02,					// bmAttributes (0x02=bulk)
 | 
				
			||||||
 | 
						CDC_TX_SIZE, 0,				// wMaxPacketSize
 | 
				
			||||||
 | 
						0,					// bInterval
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Configuration Endpoint (0) Descriptor
 | 
				
			||||||
 | 
					struct usb_string_descriptor_struct {
 | 
				
			||||||
 | 
						uint8_t bLength;
 | 
				
			||||||
 | 
						uint8_t bDescriptorType;
 | 
				
			||||||
 | 
						int16_t wString[];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const struct usb_string_descriptor_struct PROGMEM string0 = {
 | 
				
			||||||
 | 
						4,
 | 
				
			||||||
 | 
						3,
 | 
				
			||||||
 | 
						{0x0409}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const struct usb_string_descriptor_struct PROGMEM string1 = {
 | 
				
			||||||
 | 
						sizeof(STR_MANUFACTURER),
 | 
				
			||||||
 | 
						3,
 | 
				
			||||||
 | 
						STR_MANUFACTURER
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const struct usb_string_descriptor_struct PROGMEM string2 = {
 | 
				
			||||||
 | 
						sizeof(STR_PRODUCT),
 | 
				
			||||||
 | 
						3,
 | 
				
			||||||
 | 
						STR_PRODUCT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					static const struct usb_string_descriptor_struct PROGMEM string3 = {
 | 
				
			||||||
 | 
						sizeof(STR_SERIAL),
 | 
				
			||||||
 | 
						3,
 | 
				
			||||||
 | 
						STR_SERIAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This table defines which descriptor data is sent for each specific
 | 
				
			||||||
 | 
					// request from the host (in wValue and wIndex).
 | 
				
			||||||
 | 
					static const struct descriptor_list_struct {
 | 
				
			||||||
 | 
						uint16_t	wValue;
 | 
				
			||||||
 | 
						uint16_t	wIndex;
 | 
				
			||||||
 | 
						const uint8_t	*addr;
 | 
				
			||||||
 | 
						uint8_t		length;
 | 
				
			||||||
 | 
					} PROGMEM descriptor_list[] = {
 | 
				
			||||||
 | 
						{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
 | 
				
			||||||
 | 
						{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
 | 
				
			||||||
 | 
						{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
 | 
				
			||||||
 | 
						{0x2100, KEYBOARD_INTERFACE, config1_descriptor + KEYBOARD_HID_DESC_OFFSET, 9},
 | 
				
			||||||
 | 
						{0x2200, KEYBOARD_NKRO_INTERFACE, keyboard_nkro_hid_report_desc, sizeof(keyboard_nkro_hid_report_desc)},
 | 
				
			||||||
 | 
						{0x2100, KEYBOARD_NKRO_INTERFACE, config1_descriptor + KEYBOARD_NKRO_HID_DESC_OFFSET, 9},
 | 
				
			||||||
 | 
						{0x0300, 0x0000, (const uint8_t *)&string0, 4},
 | 
				
			||||||
 | 
						{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
 | 
				
			||||||
 | 
						{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)},
 | 
				
			||||||
 | 
						{0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL)}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // usb_keyboard_serial_h__
 | 
					#endif // usb_keyboard_serial_h__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,23 +45,23 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----- Function Declarations -----
 | 
					// ----- Function Declarations -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cliFunc_readLEDs  ( char* args );
 | 
					void cliFunc_kbdProtocol( char* args );
 | 
				
			||||||
void cliFunc_sendKeys  ( char* args );
 | 
					void cliFunc_readLEDs   ( char* args );
 | 
				
			||||||
void cliFunc_setKeys   ( char* args );
 | 
					void cliFunc_sendKeys   ( char* args );
 | 
				
			||||||
void cliFunc_setLEDs   ( char* args );
 | 
					void cliFunc_setKeys    ( char* args );
 | 
				
			||||||
void cliFunc_setMod    ( char* args );
 | 
					void cliFunc_setMod     ( char* args );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----- Variables -----
 | 
					// ----- Variables -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Output Module command dictionary
 | 
					// Output Module command dictionary
 | 
				
			||||||
char*       outputCLIDictName = "USB Module Commands (Not all commands fully work yet...)";
 | 
					char*       outputCLIDictName = "USB Module Commands";
 | 
				
			||||||
CLIDictItem outputCLIDict[] = {
 | 
					CLIDictItem outputCLIDict[] = {
 | 
				
			||||||
	{ "readLEDs", "Read LED byte. See \033[35msetLEDs\033[0m.", cliFunc_readLEDs },
 | 
						{ "kbdProtocol", "Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO Mode", cliFunc_kbdProtocol },
 | 
				
			||||||
	{ "sendKeys", "Send the prepared list of USB codes and modifier byte.", cliFunc_sendKeys },
 | 
						{ "readLEDs",    "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc.", cliFunc_readLEDs },
 | 
				
			||||||
	{ "setKeys",  "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m.", cliFunc_setKeys },
 | 
						{ "sendKeys",    "Send the prepared list of USB codes and modifier byte.", cliFunc_sendKeys },
 | 
				
			||||||
	{ "setLEDs",  "Set LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc.", cliFunc_setLEDs },
 | 
						{ "setKeys",     "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m.", cliFunc_setKeys },
 | 
				
			||||||
	{ "setMod",   "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI", cliFunc_setMod },
 | 
						{ "setMod",      "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI", cliFunc_setMod },
 | 
				
			||||||
	{ 0, 0, 0 } // Null entry for dictionary end
 | 
						{ 0, 0, 0 } // Null entry for dictionary end
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,10 +83,10 @@ CLIDictItem outputCLIDict[] = {
 | 
				
			||||||
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
 | 
					// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
 | 
				
			||||||
volatile uint8_t USBKeys_LEDs = 0;
 | 
					volatile uint8_t USBKeys_LEDs = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// protocol setting from the host.  We use exactly the same report
 | 
					// Protocol setting from the host.
 | 
				
			||||||
// either way, so this variable only stores the setting since we
 | 
					// 0 - Boot Mode (Default, until set by the host)
 | 
				
			||||||
// are required to be able to report which setting is in use.
 | 
					// 1 - NKRO Mode
 | 
				
			||||||
         uint8_t USBKeys_Protocol = 1;
 | 
					volatile uint8_t USBKeys_Protocol = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// the idle configuration, how often we send the report to the
 | 
					// the idle configuration, how often we send the report to the
 | 
				
			||||||
// host (ms * 4) even when it hasn't changed
 | 
					// host (ms * 4) even when it hasn't changed
 | 
				
			||||||
| 
						 | 
					@ -201,10 +201,18 @@ inline void Output_softReset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----- CLI Command Functions -----
 | 
					// ----- CLI Command Functions -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cliFunc_kbdProtocol( char* args )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						print( NL );
 | 
				
			||||||
 | 
						info_msg("Keyboard Protocol: ");
 | 
				
			||||||
 | 
						printInt8( USBKeys_Protocol );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cliFunc_readLEDs( char* args )
 | 
					void cliFunc_readLEDs( char* args )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	print( NL );
 | 
						print( NL );
 | 
				
			||||||
	info_msg("LED State: ");
 | 
						info_msg("LED State (This doesn't work yet...): ");
 | 
				
			||||||
	printInt8( USBKeys_LEDs );
 | 
						printInt8( USBKeys_LEDs );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,18 +253,6 @@ void cliFunc_setKeys( char* args )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cliFunc_setLEDs( char* args )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	// Parse number from argument
 | 
					 | 
				
			||||||
	//  NOTE: Only first argument is used
 | 
					 | 
				
			||||||
	char* arg1Ptr;
 | 
					 | 
				
			||||||
	char* arg2Ptr;
 | 
					 | 
				
			||||||
	CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	USBKeys_LEDs = decToInt( arg1Ptr );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cliFunc_setMod( char* args )
 | 
					void cliFunc_setMod( char* args )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// Parse number from argument
 | 
						// Parse number from argument
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,9 +49,9 @@ extern                       uint8_t USBKeys_Sent;
 | 
				
			||||||
extern volatile              uint8_t USBKeys_LEDs;
 | 
					extern volatile              uint8_t USBKeys_LEDs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                static const uint8_t USBKeys_MaxSize = USB_MAX_KEY_SEND;
 | 
					                static const uint8_t USBKeys_MaxSize = USB_MAX_KEY_SEND;
 | 
				
			||||||
 | 
					extern volatile              uint8_t USBKeys_Protocol; // 0 - Boot Mode, 1 - NKRO Mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Misc variables (XXX Some are only properly utilized using AVR)
 | 
					// Misc variables (XXX Some are only properly utilized using AVR)
 | 
				
			||||||
extern                       uint8_t USBKeys_Protocol;
 | 
					 | 
				
			||||||
extern                       uint8_t USBKeys_Idle_Config;
 | 
					extern                       uint8_t USBKeys_Idle_Config;
 | 
				
			||||||
extern                       uint8_t USBKeys_Idle_Count;
 | 
					extern                       uint8_t USBKeys_Idle_Count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue