summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile11
-rw-r--r--keymap.h2
-rw-r--r--matrix.h5
-rw-r--r--mykey.c127
-rw-r--r--print.c1
-rw-r--r--print.h4
-rw-r--r--usb.c (renamed from usb_device.c)119
-rw-r--r--usb.h (renamed from usb_device.h)6
-rw-r--r--usb_debug.h6
-rw-r--r--usb_keyboard.h4
-rw-r--r--usb_keycodes.h (renamed from usbkeycodes.h)24
-rw-r--r--usb_mouse.c62
-rw-r--r--usb_mouse.h20
14 files changed, 275 insertions, 117 deletions
diff --git a/.gitignore b/.gitignore
index 293c452390..c25d41d238 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
*.lst
*.map
*.sym
+tags
diff --git a/Makefile b/Makefile
index c9c668d415..1fe3ffa2b1 100644
--- 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
diff --git a/keymap.h b/keymap.h
index ac0cc5fea6..6b95fb61f6 100644
--- 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);
diff --git a/matrix.h b/matrix.h
index d5290916b5..74b5f894b1 100644
--- 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 94cbbfb5a1..a295b8c57d 100644
--- 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 8e46decac4..5395fa3480 100644
--- 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 9a42462754..d61e5de3e0 100644
--- 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_device.c b/usb.c
index 1d790f043c..c910a977ed 100644
--- a/usb_device.c
+++ b/usb.c
@@ -21,10 +21,12 @@
* THE SOFTWARE.
*/
+#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
-#include "usb_device.h"
+#include "usb.h"
#include "usb_keyboard.h"
+#include "usb_mouse.h"
#include "usb_debug.h"
@@ -64,11 +66,15 @@
#define ENDPOINT0_SIZE 32
+// 0:control endpoint is enabled automatically by controller.
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
+ // 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
};
@@ -138,6 +144,36 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = {
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
@@ -151,20 +187,22 @@ static uint8_t PROGMEM debug_hid_report_desc[] = {
0xC0 // end collection
};
-#define CONFIG1_DESC_SIZE (9+9+9+7+9+9+7)
+#define CONFIG1_DESC_SIZE (9+(9+9+7)+(9+9+7)+(9+9+7))
#define KEYBOARD_HID_DESC_OFFSET (9+9)
-#define DEBUG_HID_DESC_OFFSET (9+9+9+7+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),
- 2, // bNumInterfaces
+ 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
@@ -175,7 +213,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
0x01, // bInterfaceSubClass (0x01 = Boot)
0x01, // bInterfaceProtocol (0x01 = Keyboard)
0, // iInterface
- // HID interface descriptor, HID 1.11 spec, section 6.2.1
+ // HID descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
@@ -191,6 +229,34 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
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
@@ -201,7 +267,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
0x00, // bInterfaceSubClass
0x00, // bInterfaceProtocol
0, // iInterface
- // HID interface descriptor, HID 1.11 spec, section 6.2.1
+ // HID descriptor, HID 1.11 spec, section 6.2.1
9, // bLength
0x21, // bDescriptorType
0x11, 0x01, // bcdHID
@@ -259,6 +325,9 @@ static struct descriptor_list_struct {
{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
@@ -470,7 +539,7 @@ ISR(USB_COM_vect)
usb_configuration = wValue;
usb_send_in();
cfg = endpoint_config_table;
- for (i=1; i<5; i++) {
+ for (i=1; i<=6; i++) {
UENUM = i;
en = pgm_read_byte(cfg++);
UECONX = en;
@@ -479,7 +548,7 @@ ISR(USB_COM_vect)
UECFG1X = pgm_read_byte(cfg++);
}
}
- UERST = 0x1E;
+ UERST = 0x7E;
UERST = 0;
return;
}
@@ -571,6 +640,32 @@ ISR(USB_COM_vect)
}
}
}
+ 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;
diff --git a/usb_device.h b/usb.h
index 233e439f4e..c1347f10dd 100644
--- a/usb_device.h
+++ b/usb.h
@@ -1,10 +1,8 @@
-#ifndef USB_DEVICE_H
-#define USB_DEVICE_H 1
+#ifndef USB_H
+#define USB_H 1
#include <stdint.h>
#include <avr/io.h>
-#include "usb_keyboard.h"
-#include "usb_debug.h"
void usb_init(void); // initialize everything
diff --git a/usb_debug.h b/usb_debug.h
index acc6716cde..65ad05b04a 100644
--- a/usb_debug.h
+++ b/usb_debug.h
@@ -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_keyboard.h b/usb_keyboard.h
index cd8ec4a9d1..90c2c5af62 100644
--- a/usb_keyboard.h
+++ b/usb_keyboard.h
@@ -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/usbkeycodes.h b/usb_keycodes.h
index b0e7058363..95160398d8 100644
--- a/usbkeycodes.h
+++ b/usb_keycodes.h
@@ -1,5 +1,8 @@
-/* Some modified from Keyboard Upgrade 0.3.0
- * 2010/08/22
+/*
+ * 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.
@@ -30,17 +33,10 @@
* MA 02110-1301 USA
*/
-#ifndef USBKEYCODES_H
-#define USBKEYCODES_H
+#ifndef USB_KEYCODES_H
+#define USB_KEYCODES_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,
@@ -265,11 +261,11 @@ enum keycodes {
KB_RALT, /* 0x40 */
KB_RGUI, /* 0x80 */
- /* function keys */
+ /* extensions for internal use */
FN_0 = 0xF0,
FN_1,
FN_2,
FN_3,
};
-#endif /* USBKEYCODES_H */
+#endif /* USB_KEYCODES_H */
diff --git a/usb_mouse.c b/usb_mouse.c
new file mode 100644
index 0000000000..539f2edd37
--- /dev/null
+++ b/usb_mouse.c
@@ -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
index 0000000000..f1f39776f7
--- /dev/null
+++ b/usb_mouse.h
@@ -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