Browse Source

Port new (windows compatible) media keys to Teensy 2.0

teensy4-core
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

#ifdef M #ifdef M
#undef M #undef M
#endif #endif
#define M(n) ((n) & 0x3FFF)
#define M(n) ((n) & KEYCODE_MASK)


const KEYCODE_TYPE PROGMEM keycodes_ascii[] = { const KEYCODE_TYPE PROGMEM keycodes_ascii[] = {
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23), 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





static const uint8_t PROGMEM endpoint_config_table[] = { 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,
}; };




0x15, 0x00, // Logical Minimum (0), 0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum (1), 0x25, 0x01, // Logical Maximum (1),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte 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), 0x95, 0x05, // Report Count (5),
0x75, 0x01, // Report Size (1), 0x75, 0x01, // Report Size (1),
0x05, 0x08, // Usage Page (LEDs), 0x05, 0x08, // Usage Page (LEDs),
0xc0 // End Collection 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 // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
static const uint8_t PROGMEM mouse_hid_report_desc[] = { static const uint8_t PROGMEM mouse_hid_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop) 0x05, 0x01, // Usage Page (Generic Desktop)
#define KEYBOARD_HID_DESC_OFFSET ( 9 + 9 ) #define KEYBOARD_HID_DESC_OFFSET ( 9 + 9 )
#define MOUSE_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 ) #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 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] = { static const 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
DEBUG_RX_SIZE, 0, // wMaxPacketSize DEBUG_RX_SIZE, 0, // wMaxPacketSize
DEBUG_RX_INTERVAL, // bInterval DEBUG_RX_INTERVAL, // bInterval


#ifdef JOYSTICK_INTERFACE
// 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
0x03, // bmAttributes (0x03=intr) 0x03, // bmAttributes (0x03=intr)
12, 0, // wMaxPacketSize 12, 0, // wMaxPacketSize
JOYSTICK_INTERVAL, // bInterval 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 // If you're desperate for a little extra code memory, these strings
{0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9}, {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
{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},
#ifdef JOYSTICK_INTERFACE
{0x2200, JOYSTICK_INTERFACE, joystick_hid_report_desc, sizeof(joystick_hid_report_desc)}, {0x2200, JOYSTICK_INTERFACE, joystick_hid_report_desc, sizeof(joystick_hid_report_desc)},
{0x2100, JOYSTICK_INTERFACE, config1_descriptor+JOYSTICK_HID_DESC_OFFSET, 9}, {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}, {0x0300, 0x0000, (const uint8_t *)&string0, 4},
{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_PRODUCT)}, {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_PRODUCT)},
}; };
static uint8_t mouse_protocol USBSTATE; static uint8_t mouse_protocol USBSTATE;


// joystick data // joystick data
#ifdef JOYSTICK_INTERFACE
uint8_t joystick_report_data[12] USBSTATE; 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;





