Browse Source

Port new (windows compatible) media keys to Teensy 2.0

main
PaulStoffregen 8 years ago
parent
commit
12c5d4972d
8 changed files with 901 additions and 407 deletions
  1. +1
    -1
      teensy/keylayouts.c
  2. +572
    -202
      teensy/keylayouts.h
  3. +100
    -45
      usb_hid/usb.c
  4. +156
    -49
      usb_hid/usb_api.cpp
  5. +13
    -12
      usb_hid/usb_api.h
  6. +17
    -51
      usb_hid/usb_private.h
  7. +40
    -46
      usb_serial_hid/usb_api.cpp
  8. +2
    -1
      usb_serial_hid/usb_api.h

+ 1
- 1
teensy/keylayouts.c View File

@@ -6,7 +6,7 @@
#ifdef M
#undef M
#endif
#define M(n) ((n) & 0x3FFF)
#define M(n) ((n) & KEYCODE_MASK)

const KEYCODE_TYPE PROGMEM keycodes_ascii[] = {
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23),

+ 572
- 202
teensy/keylayouts.h
File diff suppressed because it is too large
View File


+ 100
- 45
usb_hid/usb.c View File

@@ -35,14 +35,12 @@


static const uint8_t PROGMEM endpoint_config_table[] = {
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER,
1, EP_TYPE_INTERRUPT_OUT, EP_SIZE(DEBUG_RX_SIZE) | DEBUG_RX_BUFFER,
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER,
#ifdef JOYSTICK_INTERFACE
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(JOYSTICK_SIZE) | JOYSTICK_BUFFER,
0
#endif
EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER,
EP_TYPE_INTERRUPT_OUT, EP_SIZE(DEBUG_RX_SIZE) | DEBUG_RX_BUFFER,
EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER,
EP_TYPE_INTERRUPT_IN, EP_SIZE(JOYSTICK_SIZE) | JOYSTICK_BUFFER,
EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYMEDIA_SIZE) | KEYMEDIA_BUFFER,
};


@@ -88,20 +86,9 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum (1),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
0x95, 0x08, // Report Count (8),
0x75, 0x01, // Report Size (1),
0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum (1),
0x05, 0x0C, // Usage Page (Consumer),
0x09, 0xE9, // Usage (Volume Increment),
0x09, 0xEA, // Usage (Volume Decrement),
0x09, 0xE2, // Usage (Mute),
0x09, 0xCD, // Usage (Play/Pause),
0x09, 0xB5, // Usage (Scan Next Track),
0x09, 0xB6, // Usage (Scan Previous Track),
0x09, 0xB7, // Usage (Stop),
0x09, 0xB8, // Usage (Eject),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys
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),
@@ -122,6 +109,28 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
0xc0 // End Collection
};

static const uint8_t PROGMEM keymedia_hid_report_desc[] = {
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Controls)
0xA1, 0x01, // Collection (Application)
0x75, 0x0A, // Report Size (10)
0x95, 0x04, // Report Count (4)
0x19, 0x00, // Usage Minimum (0)
0x2A, 0x9C, 0x02, // Usage Maximum (0x29C)
0x15, 0x00, // Logical Minimum (0)
0x26, 0x9C, 0x02, // Logical Maximum (0x29C)
0x81, 0x00, // Input (Data, Array)
0x05, 0x01, // Usage Page (Generic Desktop)
0x75, 0x08, // Report Size (8)
0x95, 0x03, // Report Count (3)
0x19, 0x00, // Usage Minimum (0)
0x29, 0xB7, // Usage Maximum (0xB7)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xB7, 0x00, // Logical Maximum (0xB7)
0x81, 0x00, // Input (Data, Array)
0xC0 // End Collection
};

// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
static const uint8_t PROGMEM mouse_hid_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop)
@@ -229,12 +238,9 @@ static const uint8_t PROGMEM debug_hid_report_desc[] = {
#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 )
#ifdef JOYSTICK_INTERFACE
#define JOYSTICK_HID_DESC_OFFSET ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9 )
#define CONFIG1_DESC_SIZE ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9+9+7)
#else
#define CONFIG1_DESC_SIZE ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 )
#endif
#define KEYMEDIA_HID_DESC_OFFSET ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9+9+7 + 9 )
#define CONFIG1_DESC_SIZE ( 9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9+9+7 + 9+9+7 )

static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
@@ -336,7 +342,6 @@ static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
DEBUG_RX_SIZE, 0, // wMaxPacketSize
DEBUG_RX_INTERVAL, // bInterval

#ifdef JOYSTICK_INTERFACE
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
@@ -363,7 +368,33 @@ static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
0x03, // bmAttributes (0x03=intr)
12, 0, // wMaxPacketSize
JOYSTICK_INTERVAL, // bInterval
#endif

// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
KEYMEDIA_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
LSB(sizeof(keymedia_hid_report_desc)), // wDescriptorLength
MSB(sizeof(keymedia_hid_report_desc)),
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
KEYMEDIA_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
KEYMEDIA_SIZE, 0, // wMaxPacketSize
KEYMEDIA_INTERVAL, // bInterval
};

// If you're desperate for a little extra code memory, these strings
@@ -401,10 +432,10 @@ static const struct descriptor_list_struct {
{0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
#ifdef JOYSTICK_INTERFACE
{0x2200, JOYSTICK_INTERFACE, joystick_hid_report_desc, sizeof(joystick_hid_report_desc)},
{0x2100, JOYSTICK_INTERFACE, config1_descriptor+JOYSTICK_HID_DESC_OFFSET, 9},
#endif
{0x2200, KEYMEDIA_INTERFACE, keymedia_hid_report_desc, sizeof(keymedia_hid_report_desc)},
{0x2100, KEYMEDIA_INTERFACE, config1_descriptor+KEYMEDIA_HID_DESC_OFFSET, 9},
{0x0300, 0x0000, (const uint8_t *)&string0, 4},
{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_PRODUCT)},
};
@@ -456,9 +487,13 @@ uint8_t mouse_buttons USBSTATE;
static uint8_t mouse_protocol USBSTATE;

// joystick data
#ifdef JOYSTICK_INTERFACE
uint8_t joystick_report_data[12] USBSTATE;
#endif

// keyboard media keys data
uint8_t keymedia_report_data[8] USBSTATE;
uint16_t keymedia_consumer_keys[4] USBSTATE;
uint8_t keymedia_system_keys[3] USBSTATE;



