started rewriting in C++ :)

partial-rewrite
Ben Blazak 2012-12-20 15:04:13 -08:00
parent 8ea3ea5230
commit 778e400868
54 changed files with 11 additions and 8433 deletions

7
src/.gitignore vendored
View File

@ -1,7 +0,0 @@
*.eep
*.elf
*.hex
*.map
*.o
*.o.dep

View File

@ -1,16 +0,0 @@
/* ----------------------------------------------------------------------------
* controller specific exports
*
* Files for different keyboards are used by modifying a variable in the
* Makefile
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include "../lib/variable-include.h"
#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/controller.h )
#include INCLUDE

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 158 KiB

View File

@ -1,43 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller specific code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
#include "./matrix.h"
#include "./controller/mcp23018--functions.h"
#include "./controller/teensy-2-0--functions.h"
// ----------------------------------------------------------------------------
/* returns
* - success: 0
* - error: number of the function that failed
*/
uint8_t kb_init(void) {
if (teensy_init()) // must be first
return 1;
if (mcp23018_init()) // must be second
return 2;
return 0; // success
}
/* returns
* - success: 0
* - error: number of the function that failed
*/
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
if (teensy_update_matrix(matrix))
return 1;
if (mcp23018_update_matrix(matrix))
return 2;
return 0; // success
}

View File

@ -1,27 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller specific exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__CONTROLLER_h
#define KEYBOARD__ERGODOX__CONTROLLER_h
#include <stdbool.h>
#include <stdint.h>
#include "./matrix.h"
// --------------------------------------------------------------------
#include "./controller/teensy-2-0--led.h"
// --------------------------------------------------------------------
uint8_t kb_init(void);
uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]);
#endif

View File

@ -1,27 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller : MCP23018 specific exports : functions
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__CONTROLLER__MCP23018__FUNCTIONS_h
#define KEYBOARD__ERGODOX__CONTROLLER__MCP23018__FUNCTIONS_h
#include <stdbool.h>
#include <stdint.h>
#include "../matrix.h"
// --------------------------------------------------------------------
#define MCP23018_TWI_ADDRESS 0b0100000
// --------------------------------------------------------------------
uint8_t mcp23018_init(void);
uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
#endif

View File

@ -1,206 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller: MCP23018 specific code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
#include <util/twi.h>
#include "../../../lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
#include "../options.h"
#include "../matrix.h"
#include "./mcp23018--functions.h"
// ----------------------------------------------------------------------------
// check options
#if (MCP23018__DRIVE_ROWS && MCP23018__DRIVE_COLUMNS) \
|| !(MCP23018__DRIVE_ROWS || MCP23018__DRIVE_COLUMNS)
#error "See 'Pin drive direction' in 'options.h'"
#endif
// ----------------------------------------------------------------------------
// register addresses (see "mcp23018.md")
#define IODIRA 0x00 // i/o direction register
#define IODIRB 0x01
#define GPPUA 0x0C // GPIO pull-up resistor register
#define GPPUB 0x0D
#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
#define GPIOB 0x13
#define OLATA 0x14 // output latch register
#define OLATB 0x15
// TWI aliases
#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE )
#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ )
// ----------------------------------------------------------------------------
/* returns:
* - success: 0
* - failure: twi status code
*
* notes:
* - `twi_stop()` must be called *exactly once* for each twi block, the way
* things are currently set up. this may change in the future.
*/
uint8_t mcp23018_init(void) {
uint8_t ret;
// set pin direction
// - unused : input : 1
// - input : input : 1
// - driving : output : 0
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
twi_send(IODIRA);
#if MCP23018__DRIVE_ROWS
twi_send(0b11111111); // IODIRA
twi_send(0b11000000); // IODIRB
#elif MCP23018__DRIVE_COLUMNS
twi_send(0b10000000); // IODIRA
twi_send(0b11111111); // IODIRB
#endif
twi_stop();
// set pull-up
// - unused : on : 1
// - input : on : 1
// - driving : off : 0
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
twi_send(GPPUA);
#if MCP23018__DRIVE_ROWS
twi_send(0b11111111); // GPPUA
twi_send(0b11000000); // GPPUB
#elif MCP23018__DRIVE_COLUMNS
twi_send(0b10000000); // GPPUA
twi_send(0b11111111); // GPPUB
#endif
twi_stop();
// set logical value (doesn't matter on inputs)
// - unused : hi-Z : 1
// - input : hi-Z : 1
// - driving : hi-Z : 1
twi_start();
ret = twi_send(TWI_ADDR_WRITE);
if (ret) goto out; // make sure we got an ACK
twi_send(OLATA);
twi_send(0b11111111); //OLATA
twi_send(0b11111111); //OLATB
out:
twi_stop();
return ret;
}
/* returns:
* - success: 0
* - failure: twi status code
*/
#if KB_ROWS != 6 || KB_COLUMNS != 14
#error "Expecting different keyboard dimensions"
#endif
uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
uint8_t ret, data;
// initialize things, just to make sure
// - it's not appreciably faster to skip this, and it takes care of the
// case when the i/o expander isn't plugged in during the first
// init()
ret = mcp23018_init();
// if there was an error
if (ret) {
// clear our part of the matrix
for (uint8_t row=0; row<=5; row++)
for (uint8_t col=0; col<=6; col++)
matrix[row][col] = 0;
return ret;
}
// --------------------------------------------------------------------
// update our part of the matrix
#if MCP23018__DRIVE_ROWS
for (uint8_t row=0; row<=5; row++) {
// set active row low : 0
// set other rows hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_send( 0xFF & ~(1<<(5-row)) );
twi_stop();
// read column data
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_start();
twi_send(TWI_ADDR_READ);
twi_read(&data);
twi_stop();
// update matrix
for (uint8_t col=0; col<=6; col++) {
matrix[row][col] = !( data & (1<<col) );
}
}
// set all rows hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_send(0xFF);
twi_stop();
#elif MCP23018__DRIVE_COLUMNS
for (uint8_t col=0; col<=6; col++) {
// set active column low : 0
// set other columns hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_send( 0xFF & ~(1<<col) );
twi_stop();
// read row data
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOB);
twi_start();
twi_send(TWI_ADDR_READ);
twi_read(&data);
twi_stop();
// update matrix
for (uint8_t row=0; row<=5; row++) {
matrix[row][col] = !( data & (1<<(5-row)) );
}
}
// set all columns hi-Z : 1
twi_start();
twi_send(TWI_ADDR_WRITE);
twi_send(GPIOA);
twi_send(0xFF);
twi_stop();
#endif
// /update our part of the matrix
// --------------------------------------------------------------------
return ret; // success
}

View File

@ -1,147 +0,0 @@
# Documentation : MCP23018
## Pinout and Pin assignments
* `+` indicates connected pin
* `o` indicates unconnected pin
* `=` is used to list other things the pin is connected to
* `-`s inserted between some of the pin functions for readability
### MCP23018
Vss(GND) +01---.---28+ NC
NC +02 27+ GPA7
GPB0 +03 26+ GPA6
GPB1 +04 25+ GPA5
GPB2 +05 24+ GPA4
GPB3 +06 23+ GPA3
GPB4 +07 22+ GPA2
GPB5 +08 21+ GPA1
GPB6 +09 20+ GPA0
GPB7 +10 19+ INTA
Vdd(Vcc) +11 18+ INTB
SCL +12 17+ NC
SDA +13 16+ RESET
NC +14-------15+ ADDR
### MCP32018 Pin Assignments
power_negative Vss(GND) +01---.---28o NC
NC o02 27o GPA7
row_5 GPB0 +03 26+ GPA6 column_6
row_4 GPB1 +04 25+ GPA5 column_5
row_3 GPB2 +05 24+ GPA4 column_4
row_2 GPB3 +06 23+ GPA3 column_3
row_1 GPB4 +07 22+ GPA2 column_2
row_0 GPB5 +08 21+ GPA1 column_1
GPB6 o09 20+ GPA0 column_0
GPB7 o10 19o INTA
power_positive Vdd(Vcc) +11 18o INTB
I2C SCL +12 17o NC
I2C SDA +13 16+ RESET = Vdd(Vcc) (see note)
NC o14-------15+ ADDR = Vss(GND) (see note)
* notes:
* Row and column assignments are to matrix positions, which may or may
or may not correspond to the physical position of the key: e.g. the key
where `row_4` and `column_2` cross will be scanned into the matrix at
`[4][2]`, wherever it happens to be located on the keyboard. Mapping
from one to the other (which only matters for defining layouts) is
handled elsewhere.
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
* The user-defined bits are the three least significant
* I2C addresses are 7 bits long (the last bit in the byte is used for
indicating read/write)
* RESET (pin16) must be externally biased. Since we're not going to
trigger it ourselves, we can tie it high.
* This is not noted in the I2C Pinout Description section of the
MCP23018 datasheet, but it's true (empirically), and it is noted in
the SPI Pinout Description section, and in the MCP23017 datasheet.
* I'm not the first person who's failed to notice ;)
* <http://davidn.org/wp/?p=89>
* <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293498979>
## Notes about Registers
register address function (for all bits)
-------- ------- -----------------------
IODIRA 0x00 \ 1: set corresponding pin as input
IODIRB 0x01 / 0: set ................. as output
GPPUA 0x0C \ 1: set corresponding pin internal pull-up on
GPPUB 0x0D / 0: set .......................... pull-up off
GPIOA 0x12 \ read: returns the value on the port
GPIOB 0x13 / write: modifies the OLAT register
OLATA 0x14 \ read: returns the value of this register
OLATB 0x15 / write: modifies the output latches that control the
pins configured as output
* IOCON register (see datasheet section 1.6, table 1-5, register 1-8)
* BANK: bit 7; read/write; default = 0
* 1: The registers associated with each port are separated into
different banks
* 0: The registers are in the same bank (addresses are sequential)
* SEQOP: bit 5; read/write; default = 0
* 1: Sequential operation disabled, address pointer does not increment
* 0: Sequential operation enabled, address pointer increments
* notes:
* All addresses given for IOCON.BANK = 0, since that's the default value of
the bit, and that's what we'll be using.
* Initially, we want either columns or rows (see <../options.h>) set as
hi-Z without pull-ups, and the other set of pins set as input with
pull-ups. During the update function, we'll cycle through setting the
first set low and checking each pin in the second set.
* abbreviations:
* IODIR = I/O Direction Register
* IOCON = I/O Control Register
* GPPU = GPIO Pull-Up Resistor Register
* GPIO = General Purpose I/O Port Register
* OLAT = Output Latch Register
## I&sup2;C Device Protocol (see datasheet section 1.3, figure 1-1)
S : Start OP : Device opcode
SR : Restart ADDR : Device address
P : Stop Dout : Data out from MCP23018
W : Write Din : Data in to MCP23018
R : Read
S OP W ADDR ----> Din ... Din --> P
|
|--> SR OP R Dout ... Dout ---> P
|<--------------------------|
|
|--> SR OP W ADDR ... Din --> P
|
|--> P
S OP R ----> Dout ... Dout --> P
|
|--> SR OP R Dout ... Dout ---> P
|<--------------------------|
|
|--> SR OP W ADDR Din ... Din --> P
|
|--> P
Byte and Sequential Write
-------------------------
Byte : S OP W ADDR --> Din --> P
Sequential : S OP W ADDR --> Din ... Din --> P
Byte and Sequential Read
------------------------
Byte : S OP W ADDR --> SR OP R Dout --> P
Sequential : S OP W ADDR --> SR OP R Dout ... Dout --> P
* notes:
* We'll be using sequential mode (ICON.SEQOP = 0; default) (see datasheet
section 1.3.1).
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -1,23 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller : Teensy 2.0 specific exports : functions
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__FUNCTIONS_h
#define KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__FUNCTIONS_h
#include <stdbool.h>
#include <stdint.h>
#include "../matrix.h"
// --------------------------------------------------------------------
uint8_t teensy_init(void);
uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
#endif

View File

@ -1,59 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller : Teensy 2.0 specific exports : LED control
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__LED_h
#define KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__LED_h
#include <stdint.h>
#include <avr/io.h> // for the register macros
// --------------------------------------------------------------------
#define _kb_led_1_on() (DDRB |= (1<<5))
#define _kb_led_1_off() (DDRB &= ~(1<<5))
#define _kb_led_1_set(n) (OCR1A = (uint8_t)(n))
#define _kb_led_1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF))
#define _kb_led_2_on() (DDRB |= (1<<6))
#define _kb_led_2_off() (DDRB &= ~(1<<6))
#define _kb_led_2_set(n) (OCR1B = (uint8_t)(n))
#define _kb_led_2_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF))
#define _kb_led_3_on() (DDRB |= (1<<7))
#define _kb_led_3_off() (DDRB &= ~(1<<7))
#define _kb_led_3_set(n) (OCR1C = (uint8_t)(n))
#define _kb_led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF))
#define _kb_led_all_on() do { \
_kb_led_1_on(); \
_kb_led_2_on(); \
_kb_led_3_on(); \
} while(0)
#define _kb_led_all_off() do { \
_kb_led_1_off(); \
_kb_led_2_off(); \
_kb_led_3_off(); \
} while(0)
#define _kb_led_all_set(n) do { \
_kb_led_1_set(n); \
_kb_led_2_set(n); \
_kb_led_3_set(n); \
} while(0)
#define _kb_led_all_set_percent(n) do { \
_kb_led_1_set_percent(n); \
_kb_led_2_set_percent(n); \
_kb_led_3_set_percent(n); \
} while(0)
#endif

View File