/************************************************************************** /**************************************************************************
keyboard_leds = 0; keyboard_leds = 0;
mouse_buttons = 0; mouse_buttons = 0;
mouse_protocol = 1; mouse_protocol = 1;
#ifdef JOYSTICK_INTERFACE
joystick_report_data[0] = 0; joystick_report_data[0] = 0;
joystick_report_data[1] = 0; joystick_report_data[1] = 0;
joystick_report_data[2] = 0; joystick_report_data[2] = 0;
joystick_report_data[9] = 0x08; joystick_report_data[9] = 0x08;
joystick_report_data[10] = 0x20; joystick_report_data[10] = 0x20;
joystick_report_data[11] = 0x80; 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; UDINT = 0;
UDIEN = (1<<EORSTE)|(1<<SOFE); UDIEN = (1<<EORSTE)|(1<<SOFE);
//sei(); // init() in wiring.c does this //sei(); // init() in wiring.c does this
uint8_t intbits; uint8_t intbits;
const uint8_t *list; const uint8_t *list;
const uint8_t *cfg; const uint8_t *cfg;
uint8_t i, n, len, en;
uint8_t i, n, len;
uint8_t bmRequestType; uint8_t bmRequestType;
uint8_t bRequest; uint8_t bRequest;
uint16_t wValue; uint16_t wValue;
debug_flush_timer = 0; debug_flush_timer = 0;
usb_send_in(); usb_send_in();
cfg = endpoint_config_table; cfg = endpoint_config_table;
for (i=1; i<NUM_ENDPOINTS; i++) {
for (i=1; i<7; i++) {
UENUM = 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 = 0x1E;
UERST = 0; UERST = 0;
} }
} }
} }
#ifdef JOYSTICK_INTERFACE
if (wIndex == JOYSTICK_INTERFACE) { if (wIndex == JOYSTICK_INTERFACE) {
if (bmRequestType == 0xA1) { if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) { if (bRequest == HID_GET_REPORT) {
} }
} }
} }
#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 (wIndex == DEBUG_INTERFACE) {
if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) { if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
len = wLength; len = wLength;

+ 156
- 49
usb_hid/usb_api.cpp View File



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




// Unicode code points beyond U+FFFF are not supported // Unicode code points beyond U+FFFF are not supported
// technically this input should probably be called UCS-2 // technically this input should probably be called UCS-2
if (cpoint < 32) { 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; return 0;
} }
if (cpoint < 128) { if (cpoint < 128) {
{ {
keyboard_report_data[7] = 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) void usb_keyboard_class::send_now(void)
uint8_t key, mod, msb, modrestore=0; uint8_t key, mod, msb, modrestore=0;


msb = n >> 8; 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); KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return; if (!keycode) return;
#ifdef DEADKEYS_MASK
#ifdef DEADKEYS_MASK
KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode); KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
if (deadkeycode) { if (deadkeycode) {
modrestore = keyboard_report_data[0]; modrestore = keyboard_report_data[0];
presskey(key, mod); presskey(key, mod);
releasekey(key, mod); releasekey(key, mod);
} }
#endif
#endif
mod = keycode_to_modifier(keycode); mod = keycode_to_modifier(keycode);
key = keycode_to_key(keycode); key = keycode_to_key(keycode);
presskey(key, mod | modrestore); presskey(key, mod | modrestore);
uint8_t key, mod, msb; uint8_t key, mod, msb;


msb = n >> 8; 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); KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return; if (!keycode) return;
send_now(); 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) void usb_mouse_class::move(int8_t x, int8_t y, int8_t wheel)
} }





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

void usb_joystick_class::send_now(void) void usb_joystick_class::send_now(void)
{ {
uint8_t intr_state, timeout; uint8_t intr_state, timeout;
SREG = intr_state; SREG = intr_state;
} }


#endif






} }


// transmit a character. // transmit a character.
#if ARDUINO >= 100
size_t usb_serial_class::write(uint8_t c) 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; //static uint8_t previous_timeout=0;
uint8_t timeout, intr_state; uint8_t timeout, intr_state;
debug_flush_timer = TRANSMIT_FLUSH_TIMEOUT; debug_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
} }
SREG = intr_state; SREG = intr_state;
#if ARDUINO >= 100
return 1; return 1;
#endif
error: error:
#if ARDUINO >= 100
setWriteError(); setWriteError();
return 0; return 0;
#else
return;
#endif
} }




usb_serial_class Serial = usb_serial_class(); usb_serial_class Serial = usb_serial_class();
usb_keyboard_class Keyboard = usb_keyboard_class(); usb_keyboard_class Keyboard = usb_keyboard_class();
usb_mouse_class Mouse = usb_mouse_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(); usb_joystick_class Joystick = usb_joystick_class();
#endif



+ 13
- 12
usb_hid/usb_api.h View File

public: public:
void begin(void) { } void begin(void) { }
void end(void) { } void end(void) { }
#if ARDUINO >= 100
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
using Print::write; using Print::write;
void write_unicode(uint16_t unicode) { write_keycode(unicode_to_keycode(unicode)); } void write_unicode(uint16_t unicode) { write_keycode(unicode_to_keycode(unicode)); }
void set_modifier(uint8_t); void set_modifier(uint8_t);
void set_key4(uint8_t); void set_key4(uint8_t);
void set_key5(uint8_t); void set_key5(uint8_t);
void set_key6(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 send_now(void);
void press(uint16_t n); void press(uint16_t n);
void release(uint16_t n); void release(uint16_t n);
void releasekey(uint8_t key, uint8_t modifier); void releasekey(uint8_t key, uint8_t modifier);
void write_keycode(KEYCODE_TYPE key); void write_keycode(KEYCODE_TYPE key);
void write_key(KEYCODE_TYPE code); 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; uint8_t utf8_state;
uint16_t unicode_wchar; uint16_t unicode_wchar;
}; };






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

extern uint8_t joystick_report_data[12]; extern uint8_t joystick_report_data[12];


class usb_joystick_class class usb_joystick_class


extern usb_joystick_class Joystick; extern usb_joystick_class Joystick;


#endif






virtual int read(); virtual int read();
virtual int peek(); virtual int peek();
virtual void flush(); virtual void flush();
#if ARDUINO >= 100
virtual size_t write(uint8_t); virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
using Print::write; using Print::write;
operator bool(); operator bool();
// Teensy extensions // Teensy extensions

+ 17
- 51
usb_hid/usb_private.h View File

* *
**************************************************************************/ **************************************************************************/


// 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 // Some operating systems, especially Windows, may cache USB device
// info. Changes to the device name may not update on the same // info. Changes to the device name may not update on the same
#define JOYSTICK_BUFFER EP_DOUBLE_BUFFER #define JOYSTICK_BUFFER EP_DOUBLE_BUFFER
#define JOYSTICK_INTERVAL 2 #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 // setup
extern uint8_t keyboard_idle_count; extern uint8_t keyboard_idle_count;
extern volatile uint8_t keyboard_leds; extern volatile uint8_t keyboard_leds;
extern uint8_t mouse_buttons; extern uint8_t mouse_buttons;
#ifdef JOYSTICK_INTERFACE
extern uint8_t joystick_report_data[12]; 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





// transmit a block of data // transmit a block of data
#if ARDUINO >= 100
size_t usb_serial_class::write(const uint8_t *buffer, uint16_t size) 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; uint8_t timeout, intr_state, write_size;
#if ARDUINO >= 100
size_t count=0; size_t count=0;
#endif


// if we're not online (enumerated and configured), error // if we're not online (enumerated and configured), error
if (!usb_configuration) { if (!usb_configuration) {
write_size = CDC_TX_SIZE - UEBCLX; write_size = CDC_TX_SIZE - UEBCLX;
if (write_size > size) write_size = size; if (write_size > size) write_size = size;
size -= write_size; size -= write_size;
#if ARDUINO >= 100
count += write_size; count += write_size;
#endif


#define ASM_COPY1(src, dest, tmp) "ld " tmp ", " src "\n\t" "st " dest ", " tmp "\n\t" #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) #define ASM_COPY2(src, dest, tmp) ASM_COPY1(src, dest, tmp) ASM_COPY1(src, dest, tmp)
} }
SREG = intr_state; SREG = intr_state;
end: end:
#if ARDUINO >= 100
return count; return count;
#else
return;
#endif
} }


// transmit a string // transmit a string


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




// Unicode code points beyond U+FFFF are not supported // Unicode code points beyond U+FFFF are not supported
// technically this input should probably be called UCS-2 // technically this input should probably be called UCS-2
if (cpoint < 32) { 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; return 0;
} }
if (cpoint < 128) { if (cpoint < 128) {
{ {
keyboard_report_data[7] = 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) void usb_keyboard_class::send_now(void)
uint8_t key, mod, msb, modrestore=0; uint8_t key, mod, msb, modrestore=0;


msb = n >> 8; 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); KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return; if (!keycode) return;
#ifdef DEADKEYS_MASK #ifdef DEADKEYS_MASK
uint8_t key, mod, msb; uint8_t key, mod, msb;


msb = n >> 8; 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); KEYCODE_TYPE keycode = unicode_to_keycode(n);
if (!keycode) return; if (!keycode) return;
mod = keycode_to_modifier(keycode); mod = keycode_to_modifier(keycode);

+ 2
- 1
usb_serial_hid/usb_api.h View File

void set_key4(uint8_t); void set_key4(uint8_t);
void set_key5(uint8_t); void set_key5(uint8_t);
void set_key6(uint8_t); void set_key6(uint8_t);
void set_media(uint8_t);
void set_media(uint8_t) {
}
void send_now(void); void send_now(void);
void press(uint16_t n); void press(uint16_t n);
void release(uint16_t n); void release(uint16_t n);

Loading…
Cancel
Save