/**************************************************************************
@@ -499,7 +534,6 @@ void usb_init(void)
keyboard_leds = 0;
mouse_buttons = 0;
mouse_protocol = 1;
#ifdef JOYSTICK_INTERFACE
joystick_report_data[0] = 0;
joystick_report_data[1] = 0;
joystick_report_data[2] = 0;
@@ -512,7 +546,21 @@ void usb_init(void)
joystick_report_data[9] = 0x08;
joystick_report_data[10] = 0x20;
joystick_report_data[11] = 0x80;
#endif
keymedia_report_data[0] = 0;
keymedia_report_data[1] = 0;
keymedia_report_data[2] = 0;
keymedia_report_data[3] = 0;
keymedia_report_data[4] = 0;
keymedia_report_data[5] = 0;
keymedia_report_data[6] = 0;
keymedia_report_data[7] = 0;
keymedia_consumer_keys[0] = 0;
keymedia_consumer_keys[1] = 0;
keymedia_consumer_keys[2] = 0;
keymedia_consumer_keys[3] = 0;
keymedia_system_keys[0] = 0;
keymedia_system_keys[1] = 0;
keymedia_system_keys[2] = 0;
UDINT = 0;
UDIEN = (1<<EORSTE)|(1<<SOFE);
//sei(); // init() in wiring.c does this
@@ -644,7 +692,7 @@ ISR(USB_COM_vect)
uint8_t intbits;
const uint8_t *list;
const uint8_t *cfg;
uint8_t i, n, len, en;
uint8_t i, n, len;
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
@@ -714,14 +762,11 @@ ISR(USB_COM_vect)
debug_flush_timer = 0;
usb_send_in();
cfg = endpoint_config_table;
for (i=1; i<NUM_ENDPOINTS; i++) {
for (i=1; i<7; i++) {
UENUM = i;
pgm_read_byte_postinc(en, cfg);
UECONX = en;
if (en) {
pgm_read_byte_postinc(UECFG0X, cfg);
pgm_read_byte_postinc(UECFG1X, cfg);
}
UECONX = 1;
pgm_read_byte_postinc(UECFG0X, cfg);
pgm_read_byte_postinc(UECFG1X, cfg);
}
UERST = 0x1E;
UERST = 0;
@@ -835,7 +880,6 @@ ISR(USB_COM_vect)
}
}
}
#ifdef JOYSTICK_INTERFACE
if (wIndex == JOYSTICK_INTERFACE) {
if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) {
@@ -848,7 +892,18 @@ ISR(USB_COM_vect)
}
}
}
#endif
if (wIndex == KEYMEDIA_INTERFACE) {
if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) {
usb_wait_in_ready();
for (i=0; i<8; i++) {
UEDATX = keymedia_report_data[i];
}
usb_send_in();
return;
}
}
}
if (wIndex == DEBUG_INTERFACE) {
if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
len = wLength;

+ 156
- 49
usb_hid/usb_api.cpp View File

@@ -33,11 +33,7 @@

// Step #1, decode UTF8 to Unicode code points
//
#if ARDUINO >= 100
size_t usb_keyboard_class::write(uint8_t c)
#else
void usb_keyboard_class::write(uint8_t c)
#endif
{
if (c < 0x80) {
// single byte encoded, 0x00 to 0x7F
@@ -67,9 +63,7 @@ void usb_keyboard_class::write(uint8_t c)
// or illegal, 0xF5 to 0xFF
utf8_state = 255;
}
#if ARDUINO >= 100
return 1;
#endif
}


@@ -80,7 +74,8 @@ KEYCODE_TYPE usb_keyboard_class::unicode_to_keycode(uint16_t cpoint)
// Unicode code points beyond U+FFFF are not supported
// technically this input should probably be called UCS-2
if (cpoint < 32) {
if (cpoint == 10) return KEY_ENTER & 0x3FFF;
if (cpoint == 10) return KEY_ENTER & KEYCODE_MASK;
if (cpoint == 11) return KEY_TAB & KEYCODE_MASK;
return 0;
}
if (cpoint < 128) {
@@ -253,10 +248,6 @@ void usb_keyboard_class::set_key6(uint8_t c)
{
keyboard_report_data[7] = c;
}
void usb_keyboard_class::set_media(uint8_t c)
{
keyboard_report_data[1] = c;
}


void usb_keyboard_class::send_now(void)
@@ -300,20 +291,28 @@ void usb_keyboard_class::press(uint16_t n)
uint8_t key, mod, msb, modrestore=0;

msb = n >> 8;
if (msb >= 0xC2 && msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else
if (msb == 0x80) {
presskey(0, n);
return;
} else
if (msb == 0x40) {
presskey(n, 0);
return;
if (msb >= 0xC2) {
if (msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else if (msb == 0xF0) {
presskey(n, 0);
return;
} else if (msb == 0xE0) {
presskey(0, n);
return;
} else if (msb == 0xE2) {
press_system_key(n);
return;
} else if (msb >= 0xE4 && msb <= 0xE7) {
press_consumer_key(n & 0x3FF);
return;
} else {
return;
}
}
KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return;
#ifdef DEADKEYS_MASK
#ifdef DEADKEYS_MASK
KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
if (deadkeycode) {
modrestore = keyboard_report_data[0];
@@ -328,7 +327,7 @@ void usb_keyboard_class::press(uint16_t n)
presskey(key, mod);
releasekey(key, mod);
}
#endif
#endif
mod = keycode_to_modifier(keycode);
key = keycode_to_key(keycode);
presskey(key, mod | modrestore);
@@ -339,16 +338,24 @@ void usb_keyboard_class::release(uint16_t n)
uint8_t key, mod, msb;

msb = n >> 8;
if (msb >= 0xC2 && msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else
if (msb == 0x80) {
releasekey(0, n);
return;
} else
if (msb == 0x40) {
releasekey(n, 0);
return;
if (msb >= 0xC2) {
if (msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else if (msb == 0xF0) {
releasekey(n, 0);
return;
} else if (msb == 0xE0) {
releasekey(0, n);
return;
} else if (msb == 0xE2) {
release_system_key(n);
return;
} else if (msb >= 0xE4 && msb <= 0xE7) {
release_consumer_key(n & 0x3FF);
return;
} else {
return;
}
}
KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return;
@@ -420,6 +427,122 @@ void usb_keyboard_class::releaseAll(void)
send_now();
}

void usb_keyboard_class::press_consumer_key(uint16_t key)
{
if (key == 0) return;
for (uint8_t i=0; i < 4; i++) {
if (keymedia_consumer_keys[i] == key) return;
}
for (uint8_t i=0; i < 4; i++) {
if (keymedia_consumer_keys[i] == 0) {
keymedia_consumer_keys[i] = key;
keymedia_send();
return;
}
}
}

void usb_keyboard_class::release_consumer_key(uint16_t key)
{
if (key == 0) return;
for (uint8_t i=0; i < 4; i++) {
if (keymedia_consumer_keys[i] == key) {
keymedia_consumer_keys[i] = 0;
keymedia_send();
return;
}
}
}

void usb_keyboard_class::press_system_key(uint8_t key)
{
if (key == 0) return;
for (uint8_t i=0; i < 3; i++) {
if (keymedia_system_keys[i] == key) return;
}
for (uint8_t i=0; i < 3; i++) {
if (keymedia_system_keys[i] == 0) {
keymedia_system_keys[i] = key;
keymedia_send();
return;
}
}
}

void usb_keyboard_class::release_system_key(uint8_t key)
{
if (key == 0) return;
for (uint8_t i=0; i < 3; i++) {
if (keymedia_system_keys[i] == key) {
keymedia_system_keys[i] = 0;
keymedia_send();
return;
}
}
}

void usb_keyboard_class::keymedia_release_all(void)
{
uint8_t anybits = 0;
for (uint8_t i=0; i < 4; i++) {
if (keymedia_consumer_keys[i] != 0) anybits = 1;
keymedia_consumer_keys[i] = 0;
}
for (uint8_t i=0; i < 3; i++) {
if (keymedia_system_keys[i] != 0) anybits = 1;
keymedia_system_keys[i] = 0;
}
if (anybits) keymedia_send();
}

// send the contents of keyboard_keys and keyboard_modifier_keys
void usb_keyboard_class::keymedia_send(void)
{
uint8_t intr_state, timeout;

if (!usb_configuration) return;
intr_state = SREG;
cli();
UENUM = KEYMEDIA_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_configuration) return;
// have we waited too long?
if (UDFNUML == timeout) return;
// get ready to try checking again
intr_state = SREG;
cli();
UENUM = KEYMEDIA_ENDPOINT;
}
// 44444444 44333333 33332222 22222211 11111111
// 98765432 10987654 32109876 54321098 76543210
UEDATX = keymedia_consumer_keys[0];
UEDATX = (keymedia_consumer_keys[1] << 2) | ((keymedia_consumer_keys[0] >> 8) & 0x03);
UEDATX = (keymedia_consumer_keys[2] << 4) | ((keymedia_consumer_keys[1] >> 6) & 0x0F);
UEDATX = (keymedia_consumer_keys[3] << 6) | ((keymedia_consumer_keys[2] >> 4) & 0x3F);
UEDATX = keymedia_consumer_keys[3] >> 2;
UEDATX = keymedia_system_keys[0];
UEDATX = keymedia_system_keys[1];
UEDATX = keymedia_system_keys[2];
UEINTX = 0x3A;
SREG = intr_state;
}














void usb_mouse_class::move(int8_t x, int8_t y, int8_t wheel)
@@ -499,9 +622,6 @@ bool usb_mouse_class::isPressed(uint8_t b)
}



#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)

void usb_joystick_class::send_now(void)
{
uint8_t intr_state, timeout;
@@ -540,7 +660,6 @@ void usb_joystick_class::send_now(void)
SREG = intr_state;
}

#endif



@@ -679,11 +798,7 @@ void usb_serial_class::flush()
}

// transmit a character.
#if ARDUINO >= 100
size_t usb_serial_class::write(uint8_t c)
#else
void usb_serial_class::write(uint8_t c)
#endif
{
//static uint8_t previous_timeout=0;
uint8_t timeout, intr_state;
@@ -736,16 +851,10 @@ void usb_serial_class::write(uint8_t c)
debug_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
}
SREG = intr_state;
#if ARDUINO >= 100
return 1;
#endif
error:
#if ARDUINO >= 100
setWriteError();
return 0;
#else
return;
#endif
}


@@ -814,7 +923,5 @@ usb_serial_class::operator bool()
usb_serial_class Serial = usb_serial_class();
usb_keyboard_class Keyboard = usb_keyboard_class();
usb_mouse_class Mouse = usb_mouse_class();
#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
usb_joystick_class Joystick = usb_joystick_class();
#endif


+ 13
- 12
usb_hid/usb_api.h View File

@@ -12,11 +12,7 @@ class usb_keyboard_class : public Print
public:
void begin(void) { }
void end(void) { }
#if ARDUINO >= 100
virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
using Print::write;
void write_unicode(uint16_t unicode) { write_keycode(unicode_to_keycode(unicode)); }
void set_modifier(uint8_t);
@@ -26,7 +22,13 @@ class usb_keyboard_class : public Print
void set_key4(uint8_t);
void set_key5(uint8_t);
void set_key6(uint8_t);
void set_media(uint8_t);
void set_media(uint16_t c) {
if (c == 0) {
keymedia_release_all();
} else if (c >= 0xE400 && c <= 0xE7FF) {
press(c);
}
}
void send_now(void);
void press(uint16_t n);
void release(uint16_t n);
@@ -40,6 +42,12 @@ class usb_keyboard_class : public Print
void releasekey(uint8_t key, uint8_t modifier);
void write_keycode(KEYCODE_TYPE key);
void write_key(KEYCODE_TYPE code);
void press_consumer_key(uint16_t key);
void release_consumer_key(uint16_t key);
void press_system_key(uint8_t key);
void release_system_key(uint8_t key);
void keymedia_release_all(void);
void keymedia_send(void);
uint8_t utf8_state;
uint16_t unicode_wchar;
};
@@ -70,8 +78,6 @@ extern usb_mouse_class Mouse;



#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)

extern uint8_t joystick_report_data[12];

class usb_joystick_class
@@ -171,7 +177,6 @@ class usb_joystick_class

extern usb_joystick_class Joystick;

#endif



@@ -185,11 +190,7 @@ class usb_serial_class : public Stream
virtual int read();
virtual int peek();
virtual void flush();
#if ARDUINO >= 100
virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
using Print::write;
operator bool();
// Teensy extensions

+ 17
- 51
usb_hid/usb_private.h View File

@@ -25,21 +25,13 @@ extern "C"{
*
**************************************************************************/

