*.lst | *.lst | ||||
*.map | *.map | ||||
*.sym | *.sym | ||||
tags |
# List C source files here. (C dependencies are automatically generated.) | # List C source files here. (C dependencies are automatically generated.) | ||||
SRC = $(TARGET).c \ | SRC = $(TARGET).c \ | ||||
keymap.c \ | |||||
matrix.c \ | |||||
usb_device.c \ | |||||
usb.c \ | |||||
usb_keyboard.c \ | usb_keyboard.c \ | ||||
usb_mouse.c \ | |||||
usb_debug.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 | # MCU name, you MUST set this to match the board you are using |
#define KEYMAP_H 1 | #define KEYMAP_H 1 | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include "usbkeycodes.h" | |||||
#include "usb_keycodes.h" | |||||
int get_layer(void); | int get_layer(void); | ||||
uint8_t get_keycode(int layer, int row, int col); | uint8_t get_keycode(int layer, int row, int col); |
#ifndef MATRIX_H | |||||
#define MATRIX_H 1 | |||||
#include <stdbool.h> | #include <stdbool.h> | ||||
extern uint8_t *matrix; | extern uint8_t *matrix; | ||||
bool matrix_is_modified(void); | bool matrix_is_modified(void); | ||||
bool matrix_has_ghost(void); | bool matrix_has_ghost(void); | ||||
bool matrix_has_ghost_in_row(uint8_t row); | bool matrix_has_ghost_in_row(uint8_t row); | ||||
#endif |
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||||
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "usb_device.h" | |||||
#include "usb.h" | |||||
#include "usb_keyboard.h" | |||||
#include "usb_mouse.h" | |||||
#include "print.h" | #include "print.h" | ||||
#include "matrix.h" | #include "matrix.h" | ||||
#include "keymap.h" | #include "keymap.h" | ||||
int main(void) | int main(void) | ||||
{ | { | ||||
bool modified = false; | |||||
bool has_ghost = false; | |||||
uint8_t key_index = 0; | |||||
// set for 16 MHz clock | // set for 16 MHz clock | ||||
CPU_PRESCALE(0); | CPU_PRESCALE(0); | ||||
matrix_init(); | |||||
// Initialize the USB, and then wait for the host to set configuration. | // 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, | // If the Teensy is powered without a PC connected to the USB port, | ||||
// this will wait forever. | // this will wait forever. | ||||
TCCR0B = 0x05; | TCCR0B = 0x05; | ||||
TIMSK0 = (1<<TOIE0); | TIMSK0 = (1<<TOIE0); | ||||
matrix_init(); | |||||
print("firmware 0.2 for t.m.k.\n"); | 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 loop_count = 0; | ||||
int layer = 0; | |||||
while (1) { | while (1) { | ||||
int layer = 0; | |||||
matrix_scan(); | matrix_scan(); | ||||
layer = get_layer(); | layer = get_layer(); | ||||
modified = matrix_is_modified(); | modified = matrix_is_modified(); | ||||
has_ghost = matrix_has_ghost(); | 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)) { | if (keyboard_modifier_keys == (MOD_LCTRL | MOD_LSHIFT | MOD_LALT | MOD_LGUI)) { | ||||
// cancel all keys | // cancel all keys | ||||
keyboard_modifier_keys = 0; | keyboard_modifier_keys = 0; | ||||
for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO; | for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO; | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
/* | |||||
print("jump to bootloader...\n"); | print("jump to bootloader...\n"); | ||||
_delay_ms(1000); | _delay_ms(1000); | ||||
jump_bootloader(); | 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++; | loop_count++; | ||||
_delay_ms(2); | |||||
} | } | ||||
} | } | ||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include "print.h" | #include "print.h" | ||||
void print_P(const char *s) | void print_P(const char *s) |
#ifndef print_h__ | |||||
#define print_h__ | |||||
#ifndef PRINT_H__ | |||||
#define PRINT_H__ 1 | |||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include "usb_debug.h" | #include "usb_debug.h" |
* THE SOFTWARE. | * THE SOFTWARE. | ||||
*/ | */ | ||||
#include <avr/io.h> | |||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||||
#include "usb_device.h" | |||||
#include "usb.h" | |||||
#include "usb_keyboard.h" | #include "usb_keyboard.h" | ||||
#include "usb_mouse.h" | |||||
#include "usb_debug.h" | #include "usb_debug.h" | ||||
#define ENDPOINT0_SIZE 32 | #define ENDPOINT0_SIZE 32 | ||||
// 0:control endpoint is enabled automatically by controller. | |||||
static const uint8_t PROGMEM endpoint_config_table[] = { | 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 | |||||
}; | }; | ||||
0xc0 // End Collection | 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[] = { | static uint8_t PROGMEM debug_hid_report_desc[] = { | ||||
0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) | 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) | ||||
0x09, 0x74, // Usage 0x74 | 0x09, 0x74, // Usage 0x74 | ||||
0xC0 // end collection | 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 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] = { | static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { | ||||
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 | // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 | ||||
9, // bLength; | 9, // bLength; | ||||
2, // bDescriptorType; | 2, // bDescriptorType; | ||||
LSB(CONFIG1_DESC_SIZE), // wTotalLength | LSB(CONFIG1_DESC_SIZE), // wTotalLength | ||||
MSB(CONFIG1_DESC_SIZE), | MSB(CONFIG1_DESC_SIZE), | ||||
2, // bNumInterfaces | |||||
3, // bNumInterfaces | |||||
1, // bConfigurationValue | 1, // bConfigurationValue | ||||
0, // iConfiguration | 0, // iConfiguration | ||||
0xC0, // bmAttributes | 0xC0, // bmAttributes | ||||
50, // bMaxPower | 50, // bMaxPower | ||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | ||||
9, // bLength | 9, // bLength | ||||
4, // bDescriptorType | 4, // bDescriptorType | ||||
0x01, // bInterfaceSubClass (0x01 = Boot) | 0x01, // bInterfaceSubClass (0x01 = Boot) | ||||
0x01, // bInterfaceProtocol (0x01 = Keyboard) | 0x01, // bInterfaceProtocol (0x01 = Keyboard) | ||||
0, // iInterface | 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 | 9, // bLength | ||||
0x21, // bDescriptorType | 0x21, // bDescriptorType | ||||
0x11, 0x01, // bcdHID | 0x11, 0x01, // bcdHID | ||||
0x03, // bmAttributes (0x03=intr) | 0x03, // bmAttributes (0x03=intr) | ||||
KEYBOARD_SIZE, 0, // wMaxPacketSize | KEYBOARD_SIZE, 0, // wMaxPacketSize | ||||
1, // bInterval | 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 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | ||||
9, // bLength | 9, // bLength | ||||
4, // bDescriptorType | 4, // bDescriptorType | ||||
0x00, // bInterfaceSubClass | 0x00, // bInterfaceSubClass | ||||
0x00, // bInterfaceProtocol | 0x00, // bInterfaceProtocol | ||||
0, // iInterface | 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 | 9, // bLength | ||||
0x21, // bDescriptorType | 0x21, // bDescriptorType | ||||
0x11, 0x01, // bcdHID | 0x11, 0x01, // bcdHID | ||||
{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, | {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, | ||||
{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, | {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, | ||||
// HID REPORT | // 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)}, | {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, | ||||
{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9}, | {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9}, | ||||
// STRING descriptor | // STRING descriptor | ||||
usb_configuration = wValue; | usb_configuration = wValue; | ||||
usb_send_in(); | usb_send_in(); | ||||
cfg = endpoint_config_table; | cfg = endpoint_config_table; | ||||
for (i=1; i<5; i++) { | |||||
for (i=1; i<=6; i++) { | |||||
UENUM = i; | UENUM = i; | ||||
en = pgm_read_byte(cfg++); | en = pgm_read_byte(cfg++); | ||||
UECONX = en; | UECONX = en; | ||||
UECFG1X = pgm_read_byte(cfg++); | UECFG1X = pgm_read_byte(cfg++); | ||||
} | } | ||||
} | } | ||||
UERST = 0x1E; | |||||
UERST = 0x7E; | |||||
UERST = 0; | UERST = 0; | ||||
return; | 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 (wIndex == DEBUG_INTERFACE) { | ||||
if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) { | if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) { | ||||
len = wLength; | len = wLength; |
#ifndef USB_DEVICE_H | |||||
#define USB_DEVICE_H 1 | |||||
#ifndef USB_H | |||||
#define USB_H 1 | |||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include "usb_keyboard.h" | |||||
#include "usb_debug.h" | |||||
void usb_init(void); // initialize everything | void usb_init(void); // initialize everything |
#define USB_DEBUG_H 1 | #define USB_DEBUG_H 1 | ||||
#include <stdint.h> | #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_SIZE 32 | ||||
#define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER | #define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER | ||||
#define USB_KEYBOARD_H 1 | #define USB_KEYBOARD_H 1 | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include "usb_device.h" | |||||
#include "usb.h" | |||||
#define KEYBOARD_INTERFACE 0 | #define KEYBOARD_INTERFACE 0 | ||||
#define KEYBOARD_ENDPOINT 3 | |||||
#define KEYBOARD_ENDPOINT 1 | |||||
#define KEYBOARD_SIZE 8 | #define KEYBOARD_SIZE 8 | ||||
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER | #define KEYBOARD_BUFFER EP_DOUBLE_BUFFER | ||||
/* 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. | * Keyboard Upgrade -- Firmware for homebrew computer keyboard controllers. | ||||
* MA 02110-1301 USA | * 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 { | enum keycodes { | ||||
KB_NO = 0, | KB_NO = 0, | ||||
KB_ROLL_OVER, | KB_ROLL_OVER, | ||||
KB_RALT, /* 0x40 */ | KB_RALT, /* 0x40 */ | ||||
KB_RGUI, /* 0x80 */ | KB_RGUI, /* 0x80 */ | ||||
/* function keys */ | |||||
/* extensions for internal use */ | |||||
FN_0 = 0xF0, | FN_0 = 0xF0, | ||||
FN_1, | FN_1, | ||||
FN_2, | FN_2, | ||||
FN_3, | FN_3, | ||||
}; | }; | ||||
#endif /* USBKEYCODES_H */ | |||||
#endif /* USB_KEYCODES_H */ |
#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; | |||||
} | |||||
#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 |