# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
- keymap.c \
- matrix.c \
- usb_device.c \
+ usb.c \
usb_keyboard.c \
+ usb_mouse.c \
usb_debug.c \
- print.c \
- jump_bootloader.c
+ keymap.c \
+ matrix.c \
+ jump_bootloader.c \
+ print.c
# MCU name, you MUST set this to match the board you are using
#define KEYMAP_H 1
#include <stdint.h>
-#include "usbkeycodes.h"
+#include "usb_keycodes.h"
int get_layer(void);
uint8_t get_keycode(int layer, int row, int col);
+#ifndef MATRIX_H
+#define MATRIX_H 1
+
#include <stdbool.h>
extern uint8_t *matrix;
bool matrix_is_modified(void);
bool matrix_has_ghost(void);
bool matrix_has_ghost_in_row(uint8_t row);
+
+#endif
#include <avr/interrupt.h>
#include <util/delay.h>
-#include "usb_device.h"
+#include "usb.h"
+#include "usb_keyboard.h"
+#include "usb_mouse.h"
#include "print.h"
#include "matrix.h"
#include "keymap.h"
int main(void)
{
- bool modified = false;
- bool has_ghost = false;
- uint8_t key_index = 0;
-
// set for 16 MHz clock
CPU_PRESCALE(0);
- matrix_init();
-
-
// Initialize the USB, and then wait for the host to set configuration.
// If the Teensy is powered without a PC connected to the USB port,
// this will wait forever.
TCCR0B = 0x05;
TIMSK0 = (1<<TOIE0);
+
+ matrix_init();
print("firmware 0.2 for t.m.k.\n");
+ bool modified = false;
+ bool has_ghost = false;
+ int key_index = 0;
int loop_count = 0;
+ int layer = 0;
while (1) {
- int layer = 0;
-
matrix_scan();
layer = get_layer();
-
modified = matrix_is_modified();
has_ghost = matrix_has_ghost();
- // doesnt send keys during ghost occurs
- if (modified && !has_ghost) {
- key_index = 0;
- keyboard_modifier_keys = 0;
- for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
+ // print matrix state for debug
+ if (modified) {
+ print_matrix();
- for (int row = 0; row < MATRIX_ROWS; row++) {
- for (int col = 0; col < MATRIX_COLS; col++) {
- if (matrix[row] & 1<<col) continue;
-
- uint8_t code = get_keycode(layer, row, col);
- if (code == KB_NO) {
- continue;
- } else if (KB_LCTRL <= code && code <= KB_RGUI) {
- // modifier keycode: 0xE0-0xE7
- keyboard_modifier_keys |= 1<<(code & 0x07);
- } else {
- if (key_index < 6)
- keyboard_keys[key_index] = code;
- key_index++;
- }
+ // LED flush
+ DDRD |= 1<<PD6;
+ PORTD |= 1<<PD6;
+ }
+
+ // set matrix state to keyboard_keys, keyboard_modifier_keys
+ key_index = 0;
+ keyboard_modifier_keys = 0;
+ for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
+ for (int row = 0; row < MATRIX_ROWS; row++) {
+ for (int col = 0; col < MATRIX_COLS; col++) {
+ if (matrix[row] & 1<<col) continue;
+
+ uint8_t code = get_keycode(layer, row, col);
+ if (code == KB_NO) {
+ continue;
+ } else if (KB_LCTRL <= code && code <= KB_RGUI) {
+ // modifier keycode: 0xE0-0xE7
+ keyboard_modifier_keys |= 1<<(code & 0x07);
+ } else {
+ if (key_index < 6)
+ keyboard_keys[key_index] = code;
+ key_index++;
}
}
+ }
- // run bootloader when 4 left modifier keys down
+ if (!has_ghost) {
+ // when 4 left modifier keys down
if (keyboard_modifier_keys == (MOD_LCTRL | MOD_LSHIFT | MOD_LALT | MOD_LGUI)) {
// cancel all keys
keyboard_modifier_keys = 0;
for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
usb_keyboard_send();
+ /*
print("jump to bootloader...\n");
_delay_ms(1000);
jump_bootloader();
- }
+ */
- if (key_index > 6) {
- //Rollover
- }
+ // mouse
+ print("usb_mouse_move\n");
+ usb_mouse_move(10, 0, 0);
- usb_keyboard_send();
-
-
- // variables shared with interrupt routines must be
- // accessed carefully so the interrupt routine doesn't
- // try to use the variable in the middle of our access
- cli();
- //idle_count = 0;
- sei();
- }
-
- // print matrix state for debug
- if (modified) {
- print_matrix();
-
- // LED flush
- DDRD |= 1<<PD6;
- PORTD |= 1<<PD6;
- }
+ _delay_ms(100);
+ continue;
+ }
-/*
- // print counts for debug
- if ((loop_count % 0x1000) == 0) {
- //print(".");
- print("idle_count: "); phex((idle_count & 0xFF00) >> 8); phex(idle_count & 0xFF); print("\n");
- print("loop_count: "); phex((loop_count & 0xFF00) >> 8); phex(loop_count & 0xFF); print("\n");
- print_matrix();
- }
- // teensy LED flush for debug
- if ((loop_count & 0x100) == 0) {
- DDRD |= 1<<PD6;
- PORTD |= 1<<PD6;
+ // send keys to host
+ if (modified) {
+ if (key_index > 6) {
+ //Rollover
+ }
+ usb_keyboard_send();
+ }
}
-*/
-
- // now the current pins will be the previous, and
- // wait a short delay so we're not highly sensitive
- // to mechanical "bounce".
- _delay_ms(2);
loop_count++;
+ _delay_ms(2);
}
}
#include <avr/io.h>
#include <avr/pgmspace.h>
-
#include "print.h"
void print_P(const char *s)
-#ifndef print_h__
-#define print_h__
+#ifndef PRINT_H__
+#define PRINT_H__ 1
#include <avr/pgmspace.h>
#include "usb_debug.h"
--- /dev/null
+/* USB Keyboard Plus Debug Channel 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.
+ */
+
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include "usb.h"
+#include "usb_keyboard.h"
+#include "usb_mouse.h"
+#include "usb_debug.h"
+
+
+/**************************************************************************
+ *
+ * Configurable Options
+ *
+ **************************************************************************/
+
+// You can change these to give your code its own name.
+#define STR_MANUFACTURER L"t.m.k."
+#define STR_PRODUCT L"t.m.k. keyboard"
+
+
+// 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 0xFEED
+#define PRODUCT_ID 0xBABE
+
+
+// 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
+
+// 0:control endpoint is enabled automatically by controller.
+static const uint8_t PROGMEM endpoint_config_table[] = {
+ // enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
+ 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, // 1
+ 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2
+ 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
+ 0, // 4
+ 0, // 5
+ 0, // 6
+};
+
+
+/**************************************************************************
+ *
+ * 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 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 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
+};
+
+// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
+static uint8_t PROGMEM mouse_hid_report_desc[] = {
+ 0x05, 0x01, // Usage Page (Generic Desktop)
+ 0x09, 0x02, // Usage (Mouse)
+ 0xA1, 0x01, // Collection (Application)
+ 0x05, 0x09, // Usage Page (Button)
+ 0x19, 0x01, // Usage Minimum (Button #1)
+ 0x29, 0x03, // Usage Maximum (Button #3)
+ 0x15, 0x00, // Logical Minimum (0)
+ 0x25, 0x01, // Logical Maximum (1)
+ 0x95, 0x03, // Report Count (3)
+ 0x75, 0x01, // Report Size (1)
+ 0x81, 0x02, // Input (Data, Variable, Absolute)
+ 0x95, 0x01, // Report Count (1)
+ 0x75, 0x05, // Report Size (5)
+ 0x81, 0x03, // Input (Constant)
+ 0x05, 0x01, // Usage Page (Generic Desktop)
+ 0x09, 0x30, // Usage (X)
+ 0x09, 0x31, // Usage (Y)
+ 0x15, 0x81, // Logical Minimum (-127)
+ 0x25, 0x7F, // Logical Maximum (127)
+ 0x75, 0x08, // Report Size (8),
+ 0x95, 0x02, // Report Count (2),
+ 0x81, 0x06, // Input (Data, Variable, Relative)
+ 0x09, 0x38, // Usage (Wheel)
+ 0x95, 0x01, // Report Count (1),
+ 0x81, 0x06, // Input (Data, Variable, Relative)
+ 0xC0 // End Collection
+};
+
+static uint8_t PROGMEM debug_hid_report_desc[] = {
+ 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
+ 0x09, 0x74, // Usage 0x74
+ 0xA1, 0x53, // Collection 0x53
+ 0x75, 0x08, // report size = 8 bits
+ 0x15, 0x00, // logical minimum = 0
+ 0x26, 0xFF, 0x00, // logical maximum = 255
+ 0x95, DEBUG_TX_SIZE, // report count
+ 0x09, 0x75, // usage
+ 0x81, 0x02, // Input (array)
+ 0xC0 // end collection
+};
+
+#define CONFIG1_DESC_SIZE (9+(9+9+7)+(9+9+7)+(9+9+7))
+#define KEYBOARD_HID_DESC_OFFSET (9+9)
+#define MOUSE_HID_DESC_OFFSET (9+(9+9+7)+9)
+#define DEBUG_HID_DESC_OFFSET (9+(9+9+7)+(9+9+7)+9)
+static uint8_t 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),
+ 3, // 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 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
+
+ // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+ 9, // bLength
+ 4, // bDescriptorType
+ MOUSE_INTERFACE, // bInterfaceNumber
+ 0, // bAlternateSetting
+ 1, // bNumEndpoints
+ 0x03, // bInterfaceClass (0x03 = HID)
+ 0x01, // bInterfaceSubClass (0x01 = Boot)
+ 0x02, // bInterfaceProtocol (0x02 = Mouse)
+ 0, // iInterface
+ // HID descriptor, HID 1.11 spec, section 6.2.1
+ 9, // bLength
+ 0x21, // bDescriptorType
+ 0x11, 0x01, // bcdHID
+ 0, // bCountryCode
+ 1, // bNumDescriptors
+ 0x22, // bDescriptorType
+ sizeof(mouse_hid_report_desc), // wDescriptorLength
+ 0,
+ // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+ 7, // bLength
+ 5, // bDescriptorType
+ MOUSE_ENDPOINT | 0x80, // bEndpointAddress
+ 0x03, // bmAttributes (0x03=intr)
+ 4, 0, // wMaxPacketSize
+ 1, // bInterval
+
+ // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
+ 9, // bLength
+ 4, // bDescriptorType
+ DEBUG_INTERFACE, // bInterfaceNumber
+ 0, // bAlternateSetting
+ 1, // bNumEndpoints
+ 0x03, // bInterfaceClass (0x03 = HID)
+ 0x00, // bInterfaceSubClass
+ 0x00, // bInterfaceProtocol
+ 0, // iInterface
+ // HID descriptor, HID 1.11 spec, section 6.2.1
+ 9, // bLength
+ 0x21, // bDescriptorType
+ 0x11, 0x01, // bcdHID
+ 0, // bCountryCode
+ 1, // bNumDescriptors
+ 0x22, // bDescriptorType
+ sizeof(debug_hid_report_desc), // wDescriptorLength
+ 0,
+ // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
+ 7, // bLength
+ 5, // bDescriptorType
+ DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
+ 0x03, // bmAttributes (0x03=intr)
+ DEBUG_TX_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 PROGMEM string0 = {
+ 4,
+ 3,
+ {0x0409}
+};
+static struct usb_string_descriptor_struct PROGMEM string1 = {
+ sizeof(STR_MANUFACTURER),
+ 3,
+ STR_MANUFACTURER
+};
+static struct usb_string_descriptor_struct 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; // descriptor type
+ uint16_t wIndex;
+ const uint8_t *addr;
+ uint8_t length;
+} PROGMEM descriptor_list[] = {
+ // DEVICE descriptor
+ {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
+ // CONFIGURATION descriptor
+ {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
+ // HID REPORT
+ {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
+ {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
+ // HID REPORT
+ {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
+ {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
+ // HID REPORT
+ {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
+ {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
+ // STRING descriptor
+ {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;
+
+
+/**************************************************************************
+ *
+ * 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<<PLOCK))) ; // wait for PLL lock
+ USB_CONFIG(); // start USB clock
+ UDCON = 0; // enable attach resistor
+ usb_configuration = 0;
+ UDIEN = (1<<EORSTE)|(1<<SOFE);
+ sei();
+}
+
+// return 0 if the USB is not configured, or the configuration
+// number selected by the HOST
+uint8_t usb_configured(void)
+{
+ return usb_configuration;
+}
+
+
+
+/**************************************************************************
+ *
+ * Private Functions - not intended for general user consumption....
+ *
+ **************************************************************************/
+
+
+
+// USB Device Interrupt - handle all device-level events
+// the transmit buffer flushing is triggered by the start of frame
+//
+ISR(USB_GEN_vect)
+{
+ uint8_t intbits, t, i;
+ static uint8_t div4=0;
+
+ intbits = UDINT;
+ UDINT = 0;
+ if (intbits & (1<<EORSTI)) {
+ UENUM = 0;
+ UECONX = 1;
+ UECFG0X = EP_TYPE_CONTROL;
+ UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
+ UEIENX = (1<<RXSTPE);
+ usb_configuration = 0;
+ }
+ if ((intbits & (1<<SOFI)) && usb_configuration) {
+ t = debug_flush_timer;
+ if (t) {
+ debug_flush_timer = -- t;
+ if (!t) {
+ UENUM = DEBUG_TX_ENDPOINT;
+ while ((UEINTX & (1<<RWAL))) {
+ UEDATX = 0;
+ }
+ UEINTX = 0x3A;
+ }
+ }
+ if (keyboard_idle_config && (++div4 & 3) == 0) {
+ UENUM = KEYBOARD_ENDPOINT;
+ if (UEINTX & (1<<RWAL)) {
+ keyboard_idle_count++;
+ if (keyboard_idle_count == keyboard_idle_config) {
+ keyboard_idle_count = 0;
+ UEDATX = keyboard_modifier_keys;
+ UEDATX = 0;
+ for (i=0; i<6; i++) {
+ UEDATX = keyboard_keys[i];
+ }
+ UEINTX = 0x3A;
+ }
+ }
+ }
+ }
+}
+
+
+
+// Misc functions to wait for ready and send/receive packets
+static inline void usb_wait_in_ready(void)
+{
+ while (!(UEINTX & (1<<TXINI))) ;
+}
+static inline void usb_send_in(void)
+{
+ UEINTX = ~(1<<TXINI);
+}
+static inline void usb_wait_receive_out(void)
+{
+ while (!(UEINTX & (1<<RXOUTI))) ;
+}
+static inline void usb_ack_out(void)
+{
+ UEINTX = ~(1<<RXOUTI);
+}
+
+
+
+// USB Endpoint Interrupt - endpoint 0 is handled here. The
+// other endpoints are manipulated by the user-callable
+// functions, and the start-of-frame interrupt.
+//
+ISR(USB_COM_vect)
+{
+ uint8_t intbits;
+ const uint8_t *list;
+ const uint8_t *cfg;
+ uint8_t i, n, len, en;
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+ uint16_t desc_val;
+ const uint8_t *desc_addr;
+ uint8_t desc_length;
+
+ UENUM = 0;
+ intbits = UEINTX;
+ if (intbits & (1<<RXSTPI)) {
+ bmRequestType = UEDATX;
+ bRequest = UEDATX;
+ wValue = UEDATX;
+ wValue |= (UEDATX << 8);
+ wIndex = UEDATX;
+ wIndex |= (UEDATX << 8);
+ wLength = UEDATX;
+ wLength |= (UEDATX << 8);
+ UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
+ if (bRequest == GET_DESCRIPTOR) {
+ list = (const uint8_t *)descriptor_list;
+ for (i=0; ; i++) {
+ if (i >= NUM_DESC_LIST) {
+ UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
+ return;
+ }
+ desc_val = pgm_read_word(list);
+ if (desc_val != wValue) {
+ list += sizeof(struct descriptor_list_struct);
+ continue;
+ }
+ list += 2;
+ desc_val = pgm_read_word(list);
+ if (desc_val != wIndex) {
+ list += sizeof(struct descriptor_list_struct)-2;
+ continue;
+ }
+ list += 2;
+ desc_addr = (const uint8_t *)pgm_read_word(list);
+ list += 2;
+ desc_length = pgm_read_byte(list);
+ break;
+ }
+ len = (wLength < 256) ? wLength : 255;
+ if (len > desc_length) len = desc_length;
+ do {
+ // wait for host ready for IN packet
+ do {
+ i = UEINTX;
+ } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
+ if (i & (1<<RXOUTI)) return; // abort
+ // send IN packet
+ n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
+ for (i = n; i; i--) {
+ UEDATX = pgm_read_byte(desc_addr++);
+ }
+ len -= n;
+ usb_send_in();
+ } while (len || n == ENDPOINT0_SIZE);
+ return;
+ }
+ if (bRequest == SET_ADDRESS) {
+ usb_send_in();
+ usb_wait_in_ready();
+ UDADDR = wValue | (1<<ADDEN);
+ return;
+ }
+ if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
+ usb_configuration = wValue;
+ usb_send_in();
+ cfg = endpoint_config_table;
+ for (i=1; i<=6; i++) {
+ UENUM = i;
+ en = pgm_read_byte(cfg++);
+ UECONX = en;
+ if (en) {
+ UECFG0X = pgm_read_byte(cfg++);
+ UECFG1X = pgm_read_byte(cfg++);
+ }
+ }
+ UERST = 0x7E;
+ UERST = 0;
+ return;
+ }
+ if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
+ usb_wait_in_ready();
+ UEDATX = usb_configuration;
+ usb_send_in();
+ return;
+ }
+
+ if (bRequest == GET_STATUS) {
+ usb_wait_in_ready();
+ i = 0;
+ #ifdef SUPPORT_ENDPOINT_HALT
+ if (bmRequestType == 0x82) {
+ UENUM = wIndex;
+ if (UECONX & (1<<STALLRQ)) i = 1;
+ UENUM = 0;
+ }
+ #endif
+ UEDATX = i;
+ UEDATX = 0;
+ usb_send_in();
+ return;
+ }
+ #ifdef SUPPORT_ENDPOINT_HALT
+ if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
+ && bmRequestType == 0x02 && wValue == 0) {
+ i = wIndex & 0x7F;
+ if (i >= 1 && i <= MAX_ENDPOINT) {
+ usb_send_in();
+ UENUM = i;
+ if (bRequest == SET_FEATURE) {
+ UECONX = (1<<STALLRQ)|(1<<EPEN);
+ } else {
+ UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
+ UERST = (1 << i);
+ UERST = 0;
+ }
+ return;
+ }
+ }
+ #endif
+ if (wIndex == KEYBOARD_INTERFACE) {
+ if (bmRequestType == 0xA1) {
+ if (bRequest == HID_GET_REPORT) {
+ usb_wait_in_ready();
+ UEDATX = keyboard_modifier_keys;
+ UEDATX = 0;
+ for (i=0; i<6; i++) {
+ UEDATX = keyboard_keys[i];
+ }
+ usb_send_in();
+ return;
+ }
+ if (bRequest == HID_GET_IDLE) {
+ usb_wait_in_ready();
+ UEDATX = keyboard_idle_config;
+ usb_send_in();
+ return;
+ }
+ if (bRequest == HID_GET_PROTOCOL) {
+ usb_wait_in_ready();
+ UEDATX = keyboard_protocol;
+ usb_send_in();
+ return;
+ }
+ }
+ if (bmRequestType == 0x21) {
+ if (bRequest == HID_SET_REPORT) {
+ usb_wait_receive_out();
+ keyboard_leds = UEDATX;
+ usb_ack_out();
+ usb_send_in();
+ return;
+ }
+ if (bRequest == HID_SET_IDLE) {
+ keyboard_idle_config = (wValue >> 8);
+ keyboard_idle_count = 0;
+ //usb_wait_in_ready();
+ usb_send_in();
+ return;
+ }
+ if (bRequest == HID_SET_PROTOCOL) {
+ keyboard_protocol = wValue;
+ //usb_wait_in_ready();
+ usb_send_in();
+ return;
+ }
+ }
+ }
+ if (wIndex == MOUSE_INTERFACE) {
+ if (bmRequestType == 0xA1) {
+ if (bRequest == HID_GET_REPORT) {
+ usb_wait_in_ready();
+ UEDATX = mouse_buttons;
+ UEDATX = 0;
+ UEDATX = 0;
+ UEDATX = 0;
+ usb_send_in();
+ return;
+ }
+ if (bRequest == HID_GET_PROTOCOL) {
+ usb_wait_in_ready();
+ UEDATX = mouse_protocol;
+ usb_send_in();
+ return;
+ }
+ }
+ if (bmRequestType == 0x21) {
+ if (bRequest == HID_SET_PROTOCOL) {
+ mouse_protocol = wValue;
+ usb_send_in();
+ return;
+ }
+ }
+ }
+ if (wIndex == DEBUG_INTERFACE) {
+ if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
+ len = wLength;
+ do {
+ // wait for host ready for IN packet
+ do {
+ i = UEINTX;
+ } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
+ if (i & (1<<RXOUTI)) return; // abort
+ // send IN packet
+ n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
+ for (i = n; i; i--) {
+ UEDATX = 0;
+ }
+ len -= n;
+ usb_send_in();
+ } while (len || n == ENDPOINT0_SIZE);
+ return;
+ }
+ }
+ }
+ UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
+}
+
+
--- /dev/null
+#ifndef USB_H
+#define USB_H 1
+
+#include <stdint.h>
+#include <avr/io.h>
+
+
+void usb_init(void); // initialize everything
+uint8_t usb_configured(void); // is the USB port configured
+
+
+
+
+#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<<PLLE)|(1<<PLLP0)))
+#define USB_CONFIG() (USBCON = (1<<USBE))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#elif defined(__AVR_ATmega32U4__)
+#define HW_CONFIG() (UHWCON = 0x01)
+#define PLL_CONFIG() (PLLCSR = 0x12)
+#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#elif defined(__AVR_AT90USB646__)
+#define HW_CONFIG() (UHWCON = 0x81)
+#define PLL_CONFIG() (PLLCSR = 0x1A)
+#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#elif defined(__AVR_AT90USB1286__)
+#define HW_CONFIG() (UHWCON = 0x81)
+#define PLL_CONFIG() (PLLCSR = 0x16)
+#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
+#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
+#endif
+
+// standard control endpoint request types
+#define GET_STATUS 0
+#define CLEAR_FEATURE 1
+#define SET_FEATURE 3
+#define SET_ADDRESS 5
+#define GET_DESCRIPTOR 6
+#define GET_CONFIGURATION 8
+#define SET_CONFIGURATION 9
+#define GET_INTERFACE 10
+#define SET_INTERFACE 11
+// HID (human interface device)
+#define HID_GET_REPORT 1
+#define HID_GET_IDLE 2
+#define HID_GET_PROTOCOL 3
+#define HID_SET_REPORT 9
+#define HID_SET_IDLE 10
+#define HID_SET_PROTOCOL 11
+// CDC (communication class device)
+#define CDC_SET_LINE_CODING 0x20
+#define CDC_GET_LINE_CODING 0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+
+#endif
#define USB_DEBUG_H 1
#include <stdint.h>
-#include "usb_device.h"
+#include "usb.h"
-#define DEBUG_INTERFACE 1
-#define DEBUG_TX_ENDPOINT 4
+#define DEBUG_INTERFACE 2
+#define DEBUG_TX_ENDPOINT 3
#define DEBUG_TX_SIZE 32
#define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER
+++ /dev/null
-/* USB Keyboard Plus Debug Channel 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.
- */
-
-#include <avr/pgmspace.h>
-#include <avr/interrupt.h>
-#include "usb_device.h"
-#include "usb_keyboard.h"
-#include "usb_debug.h"
-
-
-/**************************************************************************
- *
- * Configurable Options
- *
- **************************************************************************/
-
-// You can change these to give your code its own name.
-#define STR_MANUFACTURER L"t.m.k."
-#define STR_PRODUCT L"t.m.k. keyboard"
-
-
-// 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 0xFEED
-#define PRODUCT_ID 0xBABE
-
-
-// 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
-
-static const uint8_t PROGMEM endpoint_config_table[] = {
- 0,
- 0,
- 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
- 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER
-};
-
-
-/**************************************************************************
- *
- * 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 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 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
-};
-
-static uint8_t PROGMEM debug_hid_report_desc[] = {
- 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
- 0x09, 0x74, // Usage 0x74
- 0xA1, 0x53, // Collection 0x53
- 0x75, 0x08, // report size = 8 bits
- 0x15, 0x00, // logical minimum = 0
- 0x26, 0xFF, 0x00, // logical maximum = 255
- 0x95, DEBUG_TX_SIZE, // report count
- 0x09, 0x75, // usage
- 0x81, 0x02, // Input (array)
- 0xC0 // end collection
-};
-
-#define CONFIG1_DESC_SIZE (9+9+9+7+9+9+7)
-#define KEYBOARD_HID_DESC_OFFSET (9+9)
-#define DEBUG_HID_DESC_OFFSET (9+9+9+7+9)
-static uint8_t 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),
- 2, // 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
- // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
- 9, // bLength
- 4, // bDescriptorType
- DEBUG_INTERFACE, // bInterfaceNumber
- 0, // bAlternateSetting
- 1, // bNumEndpoints
- 0x03, // bInterfaceClass (0x03 = HID)
- 0x00, // bInterfaceSubClass
- 0x00, // bInterfaceProtocol
- 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(debug_hid_report_desc), // wDescriptorLength
- 0,
- // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
- 7, // bLength
- 5, // bDescriptorType
- DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
- 0x03, // bmAttributes (0x03=intr)
- DEBUG_TX_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 PROGMEM string0 = {
- 4,
- 3,
- {0x0409}
-};
-static struct usb_string_descriptor_struct PROGMEM string1 = {
- sizeof(STR_MANUFACTURER),
- 3,
- STR_MANUFACTURER
-};
-static struct usb_string_descriptor_struct 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; // descriptor type
- uint16_t wIndex;
- const uint8_t *addr;
- uint8_t length;
-} PROGMEM descriptor_list[] = {
- // DEVICE descriptor
- {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
- // CONFIGURATION descriptor
- {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
- // HID REPORT
- {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
- {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
- // HID REPORT
- {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
- {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
- // STRING descriptor
- {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;
-
-
-/**************************************************************************
- *
- * 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<<PLOCK))) ; // wait for PLL lock
- USB_CONFIG(); // start USB clock
- UDCON = 0; // enable attach resistor
- usb_configuration = 0;
- UDIEN = (1<<EORSTE)|(1<<SOFE);
- sei();
-}
-
-// return 0 if the USB is not configured, or the configuration
-// number selected by the HOST
-uint8_t usb_configured(void)
-{
- return usb_configuration;
-}
-
-
-
-/**************************************************************************
- *
- * Private Functions - not intended for general user consumption....
- *
- **************************************************************************/
-
-
-
-// USB Device Interrupt - handle all device-level events
-// the transmit buffer flushing is triggered by the start of frame
-//
-ISR(USB_GEN_vect)
-{
- uint8_t intbits, t, i;
- static uint8_t div4=0;
-
- intbits = UDINT;
- UDINT = 0;
- if (intbits & (1<<EORSTI)) {
- UENUM = 0;
- UECONX = 1;
- UECFG0X = EP_TYPE_CONTROL;
- UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
- UEIENX = (1<<RXSTPE);
- usb_configuration = 0;
- }
- if ((intbits & (1<<SOFI)) && usb_configuration) {
- t = debug_flush_timer;
- if (t) {
- debug_flush_timer = -- t;
- if (!t) {
- UENUM = DEBUG_TX_ENDPOINT;
- while ((UEINTX & (1<<RWAL))) {
- UEDATX = 0;
- }
- UEINTX = 0x3A;
- }
- }
- if (keyboard_idle_config && (++div4 & 3) == 0) {
- UENUM = KEYBOARD_ENDPOINT;
- if (UEINTX & (1<<RWAL)) {
- keyboard_idle_count++;
- if (keyboard_idle_count == keyboard_idle_config) {
- keyboard_idle_count = 0;
- UEDATX = keyboard_modifier_keys;
- UEDATX = 0;
- for (i=0; i<6; i++) {
- UEDATX = keyboard_keys[i];
- }
- UEINTX = 0x3A;
- }
- }
- }
- }
-}
-
-
-
-// Misc functions to wait for ready and send/receive packets
-static inline void usb_wait_in_ready(void)
-{
- while (!(UEINTX & (1<<TXINI))) ;
-}
-static inline void usb_send_in(void)
-{
- UEINTX = ~(1<<TXINI);
-}
-static inline void usb_wait_receive_out(void)
-{
- while (!(UEINTX & (1<<RXOUTI))) ;
-}
-static inline void usb_ack_out(void)
-{
- UEINTX = ~(1<<RXOUTI);
-}
-
-
-
-// USB Endpoint Interrupt - endpoint 0 is handled here. The
-// other endpoints are manipulated by the user-callable
-// functions, and the start-of-frame interrupt.
-//
-ISR(USB_COM_vect)
-{
- uint8_t intbits;
- const uint8_t *list;
- const uint8_t *cfg;
- uint8_t i, n, len, en;
- uint8_t bmRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
- uint16_t desc_val;
- const uint8_t *desc_addr;
- uint8_t desc_length;
-
- UENUM = 0;
- intbits = UEINTX;
- if (intbits & (1<<RXSTPI)) {
- bmRequestType = UEDATX;
- bRequest = UEDATX;
- wValue = UEDATX;
- wValue |= (UEDATX << 8);
- wIndex = UEDATX;
- wIndex |= (UEDATX << 8);
- wLength = UEDATX;
- wLength |= (UEDATX << 8);
- UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
- if (bRequest == GET_DESCRIPTOR) {
- list = (const uint8_t *)descriptor_list;
- for (i=0; ; i++) {
- if (i >= NUM_DESC_LIST) {
- UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
- return;
- }
- desc_val = pgm_read_word(list);
- if (desc_val != wValue) {
- list += sizeof(struct descriptor_list_struct);
- continue;
- }
- list += 2;
- desc_val = pgm_read_word(list);
- if (desc_val != wIndex) {
- list += sizeof(struct descriptor_list_struct)-2;
- continue;
- }
- list += 2;
- desc_addr = (const uint8_t *)pgm_read_word(list);
- list += 2;
- desc_length = pgm_read_byte(list);
- break;
- }
- len = (wLength < 256) ? wLength : 255;
- if (len > desc_length) len = desc_length;
- do {
- // wait for host ready for IN packet
- do {
- i = UEINTX;
- } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
- if (i & (1<<RXOUTI)) return; // abort
- // send IN packet
- n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
- for (i = n; i; i--) {
- UEDATX = pgm_read_byte(desc_addr++);
- }
- len -= n;
- usb_send_in();
- } while (len || n == ENDPOINT0_SIZE);
- return;
- }
- if (bRequest == SET_ADDRESS) {
- usb_send_in();
- usb_wait_in_ready();
- UDADDR = wValue | (1<<ADDEN);
- return;
- }
- if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
- usb_configuration = wValue;
- usb_send_in();
- cfg = endpoint_config_table;
- for (i=1; i<5; i++) {
- UENUM = i;
- en = pgm_read_byte(cfg++);
- UECONX = en;
- if (en) {
- UECFG0X = pgm_read_byte(cfg++);
- UECFG1X = pgm_read_byte(cfg++);
- }
- }
- UERST = 0x1E;
- UERST = 0;
- return;
- }
- if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
- usb_wait_in_ready();
- UEDATX = usb_configuration;
- usb_send_in();
- return;
- }
-
- if (bRequest == GET_STATUS) {
- usb_wait_in_ready();
- i = 0;
- #ifdef SUPPORT_ENDPOINT_HALT
- if (bmRequestType == 0x82) {
- UENUM = wIndex;
- if (UECONX & (1<<STALLRQ)) i = 1;
- UENUM = 0;
- }
- #endif
- UEDATX = i;
- UEDATX = 0;
- usb_send_in();
- return;
- }
- #ifdef SUPPORT_ENDPOINT_HALT
- if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
- && bmRequestType == 0x02 && wValue == 0) {
- i = wIndex & 0x7F;
- if (i >= 1 && i <= MAX_ENDPOINT) {
- usb_send_in();
- UENUM = i;
- if (bRequest == SET_FEATURE) {
- UECONX = (1<<STALLRQ)|(1<<EPEN);
- } else {
- UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
- UERST = (1 << i);
- UERST = 0;
- }
- return;
- }
- }
- #endif
- if (wIndex == KEYBOARD_INTERFACE) {
- if (bmRequestType == 0xA1) {
- if (bRequest == HID_GET_REPORT) {
- usb_wait_in_ready();
- UEDATX = keyboard_modifier_keys;
- UEDATX = 0;
- for (i=0; i<6; i++) {
- UEDATX = keyboard_keys[i];
- }
- usb_send_in();
- return;
- }
- if (bRequest == HID_GET_IDLE) {
- usb_wait_in_ready();
- UEDATX = keyboard_idle_config;
- usb_send_in();
- return;
- }
- if (bRequest == HID_GET_PROTOCOL) {
- usb_wait_in_ready();
- UEDATX = keyboard_protocol;
- usb_send_in();
- return;
- }
- }
- if (bmRequestType == 0x21) {
- if (bRequest == HID_SET_REPORT) {
- usb_wait_receive_out();
- keyboard_leds = UEDATX;
- usb_ack_out();
- usb_send_in();
- return;
- }
- if (bRequest == HID_SET_IDLE) {
- keyboard_idle_config = (wValue >> 8);
- keyboard_idle_count = 0;
- //usb_wait_in_ready();
- usb_send_in();
- return;
- }
- if (bRequest == HID_SET_PROTOCOL) {
- keyboard_protocol = wValue;
- //usb_wait_in_ready();
- usb_send_in();
- return;
- }
- }
- }
- if (wIndex == DEBUG_INTERFACE) {
- if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
- len = wLength;
- do {
- // wait for host ready for IN packet
- do {
- i = UEINTX;
- } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
- if (i & (1<<RXOUTI)) return; // abort
- // send IN packet
- n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
- for (i = n; i; i--) {
- UEDATX = 0;
- }
- len -= n;
- usb_send_in();
- } while (len || n == ENDPOINT0_SIZE);
- return;
- }
- }
- }
- UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
-}
-
-
+++ /dev/null
-#ifndef USB_DEVICE_H
-#define USB_DEVICE_H 1
-
-#include <stdint.h>
-#include <avr/io.h>
-#include "usb_keyboard.h"
-#include "usb_debug.h"
-
-
-void usb_init(void); // initialize everything
-uint8_t usb_configured(void); // is the USB port configured
-
-
-
-
-#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<<PLLE)|(1<<PLLP0)))
-#define USB_CONFIG() (USBCON = (1<<USBE))
-#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
-#elif defined(__AVR_ATmega32U4__)
-#define HW_CONFIG() (UHWCON = 0x01)
-#define PLL_CONFIG() (PLLCSR = 0x12)
-#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
-#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
-#elif defined(__AVR_AT90USB646__)
-#define HW_CONFIG() (UHWCON = 0x81)
-#define PLL_CONFIG() (PLLCSR = 0x1A)
-#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
-#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
-#elif defined(__AVR_AT90USB1286__)
-#define HW_CONFIG() (UHWCON = 0x81)
-#define PLL_CONFIG() (PLLCSR = 0x16)
-#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
-#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
-#endif
-
-// standard control endpoint request types
-#define GET_STATUS 0
-#define CLEAR_FEATURE 1
-#define SET_FEATURE 3
-#define SET_ADDRESS 5
-#define GET_DESCRIPTOR 6
-#define GET_CONFIGURATION 8
-#define SET_CONFIGURATION 9
-#define GET_INTERFACE 10
-#define SET_INTERFACE 11
-// HID (human interface device)
-#define HID_GET_REPORT 1
-#define HID_GET_IDLE 2
-#define HID_GET_PROTOCOL 3
-#define HID_SET_REPORT 9
-#define HID_SET_IDLE 10
-#define HID_SET_PROTOCOL 11
-// CDC (communication class device)
-#define CDC_SET_LINE_CODING 0x20
-#define CDC_GET_LINE_CODING 0x21
-#define CDC_SET_CONTROL_LINE_STATE 0x22
-
-#endif
#define USB_KEYBOARD_H 1
#include <stdint.h>
-#include "usb_device.h"
+#include "usb.h"
#define KEYBOARD_INTERFACE 0
-#define KEYBOARD_ENDPOINT 3
+#define KEYBOARD_ENDPOINT 1
#define KEYBOARD_SIZE 8
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER
--- /dev/null
+/*
+ * Key codes from HID Keyboard/Keypad Page
+ * http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
+ *
+ * Based on Keyboard Upgrade v0.3.0 http://github.com/rhomann/kbupgrade
+ */
+/*
+ * Keyboard Upgrade -- Firmware for homebrew computer keyboard controllers.
+ * Copyright (C) 2009 Robert Homann
+ *
+ * Based on RUMP (http://mg8.org/rump/), Copyright (C) 2008 Chris Lee
+ *
+ * Based on c64key (http://symlink.dk/projects/c64key/),
+ * Copyright (C) 2006-2007 Mikkel Holm Olsen
+ *
+ * Based on HID-Test by Christian Starkjohann, Objective Development
+ *
+ * This file is part of the Keyboard Upgrade package.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the Keyboard Upgrade package; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef USB_KEYCODES_H
+#define USB_KEYCODES_H
+
+
+enum keycodes {
+ KB_NO = 0,
+ KB_ROLL_OVER,
+ KB_POST_FAIL,
+ KB_UNDEFINED,
+ KB_A,
+ KB_B,
+ KB_C,
+ KB_D,
+ KB_E,
+ KB_F,
+ KB_G,
+ KB_H,
+ KB_I,
+ KB_J,
+ KB_K,
+ KB_L,
+ KB_M, /* 0x10 */
+ KB_N,
+ KB_O,
+ KB_P,
+ KB_Q,
+ KB_R,
+ KB_S,
+ KB_T,
+ KB_U,
+ KB_V,
+ KB_W,
+ KB_X,
+ KB_Y,
+ KB_Z,
+ KB_1,
+ KB_2,
+ KB_3, /* 0x20 */
+ KB_4,
+ KB_5,
+ KB_6,
+ KB_7,
+ KB_8,
+ KB_9,
+ KB_0,
+ KB_ENTER,
+ KB_ESCAPE,
+ KB_BSPACE,
+ KB_TAB,
+ KB_SPACE,
+ KB_MINUS,
+ KB_EQUAL,
+ KB_LBRACKET, /* [ */
+ KB_RBRACKET, /* ] */
+ KB_BSLASH, /* \ (and |) */
+ KB_NONUS_HASH, /* Non-US # and ~ */
+ KB_SCOLON, /* ; (and :) */
+ KB_QUOTE, /* ' and " */
+ KB_GRAVE, /* Grave accent and tilde */
+ KB_COMMA, /* , and < */
+ KB_DOT, /* . and > */
+ KB_SLASH, /* / and ? */
+ KB_CAPSLOCK,
+ KB_F1,
+ KB_F2,
+ KB_F3,
+ KB_F4,
+ KB_F5,
+ KB_F6,
+ KB_F7, /* 0x40 */
+ KB_F8,
+ KB_F9,
+ KB_F10,
+ KB_F11,
+ KB_F12,
+ KB_PSCREEN,
+ KB_SCKLOCK,
+ KB_BREAK,
+ KB_INSERT,
+ KB_HOME,
+ KB_PGUP,
+ KB_DELETE,
+ KB_END,
+ KB_PGDOWN,
+ KB_RIGHT,
+ KB_LEFT, /* 0x50 */
+ KB_DOWN,
+ KB_UP,
+ KB_NUMLOCK,
+ KP_SLASH,
+ KP_ASTERISK,
+ KP_MINUS,
+ KP_PLUS,
+ KP_ENTER,
+ KP_1,
+ KP_2,
+ KP_3,
+ KP_4,
+ KP_5,
+ KP_6,
+ KP_7,
+ KP_8, /* 0x60 */
+ KP_9,
+ KP_0,
+ KP_DOT,
+ KB_NONUS_BSLASH, /* Non-US \ and | */
+ KB_APPLICATION,
+ KB_POWER,
+ KP_EQUAL,
+ KB_F13,
+ KB_F14,
+ KB_F15,
+ KB_F16,
+ KB_F17,
+ KB_F18,
+ KB_F19,
+ KB_F20,
+ KB_F21, /* 0x70 */
+ KB_F22,
+ KB_F23,
+ KB_F24,
+ KB_EXECUTE,
+ KB_HELP,
+ KB_MENU,
+ KB_SELECT,
+ KB_STOP,
+ KB_AGAIN,
+ KB_UNDO,
+ KB_CUT,
+ KB_COPY,
+ KB_PASTE,
+ KB_FIND,
+ KB_MUTE,
+ KB_VOLUP, /* 0x80 */
+ KB_VOLDOWN,
+ KB_LOCKING_CAPS, /* locking Caps Lock */
+ KB_LOCKING_NUM, /* locking Num Lock */
+ KB_LOCKING_SCROLL, /* locking Scroll Lock */
+ KP_COMMA,
+ KP_EQUAL_AS400, /* equal sign on AS/400 */
+ KB_INT1,
+ KB_INT2,
+ KB_INT3,
+ KB_INT4,
+ KB_INT5,
+ KB_INT6,
+ KB_INT7,
+ KB_INT8,
+ KB_INT9,
+ KB_LANG1, /* 0x90 */
+ KB_LANG2,
+ KB_LANG3,
+ KB_LANG4,
+ KB_LANG5,
+ KB_LANG6,
+ KB_LANG7,
+ KB_LANG8,
+ KB_LANG9,
+ KB_ALT_ERASE,
+ KB_SYSREQ,
+ KB_CANCEL,
+ KB_CLEAR,
+ KB_PRIOR,
+ KB_RETURN,
+ KB_SEPARATOR,
+ KB_OUT,
+ KB_OPER,
+ KB_CLEAR_AGAIN,
+ KB_CRSEL,
+ KB_EXSEL,
+
+ KP_00 = 0xB0,
+ KP_000,
+ KB_THOUSANDS_SEPARATOR,
+ KB_DECIMAL_SEPARATOR,
+ CURRENCY_UNIT,
+ CURRENCY_SUB_UNIT,
+ KP_LPAREN,
+ KP_RPAREN,
+ KP_LCBRACKET, /* { */
+ KP_RCBRACKET, /* } */
+ KP_TAB,
+ KP_BSPACE,
+ KP_A,
+ KP_B,
+ KP_C,
+ KP_D,
+ KP_E,
+ KP_F,
+ KP_XOR,
+ KP_HAT,
+ KP_PERC,
+ KP_LT,
+ KP_GT,
+ KP_AND,
+ KP_LAZYAND,
+ KP_OR,
+ KP_LAZYOR,
+ KP_COLON,
+ KP_HASH,
+ KP_SPACE,
+ KP_ATMARK,
+ KP_EXCLAMATION,
+ KP_MEM_STORE,
+ KP_MEM_RECALL,
+ KP_MEM_CLEAR,
+ KP_MEM_ADD,
+ KP_MEM_SUB,
+ KP_MEM_MUL,
+ KP_MEM_DIV,
+ KP_PLUS_MINUS,
+ KP_CLEAR,
+ KP_CLEAR_ENTRY,
+ KP_BINARY,
+ KP_OCTAL,
+ KP_DECIMAL,
+ KP_HEXADECIMAL,
+
+ /* modifiers */
+ KB_LCTRL = 0xE0, /* 0x01 */
+ KB_LSHIFT, /* 0x02 */
+ KB_LALT, /* 0x04 */
+ KB_LGUI, /* 0x08 */
+ KB_RCTRL, /* 0x10 */
+ KB_RSHIFT, /* 0x20 */
+ KB_RALT, /* 0x40 */
+ KB_RGUI, /* 0x80 */
+
+ /* extensions for internal use */
+ FN_0 = 0xF0,
+ FN_1,
+ FN_2,
+ FN_3,
+};
+
+#endif /* USB_KEYCODES_H */
--- /dev/null
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "usb_mouse.h"
+
+
+// which buttons are currently pressed
+uint8_t mouse_buttons=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.
+uint8_t mouse_protocol=1;
+
+
+// Set the mouse buttons. To create a "click", 2 calls are needed,
+// one to push the button down and the second to release it
+int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right)
+{
+ uint8_t mask=0;
+
+ if (left) mask |= 1;
+ if (middle) mask |= 4;
+ if (right) mask |= 2;
+ mouse_buttons = mask;
+ return usb_mouse_move(0, 0, 0);
+}
+
+// Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement.
+int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel)
+{
+ uint8_t intr_state, timeout;
+
+ if (!usb_configured()) return -1;
+ if (x == -128) x = -127;
+ if (y == -128) y = -127;
+ if (wheel == -128) wheel = -127;
+ intr_state = SREG;
+ cli();
+ UENUM = MOUSE_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_configured()) return -1;
+ // have we waited too long?
+ if (UDFNUML == timeout) return -1;
+ // get ready to try checking again
+ intr_state = SREG;
+ cli();
+ UENUM = MOUSE_ENDPOINT;
+ }
+ UEDATX = mouse_buttons;
+ UEDATX = x;
+ UEDATX = y;
+ UEDATX = wheel;
+ UEINTX = 0x3A;
+ SREG = intr_state;
+ return 0;
+}
+
--- /dev/null
+#ifndef USB_MOUSE_H
+#define USB_MOUSE_H 1
+
+#include <stdint.h>
+#include "usb.h"
+
+
+#define MOUSE_INTERFACE 1
+#define MOUSE_ENDPOINT 2
+#define MOUSE_SIZE 8
+#define MOUSE_BUFFER EP_DOUBLE_BUFFER
+
+extern uint8_t mouse_buttons;
+extern uint8_t mouse_protocol;
+
+
+int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right);
+int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel);
+
+#endif
+++ /dev/null
-/* Some modified from Keyboard Upgrade 0.3.0
- * 2010/08/22
- */
-/*
- * Keyboard Upgrade -- Firmware for homebrew computer keyboard controllers.
- * Copyright (C) 2009 Robert Homann
- *
- * Based on RUMP (http://mg8.org/rump/), Copyright (C) 2008 Chris Lee
- *
- * Based on c64key (http://symlink.dk/projects/c64key/),
- * Copyright (C) 2006-2007 Mikkel Holm Olsen
- *
- * Based on HID-Test by Christian Starkjohann, Objective Development
- *
- * This file is part of the Keyboard Upgrade package.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with the Keyboard Upgrade package; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#ifndef USBKEYCODES_H
-#define USBKEYCODES_H
-
-/*
- * The USB keycodes are enumerated here - the first part is simply
- * an enumeration of the allowed scan-codes used for USB HID devices.
- */
-/*
- * see 10 Keyboard/Keypad Page(0x07)
- * http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
- */
-enum keycodes {
- KB_NO = 0,
- KB_ROLL_OVER,
- KB_POST_FAIL,
- KB_UNDEFINED,
- KB_A,
- KB_B,
- KB_C,
- KB_D,
- KB_E,
- KB_F,
- KB_G,
- KB_H,
- KB_I,
- KB_J,
- KB_K,
- KB_L,
- KB_M, /* 0x10 */
- KB_N,
- KB_O,
- KB_P,
- KB_Q,
- KB_R,
- KB_S,
- KB_T,
- KB_U,
- KB_V,
- KB_W,
- KB_X,
- KB_Y,
- KB_Z,
- KB_1,
- KB_2,
- KB_3, /* 0x20 */
- KB_4,
- KB_5,
- KB_6,
- KB_7,
- KB_8,
- KB_9,
- KB_0,
- KB_ENTER,
- KB_ESCAPE,
- KB_BSPACE,
- KB_TAB,
- KB_SPACE,
- KB_MINUS,
- KB_EQUAL,
- KB_LBRACKET, /* [ */
- KB_RBRACKET, /* ] */
- KB_BSLASH, /* \ (and |) */
- KB_NONUS_HASH, /* Non-US # and ~ */
- KB_SCOLON, /* ; (and :) */
- KB_QUOTE, /* ' and " */
- KB_GRAVE, /* Grave accent and tilde */
- KB_COMMA, /* , and < */
- KB_DOT, /* . and > */
- KB_SLASH, /* / and ? */
- KB_CAPSLOCK,
- KB_F1,
- KB_F2,
- KB_F3,
- KB_F4,
- KB_F5,
- KB_F6,
- KB_F7, /* 0x40 */
- KB_F8,
- KB_F9,
- KB_F10,
- KB_F11,
- KB_F12,
- KB_PSCREEN,
- KB_SCKLOCK,
- KB_BREAK,
- KB_INSERT,
- KB_HOME,
- KB_PGUP,
- KB_DELETE,
- KB_END,
- KB_PGDOWN,
- KB_RIGHT,
- KB_LEFT, /* 0x50 */
- KB_DOWN,
- KB_UP,
- KB_NUMLOCK,
- KP_SLASH,
- KP_ASTERISK,
- KP_MINUS,
- KP_PLUS,
- KP_ENTER,
- KP_1,
- KP_2,
- KP_3,
- KP_4,
- KP_5,
- KP_6,
- KP_7,
- KP_8, /* 0x60 */
- KP_9,
- KP_0,
- KP_DOT,
- KB_NONUS_BSLASH, /* Non-US \ and | */
- KB_APPLICATION,
- KB_POWER,
- KP_EQUAL,
- KB_F13,
- KB_F14,
- KB_F15,
- KB_F16,
- KB_F17,
- KB_F18,
- KB_F19,
- KB_F20,
- KB_F21, /* 0x70 */
- KB_F22,
- KB_F23,
- KB_F24,
- KB_EXECUTE,
- KB_HELP,
- KB_MENU,
- KB_SELECT,
- KB_STOP,
- KB_AGAIN,
- KB_UNDO,
- KB_CUT,
- KB_COPY,
- KB_PASTE,
- KB_FIND,
- KB_MUTE,
- KB_VOLUP, /* 0x80 */
- KB_VOLDOWN,
- KB_LOCKING_CAPS, /* locking Caps Lock */
- KB_LOCKING_NUM, /* locking Num Lock */
- KB_LOCKING_SCROLL, /* locking Scroll Lock */
- KP_COMMA,
- KP_EQUAL_AS400, /* equal sign on AS/400 */
- KB_INT1,
- KB_INT2,
- KB_INT3,
- KB_INT4,
- KB_INT5,
- KB_INT6,
- KB_INT7,
- KB_INT8,
- KB_INT9,
- KB_LANG1, /* 0x90 */
- KB_LANG2,
- KB_LANG3,
- KB_LANG4,
- KB_LANG5,
- KB_LANG6,
- KB_LANG7,
- KB_LANG8,
- KB_LANG9,
- KB_ALT_ERASE,
- KB_SYSREQ,
- KB_CANCEL,
- KB_CLEAR,
- KB_PRIOR,
- KB_RETURN,
- KB_SEPARATOR,
- KB_OUT,
- KB_OPER,
- KB_CLEAR_AGAIN,
- KB_CRSEL,
- KB_EXSEL,
-
- KP_00 = 0xB0,
- KP_000,
- KB_THOUSANDS_SEPARATOR,
- KB_DECIMAL_SEPARATOR,
- CURRENCY_UNIT,
- CURRENCY_SUB_UNIT,
- KP_LPAREN,
- KP_RPAREN,
- KP_LCBRACKET, /* { */
- KP_RCBRACKET, /* } */
- KP_TAB,
- KP_BSPACE,
- KP_A,
- KP_B,
- KP_C,
- KP_D,
- KP_E,
- KP_F,
- KP_XOR,
- KP_HAT,
- KP_PERC,
- KP_LT,
- KP_GT,
- KP_AND,
- KP_LAZYAND,
- KP_OR,
- KP_LAZYOR,
- KP_COLON,
- KP_HASH,
- KP_SPACE,
- KP_ATMARK,
- KP_EXCLAMATION,
- KP_MEM_STORE,
- KP_MEM_RECALL,
- KP_MEM_CLEAR,
- KP_MEM_ADD,
- KP_MEM_SUB,
- KP_MEM_MUL,
- KP_MEM_DIV,
- KP_PLUS_MINUS,
- KP_CLEAR,
- KP_CLEAR_ENTRY,
- KP_BINARY,
- KP_OCTAL,
- KP_DECIMAL,
- KP_HEXADECIMAL,
-
- /* modifiers */
- KB_LCTRL = 0xE0, /* 0x01 */
- KB_LSHIFT, /* 0x02 */
- KB_LALT, /* 0x04 */
- KB_LGUI, /* 0x08 */
- KB_RCTRL, /* 0x10 */
- KB_RSHIFT, /* 0x20 */
- KB_RALT, /* 0x40 */
- KB_RGUI, /* 0x80 */
-
- /* function keys */
- FN_0 = 0xF0,
- FN_1,
- FN_2,
- FN_3,
-};
-
-#endif /* USBKEYCODES_H */