// These buffer sizes are best for most applications, but perhaps if you
// want more buffering on some endpoint at the expense of others, this
// is where you can make such changes. The AT90USB162 has only 176 bytes
// of DPRAM (USB buffers) and only endpoints 3 & 4 can double buffer.


// 0: control 32 64
// 1: debug IN 64 64x2
// 2: debug OUT 32 32x2
// 3: keyboard IN 8x2 8x2
// 4: mouse + joystick IN (IDs) 16x2 16x2
// 5: joystick 16x2
// 6:

#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
// 0: control 64
// 1: debug IN 64x2
// 2: debug OUT 32x2
// 3: keyboard IN 8x2
// 4: mouse IN 16x2
// 5: joystick IN 16x2
// 6: keyboard media IN 8x2

// Some operating systems, especially Windows, may cache USB device
// info. Changes to the device name may not update on the same
@@ -77,41 +69,14 @@ extern "C"{
#define JOYSTICK_BUFFER EP_DOUBLE_BUFFER
#define JOYSTICK_INTERVAL 2

#define NUM_ENDPOINTS 7
#define NUM_INTERFACE 4

#elif defined(__AVR_AT90USB162__)

#define STR_PRODUCT L"Teensy Keyboard/Mouse"
#define ENDPOINT0_SIZE 32

#define DEBUG_INTERFACE 2
#define DEBUG_TX_ENDPOINT 1
#define DEBUG_TX_SIZE 64
#define DEBUG_TX_BUFFER EP_SINGLE_BUFFER
#define DEBUG_TX_INTERVAL 2
#define DEBUG_RX_ENDPOINT 2
#define DEBUG_RX_SIZE 32
#define DEBUG_RX_BUFFER EP_SINGLE_BUFFER
#define DEBUG_RX_INTERVAL 8

#define KEYBOARD_INTERFACE 0
#define KEYBOARD_ENDPOINT 3
#define KEYBOARD_SIZE 8
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER
#define KEYBOARD_INTERVAL 1

#define MOUSE_INTERFACE 1
#define MOUSE_ENDPOINT 4
#define MOUSE_SIZE 8
#define MOUSE_BUFFER EP_DOUBLE_BUFFER
#define MOUSE_INTERVAL 8

#define NUM_ENDPOINTS 5
#define NUM_INTERFACE 3

#endif
#define KEYMEDIA_INTERFACE 4
#define KEYMEDIA_ENDPOINT 6
#define KEYMEDIA_SIZE 8
#define KEYMEDIA_BUFFER EP_DOUBLE_BUFFER
#define KEYMEDIA_INTERVAL 4

#define NUM_ENDPOINTS 7
#define NUM_INTERFACE 5


// setup
@@ -126,9 +91,10 @@ extern uint8_t keyboard_report_data[];
extern uint8_t keyboard_idle_count;
extern volatile uint8_t keyboard_leds;
extern uint8_t mouse_buttons;
#ifdef JOYSTICK_INTERFACE
extern uint8_t joystick_report_data[12];
#endif
extern uint8_t keymedia_report_data[8];
extern uint16_t keymedia_consumer_keys[4];
extern uint8_t keymedia_system_keys[3];




+ 40
- 46
usb_serial_hid/usb_api.cpp View File

@@ -199,17 +199,10 @@ void usb_serial_class::write(uint8_t c)


// transmit a block of data
#if ARDUINO >= 100
size_t usb_serial_class::write(const uint8_t *buffer, uint16_t size)
#else
#define setWriteError()
void usb_serial_class::write(const uint8_t *buffer, uint16_t size)
#endif
{
uint8_t timeout, intr_state, write_size;
#if ARDUINO >= 100
size_t count=0;
#endif

// if we're not online (enumerated and configured), error
if (!usb_configuration) {
@@ -261,9 +254,7 @@ void usb_serial_class::write(const uint8_t *buffer, uint16_t size)
write_size = CDC_TX_SIZE - UEBCLX;
if (write_size > size) write_size = size;
size -= write_size;
#if ARDUINO >= 100
count += write_size;
#endif

#define ASM_COPY1(src, dest, tmp) "ld " tmp ", " src "\n\t" "st " dest ", " tmp "\n\t"
#define ASM_COPY2(src, dest, tmp) ASM_COPY1(src, dest, tmp) ASM_COPY1(src, dest, tmp)
@@ -315,11 +306,7 @@ void usb_serial_class::write(const uint8_t *buffer, uint16_t size)
}
SREG = intr_state;
end:
#if ARDUINO >= 100
return count;
#else
return;
#endif
}

// transmit a string
@@ -398,11 +385,7 @@ usb_serial_class::operator bool()

// Step #1, decode UTF8 to Unicode code points
//
#if ARDUINO >= 100
size_t usb_keyboard_class::write(uint8_t c)
#else
void usb_keyboard_class::write(uint8_t c)
#endif
{
if (c < 0x80) {
// single byte encoded, 0x00 to 0x7F
@@ -432,9 +415,7 @@ void usb_keyboard_class::write(uint8_t c)
// or illegal, 0xF5 to 0xFF
utf8_state = 255;
}
#if ARDUINO >= 100
return 1;
#endif
}


@@ -445,7 +426,8 @@ KEYCODE_TYPE usb_keyboard_class::unicode_to_keycode(uint16_t cpoint)
// Unicode code points beyond U+FFFF are not supported
// technically this input should probably be called UCS-2
if (cpoint < 32) {
if (cpoint == 10) return KEY_ENTER & 0x3FFF;
if (cpoint == 10) return KEY_ENTER & KEYCODE_MASK;
if (cpoint == 11) return KEY_TAB & KEYCODE_MASK;
return 0;
}
if (cpoint < 128) {
@@ -618,10 +600,6 @@ void usb_keyboard_class::set_key6(uint8_t c)
{
keyboard_report_data[7] = c;
}
void usb_keyboard_class::set_media(uint8_t c)
{
keyboard_report_data[1] = c;
}


void usb_keyboard_class::send_now(void)
@@ -665,17 +643,25 @@ void usb_keyboard_class::press(uint16_t n)
uint8_t key, mod, msb, modrestore=0;

msb = n >> 8;
if (msb >= 0xC2 && msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else
if (msb == 0x80) {
presskey(0, n);
return;
} else
if (msb == 0x40) {
presskey(n, 0);
return;
}
if (msb >= 0xC2) {
if (msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else if (msb == 0xF0) {
presskey(n, 0);
return;
} else if (msb == 0xE0) {
presskey(0, n);
return;
} else if (msb == 0xE2) {
//press_system_key(n);
return;
} else if (msb >= 0xE4 && msb <= 0xE7) {
//press_consumer_key(n & 0x3FF);
return;
} else {
return;
}
}
KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return;
#ifdef DEADKEYS_MASK
@@ -704,17 +690,25 @@ void usb_keyboard_class::release(uint16_t n)
uint8_t key, mod, msb;

msb = n >> 8;
if (msb >= 0xC2 && msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else
if (msb == 0x80) {
releasekey(0, n);
return;
} else
if (msb == 0x40) {
releasekey(n, 0);
return;
}
if (msb >= 0xC2) {
if (msb <= 0xDF) {
n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
} else if (msb == 0xF0) {
releasekey(n, 0);
return;
} else if (msb == 0xE0) {
releasekey(0, n);
return;
} else if (msb == 0xE2) {
//release_system_key(n);
return;
} else if (msb >= 0xE4 && msb <= 0xE7) {
//release_consumer_key(n & 0x3FF);
return;
} else {
return;
}
}
KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return;
mod = keycode_to_modifier(keycode);

+ 2
- 1
usb_serial_hid/usb_api.h View File

@@ -61,7 +61,8 @@ class usb_keyboard_class : public Print
void set_key4(uint8_t);
void set_key5(uint8_t);
void set_key6(uint8_t);
void set_media(uint8_t);
void set_media(uint8_t) {
}
void send_now(void);
void press(uint16_t n);
void release(uint16_t n);

Loading…
Cancel
Save