@ -1,234 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : controller: Teensy 2.0 specific code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
// for "lib/twi.h"
#define TWI_FREQ 400000
#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include "../../../lib/twi.h"
#include "../options.h"
#include "../matrix.h"
#include "./teensy-2-0--functions.h"
#include "./teensy-2-0--led.h"
// ----------------------------------------------------------------------------
// check options
#if (TEENSY__DRIVE_ROWS && TEENSY__DRIVE_COLUMNS) \
|| !(TEENSY__DRIVE_ROWS || TEENSY__DRIVE_COLUMNS)
#error "See 'Pin drive direction' in 'options.h'"
#endif
// ----------------------------------------------------------------------------
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define CPU_16MHz 0x00
#define CPU_8MHz 0x01
#define CPU_4MHz 0x02
#define CPU_2MHz 0x03
#define CPU_1MHz 0x04
#define CPU_500kHz 0x05
#define CPU_250kHz 0x06
#define CPU_125kHz 0x07
#define CPU_62kHz 0x08
/*
* pin macros
* - note: you can move the `UNUSED`, `ROW`, and `COLUMN` pins around, but be
* sure to keep the set of all the pins listed constant. other pins are not
* movable, and either are referenced explicitly or have macros defined for
* them elsewhere.
* - note: if you change pin assignments, please be sure to update
* "teensy-2-0.md", and the '.svg' circuit diagram.
*/
// --- unused
#define UNUSED_0 C, 7
#define UNUSED_1 D, 7
#define UNUSED_2 D, 4 // hard to use with breadboard (on the end)
#define UNUSED_3 D, 5 // hard to use with breadboard (on the end)
#define UNUSED_4 E, 6 // hard to use with breadboard (internal)
// --- rows
#define ROW_0 F, 7
#define ROW_1 F, 6
#define ROW_2 F, 5
#define ROW_3 F, 4
#define ROW_4 F, 1
#define ROW_5 F, 0
// --- columns
#define COLUMN_7 B, 0
#define COLUMN_8 B, 1
#define COLUMN_9 B, 2
#define COLUMN_A B, 3
#define COLUMN_B D, 2
#define COLUMN_C D, 3
#define COLUMN_D C, 6
// --- helpers
#define SET |=
#define CLEAR &=~
#define _teensypin_write(register, operation, pin_letter, pin_number) \
do { \
((register##pin_letter) operation (1<<(pin_number))); \
_delay_us(1); /* allow pins time to stabilize */ \
} while(0)
#define teensypin_write(register, operation, pin) \
_teensypin_write(register, operation, pin)
#define _teensypin_read(pin_letter, pin_number) \
((PIN##pin_letter) & (1<<(pin_number)))
#define teensypin_read(pin) \
_teensypin_read(pin)
#define teensypin_write_all_unused(register, operation) \
do { \
teensypin_write(register, operation, UNUSED_0); \
teensypin_write(register, operation, UNUSED_1); \
teensypin_write(register, operation, UNUSED_2); \
teensypin_write(register, operation, UNUSED_3); \
teensypin_write(register, operation, UNUSED_4); } \
while(0)
#define teensypin_write_all_row(register, operation) \
do { \
teensypin_write(register, operation, ROW_0); \
teensypin_write(register, operation, ROW_1); \
teensypin_write(register, operation, ROW_2); \
teensypin_write(register, operation, ROW_3); \
teensypin_write(register, operation, ROW_4); \
teensypin_write(register, operation, ROW_5); } \
while(0)
#define teensypin_write_all_column(register, operation) \
do { \
teensypin_write(register, operation, COLUMN_7); \
teensypin_write(register, operation, COLUMN_8); \
teensypin_write(register, operation, COLUMN_9); \
teensypin_write(register, operation, COLUMN_A); \
teensypin_write(register, operation, COLUMN_B); \
teensypin_write(register, operation, COLUMN_C); \
teensypin_write(register, operation, COLUMN_D); } \
while(0)
/*
* update macros
*/
#define update_rows_for_column(matrix, column) \
do { \
/* set column low (set as output) */ \
teensypin_write(DDR, SET, COLUMN_##column); \
/* read rows 0..5 and update matrix */ \
matrix[0x0][0x##column] = ! teensypin_read(ROW_0); \
matrix[0x1][0x##column] = ! teensypin_read(ROW_1); \
matrix[0x2][0x##column] = ! teensypin_read(ROW_2); \
matrix[0x3][0x##column] = ! teensypin_read(ROW_3); \
matrix[0x4][0x##column] = ! teensypin_read(ROW_4); \
matrix[0x5][0x##column] = ! teensypin_read(ROW_5); \
/* set column hi-Z (set as input) */ \
teensypin_write(DDR, CLEAR, COLUMN_##column); \
} while(0)
#define update_columns_for_row(matrix, row) \
do { \
/* set row low (set as output) */ \
teensypin_write(DDR, SET, ROW_##row); \
/* read columns 7..D and update matrix */ \
matrix[0x##row][0x7] = ! teensypin_read(COLUMN_7); \
matrix[0x##row][0x8] = ! teensypin_read(COLUMN_8); \
matrix[0x##row][0x9] = ! teensypin_read(COLUMN_9); \
matrix[0x##row][0xA] = ! teensypin_read(COLUMN_A); \
matrix[0x##row][0xB] = ! teensypin_read(COLUMN_B); \
matrix[0x##row][0xC] = ! teensypin_read(COLUMN_C); \
matrix[0x##row][0xD] = ! teensypin_read(COLUMN_D); \
/* set row hi-Z (set as input) */ \
teensypin_write(DDR, CLEAR, ROW_##row); \
} while(0)
// ----------------------------------------------------------------------------
/* returns
* - success: 0
*/
uint8_t teensy_init(void) {
// CPU speed : should match F_CPU in makefile
#if F_CPU != 16000000
#error "Expecting different CPU frequency"
#endif
CPU_PRESCALE(CPU_16MHz);
// onboard LED
// (tied to GND for hardware convenience)
DDRD &= ~(1<<6); // set D(6) as input
PORTD &= ~(1<<6); // set D(6) internal pull-up disabled
// (tied to Vcc for hardware convenience)
DDRB &= ~(1<<4); // set B(4) as input
PORTB &= ~(1<<4); // set B(4) internal pull-up disabled
// keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md")
_kb_led_all_off(); // (just to put the pins in a known state)
TCCR1A = 0b10101001; // set and configure fast PWM
TCCR1B = 0b00001001; // set and configure fast PWM
// I2C (TWI)
twi_init(); // on pins D(1,0)
// unused pins
teensypin_write_all_unused(DDR, CLEAR); // set as input
teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled
// rows and columns
teensypin_write_all_row(DDR, CLEAR); // set as input (hi-Z)
teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z)
#if TEENSY__DRIVE_ROWS
teensypin_write_all_row(PORT, CLEAR); // pull-up disabled
teensypin_write_all_column(PORT, SET); // pull-up enabled
#elif TEENSY__DRIVE_COLUMNS
teensypin_write_all_row(PORT, SET); // pull-up enabled
teensypin_write_all_column(PORT, CLEAR); // pull-up disabled
#endif
return 0; // success
}
/* returns
* - success: 0
*/
#if KB_ROWS != 6 || KB_COLUMNS != 14
#error "Expecting different keyboard dimensions"
#endif
uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) {
#if TEENSY__DRIVE_ROWS
update_columns_for_row(matrix, 0);
update_columns_for_row(matrix, 1);
update_columns_for_row(matrix, 2);
update_columns_for_row(matrix, 3);
update_columns_for_row(matrix, 4);
update_columns_for_row(matrix, 5);
#elif TEENSY__DRIVE_COLUMNS
update_rows_for_column(matrix, 7);
update_rows_for_column(matrix, 8);
update_rows_for_column(matrix, 9);
update_rows_for_column(matrix, A);
update_rows_for_column(matrix, B);
update_rows_for_column(matrix, C);
update_rows_for_column(matrix, D);
#endif
return 0; // success
}

View File

@ -1,147 +0,0 @@
# Documentation : Teensy 2.0
## Pinout and Pin assignments
* `+` indicates connected pin
* `o` indicates unconnected pin
* `=` is used to list other things the pin is connected to
* `-`s inserted between some of the pin functions for readability
* `OC**` pins enclosed in parenthesis had lines over them in the pinout
### Teensy 2.0
GND +---.....---+ Vcc
SS PB0 + + PF0 ADC0
SCLK PB1 + + PF1 ADC1
MOSI PB2 + + PF4 ADC4
MISO PB3 + + + + PF5 ADC5
RTS OC1C OC0A --------- PB7 + PE6 AREF + PF6 ADC6
OC0B INT0 SCL PD0 + AIN0 + PF7 ADC7
INT1 SDA PD1 + INT6 + PB6 ADC13 OC1B OC4B
RXD1 ----------- INT2 --- PD2 + + PB5 ADC12 OC1A (OC4B)
TXD1 ----------- INT3 --- PD3 + + PB4 ADC11
OC3A (OC4A) -------- PC6 + + PD7 ADC10 T0 -- OC4D
ICP3 ----- OC4A --------- PC7 +-+-+-+-+-+-+ PD6 ADC9 T1 - (OC4D) onboardLED
CTS XCK1 PD5 --/ | | | \-- PD4 ADC8 ------------ ICP1
Vcc ------------------/ | \-------------- RST
GND --------------------/
### Teensy 2.0 Pin Assignments
power_negative GND +---.....---+ Vcc power_positive
column_7 PB0 + + PF0 row_5
column_8 PB1 + + PF1 row_4
column_9 PB2 + + PF4 row_3
column_A PB3 + o o + PF5 row_2
(OC1C) LED_3 PB7 + PE6 AREF + PF6 row_1
(SCL) I2C PD0 + + PF7 row_0
(SDA) I2C PD1 + + PB6 LED_2 (OC1B)
column_B PD2 + + PB5 LED_1 (OC1A)
column_C PD3 + + PB4 = Vcc
column_D PC6 + o PD7
PC7 o-o-o-o-o-o-+ PD6 onboardLED = GND
PD5 --/ | | | \-- PD4
Vcc ----/ | \---- RST
GND-------/
* notes:
* Row and column assignments are to matrix positions, which may or may
or may not correspond to the physical position of the key: e.g. the key
where `row_4` and `column_2` cross will be scanned into the matrix at
`[4][2]`, wherever it happens to be located on the keyboard. Mapping
from one to the other (which only matters for defining layouts) is
handled elsewhere.
* LEDs are labeled using numbers (starting with '1') instead of letters
(starting with 'A') as on the PCB.
* SCL and SDA: Need external pull-up resistors. Sometimes the Teensy
internal pull-ups are enough (see datasheet section 20.5.1), but i think
for this project we'll want external ones. The general recommendation
for 400kHz I&sup2;C seems to be 2.2kΩ.
## Notes about Registers
### General I/O (see datasheet section 10.2.1)
DDRxn function PORTxn function
1 output 1 drive high
0 drive low
0 input 1 internal pull-up on
0 internal pull-up off
PINxn action function
write 1 toggles the value of PORTxn
read returns the logical value (1|0) of the pin
* notes:
* Unused pins should be set as input, with internal pullup enabled in order
to give them a defined level (see datasheet section 10.2.6).
* PD6 (the onboard LED) already has a defined level (low), so there's no
reason to set internal pull-up enabled on it. If we do, it will source
current to the LED, which is fine, but unnecessary.
* Initially, we want either columns or rows (see <../options.h>) set as
hi-Z without pull-ups, and the other set of pins set as input with
pull-ups. During the update function, we'll cycle through setting the
first set low and checking each pin in the second set.
* To set a pin hi-Z on this board, set it as input with pull-up
disabled.
* Switching the driving pins (the first set of pins) between hi-Z and
drive low (treating them as if they were open drain) seems just as
good as, and a little safer than, driving them high when they're not
active.
* We need to delay for at least 1 μs between changing the column pins and
reading the row pins. I would assume this is to allow the pins time to
stabalize.
* Thanks to [hasu] (http://geekhack.org/member.php?3412-hasu)
for the suggestion [here]
(http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard&p=606415&viewfull=1#post606415),
and [PrinsValium] (http://geekhack.org/member.php?6408-PrinsValium)
for noting that his firmware had erratic behavior without the delays
[here]
(http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard&p=606426&viewfull=1#post606426).
DOX tried it and confirmed that it worked for his protoype PCB (as of
3 June 2012) [here]
(http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard&p=606865&viewfull=1#post606865).
Before adding a delay we were having [strange problems with ghosting]
(http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard&p=605857&viewfull=1#post605857).
### PWM on ports OC1(A|B|C) (see datasheet section 14.10)
* notes: settings:
* PWM pins should be set as outputs.
* we want Waveform Generation Mode 5
(fast PWM, 8-bit)
(see table 14-5)
* set `TCCRB[4,3],TCCRA[1,0]` to `0,1,0,1`
* we want "Compare Output Mode, Fast PWM" to be `0b10`
"Clear OCnA/OCnB/OCnC on compare match, set OCnA/OCnB/OCnC at TOP"
(see table 14-3)
this way higher values of `OCR1(A|B|C)` will mean longer 'on' times for
the LEDs (provided they're hooked up to GND; other way around if they're
hooked up to Vcc)
* when in a fast PWM mode, set `TCCR1A[7,6,5,4,3,2]` to `1,0,1,0,1,0`
* we want "Clock Select Bit Description" to be `0b001`
"clkI/O/1 (No prescaling)"
(see table 14-6)
* set `TCCR1B[2,1,0]` to `0,0,1`
* LEDs will be at minimum brightness until OCR1(A|B|C) are changed
(since the default value of all the bits in those registers is 0)
* notes: behavior:
* The pins source current when on, and sink current when off. They aren't
set to high impediance for either.
* In Fast PWM mode setting `OCR1(A|B|C)` to `0` does not make the output on
`OC1(A|B|C)` constant low; just close. Per the datasheet, this isn't
true for every PWM mode.
* abbreviations:
* OCR = Output Compare Register
* TCCR = Timer/Counter Control Register
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -1,23 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : layout exports
*
* Different layouts are included by modifying a variable in the makefile.
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__LAYOUT_h
#define KEYBOARD__ERGODOX__LAYOUT_h
// --------------------------------------------------------------------
// include the appropriate keyboard layout header
#include "../../lib/variable-include.h"
#define INCLUDE EXP_STR( ./layout/MAKEFILE_KEYBOARD_LAYOUT.h )
#include INCLUDE
#endif

View File

@ -1,16 +0,0 @@
# Documentation : layout
Different layouts are included by modifying a variable in the makefile.
## notes
* Each full layer takes 420 bytes of memory (the matrix size is 12x7, keycodes
are 1 byte each, and function pointers are 2 bytes each).
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -1,383 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX layout : COLEMAK (modified from the Kinesis layout)
*
* Submitted by Jason Trill [jjt] (https://github.com/jjt)
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdint.h>
#include <stddef.h>
#include <avr/pgmspace.h>
#include "../../../lib/data-types/misc.h"
#include "../../../lib/usb/usage-page/keyboard--short-names.h"
#include "../../../lib/key-functions/public.h"
#include "../matrix.h"
#include "../layout.h"
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
// LAYOUT L0: COLEMAK
KB_MATRIX_LAYER( 0,
// left hand
_equal, _1, _2, _3, _4, _5, 2,
_tab, _Q, _W, _F, _P, _G, _esc,
_ctrlL, _A, _R, _S, _T, _D,
_shiftL, _Z, _X, _C, _V, _B, 2,
_guiL, _grave, _backslash, _altL, 1,
_ctrlL, _altL,
0, 0, _home,
_space, _enter, _end,
// right hand
3, _6, _7, _8, _9, _0, _dash,
_esc, _J, _L, _U, _Y, _semicolon, _backslash,
_H, _N, _E, _I, _O, _quote,
3, _K, _M, _comma, _period, _slash, _shiftR,
1, _arrowL, _arrowD, _arrowU, _arrowR,
_altR, _ctrlR,
_pageU, 0, 0,
_pageD, _del, _bs ),
// LAYOUT L1: function and symbol keys
KB_MATRIX_LAYER( 0,
// left hand
0, _F1, _F2, _F3, _F4, _F5, _F11,
0, _bracketL, _bracketR, _bracketL, _bracketR, _semicolon, 0,
0, _backslash, _slash, _9, _0, _semicolon,
0, _1, _2, _3, _4, _5, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
_F12, _F6, _F7, _F8, _F9, _F10, _power,
0, 0, _equal, _equal, _dash, _dash, 0,
_arrowL, _arrowD, _arrowU, _arrowR, 0, 0,
0, _6, _7, _8, _9, _0, _mute,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0 ),
// LAYOUT L2: QWERTY alphanum
KB_MATRIX_LAYER( 0,
// left hand
0, _1, _2, _3, _4, _5, 0,
0, _Q, _W, _E, _R, _T, 0,
0, _A, _S, _D, _F, _G,
0, _Z, _X, _C, _V, _B, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
0, _6, _7, _8, _9, _0, 0,
0, _Y, _U, _I, _O, _P, 0,
_H, _J, _K, _L, _semicolon, 0,
0, _N, _M, _comma, _period, _slash, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0 ),
// LAYOUT L3: numpad
KB_MATRIX_LAYER( 0,
// left hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, _insert, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
3, 0, 3, _equal_kp, _div_kp, _mul_kp, 0,
0, 0, _7_kp, _8_kp, _9_kp, _sub_kp, 0,
0, _4_kp, _5_kp, _6_kp, _add_kp, 0,
0, 0, _1_kp, _2_kp, _3_kp, _enter_kp, 0,
0, 0, _period, _enter_kp, 0,
0, 0,
0, 0, 0,
0, 0, _0_kp ),
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// aliases
// basic
#define kprrel &kbfun_press_release
#define ktog &kbfun_toggle
#define ktrans &kbfun_transparent
// --- layer push/pop functions
#define lpush1 &kbfun_layer_push_1
#define lpush2 &kbfun_layer_push_2
#define lpush3 &kbfun_layer_push_3
#define lpush4 &kbfun_layer_push_4
#define lpush5 &kbfun_layer_push_5
#define lpush6 &kbfun_layer_push_6
#define lpush7 &kbfun_layer_push_7
#define lpush8 &kbfun_layer_push_8
#define lpush9 &kbfun_layer_push_9
#define lpush10 &kbfun_layer_push_10
#define lpop1 &kbfun_layer_pop_1
#define lpop2 &kbfun_layer_pop_2
#define lpop3 &kbfun_layer_pop_3
#define lpop4 &kbfun_layer_pop_4
#define lpop5 &kbfun_layer_pop_5
#define lpop6 &kbfun_layer_pop_6
#define lpop7 &kbfun_layer_pop_7
#define lpop8 &kbfun_layer_pop_8
#define lpop9 &kbfun_layer_pop_9
#define lpop10 &kbfun_layer_pop_10
// ---
// device
#define dbtldr &kbfun_jump_to_bootloader
// special
#define sshprre &kbfun_shift_press_release
#define s2kcap &kbfun_2_keys_capslock_press_release
#define slpunum &kbfun_layer_push_numpad
#define slponum &kbfun_layer_pop_numpad
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
// PRESS L0: COLEMAK
KB_MATRIX_LAYER( NULL,
// left hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, lpush2,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpush2,
kprrel, kprrel, kprrel, kprrel, lpush1,
kprrel, kprrel,
NULL, NULL, kprrel,
kprrel, kprrel, kprrel,
// right hand
slpunum, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
slpunum, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap,
lpush1, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
kprrel, NULL, NULL,
kprrel, kprrel, kprrel ),
// PRESS L1: function and symbol keys
KB_MATRIX_LAYER( NULL,
// left hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, sshprre, sshprre, kprrel, kprrel, sshprre, ktrans,
ktrans, kprrel, kprrel, sshprre, sshprre, kprrel,
ktrans, sshprre, sshprre, sshprre, sshprre, sshprre, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, kprrel, kprrel, sshprre, kprrel, sshprre, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, sshprre, sshprre, sshprre, sshprre, sshprre, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
// PRESS L2: QWERTY
KB_MATRIX_LAYER( NULL,
// left hand
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, lpop2,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
// PRESS L3: numpad
KB_MATRIX_LAYER( NULL,
// left hand
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, kprrel, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
slponum, ktrans, slponum, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, kprrel ),
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
// RELEASE L0: COLEMAK
KB_MATRIX_LAYER( NULL,
// left hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, NULL,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpop2,
kprrel, kprrel, kprrel, kprrel, lpop1,
kprrel, kprrel,
NULL, NULL, kprrel,
kprrel, kprrel, kprrel,
// right hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
slponum, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap,
lpop1, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
kprrel, NULL, NULL,
kprrel, kprrel, kprrel ),
// RELEASE L1: function and symbol keys
KB_MATRIX_LAYER( NULL,
// left hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, sshprre, sshprre, kprrel, kprrel, sshprre, ktrans,
ktrans, kprrel, kprrel, sshprre, sshprre, kprrel,
ktrans, sshprre, sshprre, sshprre, sshprre, sshprre, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, kprrel, kprrel, sshprre, kprrel, sshprre, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, sshprre, sshprre, sshprre, sshprre, sshprre, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
// RELEASE L2: QWERTY
KB_MATRIX_LAYER( NULL,
// left hand
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, NULL,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
// RELEASE L3: numpad
KB_MATRIX_LAYER( NULL,
// left hand
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, kprrel, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
NULL, ktrans, NULL, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
lpop3, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, kprrel ),
// RELEASE L3: nothing (just making sure unused
// functions don't get compiled out)
KB_MATRIX_LAYER( NULL,
// other
kprrel, lpush8, lpop8, NULL, NULL, NULL, NULL, NULL,
ktog, lpush9, lpop9, NULL, NULL, NULL, NULL, NULL,
ktrans, lpush10,lpop10, NULL, NULL, NULL, NULL, NULL,
lpush1, lpop1, NULL, NULL, NULL, NULL, NULL, NULL,
lpush2, lpop2, dbtldr, NULL, NULL, NULL, NULL, NULL,
lpush3, lpop3, NULL, NULL, NULL, NULL, NULL, NULL,
lpush4, lpop4, s2kcap, NULL, NULL, NULL, NULL, NULL,
lpush5, lpop5, slpunum,NULL, NULL, NULL, NULL, NULL,
lpush6, lpop6, slponum,NULL, NULL, NULL, NULL, NULL,
lpush7, lpop7, NULL, NULL, NULL, NULL, NULL, NULL )
};

View File

@ -1,32 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : layout : COLEMAK : exports
*
* Submitted by Jason Trill [jjt] (https://github.com/jjt)
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__LAYOUT__COLEMAK_h
#define KEYBOARD__ERGODOX__LAYOUT__COLEMAK_h
#include "../controller.h"
// --------------------------------------------------------------------
#define kb_led_num_on() _kb_led_1_on()
#define kb_led_num_off() _kb_led_1_off()
#define kb_led_caps_on() _kb_led_2_on()
#define kb_led_caps_off() _kb_led_2_off()
#define kb_led_scroll_on() _kb_led_3_on()
#define kb_led_scroll_off() _kb_led_3_off()
// --------------------------------------------------------------------
#include "./default--led-control.h"
#include "./default--matrix-control.h"
#endif

View File

@ -1,86 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : layout : default LED control
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__LAYOUT__DEFAULT__LED_CONTROL_h
#define KEYBOARD__ERGODOX__LAYOUT__DEFAULT__LED_CONTROL_h
// --------------------------------------------------------------------
/*
* state and delay macros
*/
#ifndef kb_led_state_power_on
#define kb_led_state_power_on() do { \
_kb_led_all_set_percent(MAKEFILE_LED_BRIGHTNESS/10); \
_kb_led_all_on(); \
} while(0)
#endif
// note: need to delay for a total of ~1 second
#ifndef kb_led_delay_usb_init
#define kb_led_delay_usb_init() do { \
_kb_led_1_set_percent(MAKEFILE_LED_BRIGHTNESS); \
_delay_ms(333); \
_kb_led_2_set_percent(MAKEFILE_LED_BRIGHTNESS); \
_delay_ms(333); \
_kb_led_3_set_percent(MAKEFILE_LED_BRIGHTNESS); \
_delay_ms(333); \
} while(0)
#endif
#ifndef kb_led_state_ready
#define kb_led_state_ready() do { \
_kb_led_all_off(); \
_kb_led_all_set_percent(MAKEFILE_LED_BRIGHTNESS); \
} while(0)
#endif
/*
* logical LED macros
* - unused macros should be defined to nothing
* - they all are here, because they really need to be specified in
* the layout specific file
*/
#ifndef kb_led_num_on
#define kb_led_num_on()
#endif
#ifndef kb_led_num_off
#define kb_led_num_off()
#endif
#ifndef kb_led_caps_on
#define kb_led_caps_on()
#endif
#ifndef kb_led_caps_off
#define kb_led_caps_off()
#endif
#ifndef kb_led_scroll_on
#define kb_led_scroll_on()
#endif
#ifndef kb_led_scroll_off
#define kb_led_scroll_off()
#endif
#ifndef kb_led_compose_on
#define kb_led_compose_on()
#endif
#ifndef kb_led_compose_off
#define kb_led_compose_off()
#endif
#ifndef kb_led_kana_on
#define kb_led_kana_on()
#endif
#ifndef kb_led_kana_off
#define kb_led_kana_off()
#endif
#endif

View File

@ -1,81 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : layout : default matrix control
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__LAYOUT__DEFAULT__MATRIX_CONTROL_h
#define KEYBOARD__ERGODOX__LAYOUT__DEFAULT__MATRIX_CONTROL_h
#include <stdint.h>
#include <avr/pgmspace.h>
#include "../../../lib/data-types/misc.h"
#include "../../../lib/key-functions/public.h"
#include "../matrix.h"
// --------------------------------------------------------------------
#ifndef KB_LAYERS
#define KB_LAYERS 10
#endif
// --------------------------------------------------------------------
/*
* matrix 'get' macros, and `extern` matrix declarations
*
* These are written for when the matrices are stored solely in Flash.
* Layouts may redefine them if they wish and use Flash, RAM, EEPROM,
* or any combination of the three, as long as they maintain the same
* interface.
*
* - If the macro is overridden, the matrix declaration must be too,
* and vice versa.
*
* - 'set' functions are optional, and should be defined in the layout
* specific '.h'. They'll require the use of the EEPROM, possibly in
* clever conjunction with one of the other two memories (since the
* EEPROM is small). Custom key functions will also need to be
* written.
*
* - To override these macros with real functions, set the macro equal
* to itself (e.g. `#define kb_layout_get kb_layout_get`) and provide
* function prototypes, in the layout specific '.h'
*/
#ifndef kb_layout_get
extern const uint8_t PROGMEM \
_kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS];
#define kb_layout_get(layer,row,column) \
( (uint8_t) \
pgm_read_byte(&( \
_kb_layout[layer][row][column] )) )
#endif
#ifndef kb_layout_press_get
extern const void_funptr_t PROGMEM \
_kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS];
#define kb_layout_press_get(layer,row,column) \
( (void_funptr_t) \
pgm_read_word(&( \
_kb_layout_press[layer][row][column] )) )
#endif
#ifndef kb_layout_release_get
extern const void_funptr_t PROGMEM \
_kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS];
#define kb_layout_release_get(layer,row,column) \
( (void_funptr_t) \
pgm_read_word(&( \
_kb_layout_release[layer][row][column] )) )
#endif
#endif

View File

@ -1,370 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX layout : Dvorak (modified from the Kinesis layout)
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdint.h>
#include <stddef.h>
#include <avr/pgmspace.h>
#include "../../../lib/data-types/misc.h"
#include "../../../lib/usb/usage-page/keyboard--short-names.h"
#include "../../../lib/key-functions/public.h"
#include "../matrix.h"
#include "../layout.h"
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
KB_MATRIX_LAYER( // layout: layer 0: default
// unused
0,
// left hand
_equal, _1, _2, _3, _4, _5, _esc,
_backslash, _quote, _comma, _period, _P, _Y, 1,
_tab, _A, _O, _E, _U, _I,
_shiftL, _semicolon, _Q, _J, _K, _X, 1,
_guiL, _grave, _backslash, _arrowL, _arrowR,
_ctrlL, _altL,
0, 0, _home,
_bs, _del, _end,
// right hand
3, _6, _7, _8, _9, _0, _dash,
_bracketL, _F, _G, _C, _R, _L, _bracketR,
_D, _H, _T, _N, _S, _slash,
1, _B, _M, _W, _V, _Z, _shiftR,
_arrowL, _arrowD, _arrowU, _arrowR, _guiR,
_altR, _ctrlR,
_pageU, 0, 0,
_pageD, _enter, _space ),
KB_MATRIX_LAYER( // layout: layer 1: function and symbol keys
// unused
0,
// left hand
0, _F1, _F2, _F3, _F4, _F5, _F11,
0, _bracketL, _bracketR, _bracketL, _bracketR, 0, 1,
0, _semicolon, _slash, _dash, _0_kp,_semicolon,
0, _6_kp, _7_kp, _8_kp, _9_kp, _equal, 2,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
_F12, _F6, _F7, _F8, _F9, _F10, _power,
0, 0, _dash, _comma, _period,_currencyUnit, _volumeU,
_backslash, _1_kp, _9, _0, _equal, _volumeD,
2, _8, _2_kp, _3_kp, _4_kp, _5_kp, _mute,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0 ),
KB_MATRIX_LAYER( // layout: layer 2: keyboard functions
// unused
0,
// left hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0 ),
KB_MATRIX_LAYER( // layout: layer 3: numpad
// unused
0,
// left hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, _insert, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
3, 0, 3, _equal_kp, _div_kp, _mul_kp, 0,
0, 0, _7_kp, _8_kp, _9_kp, _sub_kp, 0,
0, _4_kp, _5_kp, _6_kp, _add_kp, 0,
0, 0, _1_kp, _2_kp, _3_kp, _enter_kp, 0,
0, 0, _period, _enter_kp, 0,
0, 0,
0, 0, 0,
0, 0, _0_kp ),
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// aliases
// basic
#define kprrel &kbfun_press_release
#define ktog &kbfun_toggle
#define ktrans &kbfun_transparent
// --- layer push/pop functions
#define lpush1 &kbfun_layer_push_1
#define lpush2 &kbfun_layer_push_2
#define lpush3 &kbfun_layer_push_3
#define lpush4 &kbfun_layer_push_4
#define lpush5 &kbfun_layer_push_5
#define lpush6 &kbfun_layer_push_6
#define lpush7 &kbfun_layer_push_7
#define lpush8 &kbfun_layer_push_8
#define lpush9 &kbfun_layer_push_9
#define lpush10 &kbfun_layer_push_10
#define lpop1 &kbfun_layer_pop_1
#define lpop2 &kbfun_layer_pop_2
#define lpop3 &kbfun_layer_pop_3
#define lpop4 &kbfun_layer_pop_4
#define lpop5 &kbfun_layer_pop_5
#define lpop6 &kbfun_layer_pop_6
#define lpop7 &kbfun_layer_pop_7
#define lpop8 &kbfun_layer_pop_8
#define lpop9 &kbfun_layer_pop_9
#define lpop10 &kbfun_layer_pop_10
// ---
// device
#define dbtldr &kbfun_jump_to_bootloader
// special
#define sshprre &kbfun_shift_press_release
#define s2kcap &kbfun_2_keys_capslock_press_release
#define slpunum &kbfun_layer_push_numpad
#define slponum &kbfun_layer_pop_numpad
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
KB_MATRIX_LAYER( // press: layer 0: default
// unused
NULL,
// left hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
NULL, NULL, kprrel,
kprrel, kprrel, kprrel,
// right hand
slpunum, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
lpush1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
kprrel, NULL, NULL,
kprrel, kprrel, kprrel ),
KB_MATRIX_LAYER( // press: layer 1: function and symbol keys
// unused
NULL,
// left hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans,sshprre,sshprre, kprrel, kprrel, NULL, lpop1,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpush2,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel,
kprrel, kprrel,sshprre,sshprre,sshprre, kprrel,
lpush2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
KB_MATRIX_LAYER( // press: layer 2: keyboard functions
// unused
NULL,
// left hand
dbtldr, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
// right hand
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL ),
KB_MATRIX_LAYER( // press: layer 3: numpad
// unused
NULL,
// left hand
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, kprrel, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
slponum, ktrans,slponum, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, kprrel ),
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
KB_MATRIX_LAYER( // release: layer 0: default
// unused
NULL,
// left hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, NULL,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpop1,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
NULL, NULL, kprrel,
kprrel, kprrel, kprrel,
// right hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
lpop1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
kprrel, NULL, NULL,
kprrel, kprrel, kprrel ),
KB_MATRIX_LAYER( // release: layer 1: function and symbol keys
// unused
NULL,
// left hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans,sshprre,sshprre, kprrel, kprrel, NULL, NULL,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpop2,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel,
kprrel, kprrel,sshprre,sshprre,sshprre, kprrel,
lpop2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
KB_MATRIX_LAYER( // release: layer 2: keyboard functions
// unused
NULL,
// left hand
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
// right hand
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL ),
KB_MATRIX_LAYER( // release: layer 3: numpad
// unused
NULL,
// left hand
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, kprrel, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
NULL, ktrans, NULL, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, kprrel ),
KB_MATRIX_LAYER( // release: layer 3: nothing (just making sure unused
// functions don't get compiled out)
// unused
NULL,
// other
kprrel, lpush8, lpop8, NULL, NULL, NULL, NULL, NULL,
ktog, lpush9, lpop9, NULL, NULL, NULL, NULL, NULL,
ktrans,lpush10, lpop10, NULL, NULL, NULL, NULL, NULL,
lpush1, lpop1, NULL, NULL, NULL, NULL, NULL, NULL,
lpush2, lpop2, dbtldr, NULL, NULL, NULL, NULL, NULL,
lpush3, lpop3, NULL, NULL, NULL, NULL, NULL, NULL,
lpush4, lpop4, s2kcap, NULL, NULL, NULL, NULL, NULL,
lpush5, lpop5,slpunum, NULL, NULL, NULL, NULL, NULL,
lpush6, lpop6,slponum, NULL, NULL, NULL, NULL, NULL,
lpush7, lpop7, NULL, NULL, NULL, NULL, NULL, NULL )
};

View File

@ -1,30 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : layout : Dvorak : exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__LAYOUT__DVORAK_h
#define KEYBOARD__ERGODOX__LAYOUT__DVORAK_h
#include "../controller.h"
// --------------------------------------------------------------------
#define kb_led_num_on() _kb_led_1_on()
#define kb_led_num_off() _kb_led_1_off()
#define kb_led_caps_on() _kb_led_2_on()
#define kb_led_caps_off() _kb_led_2_off()
#define kb_led_scroll_on() _kb_led_3_on()
#define kb_led_scroll_off() _kb_led_3_off()
// --------------------------------------------------------------------
#include "./default--led-control.h"
#include "./default--matrix-control.h"
#endif

View File

@ -1,370 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX layout : QWERTY (modified from the Kinesis layout)
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdint.h>
#include <stddef.h>
#include <avr/pgmspace.h>
#include "../../../lib/data-types/misc.h"
#include "../../../lib/usb/usage-page/keyboard--short-names.h"
#include "../../../lib/key-functions/public.h"
#include "../matrix.h"
#include "../layout.h"
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
KB_MATRIX_LAYER( // layout: layer 0: default
// unused
0,
// left hand
_equal, _1, _2, _3, _4, _5, _esc,
_backslash, _Q, _W, _E, _R, _T, 1,
_tab, _A, _S, _D, _F, _G,
_shiftL, _Z, _X, _C, _V, _B, 1,
_guiL, _grave, _backslash, _arrowL, _arrowR,
_ctrlL, _altL,
0, 0, _home,
_bs, _del, _end,
// right hand
3, _6, _7, _8, _9, _0, _dash,
_bracketL, _Y, _U, _I, _O, _P, _bracketR,
_H, _J, _K, _L, _semicolon, _quote,
1, _N, _M, _comma, _period, _slash, _shiftR,
_arrowL, _arrowD, _arrowU, _arrowR, _guiR,
_altR, _ctrlR,
_pageU, 0, 0,
_pageD, _enter, _space ),
KB_MATRIX_LAYER( // layout: layer 1: function and symbol keys
// unused
0,
// left hand
0, _F1, _F2, _F3, _F4, _F5, _F11,
0, _bracketL, _bracketR, _bracketL, _bracketR, 0, 1,
0, _semicolon, _slash, _dash, _0_kp,_semicolon,
0, _6_kp, _7_kp, _8_kp, _9_kp, _equal, 2,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
_F12, _F6, _F7, _F8, _F9, _F10, _power,
0, 0, _dash, _comma, _period,_currencyUnit, _volumeU,
_backslash, _1_kp, _9, _0, _equal, _volumeD,
2, _8, _2_kp, _3_kp, _4_kp, _5_kp, _mute,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0 ),
KB_MATRIX_LAYER( // layout: layer 2: keyboard functions
// unused
0,
// left hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0 ),
KB_MATRIX_LAYER( // layout: layer 3: numpad
// unused
0,
// left hand
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, _insert, 0, 0, 0,
0, 0,
0, 0, 0,
0, 0, 0,
// right hand
3, 0, 3, _equal_kp, _div_kp, _mul_kp, 0,
0, 0, _7_kp, _8_kp, _9_kp, _sub_kp, 0,
0, _4_kp, _5_kp, _6_kp, _add_kp, 0,
0, 0, _1_kp, _2_kp, _3_kp, _enter_kp, 0,
0, 0, _period, _enter_kp, 0,
0, 0,
0, 0, 0,
0, 0, _0_kp ),
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// aliases
// basic
#define kprrel &kbfun_press_release
#define ktog &kbfun_toggle
#define ktrans &kbfun_transparent
// --- layer push/pop functions
#define lpush1 &kbfun_layer_push_1
#define lpush2 &kbfun_layer_push_2
#define lpush3 &kbfun_layer_push_3
#define lpush4 &kbfun_layer_push_4
#define lpush5 &kbfun_layer_push_5
#define lpush6 &kbfun_layer_push_6
#define lpush7 &kbfun_layer_push_7
#define lpush8 &kbfun_layer_push_8
#define lpush9 &kbfun_layer_push_9
#define lpush10 &kbfun_layer_push_10
#define lpop1 &kbfun_layer_pop_1
#define lpop2 &kbfun_layer_pop_2
#define lpop3 &kbfun_layer_pop_3
#define lpop4 &kbfun_layer_pop_4
#define lpop5 &kbfun_layer_pop_5
#define lpop6 &kbfun_layer_pop_6
#define lpop7 &kbfun_layer_pop_7
#define lpop8 &kbfun_layer_pop_8
#define lpop9 &kbfun_layer_pop_9
#define lpop10 &kbfun_layer_pop_10
// ---
// device
#define dbtldr &kbfun_jump_to_bootloader
// special
#define sshprre &kbfun_shift_press_release
#define s2kcap &kbfun_2_keys_capslock_press_release
#define slpunum &kbfun_layer_push_numpad
#define slponum &kbfun_layer_pop_numpad
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
KB_MATRIX_LAYER( // press: layer 0: default
// unused
NULL,
// left hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
NULL, NULL, kprrel,
kprrel, kprrel, kprrel,
// right hand
slpunum, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
lpush1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
kprrel, NULL, NULL,
kprrel, kprrel, kprrel ),
KB_MATRIX_LAYER( // press: layer 1: function and symbol keys
// unused
NULL,
// left hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans,sshprre,sshprre, kprrel, kprrel, NULL, lpop1,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpush2,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel,
kprrel, kprrel,sshprre,sshprre,sshprre, kprrel,
lpush2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
KB_MATRIX_LAYER( // press: layer 2: keyboard functions
// unused
NULL,
// left hand
dbtldr, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
// right hand
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL ),
KB_MATRIX_LAYER( // press: layer 3: numpad
// unused
NULL,
// left hand
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, kprrel, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
slponum, ktrans,slponum, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, kprrel ),
};
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
const void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = {
KB_MATRIX_LAYER( // release: layer 0: default
// unused
NULL,
// left hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, NULL,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpop1,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
NULL, NULL, kprrel,
kprrel, kprrel, kprrel,
// right hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
lpop1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap,
kprrel, kprrel, kprrel, kprrel, kprrel,
kprrel, kprrel,
kprrel, NULL, NULL,
kprrel, kprrel, kprrel ),
KB_MATRIX_LAYER( // release: layer 1: function and symbol keys
// unused
NULL,
// left hand
NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans,sshprre,sshprre, kprrel, kprrel, NULL, NULL,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre,
ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpop2,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel,
kprrel, kprrel,sshprre,sshprre,sshprre, kprrel,
lpop2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel,
ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans ),
KB_MATRIX_LAYER( // release: layer 2: keyboard functions
// unused
NULL,
// left hand
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
// right hand
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL ),
KB_MATRIX_LAYER( // release: layer 3: numpad
// unused
NULL,
// left hand
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans,
ktrans, kprrel, ktrans, ktrans, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, ktrans,
// right hand
NULL, ktrans, NULL, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans,
ktrans, ktrans, kprrel, kprrel, ktrans,
ktrans, ktrans,
ktrans, ktrans, ktrans,
ktrans, ktrans, kprrel ),
KB_MATRIX_LAYER( // release: layer 3: nothing (just making sure unused
// functions don't get compiled out)
// unused
NULL,
// other
kprrel, lpush8, lpop8, NULL, NULL, NULL, NULL, NULL,
ktog, lpush9, lpop9, NULL, NULL, NULL, NULL, NULL,
ktrans,lpush10, lpop10, NULL, NULL, NULL, NULL, NULL,
lpush1, lpop1, NULL, NULL, NULL, NULL, NULL, NULL,
lpush2, lpop2, dbtldr, NULL, NULL, NULL, NULL, NULL,
lpush3, lpop3, NULL, NULL, NULL, NULL, NULL, NULL,
lpush4, lpop4, s2kcap, NULL, NULL, NULL, NULL, NULL,
lpush5, lpop5,slpunum, NULL, NULL, NULL, NULL, NULL,
lpush6, lpop6,slponum, NULL, NULL, NULL, NULL, NULL,
lpush7, lpop7, NULL, NULL, NULL, NULL, NULL, NULL )
};

View File

@ -1,30 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : layout : QWERTY : exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__LAYOUT__QWERTY_h
#define KEYBOARD__ERGODOX__LAYOUT__QWERTY_h
#include "../controller.h"
// --------------------------------------------------------------------
#define kb_led_num_on() _kb_led_1_on()
#define kb_led_num_off() _kb_led_1_off()
#define kb_led_caps_on() _kb_led_2_on()
#define kb_led_caps_off() _kb_led_2_off()
#define kb_led_scroll_on() _kb_led_3_on()
#define kb_led_scroll_off() _kb_led_3_off()
// --------------------------------------------------------------------
#include "./default--led-control.h"
#include "./default--matrix-control.h"
#endif

View File

@ -1,104 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : matrix specific exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__MATRIX_h
#define KEYBOARD__ERGODOX__MATRIX_h
// --------------------------------------------------------------------
#define KB_ROWS 6 // must match real life
#define KB_COLUMNS 14 // must match real life
// --------------------------------------------------------------------
/* mapping from spatial position to matrix position
* - spatial position: where the key is spatially, relative to other
* keys both on the keyboard and in the layout
* - matrix position: the coordinate in the matrix to which a key is
* scanned by the update functions
*
* - location numbers are in the format `row##column`, where both 'row'
* and 'column' are single digit hex numbers corresponding to the
* matrix position (which also corresponds to the row and column pin
* labels used in the teensy and mcp23018 files)
*
* - coordinates
* - optional keys
* k15, k16 (left hand thumb group)
* k17, k18 (right hand thumb group)
* - unused keys
* k36, k00 (left hand)
* k37, k0D (right hand)
*
* --- other info -----------------------------------------------------
* rows x columns = positions; used, unused
* per hand: 6 x 7 = 42; 40, 2
* total: 6 x 14 = 84; 80, 4
*
* left hand : rows 0..5, cols 0..6
* right hand : rows 0..5, cols 7..D
* --------------------------------------------------------------------
*/
#define KB_MATRIX_LAYER( \
/* for unused positions */ \
na, \
\
/* left hand, spatial positions */ \
k50,k51,k52,k53,k54,k55,k56, \
k40,k41,k42,k43,k44,k45,k46, \
k30,k31,k32,k33,k34,k35, \
k20,k21,k22,k23,k24,k25,k26, \
k10,k11,k12,k13,k14, \
k05,k06, \
k15,k16,k04, \
k03,k02,k01, \
\
/* right hand, spatial positions */ \
k57,k58,k59,k5A,k5B,k5C,k5D, \
k47,k48,k49,k4A,k4B,k4C,k4D, \
k38,k39,k3A,k3B,k3C,k3D, \
k27,k28,k29,k2A,k2B,k2C,k2D, \
k19,k1A,k1B,k1C,k1D, \
k07,k08, \
k09,k17,k18, \
k0C,k0B,k0A ) \
\
/* matrix positions */ \
{{ na,k01,k02,k03,k04,k05,k06, k07,k08,k09,k0A,k0B,k0C, na }, \
{ k10,k11,k12,k13,k14,k15,k16, k17,k18,k19,k1A,k1B,k1C,k1D }, \
{ k20,k21,k22,k23,k24,k25,k26, k27,k28,k29,k2A,k2B,k2C,k2D }, \
{ k30,k31,k32,k33,k34,k35, na, na,k38,k39,k3A,k3B,k3C,k3D }, \
{ k40,k41,k42,k43,k44,k45,k46, k47,k48,k49,k4A,k4B,k4C,k4D }, \
{ k50,k51,k52,k53,k54,k55,k56, k57,k58,k59,k5A,k5B,k5C,k5D }}
#define KB_MATRIX_LAYER_SET_ALL(na, kxx) \
LAYER( \
na, \
\
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx, \
kxx,kxx, \
kxx,kxx,kxx, \
kxx,kxx,kxx, \
\
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx,kxx,kxx, \
kxx,kxx,kxx,kxx,kxx, \
kxx,kxx, \
kxx,kxx,kxx, \
kxx,kxx,kxx ) \
#endif

View File

@ -1,40 +0,0 @@
/* ----------------------------------------------------------------------------
* ergoDOX : keyboard specific options
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef KEYBOARD__ERGODOX__OPTIONS_h
#define KEYBOARD__ERGODOX__OPTIONS_h
// --------------------------------------------------------------------
/*
* DRIVE_ROWS and DRIVE_COLUMNS
* - Select which pins will drive (alternate between hi-Z and drive
* low) and which will be inputs
*
* Notes
* - You must set exactly one of each 'TEENSY' macro, and of each
* 'MCP23018' macro
* - If you are using internal diodes (inside the key switches)... then
* i don't know what to tell you. You will set one chip to drive
* rows, and the other to drive columns, but i don't have a key
* switch to check which at the moment, and i couldn't seem to find
* it online.
* - If the diode cathode is towards the square solder pad, set
* #define TEENSY__DRIVE_COLUMNS 1
* #define MCP23018__DRIVE_COLUMNS 1
* - If the diode cathode is towards the circular solder pad, set
* #define TEENSY__DRIVE_ROWS 1
* #define MCP23018__DRIVE_ROWS 1
*/
#define TEENSY__DRIVE_ROWS 0
#define TEENSY__DRIVE_COLUMNS 1
#define MCP23018__DRIVE_ROWS 0
#define MCP23018__DRIVE_COLUMNS 1
#endif

View File

@ -1,16 +0,0 @@
/* ----------------------------------------------------------------------------
* layout specific exports
*
* Files for different keyboards are used by modifying a variable in the
* Makefile
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include "../lib/variable-include.h"
#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/layout.h )
#include INCLUDE

View File

@ -1,16 +0,0 @@
/* ----------------------------------------------------------------------------
* matrix specific exports
*
* Files for different keyboards are used by modifying a variable in the
* Makefile
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include "../lib/variable-include.h"
#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/matrix.h )
#include INCLUDE

View File

@ -1,19 +0,0 @@
# src/lib/pjrc
## links to original files
* [pjrc] (http://pjrc.com/teensy/)
* [usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip)
<!--
* [usb_mouse] (http://pjrc.com/teensy/usb_mouse.zip)
* [usb_serial] (http://pjrc.com/teensy/usb_serial.zip)
* Directions for host setup [here]
(http://pjrc.com/teensy/usb_serial.html)
-->
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -1,593 +0,0 @@
/* USB Keyboard Example for Teensy USB Development Board
* http://www.pjrc.com/teensy/usb_keyboard.html
* Copyright (c) 2009 PJRC.COM, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Version 1.0: Initial Release
// Version 1.1: Add support for Teensy 2.0
#define USB_SERIAL_PRIVATE_INCLUDE
#include "usb_keyboard.h"
/**************************************************************************
*
* Configurable Options
*
**************************************************************************/
// You can change these to give your code its own name.
#define STR_MANUFACTURER L"unspecified" // TODO
#define STR_PRODUCT L"ErgoDox ergonomic keyboard"
// Mac OS-X and Linux automatically load the correct drivers. On
// Windows, even though the driver is supplied by Microsoft, an
// INF file is needed to load the driver. These numbers need to
// match the INF file.
#define VENDOR_ID 0x1d50 // Openmoko, Inc.
#define PRODUCT_ID 0x6028 // ErgoDox ergonomic keyboard
// USB devices are supposed to implment a halt feature, which is
// rarely (if ever) used. If you comment this line out, the halt
// code will be removed, saving 102 bytes of space (gcc 4.3.0).
// This is not strictly USB compliant, but works with all major
// operating systems.
#define SUPPORT_ENDPOINT_HALT
/**************************************************************************
*
* Endpoint Buffer Configuration
*
**************************************************************************/
#define ENDPOINT0_SIZE 32
#define KEYBOARD_INTERFACE 0
#define KEYBOARD_ENDPOINT 3
#define KEYBOARD_SIZE 8
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER
static const uint8_t PROGMEM endpoint_config_table[] = {
0,
0,
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER,
0
};
/**************************************************************************
*
* Descriptor Data
*
**************************************************************************/
// Descriptors are the data that your computer reads when it auto-detects
// this USB device (called "enumeration" in USB lingo). The most commonly
// changed items are editable at the top of this file. Changing things
// in here should only be done by those who've read chapter 9 of the USB
// spec and relevant portions of any USB class specifications!
static const uint8_t PROGMEM device_descriptor[] = {
18, // bLength
1, // bDescriptorType
0x00, 0x02, // bcdUSB
0, // bDeviceClass
0, // bDeviceSubClass
0, // bDeviceProtocol
ENDPOINT0_SIZE, // bMaxPacketSize0
LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
0x00, 0x01, // bcdDevice
1, // iManufacturer
2, // iProduct
0, // iSerialNumber
1 // bNumConfigurations
};
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
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 (Key Codes),
0x19, 0xE0, // Usage Minimum (224),
0x29, 0xE7, // Usage Maximum (231),
0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum (1),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
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),
0x19, 0x01, // Usage Minimum (1),
0x29, 0x05, // Usage Maximum (5),
0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
0x95, 0x01, // Report Count (1),
0x75, 0x03, // Report Size (3),
0x91, 0x03, // Output (Constant), ;LED report padding
0x95, 0x06, // Report Count (6),
0x75, 0x08, // Report Size (8),
0x15, 0x00, // Logical Minimum (0),
0x25, 0x68, // Logical Maximum(104),
0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0),
0x29, 0x68, // Usage Maximum (104),
0x81, 0x00, // Input (Data, Array),
0xc0 // End Collection
};
#define CONFIG1_DESC_SIZE (9+9+9+7)
#define KEYBOARD_HID_DESC_OFFSET (9+9)
static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
9, // bLength;
2, // bDescriptorType;
LSB(CONFIG1_DESC_SIZE), // wTotalLength
MSB(CONFIG1_DESC_SIZE),
1, // bNumInterfaces
1, // bConfigurationValue
0, // iConfiguration
0xC0, // bmAttributes
50, // bMaxPower
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
KEYBOARD_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
1, // bNumEndpoints
0x03, // bInterfaceClass (0x03 = HID)
0x01, // bInterfaceSubClass (0x01 = Boot)
0x01, // bInterfaceProtocol (0x01 = Keyboard)
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
sizeof(keyboard_hid_report_desc), // wDescriptorLength
0,
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
5, // bDescriptorType
KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
0x03, // bmAttributes (0x03=intr)
KEYBOARD_SIZE, 0, // wMaxPacketSize
1 // bInterval
};
// If you're desperate for a little extra code memory, these strings
// can be completely removed if iManufacturer, iProduct, iSerialNumber
// in the device desciptor are changed to zeros.
struct usb_string_descriptor_struct {
uint8_t bLength;
uint8_t bDescriptorType;
int16_t wString[];
};
static const struct usb_string_descriptor_struct PROGMEM string0 = {
4,
3,
{0x0409}
};
static const struct usb_string_descriptor_struct PROGMEM string1 = {
sizeof(STR_MANUFACTURER),
3,
STR_MANUFACTURER
};
static const struct usb_string_descriptor_struct PROGMEM string2 = {
sizeof(STR_PRODUCT),
3,
STR_PRODUCT
};
// This table defines which descriptor data is sent for each specific
// request from the host (in wValue and wIndex).
static struct descriptor_list_struct {
uint16_t wValue;
uint16_t wIndex;
const uint8_t *addr;
uint8_t length;
} const PROGMEM descriptor_list[] = {
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
{0x0300, 0x0000, (const uint8_t *)&string0, 4},
{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
};
#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
/**************************************************************************
*
* Variables - these are the only non-stack RAM usage
*
**************************************************************************/
// zero when we are not configured, non-zero when enumerated
static volatile uint8_t usb_configuration=0;
// which modifier keys are currently pressed
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
uint8_t keyboard_modifier_keys=0;
// which keys are currently pressed, up to 6 keys may be down at once
uint8_t keyboard_keys[6]={0,0,0,0,0,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.
static uint8_t keyboard_protocol=1;
// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
static uint8_t keyboard_idle_config=125;
// count until idle timeout
static uint8_t keyboard_idle_count=0;
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t keyboard_leds=0;
/**************************************************************************
*
* Public Functions - these are the API intended for the user
*
**************************************************************************/
// initialize USB
void usb_init(void)
{
HW_CONFIG();
USB_FREEZE(); // enable USB
PLL_CONFIG(); // config PLL
while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
USB_CONFIG(); // start USB clock
UDCON = 0; // enable attach resistor
usb_configuration = 0;
UDIEN = (1<<EORSTE)|(1<<SOFE);
sei();
}
// return 0 if the USB is not configured, or the configuration
// number selected by the HOST
uint8_t usb_configured(void)
{
return usb_configuration;
}
// perform a single keystroke
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
{
int8_t r;
keyboard_modifier_keys = modifier;
keyboard_keys[0] = key;
r = usb_keyboard_send();
if (r) return r;
keyboard_modifier_keys = 0;
keyboard_keys[0] = 0;
return usb_keyboard_send();
}
// send the contents of keyboard_keys and keyboard_modifier_keys
int8_t usb_keyboard_send(void)
{
uint8_t i, intr_state, timeout;
if (!usb_configuration) return -1;
intr_state = SREG;
cli();
UENUM = KEYBOARD_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 -1;
// have we waited too long?
if (UDFNUML == timeout) return -1;
// get ready to try checking again
intr_state = SREG;
cli();
UENUM = KEYBOARD_ENDPOINT;
}
UEDATX = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
UEINTX = 0x3A;
keyboard_idle_count = 0;
SREG = intr_state;
return 0;
}
/**************************************************************************
*
* Private Functions - not intended for general user consumption....
*
**************************************************************************/
// USB Device Interrupt - handle all device-level events
// the transmit buffer flushing is triggered by the start of frame
//
ISR(USB_GEN_vect)
{
uint8_t intbits, i; // used to declare a variable `t` as well, but it
// wasn't used ::Ben Blazak, 2012::
static uint8_t div4=0;
intbits = UDINT;
UDINT = 0;
if (intbits & (1<<EORSTI)) {
UENUM = 0;
UECONX = 1;
UECFG0X = EP_TYPE_CONTROL;
UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
UEIENX = (1<<RXSTPE);
usb_configuration = 0;
}
if ((intbits & (1<<SOFI)) && usb_configuration) {
if (keyboard_idle_config && (++div4 & 3) == 0) {
UENUM = KEYBOARD_ENDPOINT;
if (UEINTX & (1<<RWAL)) {
keyboard_idle_count++;
if (keyboard_idle_count == keyboard_idle_config) {
keyboard_idle_count = 0;
UEDATX = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
UEINTX = 0x3A;
}
}
}
}
}
// Misc functions to wait for ready and send/receive packets
static inline void usb_wait_in_ready(void)
{
while (!(UEINTX & (1<<TXINI))) ;
}
static inline void usb_send_in(void)
{
UEINTX = ~(1<<TXINI);
}
static inline void usb_wait_receive_out(void)
{
while (!(UEINTX & (1<<RXOUTI))) ;
}
static inline void usb_ack_out(void)
{
UEINTX = ~(1<<RXOUTI);
}
// USB Endpoint Interrupt - endpoint 0 is handled here. The
// other endpoints are manipulated by the user-callable
// functions, and the start-of-frame interrupt.
//
ISR(USB_COM_vect)
{
uint8_t intbits;
const uint8_t *list;
const uint8_t *cfg;
uint8_t i, n, len, en;
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t desc_val;
const uint8_t *desc_addr;
uint8_t desc_length;
UENUM = 0;
intbits = UEINTX;
if (intbits & (1<<RXSTPI)) {
bmRequestType = UEDATX;
bRequest = UEDATX;
wValue = UEDATX;
wValue |= (UEDATX << 8);
wIndex = UEDATX;
wIndex |= (UEDATX << 8);
wLength = UEDATX;
wLength |= (UEDATX << 8);
UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
if (bRequest == GET_DESCRIPTOR) {
list = (const uint8_t *)descriptor_list;
for (i=0; ; i++) {
if (i >= NUM_DESC_LIST) {
UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
return;
}
desc_val = pgm_read_word(list);
if (desc_val != wValue) {
list += sizeof(struct descriptor_list_struct);
continue;
}
list += 2;
desc_val = pgm_read_word(list);
if (desc_val != wIndex) {
list += sizeof(struct descriptor_list_struct)-2;
continue;
}
list += 2;
desc_addr = (const uint8_t *)pgm_read_word(list);
list += 2;
desc_length = pgm_read_byte(list);
break;
}
len = (wLength < 256) ? wLength : 255;
if (len > desc_length) len = desc_length;
do {
// wait for host ready for IN packet
do {
i = UEINTX;
} while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
if (i & (1<<RXOUTI)) return; // abort
// send IN packet
n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
for (i = n; i; i--) {
UEDATX = pgm_read_byte(desc_addr++);
}
len -= n;
usb_send_in();
} while (len || n == ENDPOINT0_SIZE);
return;
}
if (bRequest == SET_ADDRESS) {
usb_send_in();
usb_wait_in_ready();
UDADDR = wValue | (1<<ADDEN);
return;
}
if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
usb_configuration = wValue;
usb_send_in();
cfg = endpoint_config_table;
for (i=1; i<5; i++) {
UENUM = i;
en = pgm_read_byte(cfg++);
UECONX = en;
if (en) {
UECFG0X = pgm_read_byte(cfg++);
UECFG1X = pgm_read_byte(cfg++);
}
}
UERST = 0x1E;
UERST = 0;
return;
}
if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
usb_wait_in_ready();
UEDATX = usb_configuration;
usb_send_in();
return;
}
if (bRequest == GET_STATUS) {
usb_wait_in_ready();
i = 0;
#ifdef SUPPORT_ENDPOINT_HALT
if (bmRequestType == 0x82) {
UENUM = wIndex;
if (UECONX & (1<<STALLRQ)) i = 1;
UENUM = 0;
}
#endif
UEDATX = i;
UEDATX = 0;
usb_send_in();
return;
}
#ifdef SUPPORT_ENDPOINT_HALT
if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
&& bmRequestType == 0x02 && wValue == 0) {
i = wIndex & 0x7F;
if (i >= 1 && i <= MAX_ENDPOINT) {
usb_send_in();
UENUM = i;
if (bRequest == SET_FEATURE) {
UECONX = (1<<STALLRQ)|(1<<EPEN);
} else {
UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
UERST = (1 << i);
UERST = 0;
}
return;
}
}
#endif
if (wIndex == KEYBOARD_INTERFACE) {
if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) {
usb_wait_in_ready();
UEDATX = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
usb_send_in();
return;
}
if (bRequest == HID_GET_IDLE) {
usb_wait_in_ready();
UEDATX = keyboard_idle_config;
usb_send_in();
return;
}
if (bRequest == HID_GET_PROTOCOL) {
usb_wait_in_ready();
UEDATX = keyboard_protocol;
usb_send_in();
return;
}
}
if (bmRequestType == 0x21) {
if (bRequest == HID_SET_REPORT) {
usb_wait_receive_out();
keyboard_leds = UEDATX;
usb_ack_out();
usb_send_in();
return;
}
if (bRequest == HID_SET_IDLE) {
keyboard_idle_config = (wValue >> 8);
keyboard_idle_count = 0;
usb_send_in();
return;
}
if (bRequest == HID_SET_PROTOCOL) {
keyboard_protocol = wValue;
usb_send_in();
return;
}
}
}
}
UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
}

View File

@ -1,210 +0,0 @@
#ifndef usb_serial_h__
#define usb_serial_h__
#include <stdint.h>
void usb_init(void); // initialize everything
uint8_t usb_configured(void); // is the USB port configured
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);
int8_t usb_keyboard_send(void);
extern uint8_t keyboard_modifier_keys;
extern uint8_t keyboard_keys[6];
extern volatile uint8_t keyboard_leds;
// This file does not include the HID debug functions, so these empty
// macros replace them with nothing, so users can compile code that
// has calls to these functions.
#define usb_debug_putchar(c)
#define usb_debug_flush_output()
#if 0 // removed in favor of equivalent code elsewhere ::Ben Blazak, 2012::
#define KEY_CTRL 0x01
#define KEY_SHIFT 0x02
#define KEY_ALT 0x04
#define KEY_GUI 0x08
#define KEY_LEFT_CTRL 0x01
#define KEY_LEFT_SHIFT 0x02
#define KEY_LEFT_ALT 0x04
#define KEY_LEFT_GUI 0x08
#define KEY_RIGHT_CTRL 0x10
#define KEY_RIGHT_SHIFT 0x20
#define KEY_RIGHT_ALT 0x40
#define KEY_RIGHT_GUI 0x80
#define KEY_A 4
#define KEY_B 5
#define KEY_C 6
#define KEY_D 7
#define KEY_E 8
#define KEY_F 9
#define KEY_G 10
#define KEY_H 11
#define KEY_I 12
#define KEY_J 13
#define KEY_K 14
#define KEY_L 15
#define KEY_M 16
#define KEY_N 17
#define KEY_O 18
#define KEY_P 19
#define KEY_Q 20
#define KEY_R 21
#define KEY_S 22
#define KEY_T 23
#define KEY_U 24
#define KEY_V 25
#define KEY_W 26
#define KEY_X 27
#define KEY_Y 28
#define KEY_Z 29
#define KEY_1 30
#define KEY_2 31
#define KEY_3 32
#define KEY_4 33
#define KEY_5 34
#define KEY_6 35
#define KEY_7 36
#define KEY_8 37
#define KEY_9 38
#define KEY_0 39
#define KEY_ENTER 40
#define KEY_ESC 41
#define KEY_BACKSPACE 42
#define KEY_TAB 43
#define KEY_SPACE 44
#define KEY_MINUS 45
#define KEY_EQUAL 46
#define KEY_LEFT_BRACE 47
#define KEY_RIGHT_BRACE 48
#define KEY_BACKSLASH 49
#define KEY_NUMBER 50
#define KEY_SEMICOLON 51
#define KEY_QUOTE 52
#define KEY_TILDE 53
#define KEY_COMMA 54
#define KEY_PERIOD 55
#define KEY_SLASH 56
#define KEY_CAPS_LOCK 57
#define KEY_F1 58
#define KEY_F2 59
#define KEY_F3 60
#define KEY_F4 61
#define KEY_F5 62
#define KEY_F6 63
#define KEY_F7 64
#define KEY_F8 65
#define KEY_F9 66
#define KEY_F10 67
#define KEY_F11 68
#define KEY_F12 69
#define KEY_PRINTSCREEN 70
#define KEY_SCROLL_LOCK 71
#define KEY_PAUSE 72
#define KEY_INSERT 73
#define KEY_HOME 74
#define KEY_PAGE_UP 75
#define KEY_DELETE 76
#define KEY_END 77
#define KEY_PAGE_DOWN 78
#define KEY_RIGHT 79
#define KEY_LEFT 80
#define KEY_DOWN 81
#define KEY_UP 82
#define KEY_NUM_LOCK 83
#define KEYPAD_SLASH 84
#define KEYPAD_ASTERIX 85
#define KEYPAD_MINUS 86
#define KEYPAD_PLUS 87
#define KEYPAD_ENTER 88
#define KEYPAD_1 89
#define KEYPAD_2 90
#define KEYPAD_3 91
#define KEYPAD_4 92
#define KEYPAD_5 93
#define KEYPAD_6 94
#define KEYPAD_7 95
#define KEYPAD_8 96
#define KEYPAD_9 97
#define KEYPAD_0 98
#define KEYPAD_PERIOD 99
#endif
// Everything below this point is only intended for usb_serial.c
#ifdef USB_SERIAL_PRIVATE_INCLUDE
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#define EP_TYPE_CONTROL 0x00
#define EP_TYPE_BULK_IN 0x81
#define EP_TYPE_BULK_OUT 0x80
#define EP_TYPE_INTERRUPT_IN 0xC1
#define EP_TYPE_INTERRUPT_OUT 0xC0
#define EP_TYPE_ISOCHRONOUS_IN 0x41
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
#define EP_SINGLE_BUFFER 0x02
#define EP_DOUBLE_BUFFER 0x06
#define EP_SIZE(s) ((s) == 64 ? 0x30 : \
((s) == 32 ? 0x20 : \
((s) == 16 ? 0x10 : \
0x00)))
#define MAX_ENDPOINT 4
#define LSB(n) (n & 255)
#define MSB(n) ((n >> 8) & 255)
#if defined(__AVR_AT90USB162__)
#define HW_CONFIG()
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
#define USB_CONFIG() (USBCON = (1<<USBE))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_ATmega32U4__)
#define HW_CONFIG() (UHWCON = 0x01)
#define PLL_CONFIG() (PLLCSR = 0x12)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB646__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x1A)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB1286__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x16)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#endif
// standard control endpoint request types
#define GET_STATUS 0
#define CLEAR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADDRESS 5
#define GET_DESCRIPTOR 6
#define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
// HID (human interface device)
#define HID_GET_REPORT 1
#define HID_GET_IDLE 2
#define HID_GET_PROTOCOL 3
#define HID_SET_REPORT 9
#define HID_SET_IDLE 10
#define HID_SET_PROTOCOL 11
// CDC (communication class device)
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#endif
#endif

View File

@ -1,121 +0,0 @@
/* ----------------------------------------------------------------------------
* key functions : private : code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
#include "../../lib-other/pjrc/usb_keyboard/usb_keyboard.h"
#include "../../lib/usb/usage-page/keyboard.h"
#include "../../keyboard/layout.h"
#include "../../keyboard/matrix.h"
#include "../../main.h"
#include "./public.h"
// ----------------------------------------------------------------------------
/*
* Generate a normal keypress or keyrelease
*
* Arguments
* - press: whether to generate a keypress (true) or keyrelease (false)
* - keycode: the keycode to use
*
* Note
* - Because of the way USB does things, what this actually does is either add
* or remove 'keycode' from the list of currently pressed keys, to be sent at
* the end of the current cycle (see main.c)
*/
void _kbfun_press_release(bool press, uint8_t keycode) {
// no-op
if (keycode == 0)
return;
// modifier keys
switch (keycode) {
case KEY_LeftControl: (press)
? (keyboard_modifier_keys |= (1<<0))
: (keyboard_modifier_keys &= ~(1<<0));
return;
case KEY_LeftShift: (press)
? (keyboard_modifier_keys |= (1<<1))
: (keyboard_modifier_keys &= ~(1<<1));
return;
case KEY_LeftAlt: (press)
? (keyboard_modifier_keys |= (1<<2))
: (keyboard_modifier_keys &= ~(1<<2));
return;
case KEY_LeftGUI: (press)
? (keyboard_modifier_keys |= (1<<3))
: (keyboard_modifier_keys &= ~(1<<3));
return;
case KEY_RightControl: (press)
? (keyboard_modifier_keys |= (1<<4))
: (keyboard_modifier_keys &= ~(1<<4));
return;
case KEY_RightShift: (press)
? (keyboard_modifier_keys |= (1<<5))
: (keyboard_modifier_keys &= ~(1<<5));
return;
case KEY_RightAlt: (press)
? (keyboard_modifier_keys |= (1<<6))
: (keyboard_modifier_keys &= ~(1<<6));
return;
case KEY_RightGUI: (press)
? (keyboard_modifier_keys |= (1<<7))
: (keyboard_modifier_keys &= ~(1<<7));
return;
}
// all others
for (uint8_t i=0; i<6; i++) {
if (press) {
if (keyboard_keys[i] == 0) {
keyboard_keys[i] = keycode;
return;
}
} else {
if (keyboard_keys[i] == keycode) {
keyboard_keys[i] = 0;
return;
}
}
}
}
/*
* Is the given keycode pressed?
*/
bool _kbfun_is_pressed(uint8_t keycode) {
// modifier keys
switch (keycode) {
case KEY_LeftControl: if (keyboard_modifier_keys & (1<<0))
return true;
case KEY_LeftShift: if (keyboard_modifier_keys & (1<<1))
return true;
case KEY_LeftAlt: if (keyboard_modifier_keys & (1<<2))
return true;
case KEY_LeftGUI: if (keyboard_modifier_keys & (1<<3))
return true;
case KEY_RightControl: if (keyboard_modifier_keys & (1<<4))
return true;
case KEY_RightShift: if (keyboard_modifier_keys & (1<<5))
return true;
case KEY_RightAlt: if (keyboard_modifier_keys & (1<<6))
return true;
case KEY_RightGUI: if (keyboard_modifier_keys & (1<<7))
return true;
}
// all others
for (uint8_t i=0; i<6; i++)
if (keyboard_keys[i] == keycode)
return true;
return false;
}

View File

@ -1,26 +0,0 @@
/* ----------------------------------------------------------------------------
* key functions : private : exports
*
* Things to be used only by keyfunctions. Exported so layouts can use these
* functions to help define their own, if they like.
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef LIB__KEY_FUNCTIONS__INTERNAL_h
#define LIB__KEY_FUNCTIONS__INTERNAL_h
#include <stdbool.h>
#include <stdint.h>
#include "../../keyboard/matrix.h"
// --------------------------------------------------------------------
void _kbfun_press_release (bool press, uint8_t keycode);
bool _kbfun_is_pressed (uint8_t keycode);
#endif

View File

@ -1,55 +0,0 @@
/* ----------------------------------------------------------------------------
* key functions : public exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef LIB__KEY_FUNCTIONS__COMMON_h
#define LIB__KEY_FUNCTIONS__COMMON_h
#include <stdbool.h>
#include <stdint.h>
// --------------------------------------------------------------------
// basic
void kbfun_press_release (void);
void kbfun_toggle (void);
void kbfun_transparent (void);
// --- layer push/pop functions
void kbfun_layer_push_1 (void);
void kbfun_layer_push_2 (void);
void kbfun_layer_push_3 (void);
void kbfun_layer_push_4 (void);
void kbfun_layer_push_5 (void);
void kbfun_layer_push_6 (void);
void kbfun_layer_push_7 (void);
void kbfun_layer_push_8 (void);
void kbfun_layer_push_9 (void);
void kbfun_layer_push_10 (void);
void kbfun_layer_pop_1 (void);
void kbfun_layer_pop_2 (void);
void kbfun_layer_pop_3 (void);
void kbfun_layer_pop_4 (void);
void kbfun_layer_pop_5 (void);
void kbfun_layer_pop_6 (void);
void kbfun_layer_pop_7 (void);
void kbfun_layer_pop_8 (void);
void kbfun_layer_pop_9 (void);
void kbfun_layer_pop_10 (void);
// ---
// device
void kbfun_jump_to_bootloader (void);
// special
void kbfun_shift_press_release (void);
void kbfun_2_keys_capslock_press_release (void);
void kbfun_layer_push_numpad (void);
void kbfun_layer_pop_numpad (void);
#endif

View File

@ -1,344 +0,0 @@
/* ----------------------------------------------------------------------------
* key functions : basic : code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include "../../../main.h"
#include "../../../keyboard/layout.h"
#include "../public.h"
#include "../private.h"
// ----------------------------------------------------------------------------
#define MAX_LAYER_PUSH_POP_FUNCTIONS 10
// ----------------------------------------------------------------------------
// convenience macros
#define LAYER main_arg_layer
#define LAYER_OFFSET main_arg_layer_offset
#define ROW main_arg_row
#define COL main_arg_col
#define IS_PRESSED main_arg_is_pressed
#define WAS_PRESSED main_arg_was_pressed
// ----------------------------------------------------------------------------
/*
* [name]
* Press|Release
*
* [description]
* Generate a normal keypress or keyrelease
*/
void kbfun_press_release(void) {
uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
_kbfun_press_release(IS_PRESSED, keycode);
}
/*
* [name]
* Toggle
*
* [description]
* Toggle the key pressed or unpressed
*/
void kbfun_toggle(void) {
uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
if (_kbfun_is_pressed(keycode))
_kbfun_press_release(false, keycode);
else
_kbfun_press_release(true, keycode);
}
/*
* [name]
* Transparent
*
* [description]
* Execute the key that would have been executed if the current layer was not
* active
*/
void kbfun_transparent(void) {
LAYER_OFFSET++;
LAYER = main_layers_peek(LAYER_OFFSET);
main_layers_pressed[ROW][COL] = LAYER;
main_exec_key();
}
/* ----------------------------------------------------------------------------
* layer push/pop functions
* ------------------------------------------------------------------------- */
static layer_ids[MAX_LAYER_PUSH_POP_FUNCTIONS];
static void layer_push(uint8_t local_id) {
uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
main_layers_pop_id(layer_ids[local_id]);
layer_ids[local_id] = main_layers_push(keycode);
}
static void layer_pop(uint8_t local_id) {
main_layers_pop_id(layer_ids[local_id]);
layer_ids[local_id] = 0;
}
/*
* [name]
* Layer push #1
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_1(void) {
layer_push(1);
}
/*
* [name]
* Layer pop #1
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_1(void) {
layer_pop(1);
}
/*
* [name]
* Layer push #2
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_2(void) {
layer_push(2);
}
/*
* [name]
* Layer pop #2
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_2(void) {
layer_pop(2);
}
/*
* [name]
* Layer push #3
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_3(void) {
layer_push(3);
}
/*
* [name]
* Layer pop #3
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_3(void) {
layer_pop(3);
}
/*
* [name]
* Layer push #4
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_4(void) {
layer_push(4);
}
/*
* [name]
* Layer pop #4
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_4(void) {
layer_pop(4);
}
/*
* [name]
* Layer push #5
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_5(void) {
layer_push(5);
}
/*
* [name]
* Layer pop #5
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_5(void) {
layer_pop(5);
}
/*
* [name]
* Layer push #6
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_6(void) {
layer_push(6);
}
/*
* [name]
* Layer pop #6
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_6(void) {
layer_pop(6);
}
/*
* [name]
* Layer push #7
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_7(void) {
layer_push(7);
}
/*
* [name]
* Layer pop #7
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_7(void) {
layer_pop(7);
}
/*
* [name]
* Layer push #8
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_8(void) {
layer_push(8);
}
/*
* [name]
* Layer pop #8
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_8(void) {
layer_pop(8);
}
/*
* [name]
* Layer push #9
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_9(void) {
layer_push(9);
}
/*
* [name]
* Layer pop #9
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_9(void) {
layer_pop(9);
}
/*
* [name]
* Layer push #10
*
* [description]
* Push a layer element containing the layer value specified in the keymap to
* the top of the stack, and record the id of that layer element
*/
void kbfun_layer_push_10(void) {
layer_push(10);
}
/*
* [name]
* Layer pop #10
*
* [description]
* Pop the layer element created by the corresponding "layer push" function
* out of the layer stack (no matter where it is in the stack, without
* touching any other elements)
*/
void kbfun_layer_pop_10(void) {
layer_pop(10);
}
/* ----------------------------------------------------------------------------
* ------------------------------------------------------------------------- */

View File

@ -1,67 +0,0 @@
/* ----------------------------------------------------------------------------
* key functions : device specific : code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <avr/interrupt.h>
#include <util/delay.h>
#include "../public.h"
// ----------------------------------------------------------------------------
// descriptions
// ----------------------------------------------------------------------------
/*
* [name]
* Jump to Bootloader
*
* [description]
* For reflashing the controller
*/
void kbfun_jump_to_bootloader(void);
// ----------------------------------------------------------------------------
#if MAKEFILE_BOARD == teensy-2-0
// ----------------------------------------------------------------------------
// from PJRC (slightly modified)
// <http://www.pjrc.com/teensy/jump_to_bootloader.html>
void kbfun_jump_to_bootloader(void) {
// --- for all Teensy boards ---
cli();
// disable watchdog, if enabled
// disable all peripherals
UDCON = 1;
USBCON = (1<<FRZCLK); // disable USB
UCSR1B = 0;
_delay_ms(5);
// --- Teensy 2.0 specific ---
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
asm volatile("jmp 0x7E00");
}
// ----------------------------------------------------------------------------
#else
// ----------------------------------------------------------------------------
void kbfun_jump_to_bootloader(void) {}
// ----------------------------------------------------------------------------
#endif
// ----------------------------------------------------------------------------

View File

@ -1,152 +0,0 @@
/* ----------------------------------------------------------------------------
* key functions : special : code
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
#include "../../../lib-other/pjrc/usb_keyboard/usb_keyboard.h"
#include "../../../lib/usb/usage-page/keyboard.h"
#include "../../../keyboard/layout.h"
#include "../../../main.h"
#include "../public.h"
#include "../private.h"
// ----------------------------------------------------------------------------
// convenience macros
#define LAYER main_arg_layer
#define LAYER_OFFSET main_arg_layer_offset
#define ROW main_arg_row
#define COL main_arg_col
#define IS_PRESSED main_arg_is_pressed
#define WAS_PRESSED main_arg_was_pressed
// ----------------------------------------------------------------------------
/*
* [name]
* Shift + press|release
*
* [description]
* Generate a 'shift' press or release before the normal keypress or
* keyrelease
*/
void kbfun_shift_press_release(void) {
_kbfun_press_release(IS_PRESSED, KEY_LeftShift);
kbfun_press_release();
}
/*
* [name]
* Two keys => capslock
*
* [description]
* When assigned to two keys (e.g. the physical left and right shift keys)
* (in both the press and release matrices), pressing and holding down one of
* the keys will make the second key toggle capslock
*
* [note]
* If either of the shifts are pressed when the second key is pressed, they
* wil be released so that capslock will register properly when pressed.
* Capslock will then be pressed and released, and the original state of the
* shifts will be restored
*/
void kbfun_2_keys_capslock_press_release(void) {
static uint8_t keys_pressed;
static bool lshift_pressed;
static bool rshift_pressed;
uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
if (!IS_PRESSED) keys_pressed--;
// take care of the key that was actually pressed
_kbfun_press_release(IS_PRESSED, keycode);
// take care of capslock (only on the press of the 2nd key)
if (keys_pressed == 1 && IS_PRESSED) {
// save the state of left and right shift
lshift_pressed = _kbfun_is_pressed(KEY_LeftShift);
rshift_pressed = _kbfun_is_pressed(KEY_RightShift);
// disable both
_kbfun_press_release(false, KEY_LeftShift);
_kbfun_press_release(false, KEY_RightShift);
// press capslock, then release it
_kbfun_press_release(true, KEY_CapsLock);
usb_keyboard_send();
_kbfun_press_release(false, KEY_CapsLock);
usb_keyboard_send();
// restore the state of left and right shift
if (lshift_pressed)
_kbfun_press_release(true, KEY_LeftShift);
if (rshift_pressed)
_kbfun_press_release(true, KEY_RightShift);
}
if (IS_PRESSED) keys_pressed++;
}
/* ----------------------------------------------------------------------------
* numpad functions
* ------------------------------------------------------------------------- */
static uint8_t numpad_layer_id;
static inline void numpad_toggle_numlock(void) {
_kbfun_press_release(true, KEY_LockingNumLock);
usb_keyboard_send();
_kbfun_press_release(false, KEY_LockingNumLock);
usb_keyboard_send();
}
/*
* [name]
* Numpad on
*
* [description]
* Set the numpad to on (put the numpad layer, specified in the keymap, in an
* element at the top of the layer stack, and record that element's id) and
* toggle numlock (regardless of whether or not numlock is currently on)
*
* [note]
* Meant to be assigned (along with "numpad off") instead of a normal numlock
* key
*/
void kbfun_layer_push_numpad(void) {
uint8_t keycode = kb_layout_get(LAYER, ROW, COL);
main_layers_pop_id(numpad_layer_id);
numpad_layer_id = main_layers_push(keycode);
numpad_toggle_numlock();
}
/*
* [name]
* Numpad off
*
* [description]
* Set the numpad to off (pop the layer element created by "numpad on" out of
* the stack) and toggle numlock (regardless of whether or not numlock is
* currently on)
*
* [note]
* Meant to be assigned (along with "numpad on") instead of a normal numlock
* key
*/
void kbfun_layer_pop_numpad(void) {
main_layers_pop_id(numpad_layer_id);
numpad_layer_id = 0;
numpad_toggle_numlock();
}
/* ----------------------------------------------------------------------------
* ------------------------------------------------------------------------- */

View File

@ -1,12 +0,0 @@
# src/lib/key-functions
These functions may do.. pretty much anything rational that they like. If they
want keycodes to be sent to the host in an aggregate report, they're responsible
for modifying the appropriate report variables.
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------------
* miscellaneous data types
* Common macros
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
@ -7,10 +7,6 @@
* ------------------------------------------------------------------------- */
#ifndef LIB__DATA_TYPES_h
#define LIB__DATA_TYPES_h
typedef void (*void_funptr_t)(void);
#endif
#define STRINGIFY(s) #s
#define EXPAND_STRINGIFY(s) STRINGIFY(s)

View File

@ -1,9 +0,0 @@
# src/lib
Stuff that's generally useful
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -1,16 +0,0 @@
/* ----------------------------------------------------------------------------
* TWI (I2C) : exports
*
* Code specific to different development boards is used by modifying a
* variable in the makefile.
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include "../lib/variable-include.h"
#define INCLUDE EXP_STR( ./twi/MAKEFILE_BOARD.h )
#include INCLUDE

View File

@ -1,95 +0,0 @@
/* ----------------------------------------------------------------------------
* Very simple Teensy 2.0 TWI library : code
*
* - This is mostly straight from the datasheet, section 20.6.6, figure 20-11
* (the code example in C), and section 20.8.1, figure 20-12
* - Also see the documentation for `<util/twi.h>` at
* <http://www.nongnu.org/avr-libc/user-manual/group__util__twi.html#ga8d3aca0acc182f459a51797321728168>
*
* Some other (more complete) TWI libraries for the Teensy 2.0 (and other Atmel
* processors):
* - [i2cmaster] (http://homepage.hispeed.ch/peterfleury/i2cmaster.zip)
* - written by [peter-fleury] (http://homepage.hispeed.ch/peterfleury/)
* - [the arduino twi library]
* (https://github.com/arduino/Arduino/tree/master/libraries/Wire/utility)
* - look for an older version if you need one that doesn't depend on all the
* other Arduino stuff
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
// ----------------------------------------------------------------------------
// conditional compile
#if MAKEFILE_BOARD == teensy-2-0
// ----------------------------------------------------------------------------
#include <util/twi.h>
#include "./teensy-2-0.h"
// ----------------------------------------------------------------------------
void twi_init(void) {
// set the prescaler value to 0
TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
// set the bit rate
// - TWBR should be 10 or higher (datasheet section 20.5.2)
// - TWI_FREQ should be 400000 (400kHz) max (datasheet section 20.1)
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
}
uint8_t twi_start(void) {
// send start
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
// wait for transmission to complete
while (!(TWCR & (1<<TWINT)));
// if it didn't work, return the status code (else return 0)
if ( (TW_STATUS != TW_START) &&
(TW_STATUS != TW_REP_START) )
return TW_STATUS; // error
return 0; // success
}
void twi_stop(void) {
// send stop
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
// wait for transmission to complete
while (TWCR & (1<<TWSTO));
}
uint8_t twi_send(uint8_t data) {
// load data into the data register
TWDR = data;
// send data
TWCR = (1<<TWINT)|(1<<TWEN);
// wait for transmission to complete
while (!(TWCR & (1<<TWINT)));
// if it didn't work, return the status code (else return 0)
if ( (TW_STATUS != TW_MT_SLA_ACK) &&
(TW_STATUS != TW_MT_DATA_ACK) &&
(TW_STATUS != TW_MR_SLA_ACK) )
return TW_STATUS; // error
return 0; // success
}
uint8_t twi_read(uint8_t * data) {
// read 1 byte to TWDR, send ACK
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
// wait for transmission to complete
while (!(TWCR & (1<<TWINT)));
// set data variable
*data = TWDR;
// if it didn't work, return the status code (else return 0)
if (TW_STATUS != TW_MR_DATA_ACK)
return TW_STATUS; // error
return 0; // success
}
// ----------------------------------------------------------------------------
#endif
// ----------------------------------------------------------------------------

View File

@ -1,28 +0,0 @@
/* ----------------------------------------------------------------------------
* Very simple Teensy 2.0 TWI library : exports
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef TWI_h
#define TWI_h
// --------------------------------------------------------------------
#ifndef TWI_FREQ
#define TWI_FREQ 100000 // in Hz
#endif
// --------------------------------------------------------------------
void twi_init (void);
uint8_t twi_start (void);
void twi_stop (void);
uint8_t twi_send (uint8_t data);
uint8_t twi_read (uint8_t * data);
#endif

View File

@ -1,30 +0,0 @@
# Documentation : I&sup2;C : Teensy 2.0
## I&sup2;C Status Codes (for Master modes)
### Master Transmitter (datasheet section 20.8.1, table 20-3)
* `0x08` A START condition has been transmitted
* `0x10` A repeated START condition has been transmitted
* `0x18` SLA+W has been transmitted; ACK has been received
* `0x20` SLA+W has been transmitted; NOT ACK has been received
* `0x28` Data byte has been transmitted; ACK has been received
* `0x30` Data byte has been transmitted; NOT ACK has been received
* `0x38` Arbitration lost in SLA+W or data bytes
### Master Receiver (datasheet section 20.8.2, table 20-4)
* `0x08` A START condition has been transmitted
* `0x10` A repeated START condition has been transmitted
* `0x38` Arbitration lost in SLA+R or NOT ACK bit
* `0x40` SLA+R has been transmitted; ACK has been received
* `0x48` SLA+R has been transmitted; NOT ACK has been received
* `0x50` Data byte has been received; ACK has been returned
* `0x58` Data byte has been received; NOT ACK has been returned
-------------------------------------------------------------------------------
Copyright &copy; 2012 Ben Blazak <benblazak.dev@gmail.com>
Released under The MIT License (MIT) (see "license.md")
Project located at <https://github.com/benblazak/ergodox-firmware>

View File

@ -21,8 +21,8 @@
* ------------------------------------------------------------------------- */
#ifndef USB_USAGE_PAGE_KEYBOARD_h
#define USB_USAGE_PAGE_KEYBOARD_h
#ifndef LIB__USB__USAGE_PAGE__KEYBOARD__H
#define LIB__USB__USAGE_PAGE__KEYBOARD__H
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

View File

@ -2,8 +2,7 @@
* USB Keyboard Key Codes : short names
*
* These are for convenience (and to help with formatting, keeping stuff from
* getting too long). See "keyboard-usage-page.h" for definitions and
* everything.
* getting too long). See "../keyboard.h" for definitions and everything.
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
@ -11,13 +10,13 @@
* ------------------------------------------------------------------------- */
#ifndef USB_USAGE_PAGE_KEYBOARD_SHORT_NAMES_h
#define USB_USAGE_PAGE_KEYBOARD_SHORT_NAMES_h
#ifndef LIB__USB__USAGE_PAGE__KEYBOARD__SHORT_NAMES__H
#define LIB__USB__USAGE_PAGE__KEYBOARD__SHORT_NAMES__H
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#include "./keyboard.h"
#include "./long-names.h"
// ----------------------------------------------------------------------------

View File

@ -20,8 +20,8 @@
* ------------------------------------------------------------------------- */
#ifndef USB_USAGE_PAGE_LED_h
#define USB_USAGE_PAGE_LED_h
#ifndef LIB__USB__USAGE_PAGE__LED__H
#define LIB__USB__USAGE_PAGE__LED__H
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

View File

@ -1,13 +0,0 @@
/* ----------------------------------------------------------------------------
* Macros to help with conditional includes
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#undef INCLUDE
#define STR(s) #s // stringify
#define EXP_STR(s) STR(s) // expand -> stringify

View File

@ -1,272 +0,0 @@
// vim: ts=4 sw=4 sts=4
/* ----------------------------------------------------------------------------
* main()
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
#include <util/delay.h>
#include "./lib-other/pjrc/usb_keyboard/usb_keyboard.h"
#include "./lib/key-functions/public.h"
#include "./keyboard/controller.h"
#include "./keyboard/layout.h"
#include "./keyboard/matrix.h"
#include "./main.h"
// ----------------------------------------------------------------------------
#define MAX_ACTIVE_LAYERS 20
// ----------------------------------------------------------------------------
static bool _main_kb_is_pressed[KB_ROWS][KB_COLUMNS];
bool (*main_kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_main_kb_is_pressed;
static bool _main_kb_was_pressed[KB_ROWS][KB_COLUMNS];
bool (*main_kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_main_kb_was_pressed;
uint8_t main_layers_pressed[KB_ROWS][KB_COLUMNS];
uint8_t main_loop_row;
uint8_t main_loop_col;
uint8_t main_arg_layer;
uint8_t main_arg_layer_offset;
uint8_t main_arg_row;
uint8_t main_arg_col;
bool main_arg_is_pressed;
bool main_arg_was_pressed;
// ----------------------------------------------------------------------------
/*
* main()
*/
int main(void) {
kb_init(); // does controller initialization too
kb_led_state_power_on();
usb_init();
while (!usb_configured());
kb_led_delay_usb_init(); // give the OS time to load drivers, etc.
kb_led_state_ready();
for (;;) {
// swap `main_kb_is_pressed` and `main_kb_was_pressed`, then update
bool (*temp)[KB_ROWS][KB_COLUMNS] = main_kb_was_pressed;
main_kb_was_pressed = main_kb_is_pressed;
main_kb_is_pressed = temp;
kb_update_matrix(*main_kb_is_pressed);
// this loop is responsible to
// - "execute" keys when they change state
// - keep track of which layers the keys were on when they were pressed
// (so they can be released using the function from that layer)
//
// note
// - everything else is the key function's responsibility
// - see the keyboard layout file ("keyboard/ergodox/layout/*.c") for
// which key is assigned which function (per layer)
// - see "lib/key-functions/public/*.c" for the function definitions
#define row main_loop_row
#define col main_loop_col
#define layer main_arg_layer
#define is_pressed main_arg_is_pressed
#define was_pressed main_arg_was_pressed
for (row=0; row<KB_ROWS; row++) {
for (col=0; col<KB_COLUMNS; col++) {
is_pressed = (*main_kb_is_pressed)[row][col];
was_pressed = (*main_kb_was_pressed)[row][col];
if (is_pressed != was_pressed) {
if (is_pressed) {
layer = main_layers_peek(0);
main_layers_pressed[row][col] = layer;
} else {
layer = main_layers_pressed[row][col];
}
// set remaining vars, and "execute" key
main_arg_row = row;
main_arg_col = col;
main_arg_layer_offset = 0;
main_exec_key();
}
}
}
#undef row
#undef col
#undef layer
#undef is_pressed
#undef was_pressed
// send the USB report (even if nothing's changed)
usb_keyboard_send();
_delay_ms(MAKEFILE_DEBOUNCE_TIME);
// update LEDs
if (keyboard_leds & (1<<0)) { kb_led_num_on(); }
else { kb_led_num_off(); }
if (keyboard_leds & (1<<1)) { kb_led_caps_on(); }
else { kb_led_caps_off(); }
if (keyboard_leds & (1<<2)) { kb_led_scroll_on(); }
else { kb_led_scroll_off(); }
if (keyboard_leds & (1<<3)) { kb_led_compose_on(); }
else { kb_led_compose_off(); }
if (keyboard_leds & (1<<4)) { kb_led_kana_on(); }
else { kb_led_kana_off(); }
}
return 0;
}
// ----------------------------------------------------------------------------
// convenience macros (for the helper functions below)
#define layer main_arg_layer
#define row main_arg_row
#define col main_arg_col
#define is_pressed main_arg_is_pressed
#define was_pressed main_arg_was_pressed
// ----------------------------------------------------------------------------
/*
* Exec key
* - Execute the keypress or keyrelease function (if it exists) of the key at
* the current possition.
*/
void main_exec_key(void) {
void (*key_function)(void) =
( (is_pressed)
? kb_layout_press_get(layer, row, col)
: kb_layout_release_get(layer, row, col) );
if (key_function)
(*key_function)();
}
/* ----------------------------------------------------------------------------
* Layer Functions
* ----------------------------------------------------------------------------
* We keep track of which layer is foremost by placing it on a stack. Layers
* may appear in the stack more than once. The base layer will always be
* layer-0.
*
* Implemented as a fixed size stack.
* ------------------------------------------------------------------------- */
// ----------------------------------------------------------------------------
struct layers {
uint8_t layer;
uint8_t id;
};
// ----------------------------------------------------------------------------
struct layers layers[MAX_ACTIVE_LAYERS];
uint8_t layers_head = 0;
uint8_t layers_ids_in_use[MAX_ACTIVE_LAYERS] = {true};
/*
* peek()
*
* Arguments
* - 'offset': the offset (down the stack) from the head element
*
* Returns
* - success: the layer-number of the requested element (which may be 0)
* - failure: 0 (default) (out of bounds)
*/
uint8_t main_layers_peek(uint8_t offset) {
if (offset <= layers_head)
return layers[layers_head - offset].layer;
return 0; // default, or error
}
/*
* push()
*
* Arguments
* - 'layer': the layer-number to push to the top of the stack
*
* Returns
* - success: the id assigned to the newly added element
* - failure: 0 (the stack was already full)
*/
uint8_t main_layers_push(uint8_t layer) {
// look for an available id
for (uint8_t id=1; id<MAX_ACTIVE_LAYERS; id++)
// if one is found
if (layers_ids_in_use[id] == false) {
layers_ids_in_use[id] = true;
layers_head++;
layers[layers_head].layer = layer;
layers[layers_head].id = id;
return id;
}
return 0; // default, or error
}
/*
* pop_id()
*
* Arguments
* - 'id': the id of the element to pop from the stack
*/
void main_layers_pop_id(uint8_t id) {
// look for the element with the id we want to pop
for (uint8_t element=1; element<=layers_head; element++)
// if we find it
if (layers[element].id == id) {
// move all layers above it down one
for (; element<layers_head; element++) {
layers[element].layer = layers[element+1].layer;
layers[element].id = layers[element+1].id;
}
// reinitialize the topmost (now unused) slot
layers[layers_head].layer = 0;
layers[layers_head].id = 0;
// record keeping
layers_ids_in_use[id] = false;
layers_head--;
}
}
/*
* get_offset_id()
*
* Arguments
* - 'id': the id of the element you want the offset of
*
* Returns
* - success: the offset (down the stack from the head element) of the element
* with the given id
* - failure: 0 (default) (id unassigned)
*/
uint8_t main_layers_get_offset_id(uint8_t id) {
// look for the element with the id we want to get the offset of
for (uint8_t element=1; element<=layers_head; element++)
// if we find it
if (layers[element].id == id)
return (layers_head - element);
return 0; // default, or error
}
/* ----------------------------------------------------------------------------
* ------------------------------------------------------------------------- */

View File

@ -1,45 +0,0 @@
/* ----------------------------------------------------------------------------
* main() : functions and data that may be useful externally
* ----------------------------------------------------------------------------
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (MIT) (see "license.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
#ifndef MAIN_h
#define MAIN_h
#include <stdbool.h>
#include <stdint.h>
#include "./keyboard/matrix.h"
// --------------------------------------------------------------------
extern bool (*main_kb_is_pressed)[KB_ROWS][KB_COLUMNS];
extern bool (*main_kb_was_pressed)[KB_ROWS][KB_COLUMNS];
extern uint8_t main_layers_pressed[KB_ROWS][KB_COLUMNS];
extern uint8_t main_loop_row;
extern uint8_t main_loop_col;
extern uint8_t main_arg_layer;
extern uint8_t main_arg_layer_offset;
extern uint8_t main_arg_row;
extern uint8_t main_arg_col;
extern bool main_arg_is_pressed;
extern bool main_arg_was_pressed;
// --------------------------------------------------------------------
void main_exec_key (void);
uint8_t main_layers_peek (uint8_t offset);
uint8_t main_layers_push (uint8_t layer);
void main_layers_pop_id (uint8_t id);
uint8_t main_layers_get_offset_id (uint8_t id);
#endif

View File

@ -1,161 +0,0 @@
# -----------------------------------------------------------------------------
# makefile for the ergoDOX firmware
#
# - .h file dependencies are automatically generated
#
# - This makefile was originally (extensively) modified from the WinAVR
# makefile template, mostly by removing stuff. The copy I used was from
# [pjrc : usb_keyboard] (http://pjrc.com/teensy/usb_keyboard.zip).
# -----------------------------------------------------------------------------
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
# Released under The MIT License (MIT) (see "license.md")
# Project located at <https://github.com/benblazak/ergodox-firmware>
# -----------------------------------------------------------------------------
include makefile-options
FORMAT := ihex # the program binary's format
MCU := atmega32u4 # processor type (for teensy 2.0); must match real life
BOARD := teensy-2-0 # see the libraries you're using for what's available
F_CPU := 16000000 # processor speed, in Hz
# firmware stuff
SRC := $(wildcard *.c)
# keyboard and layout stuff
# --- remove whitespace from vars
KEYBOARD := $(strip $(KEYBOARD))
LAYOUT := $(strip $(LAYOUT))
# --- include stuff
SRC += $(wildcard keyboard/$(KEYBOARD)*.c)
SRC += $(wildcard keyboard/$(KEYBOARD)/*.c)
SRC += $(wildcard keyboard/$(KEYBOARD)/controller/*.c)
SRC += $(wildcard keyboard/$(KEYBOARD)/layout/$(LAYOUT)*.c)
# library stuff
# - should be last in the list of files to compile, in case there are default
# macros that have to be overridden in other source files
# - add more "*/*/..."s as necessary to compile everything.
# - parts of the stuff under "lib" may not be necessary, depending on other
# options, but it's all included here. hopefully any unnecessary stuff gets
# compiled out. else, the makefile will have to become more complicated.
SRC += $(wildcard lib/*.c)
SRC += $(wildcard lib/*/*.c)
SRC += $(wildcard lib/*/*/*.c)
SRC += $(wildcard lib-other/*.c)
SRC += $(wildcard lib-other/*/*.c)
SRC += $(wildcard lib-other/*/*/*.c)
OBJ = $(SRC:%.c=%.o)
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CFLAGS := -mmcu=$(MCU) # processor type (teensy 2.0); must match real
# life
CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization
# in source
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CFLAGS += -DMAKEFILE_BOARD='$(strip $(BOARD))'
CFLAGS += -DMAKEFILE_KEYBOARD='$(strip $(KEYBOARD))'
CFLAGS += -DMAKEFILE_KEYBOARD_LAYOUT='$(strip $(LAYOUT))'
CFLAGS += -DMAKEFILE_DEBOUNCE_TIME='$(strip $(DEBOUNCE_TIME))'
CFLAGS += -DMAKEFILE_LED_BRIGHTNESS='$(strip $(LED_BRIGHTNESS))'
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CFLAGS += -std=gnu99 # use C99 plus GCC extensions
CFLAGS += -Os # optimize for size
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CFLAGS += -Wall # enable lots of common warnings
CFLAGS += -Wstrict-prototypes # "warn if a function is declared or defined
# without specifying the argument types"
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CFLAGS += -fpack-struct # "pack all structure members together without holes"
CFLAGS += -fshort-enums # "allocate to an 'enum' type only as many bytes as it
# needs for the declared range of possible values"
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CFLAGS += -ffunction-sections # \ "place each function or data into its own
CFLAGS += -fdata-sections # / section in the output file if the
# target supports arbitrary sections." for
# linker optimizations, and discarding
# unused code.
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LDFLAGS := -Wl,-Map=$(strip $(TARGET)).map,--cref # generate a link map, with
# a cross reference table
LDFLAGS += -Wl,--relax # for some linker optimizations
LDFLAGS += -Wl,--gc-sections # discard unused functions and data
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
GENDEPFLAGS += -MMD -MP -MF $@.dep # generate dependency files
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CC := avr-gcc
OBJCOPY := avr-objcopy
SIZE := avr-size
# remove whitespace from some of the options
FORMAT := $(strip $(FORMAT))
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
.PHONY: all clean
all: $(TARGET).hex $(TARGET).eep
@echo
@echo '---------------------------------------------------------------'
@echo '------- done --------------------------------------------------'
@echo
$(SIZE) --target=$(FORMAT) $(TARGET).hex
@echo
$(SIZE) --target=$(FORMAT) $(TARGET).eep
@echo
@echo 'you can load "$(TARGET).hex" and "$(TARGET).eep" onto the'
@echo 'Teensy using the Teensy loader'
@echo
@echo '---------------------------------------------------------------'
@echo
clean:
@echo
@echo --- cleaning ---
git clean -dX # remove ignored files and directories
# -----------------------------------------------------------------------------
.SECONDARY:
%.hex: %.elf
@echo
@echo --- making $@ ---
# from the WinAVR makefile template (modified)
$(OBJCOPY) -O $(FORMAT) \
-R .eeprom -R .fuse -R .lock -R .signature \
$< $@
%.eep: %.elf
@echo
@echo --- making $@ ---
# from the WinAVR makefile template (modified)
-$(OBJCOPY) -O $(FORMAT) \
-j .eeprom \
--set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 \
--no-change-warnings \
$< $@ || exit 0
%.elf: $(OBJ)
@echo
@echo --- making $@ ---
$(CC) $(strip $(CFLAGS)) $(strip $(LDFLAGS)) $^ --output $@
%.o: %.c
@echo
@echo --- making $@ ---
$(CC) -c $(strip $(CFLAGS)) $(strip $(GENDEPFLAGS)) $< -o $@
# -----------------------------------------------------------------------------
-include $(OBJ:%=%.dep)

View File

@ -1,26 +0,0 @@
# -----------------------------------------------------------------------------
# certain compilations options
# -----------------------------------------------------------------------------
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
# Released under The MIT License (MIT) (see "license.md")
# Project located at <https://github.com/benblazak/ergodox-firmware>
# -----------------------------------------------------------------------------
TARGET := firmware # the name we want for our program binary
KEYBOARD := ergodox # keyboard model; see "src/keyboard" for what's available
LAYOUT := qwerty-kinesis-mod # keyboard layout
# see "src/keyboard/*/layout" for what's
# available
LED_BRIGHTNESS := 0.5 # a multiplier, with 1 being the max
DEBOUNCE_TIME := 5 # in ms; see keyswitch spec for necessary value; 5ms should
# be good for cherry mx switches
# remove whitespace
TARGET := $(strip $(TARGET))
KEYBOARD := $(strip $(KEYBOARD))
LAYOUT := $(strip $(LAYOUT))
DEBOUNCE_TIME := $(strip $(DEBOUNCE_TIME))