diff --git a/src/keyboard/ergodox/layout/_defaults.h b/src/keyboard/ergodox/layout/_defaults.h index 8727352..1cf8c25 100644 --- a/src/keyboard/ergodox/layout/_defaults.h +++ b/src/keyboard/ergodox/layout/_defaults.h @@ -7,8 +7,8 @@ * ------------------------------------------------------------------------- */ -#ifndef _DEFAULTS_h - #define _DEFAULTS_h +#ifndef LAYOUT__DEFAULTS_h + #define LAYOUT__DEFAULTS_h // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/qwerty.h index dc90619..f44fff1 100644 --- a/src/keyboard/ergodox/layout/qwerty.h +++ b/src/keyboard/ergodox/layout/qwerty.h @@ -7,5 +7,11 @@ * ------------------------------------------------------------------------- */ -#define KB_LAYERS 1 // must match what's defined in the layout '.c' file +#ifndef LAYOUT_QWERTY_h + #define LAYOUT_QWERTY_h + + #define KB_LAYERS 1 // must match what's defined in the layout '.c' + // file + +#endif diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c index 4e68fb2..40bd64a 100644 --- a/src/keyboard/ergodox/teensy-2-0.c +++ b/src/keyboard/ergodox/teensy-2-0.c @@ -124,9 +124,9 @@ uint8_t teensy_init(void) { TCCR1A = 0b10101001; // set and configure fast PWM TCCR1B = 0b00001001; // set and configure fast PWM - KB_LED1_SET_PERCENT(0.5); KB_LED1_OFF; - KB_LED2_SET_PERCENT(0.5); KB_LED2_OFF; - KB_LED3_SET_PERCENT(0.5); KB_LED3_OFF; + kb_led1_set_percent(0.5); kb_led1_off(); + kb_led2_set_percent(0.5); kb_led2_off(); + kb_led3_set_percent(0.5); kb_led3_off(); // I2C (TWI) twi_init(); // on pins D(1,0) diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/teensy-2-0.h index dfdf990..e082d95 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/teensy-2-0.h @@ -16,18 +16,18 @@ #include "matrix.h" // LED control - #define KB_LED1_ON (DDRB |= (1<<5)) - #define KB_LED1_OFF (DDRB &= ~(1<<5)) - #define KB_LED1_SET(n) (OCR1A = (uint8_t)(n)) - #define KB_LED1_SET_PERCENT(n) (OCR1A = (uint8_t)((n) * 0xFF)) - #define KB_LED2_ON (DDRB |= (1<<6)) - #define KB_LED2_OFF (DDRB &= ~(1<<6)) - #define KB_LED2_SET(n) (OCR1B = (uint8_t)(n)) - #define KB_LED2_SET_PERCENT(n) (OCR1B = (uint8_t)((n) * 0xFF)) - #define KB_LED3_ON (DDRB |= (1<<7)) - #define KB_LED3_OFF (DDRB &= ~(1<<7)) - #define KB_LED3_SET(n) (OCR1C = (uint8_t)(n)) - #define KB_LED3_SET_PERCENT(n) (OCR1C = (uint8_t)((n) * 0xFF)) + #define kb_led1_on() (DDRB |= (1<<5)) + #define kb_led1_off() (DDRB &= ~(1<<5)) + #define kb_led1_set(n) (OCR1A = (uint8_t)(n)) + #define kb_led1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) + #define kb_led2_on() (DDRB |= (1<<6)) + #define kb_led2_off() (DDRB &= ~(1<<6)) + #define kb_led2_set(n) (OCR1B = (uint8_t)(n)) + #define kb_led2_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF)) + #define kb_led3_on() (DDRB |= (1<<7)) + #define kb_led3_off() (DDRB &= ~(1<<7)) + #define kb_led3_set(n) (OCR1C = (uint8_t)(n)) + #define kb_led3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF)) #ifdef KEYBOARD_INCLUDE_PRIVATE diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c index 9d34015..46e1b20 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c @@ -350,7 +350,7 @@ int8_t usb_keyboard_send(void) ISR(USB_GEN_vect) { uint8_t intbits, i; // used to declare a variable `t` as well, but it - // wasn't used ::Blazak, 2012:: + // wasn't used ::Ben Blazak, 2012:: static uint8_t div4=0; intbits = UDINT; diff --git a/src/lib/usb/TODO--common-data.h b/src/lib/usb/TODO--common-data.h new file mode 100644 index 0000000..20922a4 --- /dev/null +++ b/src/lib/usb/TODO--common-data.h @@ -0,0 +1,336 @@ +/* ---------------------------------------------------------------------------- + * Common data structures, macros, and other definitions from the USB spec and + * related documents + * + * - The following document versions were used, unless otherwise noted: + * - USB Specification: revision 2.0 + * - HID Usage Tables: version 1.12 + * - Device Class Definition for Human Interface Devices (HID): version 1.11 + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef USB_DATA_STRUCTURES_h + #define USB_DATA_STRUCTURES_h +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + + +#include "lib/data-types.h" + + +// - spec sec 9.3 (USB Device Requests) +// - table 9-2 (Format of Setup Data) +struct usb_setup_data { + uint8_t bmRequestType; + // value: bitmap + // - data transfer direction, type, recipient + // (see macros below) + + uint8_t bRequest; + // value: value + // - type of request (depending on bmRequestType) + // (see spec table 9-3 (Standard Device Requests)) + + uint16_t wValue; + // value: value + // - varies according to request; used to pass a request specific + // parameter to the device + + uint16_t wIndex; + // value: index or offset + // - varies according to request; often used to specify an endpoint or + // an interface + // (see spec figure 9-2 and 9-3, copied below) + + uint16_t wLength; + // value: count + // - number of bytes to transfer if there is a data stage +}; + +// - table 9-2 (Format of Setup Data) +// - bmRequestType +// --- data transfer direction +#define usb_bmRequestType_hostToDevice(val) (((val) & 0x80) == 0x00) +#define usb_bmRequestType_deviceToHost(val) (((val) & 0x80) == 0x80) +// --- type +#define usb_bmRequestType_standard(val) (((val) & 0x60) == 0x00) +#define usb_bmRequestType_class(val) (((val) & 0x60) == 0x20) +#define usb_bmRequestType_vendor(val) (((val) & 0x60) == 0x40) +#define usb_bmRequestType_reserved(val) (((val) & 0x60) == 0x60) +// --- recipient +#define usb_bmRequestType_device(val) (((val) & 0x1F) == 0x00) +#define usb_bmRequestType_interface(val) (((val) & 0x1F) == 0x01) +#define usb_bmRequestType_endpoint(val) (((val) & 0x1F) == 0x02) +#define usb_bmRequestType_other(val) (((val) & 0x1F) == 0x03) +#define usb_bmRequestType_reserved(val) (((val) & 0x1C) != 0x00) + +// - spec sec 9.3.4 (wIndex) +// - figure 9-2 (format when specifying an endpoint) +// .-------------------------------------------------------. +// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | +// |-------------------------------------------------------| +// | direction | reserved (reset to 0) | endpoint number | +// >-----------------------------------------------------< +// | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | +// |-------------------------------------------------------| +// | reserved (reset to 0) | +// '-------------------------------------------------------' +// - direction bit: 0 => out (to device), 1 => in (to host) +#define usb_wIndex_endpoint(direction, endpoint_number) \ + ( (uint16_t) (((direction) << 7) | (endpoint_number)) ) + +// - spec sec 9.3.4 (wIndex) +// - figure 9-3 (format when specifying an interface) +// .-------------------------------------------------------. +// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | +// |-------------------------------------------------------| +// | interface number | +// >-----------------------------------------------------< +// | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | +// |-------------------------------------------------------| +// | reserved (reset to 0) | +// '-------------------------------------------------------' +#define usb_wIndex_interface(interface_number) \ + ( (uint16_t) (interface_number) ) + +// - spec table 9-4 (Standard Request Codes) +#define USB_GET_STATUS 0 +#define USB_CLEAR FEATURE 1 +// (reserved for future use): 2 +#define USB_SET_FEATURE 3 +// (reserved for future use): 4 +#define USB_SET_ADDRESS 5 +#define USB_GET_DESCRIPTOR 6 +#define USB_SET_DESCRIPTOR 7 +#define USB_GET_CONFIGURATION 8 +#define USB_SET_CONFIGURATION 9 +#define USB_GET_INTERFACE 10 +#define USB_SET_INTERFACE 11 +#define USB_SYNCH_FRAME 12 + +// - spec table 9-5 (Descriptor Types) +#define USB_DEVICE 1 +#define USB_CONFIGURATION 2 +#define USB_STRING 3 +#define USB_INTERFACE 4 +#define USB_ENDPOINT 5 +#define USB_DEVICE_QUALIFIER 6 +#define USB_OTHER_SPEED_CONFIGURATION 7 +#define USB_INTERFACE_POWER 8 + +// - spec table 9-6 (Standard Feature Selectors) +#define USB_DEVICE_REMOTE_WAKEUP 1 // recipient: device +#define USB_ENDPOINT_HALT 0 // recipient: endpoint +#define USB_TEST_MODE 2 // recipient: device + +// - spec sec 9.4.5 (Standard Device Requests / Get Status) +// - figure 9-4 (information returned by a GetStatus() request to a device) +// .------------------------------------------------------------. +// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | +// |------------------------------------------------------------| +// | reserved (reset to 0) | remote wakeup | self powered | +// >----------------------------------------------------------< +// | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | +// |------------------------------------------------------------| +// | reserved (reset to 0) | +// '------------------------------------------------------------' +// - remote wakeup bit: 0 => ability of device to signal remote wakeup disabled +// (default) +// 1 => ability ................................. enabled +// - self powered bit: 0 => device is bus powered, 1=> device is self powered +#define usb_getStatus_device(remote_wakeup, self_powered) \ + ( (uint16_t) (((remote_wakeup) << 1) | (self_powered)) ) + +// - spec sec 9.4.5 (Standard Device Requests / Get Status) +// - figure 9-5 (information returned by a GetStatus() request to an +// interface) +// .------------------------------------------------------------. +// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | +// |------------------------------------------------------------| +// | reserved (reset to 0) | +// >----------------------------------------------------------< +// | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | +// |------------------------------------------------------------| +// | reserved (reset to 0) | +// '------------------------------------------------------------' +#define usb_getStatus_interface() ( (uint16_t) 0 ) + +// - spec sec 9.4.5 (Standard Device Requests / Get Status) +// - figure 9-6 (information returned by a GetStatus() request to an +// endpoint) +// .------------------------------------------------------------. +// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | +// |------------------------------------------------------------| +// | reserved (reset to 0) | halt | +// >----------------------------------------------------------< +// | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 | +// |------------------------------------------------------------| +// | reserved (reset to 0) | +// '------------------------------------------------------------' +// - halt bit: 0 => endpoint not currently halted +// 1 => endpoint currently halted +#define usb_getStatus_endpoint(halt) ( (uint16_t) (halt) ) + +// - spec sec 9.4.9 (Set Feature) +// - table 9-7 (Test Mode Selectors) +// - in the case of a SetFeature(TEST_MODE...): +// - the most significant byte of wIndex is used to specify the test mode +// - the lower byte of wIndex must be zero, because the recipient must be the +// device +// (reserved): (0x0000) +#define USB_TEST_MODE_wIndex_Test_J (0x0100) +#define USB_TEST_MODE_wIndex_Test_K (0x0200) +#define USB_TEST_MODE_wIndex_Test_SE0_NAK (0x0300) +#define USB_TEST_MODE_wIndex_Test_Packet (0x0400) +#define USB_TEST_MODE_wIndex_Test_Force_Enable (0x0500) +// (reserved for standard test selectors): (0x0600)..(0x3F00) +// (reserved): (0x3F00)..(0xBF00) +// (reserved for vendor-specific test modes): (0xC000)..(0xFF00) + +// - spec sec 9.6.1 (Standard USB Descriptor Definitions / Device) +// - table 9-8 (Standard Device Descriptor) +struct usb_standard_device_descriptor { + uint8_t bLength; + // value: number + // - size of this descriptor in bytes + + uint8_t bDescriptorType; + // value: constant + // - DEVICE Descriptor Type + // - a high speed capable device will set this to 2.0 (0x0200). if the + // device is full-speed or low-speed only, this version number only + // means that it'll send a request error when asked for the + // device_qualifier descriptor + + uint16_t bcdUSB; + // value: BCD (binary coded decimal) + // - usb spec release number + // - format: 0xJJMN, where JJ = major version, M = minor version, + // N = sub-minor version; e.g. version 2.1.3 => 0x0213 + + uint8_t bDeviceClass; + // value: class + // - class code (assigned by the USB-IF) + // - 0x00 => each interface within a configuration specifies its own + // class information and the various interfaces operate independently + // - 0x01..0xFE => the device supports different class specifications + // on different interfaces and the interfaces may not operate + // independently. this value identifies the class definition used + // for the aggregate interfaces + // - 0xFF => the device class is vendor-specific + + uint8_t bDeviceSubClass; + // value: subclass + // - subclass code (assigned by the USB-IF) + // - qualified by bDeviceClass + // - if bDeviceClass is reset to 0, this field must be also + // - if bDeviceClass != 0xFF , all values are reserved for assignment + // by the USB-IF + + uint8_t bDeviceProtocol; + // value: protocol + // - protocol code (assigned by the USB-IF) + // - qualified by bDeviceClass and bDeviceSubClass + // - if a device supports class-specific protocols on a device basis as + // opposed to an interface basis, this code identifies the protocols + // that the device uses as defined by the specification of the device + // class + // - 0x00 => the device does not use class-specific protocols on a + // device basis. however, it may use class-specific protocols on an + // interface basis + // - 0xFF => the device uses a vendor-specific protocol on a device + // basis + + uint8_t bMaxPacketSize0; + // value: number + // - max packet size for endpoint 0 + // - only 8, 16, 32, or 64 are valid + // - if operating at high-speed, the value must be 64 + + uint16_t idVendor; + // value: id + // - vendor ID (assigned by the USB-IF) + + uint16_t idProduct; + // value: id + // - product ID (assigned by the manufacturer) + + uint16_t bcdDevice; + // value: BCD (binary coded decimal) + // - device release number + + uint8_t iManufacturer; + // value: index + // - index of string descriptor describing manufacturer + + uint8_t iProduct; + // value: index + // - index of string descriptor describing product + + uint8_t iSerialNumber; + // value: index + // - index of string descriptor describing the device's serial number + + uint8_t bNumConfigurations; + // value: number + // - number of possible configurations (at the current operating speed) +}; + +// - spec sec 9.6.2 (Standard USB Descriptor Definitions / Device_Qualifier) +// - table 9-9 (Device_Qualifier Descriptor) +// - required if the device has different device information for full-speed and +// high-speed +// - not valid for a full-speed only device (with a device descriptor version +// number equal to 0x0200); if requested, the device must respond with a +// request error +struct usb_device_qualifier_descriptor { + uint8_t bLength; + // value: number + // - size of descriptor + + uint8_t bDescriptorType; + // value: constant + // - device qualifier type + + uint16_t bcdUSB; + // value: BCD (binary coded decimal) + // - usb spec release number + // - format: (see note for usb_standard_device_descriptor.bcdUSB) + // - must be at least 2.0 (0x0200) for this descriptor + + uint8_t bDeviceClass; + // value: class + + uint8_t bDeviceSubClass; + // value: subclass + + uint8_t bDeviceProtocol; + // value: protocol + + uint8_t bMaxPacketSize0; + // value: number + // - max packet size for other speed + + uint8_t bNumConfigurations; + // value: number + // - number of other-speed configurations + + uint8_t bReserved; + // value: 0 + // - reserved for future use +}; + +// - spec sec 9.6.4 (Standard USB Descriptor Definitions / +// Other_Speed_Configuration) +// - table 9-10 (Standard Configuration Descriptor) +// TODO + + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +#endif + diff --git a/src/lib/usb/TODO.c b/src/lib/usb/TODO.c new file mode 100644 index 0000000..26ea8e5 --- /dev/null +++ b/src/lib/usb/TODO.c @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------------- + * TODO: not sure where this stuff should be yet. a lot of it (depending on + * what ends up here) will likely be device and application specific. + * + * - The following document versions were used, unless otherwise noted: + * - USB Specification: revision 2.0 + * - HID Usage Tables: version 1.12 + * - Device Class Definition for Human Interface Devices (HID): version 1.11 + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +// TODO: does stuff from spec sec 9.4.* belong directly in an interrupt vector? + +// - spec sec 9.4.1 (Standard Device Requests / Clear Feature) (pg 252) + +// - spec sec 9.4.2 (Standard Device Requests / Get Configuration) (pg 253) + +// - spec sec 9.4.3 (Standard Device Requests / Get Descriptor) (pg 253) + +// - spec sec 9.4.4 (Standard Device Requests / Get Interface) (pg 254) + +// - spec sec 9.4.5 (Standard Device Requests / Get Status) (pg 254) + +// - spec sec 9.4.6 (Standard Device Requests / Set Address) (pg 256) + +// - spec sec 9.4.7 (Standard Device Requests / Set Configuration) (pg 257) + +// - spec sec 9.4.8 (Standard Device Requests / Set Descriptor) (pg 257) + +// - spec sec 9.4.9 (Standard Device Requests / Set Feature) (pg 258) + +// - spec sec 9.4.10 (Standard Device Requests / Set Interface) (pg 259) + +// - spec sec 9.4.11 (Standard Device Requests / Synch Frame) (pg 260) + +// TODO +// - read the hid usage tables .pdf +// - read the hid device class definition .pdf +// - add a note about the variable prefixes (w, b, bcd, ...) + diff --git a/src/lib/usb/keyboard-usage-page--short-names.h b/src/lib/usb/keyboard-usage-page--short-names.h index 8e09729..275f25c 100644 --- a/src/lib/usb/keyboard-usage-page--short-names.h +++ b/src/lib/usb/keyboard-usage-page--short-names.h @@ -11,6 +11,12 @@ * ------------------------------------------------------------------------- */ +#ifndef USB_KEYBOARD_USAGE_PAGE_SHORT_NAMES_h + #define USB_KEYBOARD_USAGE_PAGE_SHORT_NAMES_h +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + + #include "keyboard-usage-page.h" @@ -298,3 +304,8 @@ #define _memMul_kp KEYPAD_MemoryMultiply #define _memDiv_kp KEYPAD_MemoryDivide + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +#endif + diff --git a/src/lib/usb/keyboard-usage-page.h b/src/lib/usb/keyboard-usage-page.h index 81c042b..7d9c8b4 100644 --- a/src/lib/usb/keyboard-usage-page.h +++ b/src/lib/usb/keyboard-usage-page.h @@ -21,6 +21,12 @@ * ------------------------------------------------------------------------- */ +#ifndef USB_KEYBOARD_USAGE_PAGE_h + #define USB_KEYBOARD_USAGE_PAGE_h +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + + // Name ID // PC Mac Unix Boot Keyboard Req. // --------------------------- ---- -- --- ---- --------------------- @@ -262,3 +268,8 @@ // (Reserved) 0xE8..0xFFFF // - - - - + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +#endif + diff --git a/src/lib/usb/led-usage-page.h b/src/lib/usb/led-usage-page.h index 45c9754..e98d303 100644 --- a/src/lib/usb/led-usage-page.h +++ b/src/lib/usb/led-usage-page.h @@ -20,6 +20,12 @@ * ------------------------------------------------------------------------- */ +#ifndef USB_LED_USAGE_PAGE_h + #define USB_LED_USAGE_PAGE_h +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + + // Name ID Usage Type Section of HID Tables // --------------------------- ---- ---------- ---------------------- @@ -104,3 +110,9 @@ #define LED_ExternalPowerConnected 0x4D // OOC 11.6 // (Reserved) 0x4E..0xFFFF // - - + + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +#endif + diff --git a/src/main.c b/src/main.c index 6191b1e..4368f46 100644 --- a/src/main.c +++ b/src/main.c @@ -18,7 +18,7 @@ // note: // - see your keyswitch specification for the necessary value. for cherry mx // switches, bounce time should be <= 5ms. it looks like most switches are -// speced between 5 and 8ms. +// speced between 5 and 8 ms. // - if timing is important, balance this value with the main() loop run time // (~5ms, last i checked, nearly all of it in the i2c update() function) #define DEBOUNCE_TIME 5 // in ms @@ -27,17 +27,17 @@ int main(void) { kb_init(); // does controller initialization too - KB_LED1_ON; - KB_LED2_ON; - KB_LED3_ON; + kb_led1_on(); + kb_led2_on(); + kb_led3_on(); usb_init(); while (!usb_configured()); _delay_ms(1000); // make sure the OS has had time to load drivers, etc. - KB_LED1_OFF; - KB_LED2_OFF; - KB_LED3_OFF; + kb_led1_off(); + kb_led2_off(); + kb_led3_off(); for (;;) { static uint8_t current_layer = 0; @@ -52,7 +52,7 @@ int main(void) { // call the appropriate function for each key, then send the usb report // if necessary // - everything else is the key function's responsibility; see the - // keyboard layout file ("keyboard/ergodox/layout.c") for which key + // keyboard layout file ("keyboard/ergodox/layout/*.c") for which key // is assigned which function (per layer), and "lib/key-functions.c" // for their definitions for (uint8_t row=0; row