Skip to content

Instantly share code, notes, and snippets.

@allanlei
Last active March 4, 2018 03:44
Show Gist options
  • Save allanlei/591688d8e47ee505b74e to your computer and use it in GitHub Desktop.
Save allanlei/591688d8e47ee505b74e to your computer and use it in GitHub Desktop.
#include "DigiKeyboard.h"
// Delay between keystrokes
#define KEYSTROKE_DELAY 1000
// Blinking control
int iterationCounter = 0;
#define BLINK_RATE 2
void setup() {
// initialize the digital pin as an output.
pinMode(0, OUTPUT); //LED on Model B
pinMode(1, OUTPUT); //LED on Model A
// don't need to set anything up to use DigiKeyboard
}
void loop() {
DigiKeyboard.update();
if (iterationCounter % BLINK_RATE == 0)
turnLedOn ();
// this is generally not necessary but with some older systems it seems to
// prevent missing the first character after a delay:
DigiKeyboard.sendKeyStroke(0);
// It's better to use DigiKeyboard.delay() over the regular Arduino delay()
// if doing keyboard stuff because it keeps talking to the computer to make
// sure the computer knows the keyboard is alive and connected
DigiKeyboard.delay(KEYSTROKE_DELAY);
// UP
DigiKeyboard.sendKeyStroke(KEY_ARROW_UP);
DigiKeyboard.delay(KEYSTROKE_DELAY);
// DOWN
DigiKeyboard.sendKeyStroke(KEY_ARROW_DOWN);
DigiKeyboard.delay(KEYSTROKE_DELAY);
if (iterationCounter % BLINK_RATE == 0)
turnLedOff ();
iterationCounter++;
}
void turnLedOn ()
{
digitalWrite(0, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(1, HIGH);
}
void turnLedOff ()
{
digitalWrite(0, LOW); // turn the LED off by making the voltage LOW
digitalWrite(1, LOW);
}
1. Mark device as boot device in configuration descriptor:
#define USB_CFG_DEVICE_CLASS 0 /* set to 0 if deferred to interface */
#define USB_CFG_DEVICE_SUBCLASS 0
/* See USB specification if you want to conform to an existing device class.
* Class 0xff is "vendor specific".
*/
#define USB_CFG_INTERFACE_CLASS 3 /* define class here if not at device level */
#define USB_CFG_INTERFACE_SUBCLASS 1
#define USB_CFG_INTERFACE_PROTOCOL 1
2. Use a HID report descriptor indicating boot support (see http://www.usb.org/developers/devclass_docs/HID1_11.pdf , Appendix B: Boot Interface
Descriptors) (Update USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH to the new size, mine is 63 bytes):
PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
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 (Keyboard)(Key Codes)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)(224)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)(231)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x81, 0x02, // INPUT (Data,Var,Abs) ; Modifier byte
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs) ; Reserved byte
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs) ; LED report
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs) ; LED report padding
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))(0)
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)(101)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
3. Fill a report structure for boot protocol. Send it when needed. Up to 6 at the same time. For example
typedef struct {
uint8_t modifier;
uint8_t reserved;
uint8_t keycode[6];
} keyboard_report_t;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment