From da2d5ef791e6b3e4b37b9f39e0c06f852f724eb4 Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Wed, 3 Dec 2014 20:00:25 -0800 Subject: [PATCH] Initial commit. --- .gitignore | 4 + Makefile | 30 +++ README.md | 14 ++ keyboard.scm | 29 +++ menelaus.scm | 18 ++ usb_keyboard.c | 603 +++++++++++++++++++++++++++++++++++++++++++++++++ usb_keyboard.h | 329 +++++++++++++++++++++++++++ 7 files changed, 1027 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 keyboard.scm create mode 100644 menelaus.scm create mode 100644 usb_keyboard.c create mode 100644 usb_keyboard.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45780f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.elf +*.s +*.hex diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..36c590c --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +MCU=atmega32u4 + +F_CPU=16000000 + +TARGET=menelaus + +USB_DEVICE=/dev/ttyACM0 + +build: $(TARGET).hex + +upload: $(TARGET).hex + while [ ! -r $(USB_DEVICE) ]; do sleep 1; done; \ + avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB_DEVICE) + +clean: + -rm -f $(TARGET){,.hex} *.o *.elf *.s + +$(TARGET).hex: $(TARGET).elf + avr-size $(TARGET).elf + avr-objcopy --output-target=ihex $(TARGET).elf $(TARGET).hex + +%.s: %.scm + microscheme -m LEO $(TARGET).scm + +%.elf: %.s usb_keyboard.s + avr-gcc -mmcu=$(MCU) -o $(TARGET).elf $(TARGET).s usb_keyboard.s + +usb_keyboard.s: usb_keyboard.h usb_keyboard.c + avr-gcc -std=gnu99 -S -D F_CPU=$(F_CPU)UL -mmcu=$(MCU) -c \ + -o usb_keyboard.s usb_keyboard.c diff --git a/README.md b/README.md new file mode 100644 index 0000000..cd913a7 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# Menelaus + +A keyboard firmware for +[Atmega32u4](http://www.atmel.com/devices/ATMEGA32U4.aspx), written in +[Microscheme](http://microscheme.org). + +Written one step at a time. Requires microscheme newer than 0.8; at +the time of this writing only available on git master. + +## License + +Copyright © 2014 Phil Hagelberg and contributors + +Released under the [GNU GPL version 3](https://www.gnu.org/licenses/gpl.html). diff --git a/keyboard.scm b/keyboard.scm new file mode 100644 index 0000000..a4558ed --- /dev/null +++ b/keyboard.scm @@ -0,0 +1,29 @@ +;; port of usb_keyboard.h + +(define key-a 4) +(define key-b 5) +(define key-c 6) +(define key-d 7) +(define key-e 8) +(define key-f 9) +(define key-g 10) +(define key-h 11) +(define key-i 12) +(define key-j 13) +(define key-k 14) +(define key-l 15) +(define key-m 16) +(define key-n 17) +(define key-o 18) +(define key-p 19) +(define key-q 20) +(define key-r 21) +(define key-s 22) +(define key-t 23) +(define key-u 24) +(define key-v 25) +(define key-w 26) +(define key-x 27) +(define key-y 28) +(define key-z 29) +(define key-semicolon 51) diff --git a/menelaus.scm b/menelaus.scm new file mode 100644 index 0000000..7022818 --- /dev/null +++ b/menelaus.scm @@ -0,0 +1,18 @@ +;; -*- scheme -*- + +;; menelaus.scm + +(define (loop) + (if (low? 11) + (call-c-func "usb_send" 0 4 0 0 0 0 0) + (call-c-func "usb_send" 0 0 0 0 0 0 0)) + (loop)) + +(define (init) + (input 11) + (high 11) ; activate pullup resistor + (call-c-func "usb_init") + (pause 200)) + +(init) +(loop) diff --git a/usb_keyboard.c b/usb_keyboard.c new file mode 100644 index 0000000..3fbe4a6 --- /dev/null +++ b/usb_keyboard.c @@ -0,0 +1,603 @@ +/* USB Keyboard Example for Teensy USB Development Board + * http://www.pjrc.com/teensy/usb_keyboard.html + * Copyright (c) 2009 PJRC.COM, LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Version 1.0: Initial Release +// Version 1.1: Add support for Teensy 2.0 + +#define USB_SERIAL_PRIVATE_INCLUDE +#include "usb_keyboard.h" + +/************************************************************************** + * + * Configurable Options + * + **************************************************************************/ + +// You can change these to give your code its own name. +#define STR_MANUFACTURER L"Technomancy" +#define STR_PRODUCT L"Atreus" + + +// Mac OS-X and Linux automatically load the correct drivers. On +// Windows, even though the driver is supplied by Microsoft, an +// INF file is needed to load the driver. These numbers need to +// match the INF file. +#define VENDOR_ID 0x16C0 +#define PRODUCT_ID 0x047C + + +// 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 102 bytes of space (gcc 4.3.0). +// This is not strictly USB compliant, but works with all major +// operating systems. +#define SUPPORT_ENDPOINT_HALT + + + +/************************************************************************** + * + * Endpoint Buffer Configuration + * + **************************************************************************/ + +#define ENDPOINT0_SIZE 32 + +#define KEYBOARD_INTERFACE 0 +#define KEYBOARD_ENDPOINT 3 +#define KEYBOARD_SIZE 8 +#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER + +static const uint8_t PROGMEM endpoint_config_table[] = { + 0, + 0, + 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, + 0 +}; + + +/************************************************************************** + * + * 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 uint8_t const 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 + 0, // iSerialNumber + 1 // bNumConfigurations +}; + +// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 +static uint8_t const 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, 0x01, // Report Count (1), + 0x75, 0x08, // Report Size (8), + 0x81, 0x03, // Input (Constant), ;Reserved byte + 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, 0x68, // Logical Maximum(104), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, 0x68, // Usage Maximum (104), + 0x81, 0x00, // Input (Data, Array), + 0xc0 // End Collection +}; + +#define CONFIG1_DESC_SIZE (9+9+9+7) +#define KEYBOARD_HID_DESC_OFFSET (9+9) +static uint8_t const PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { + // 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), + 1, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xC0, // bmAttributes + 50, // bMaxPower + // 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 + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + sizeof(keyboard_hid_report_desc), // wDescriptorLength + 0, + // 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 +}; + +// 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 struct usb_string_descriptor_struct const PROGMEM string0 = { + 4, + 3, + {0x0409} +}; +static struct usb_string_descriptor_struct const PROGMEM string1 = { + sizeof(STR_MANUFACTURER), + 3, + STR_MANUFACTURER +}; +static struct usb_string_descriptor_struct const PROGMEM string2 = { + sizeof(STR_PRODUCT), + 3, + STR_PRODUCT +}; + +// This table defines which descriptor data is sent for each specific +// request from the host (in wValue and wIndex). +static struct descriptor_list_struct { + uint16_t wValue; + uint16_t wIndex; + const uint8_t *addr; + uint8_t length; +} const 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)} +}; +#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 +static volatile uint8_t usb_configuration=0; + +// which modifier keys are currently pressed +// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui +// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui +uint8_t keyboard_modifier_keys=0; + +// which keys are currently pressed, up to 6 keys may be down at once +uint8_t keyboard_keys[6]={0,0,0,0,0,0}; + +// protocol setting from the host. We use exactly the same report +// either way, so this variable only stores the setting since we +// are required to be able to report which setting is in use. +static uint8_t keyboard_protocol=1; + +// the idle configuration, how often we send the report to the +// host (ms * 4) even when it hasn't changed +static uint8_t keyboard_idle_config=125; + +// count until idle timeout +static uint8_t keyboard_idle_count=0; + +// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana +volatile uint8_t keyboard_leds=0; + + +/************************************************************************** + * + * Public Functions - these are the API intended for the user + * + **************************************************************************/ + + +// initialize USB +void usb_init(void) +{ + HW_CONFIG(); + USB_FREEZE(); // enable USB + PLL_CONFIG(); // config PLL + while (!(PLLCSR & (1<= NUM_DESC_LIST) { + UECONX = (1< desc_length) len = desc_length; + do { + // wait for host ready for IN packet + do { + i = UEINTX; + } while (!(i & ((1<= 1 && i <= MAX_ENDPOINT) { + usb_send_in(); + UENUM = i; + if (bRequest == SET_FEATURE) { + UECONX = (1<> 8); + keyboard_idle_count = 0; + usb_send_in(); + return; + } + if (bRequest == HID_SET_PROTOCOL) { + keyboard_protocol = wValue; + usb_send_in(); + return; + } + } + } + } + UECONX = (1< + +void usb_init(void); // initialize everything +uint8_t usb_configured(void); // is the USB port configured + +int8_t usb_keyboard_press(uint8_t key, uint8_t modifier); +int8_t usb_keyboard_send(void); +extern uint8_t keyboard_modifier_keys; +extern uint8_t keyboard_keys[6]; +extern volatile uint8_t keyboard_leds; + +// This file does not include the HID debug functions, so these empty +// macros replace them with nothing, so users can compile code that +// has calls to these functions. +#define usb_debug_putchar(c) +#define usb_debug_flush_output() + + +#define KEY_CTRL 0x01 +#define KEY_SHIFT 0x02 +#define KEY_ALT 0x04 +#define KEY_GUI 0x08 +#define KEY_LEFT_CTRL 0x01 +#define KEY_LEFT_SHIFT 0x02 +#define KEY_LEFT_ALT 0x04 +#define KEY_LEFT_GUI 0x08 +#define KEY_RIGHT_CTRL 0x10 +#define KEY_RIGHT_SHIFT 0x20 +#define KEY_RIGHT_ALT 0x40 +#define KEY_RIGHT_GUI 0x80 + +#define KEY_A 4 +#define KEY_B 5 +#define KEY_C 6 +#define KEY_D 7 +#define KEY_E 8 +#define KEY_F 9 +#define KEY_G 10 +#define KEY_H 11 +#define KEY_I 12 +#define KEY_J 13 +#define KEY_K 14 +#define KEY_L 15 +#define KEY_M 16 +#define KEY_N 17 +#define KEY_O 18 +#define KEY_P 19 +#define KEY_Q 20 +#define KEY_R 21 +#define KEY_S 22 +#define KEY_T 23 +#define KEY_U 24 +#define KEY_V 25 +#define KEY_W 26 +#define KEY_X 27 +#define KEY_Y 28 +#define KEY_Z 29 +#define KEY_1 30 +#define KEY_2 31 +#define KEY_3 32 +#define KEY_4 33 +#define KEY_5 34 +#define KEY_6 35 +#define KEY_7 36 +#define KEY_8 37 +#define KEY_9 38 +#define KEY_0 39 +#define KEY_ENTER 40 +#define KEY_ESC 41 +#define KEY_BACKSPACE 42 +#define KEY_TAB 43 +#define KEY_SPACE 44 +#define KEY_MINUS 45 +#define KEY_EQUAL 46 +#define KEY_LEFT_BRACE 47 +#define KEY_RIGHT_BRACE 48 +#define KEY_BACKSLASH 49 +#define KEY_NUMBER 50 +#define KEY_SEMICOLON 51 +#define KEY_QUOTE 52 +#define KEY_TILDE 53 +#define KEY_COMMA 54 +#define KEY_PERIOD 55 +#define KEY_SLASH 56 +#define KEY_CAPS_LOCK 57 +#define KEY_F1 58 +#define KEY_F2 59 +#define KEY_F3 60 +#define KEY_F4 61 +#define KEY_F5 62 +#define KEY_F6 63 +#define KEY_F7 64 +#define KEY_F8 65 +#define KEY_F9 66 +#define KEY_F10 67 +#define KEY_F11 68 +#define KEY_F12 69 +#define KEY_PRINTSCREEN 70 +#define KEY_SCROLL_LOCK 71 +#define KEY_PAUSE 72 +#define KEY_INSERT 73 +#define KEY_HOME 74 +#define KEY_PAGE_UP 75 +#define KEY_DELETE 76 +#define KEY_END 77 +#define KEY_PAGE_DOWN 78 +#define KEY_RIGHT 79 +#define KEY_LEFT 80 +#define KEY_DOWN 81 +#define KEY_UP 82 +#define KEY_NUM_LOCK 83 +#define KEYPAD_SLASH 84 +#define KEYPAD_ASTERIX 85 +#define KEYPAD_MINUS 86 +#define KEYPAD_PLUS 87 +#define KEYPAD_ENTER 88 +#define KEYPAD_1 89 +#define KEYPAD_2 90 +#define KEYPAD_3 91 +#define KEYPAD_4 92 +#define KEYPAD_5 93 +#define KEYPAD_6 94 +#define KEYPAD_7 95 +#define KEYPAD_8 96 +#define KEYPAD_9 97 +#define KEYPAD_0 98 +#define KEYPAD_PERIOD 99 +#define KEYBOARD_NON_US_SLASH_PIPE 100 +#define KEYBOARD_APPLICATION 101 +#define KEYBOARD_POWER 102 +#define KEYPAD_EQUAL 103 +#define KEYBOARD_F13 104 +#define KEYBOARD_F14 105 +#define KEYBOARD_F15 106 +#define KEYBOARD_F16 107 +#define KEYBOARD_F17 108 +#define KEYBOARD_F18 109 +#define KEYBOARD_F19 110 +#define KEYBOARD_F20 111 +#define KEYBOARD_F21 112 +#define KEYBOARD_F22 113 +#define KEYBOARD_F23 114 +#define KEYBOARD_F24 115 +#define KEYBOARD_EXECUTE 116 +#define KEYBOARD_HELP 117 +#define KEYBOARD_MENU 118 +#define KEYBOARD_SELECT 119 +#define KEYBOARD_STOP 120 +#define KEYBOARD_AGAIN 121 +#define KEYBOARD_UNDO 122 +#define KEYBOARD_CUT 123 +#define KEYBOARD_COPY 124 +#define KEYBOARD_PASTE 125 +#define KEYBOARD_FIND 126 +#define KEYBOARD_MUTE 127 +#define KEYBOARD_VOLUME_UP 128 +#define KEYBOARD_VOLUME_DOWN 129 +#define KEYBOARD_LOCKING_CAPS_LOCK 130 +#define KEYBOARD_LOCKING_NUM_LOCK 131 +#define KEYBOARD_LOCKING_SCROLL_LOCK 132 +#define KEYPAD_COMMA 133 +#define KEYPAD_EQUAL_SIGN 134 +#define KEYBOARD_INTERNATIONAL1 135 +#define KEYBOARD_INTERNATIONAL2 136 +#define KEYBOARD_INTERNATIONAL3 137 +#define KEYBOARD_INTERNATIONAL4 138 +#define KEYBOARD_INTERNATIONAL5 139 +#define KEYBOARD_INTERNATIONAL6 140 +#define KEYBOARD_INTERNATIONAL7 141 +#define KEYBOARD_INTERNATIONAL8 142 +#define KEYBOARD_INTERNATIONAL9 143 +#define KEYBOARD_LANG1ONAL9 144 +#define KEYBOARD_LANG2 145 +#define KEYBOARD_LANG3 146 +#define KEYBOARD_LANG4 147 +#define KEYBOARD_LANG5 148 +#define KEYBOARD_LANG6 149 +#define KEYBOARD_LANG7 150 +#define KEYBOARD_LANG8 151 +#define KEYBOARD_LANG9 152 +#define KEYBOARD_ALTERNATE_ERASE 153 +#define KEYBOARD_SYSREQ_ATTENTION 154 +#define KEYBOARD_CANCEL 155 +#define KEYBOARD_CLEAR 156 +#define KEYBOARD_PRIOR 157 +#define KEYBOARD_RETURN 158 +#define KEYBOARD_SEPARATOR 159 +#define KEYBOARD_OUT 160 +#define KEYBOARD_OPER 161 +#define KEYBOARD_CLEAR_AGAIN 162 +#define KEYBOARD_CRSEL_PROPS 163 +#define KEYBOARD_EXSEL 164 + +#define KEYPAD_00 176 +#define KEYPAD_000 177 +#define THOUSANDS_SEPARATOR 178 +#define DECIMAL_SEPARATOR 179 +#define CURRENCY_UNIT 180 +#define CURRENCY_SUBUNIT 181 +#define KEYPAD_LEFT_PAREN 182 +#define KEYPAD_RIGHT_PAREN 183 +#define KEYPAD_LEFT_BRACE 184 +#define KEYPAD_RIGHT_BRACE 185 +#define KEYPAD_TAB 186 +#define KEYPAD_BACKSPACE 187 +#define KEYPAD_A 188 +#define KEYPAD_B 189 +#define KEYPAD_C 190 +#define KEYPAD_D 191 +#define KEYPAD_E 192 +#define KEYPAD_F 193 +#define KEYPAD_XOR 194 +#define KEYPAD_CARET 195 +#define KEYPAD_PERCENT 196 +#define KEYPAD_LESS_THAN 197 +#define KEYPAD_GREATER_THAN 198 +#define KEYPAD_AMPERSAND 199 +#define KEYPAD_DOUBLE_AMPERSAND 200 +#define KEYPAD_PIPE 201 +#define KEYPAD_DOUBLE_PIPE 202 +#define KEYPAD_COLON 203 +#define KEYPAD_POUND 204 +#define KEYPAD_SPACE 205 +#define KEYPAD_AT 206 +#define KEYPAD_BANG 207 +#define KEYPAD_MEM_STORE 208 +#define KEYPAD_MEM_RECALL 209 +#define KEYPAD_MEM_CLEAR 210 +#define KEYPAD_MEM_ADD 211 +#define KEYPAD_MEM_SUBTRACT 212 +#define KEYPAD_MEM_MULTIPLY 213 +#define KEYPAD_MEM_DIVIDE 214 +#define KEYPAD_PLUS_MINUS 215 +#define KEYPAD_CLEAR 216 +#define KEYPAD_CLEAR_ENTRY 217 +#define KEYPAD_BINARY 218 +#define KEYPAD_OCTAL 219 +#define KEYPAD_DECIMAL 220 +#define KEYPAD_HEXADECIMAL 221 + +#define KEYBOARD_LEFT_CTRL 224 +#define KEYBOARD_LEFT_SHIFT 225 +#define KEYBOARD_LEFT_ALT 226 +#define KEYBOARD_LEFT_GUI 227 +#define KEYBOARD_RIGHT_CTRL 228 +#define KEYBOARD_RIGHT_SHIFT 229 +#define KEYBOARD_RIGHT_ALT 230 +#define KEYBOARD_RIGHT_GUI 231 + +#define USB_MIN_MODIFIER KEYBOARD_LEFT_CTRL +#define USB_MAX_MODIFIER KEYBOARD_RIGHT_GUI + +#define USB_MAX_KEY KEYBOARD_RIGHT_GUI + +// Everything below this point is only intended for usb_serial.c +#ifdef USB_SERIAL_PRIVATE_INCLUDE +#include +#include +#include + +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + +#define EP_SINGLE_BUFFER 0x02 +#define EP_DOUBLE_BUFFER 0x06 + +#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ + ((s) == 32 ? 0x20 : \ + ((s) == 16 ? 0x10 : \ + 0x00))) + +#define MAX_ENDPOINT 4 + +#define LSB(n) (n & 255) +#define MSB(n) ((n >> 8) & 255) + +#if defined(__AVR_AT90USB162__) +#define HW_CONFIG() +#define PLL_CONFIG() (PLLCSR = ((1<