]> git.donarmstrong.com Git - tmk_firmware.git/commitdiff
add mouse function.
authortmk <nobody@nowhere>
Thu, 30 Sep 2010 05:17:01 +0000 (14:17 +0900)
committertmk <nobody@nowhere>
Thu, 30 Sep 2010 05:50:23 +0000 (14:50 +0900)
17 files changed:
.gitignore
Makefile
keymap.h
matrix.h
mykey.c
print.c
print.h
usb.c [new file with mode: 0644]
usb.h [new file with mode: 0644]
usb_debug.h
usb_device.c [deleted file]
usb_device.h [deleted file]
usb_keyboard.h
usb_keycodes.h [new file with mode: 0644]
usb_mouse.c [new file with mode: 0644]
usb_mouse.h [new file with mode: 0644]
usbkeycodes.h [deleted file]

index 293c4523908f07042e1436dc8e3c831060e79d5c..c25d41d2386b2d7b9977ca7321a15bed6aece68e 100644 (file)
@@ -7,3 +7,4 @@
 *.lst
 *.map
 *.sym
+tags
index c9c668d4157ec248ae1cd7c98b97e3f95432c71a..1fe3ffa2b10ac859da10260ce27b93838494f07d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -46,13 +46,14 @@ TARGET = mykey
 
 # 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
index ac0cc5fea66bd64bfd777f8f0e819fdc15c7491b..6b95fb61f6e8595610cda068122153d50951b426 100644 (file)
--- a/keymap.h
+++ b/keymap.h
@@ -2,7 +2,7 @@
 #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);
index d5290916b5bf5261787437e173a4d1848600fa9b..74b5f894b1173efc5e411409c4947fbbe604377b 100644 (file)
--- a/matrix.h
+++ b/matrix.h
@@ -1,3 +1,6 @@
+#ifndef MATRIX_H
+#define  MATRIX_H 1
+
 #include <stdbool.h>
 
 extern uint8_t *matrix;
@@ -8,3 +11,5 @@ uint8_t matrix_scan(void);
 bool matrix_is_modified(void);
 bool matrix_has_ghost(void);
 bool matrix_has_ghost_in_row(uint8_t row);
+
+#endif
diff --git a/mykey.c b/mykey.c
index 94cbbfb5a183fda226d1be862b3c71e3177597ec..a295b8c57d7b0a724baa65c4da1ef1bf26f590d1 100644 (file)
--- a/mykey.c
+++ b/mykey.c
@@ -30,7 +30,9 @@
 #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"
@@ -50,16 +52,9 @@ uint16_t idle_count=0;
 
 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.
@@ -78,99 +73,85 @@ int main(void)
     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);
     }
 }
 
diff --git a/print.c b/print.c
index 8e46decac4304f70a876fe018ce346faf129e312..5395fa3480227a3a7724fd7a1c901bce402ca168 100644 (file)
--- a/print.c
+++ b/print.c
@@ -25,7 +25,6 @@
 
 #include <avr/io.h>
 #include <avr/pgmspace.h>
-
 #include "print.h"
 
 void print_P(const char *s)
diff --git a/print.h b/print.h
index 9a42462754b05f6cbdf75dabeef74e9e4ee91312..d61e5de3e096101975f126ff8863925e80bee1a9 100644 (file)
--- a/print.h
+++ b/print.h
@@ -1,5 +1,5 @@
-#ifndef print_h__
-#define print_h__
+#ifndef PRINT_H__
+#define PRINT_H__ 1
 
 #include <avr/pgmspace.h>
 #include "usb_debug.h"
diff --git a/usb.c b/usb.c
new file mode 100644 (file)
index 0000000..c910a97
--- /dev/null
+++ b/usb.c
@@ -0,0 +1,693 @@
+/* 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
+}
+
+
diff --git a/usb.h b/usb.h
new file mode 100644 (file)
index 0000000..c1347f1
--- /dev/null
+++ b/usb.h
@@ -0,0 +1,79 @@
+#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
index acc6716cdebcfc072d05537b56a3e3c9278125a3..65ad05b04a2bc8f1b658b4b6f585d6afe5418d6b 100644 (file)
@@ -2,11 +2,11 @@
 #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
 
diff --git a/usb_device.c b/usb_device.c
deleted file mode 100644 (file)
index 1d790f0..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-/* 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
-}
-
-
diff --git a/usb_device.h b/usb_device.h
deleted file mode 100644 (file)
index 233e439..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#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
index cd8ec4a9d19b41753784402d6f3db1aaed15e9c9..90c2c5af62ca3f83a6b7fa889e1fd8bc64e30c54 100644 (file)
@@ -2,11 +2,11 @@
 #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
 
diff --git a/usb_keycodes.h b/usb_keycodes.h
new file mode 100644 (file)
index 0000000..9516039
--- /dev/null
@@ -0,0 +1,271 @@
+/* 
+ * 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 */
diff --git a/usb_mouse.c b/usb_mouse.c
new file mode 100644 (file)
index 0000000..539f2ed
--- /dev/null
@@ -0,0 +1,62 @@
+#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;
+}
+
diff --git a/usb_mouse.h b/usb_mouse.h
new file mode 100644 (file)
index 0000000..f1f3977
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/usbkeycodes.h b/usbkeycodes.h
deleted file mode 100644 (file)
index b0e7058..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/* 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 */