aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2015-08-21 23:14:48 -0400
committerJack Humbert <jack.humb@gmail.com>2015-08-21 23:14:48 -0400
commit476e29d1190ac45b810109512bbb50cc4769493b (patch)
tree1d493bae3b0ae91a6202918aa1bf53fb0da936fa
parent2d76b5c3d421c984f6b4b9da757383cc87e3f808 (diff)
parentb191f8c60fbbaf1fb55d67edb86a6c33489b2ce3 (diff)
downloadqmk_firmware-476e29d1190ac45b810109512bbb50cc4769493b.tar.gz
qmk_firmware-476e29d1190ac45b810109512bbb50cc4769493b.zip
Merge pull request #26 from jackhumbert/midi
Midi
-rw-r--r--common.mk4
-rw-r--r--keyboard/atomic/README.md6
-rw-r--r--keyboard/atomic_old/Makefile135
-rw-r--r--keyboard/atomic_old/Makefile.pjrc116
-rw-r--r--keyboard/atomic_old/README 2.md141
-rw-r--r--keyboard/atomic_old/config.h70
-rw-r--r--keyboard/atomic_old/keymap_common.c30
-rw-r--r--keyboard/atomic_old/keymap_common.h87
-rw-r--r--keyboard/atomic_old/keymap_plain.c46
-rw-r--r--keyboard/atomic_old/keymap_ricky.c15
-rw-r--r--keyboard/atomic_old/keymap_vlad.c14
-rw-r--r--keyboard/atomic_old/led.c25
-rw-r--r--keyboard/atomic_old/matrix.c211
-rwxr-xr-xkeyboard/planck/Config/LUFAConfig.h93
-rw-r--r--keyboard/planck/Makefile6
-rw-r--r--keyboard/planck/config.h7
-rw-r--r--keyboard/planck/config_definitions.h50
-rw-r--r--keyboard/planck/extended_keymap_common.h1
-rw-r--r--keyboard/planck/extended_keymaps/extended_keymap_default.c4
-rw-r--r--keyboard/planck/matrix.c235
-rw-r--r--keyboard/planck/matrix_pcb.c1
-rw-r--r--keyboard/preonic/Makefile138
-rw-r--r--keyboard/preonic/Makefile.pjrc116
-rw-r--r--keyboard/preonic/PCB_GUIDE.md116
-rw-r--r--keyboard/preonic/README.md56
-rw-r--r--keyboard/preonic/__avr_gdbinit6
-rw-r--r--keyboard/preonic/analog.c53
-rw-r--r--keyboard/preonic/analog.h36
-rw-r--r--keyboard/preonic/backlight.c61
-rw-r--r--keyboard/preonic/beeps.c238
-rw-r--r--keyboard/preonic/beeps.h9
-rw-r--r--keyboard/preonic/config.h76
-rw-r--r--keyboard/preonic/config_definitions.h50
-rw-r--r--keyboard/preonic/extended_keymap_common.c210
-rw-r--r--keyboard/preonic/extended_keymap_common.h180
-rw-r--r--keyboard/preonic/extended_keymaps/extended_keymap_default.c65
-rw-r--r--keyboard/preonic/extended_keymaps/extended_keymap_lock.c73
-rw-r--r--keyboard/preonic/led.c38
-rw-r--r--keyboard/preonic/matrix.c234
-rw-r--r--protocol/lufa.mk7
-rw-r--r--protocol/lufa/descriptor.c159
-rw-r--r--protocol/lufa/descriptor.h36
-rw-r--r--protocol/lufa/lufa.c226
-rw-r--r--protocol/lufa/lufa.h3
-rwxr-xr-xprotocol/lufa/midi/Config/LUFAConfig.h93
-rwxr-xr-xprotocol/lufa/midi/bytequeue/COPYING674
-rwxr-xr-xprotocol/lufa/midi/bytequeue/bytequeue.c65
-rwxr-xr-xprotocol/lufa/midi/bytequeue/bytequeue.h59
-rwxr-xr-xprotocol/lufa/midi/bytequeue/interrupt_setting.c36
-rwxr-xr-xprotocol/lufa/midi/bytequeue/interrupt_setting.h39
-rwxr-xr-xprotocol/lufa/midi/midi.c277
-rwxr-xr-xprotocol/lufa/midi/midi.h498
-rwxr-xr-xprotocol/lufa/midi/midi_device.c291
-rwxr-xr-xprotocol/lufa/midi/midi_device.h156
-rwxr-xr-xprotocol/lufa/midi/midi_function_types.h50
-rwxr-xr-xprotocol/lufa/midi/sysex_tools.c99
-rwxr-xr-xprotocol/lufa/midi/sysex_tools.h95
57 files changed, 5902 insertions, 13 deletions
diff --git a/common.mk b/common.mk
index b854f09cd..e61ae69e5 100644
--- a/common.mk
+++ b/common.mk
@@ -49,6 +49,10 @@ ifdef NKRO_ENABLE
49 OPT_DEFS += -DNKRO_ENABLE 49 OPT_DEFS += -DNKRO_ENABLE
50endif 50endif
51 51
52ifdef MIDI_ENABLE
53 OPT_DEFS += -DMIDI_ENABLE
54endif
55
52ifdef USB_6KRO_ENABLE 56ifdef USB_6KRO_ENABLE
53 OPT_DEFS += -DUSB_6KRO_ENABLE 57 OPT_DEFS += -DUSB_6KRO_ENABLE
54endif 58endif
diff --git a/keyboard/atomic/README.md b/keyboard/atomic/README.md
index ee824d26e..3ddaed3a3 100644
--- a/keyboard/atomic/README.md
+++ b/keyboard/atomic/README.md
@@ -1,9 +1,9 @@
1Planck keyboard firmware 1Atomic keyboard firmware
2====================== 2======================
3DIY/Assembled compact ortholinear 40% keyboard by [Ortholinear Keyboards](http://ortholinearkeyboards.com). 3DIY/Assembled ortholinear 60% keyboard by [Ortholinear Keyboards](http://ortholinearkeyboards.com).
4 4
5## Extended Keymap 5## Extended Keymap
6If you include extended_keymap_common.h instead of keymap_common.h at the top of your file, you'll have access to a bunch of goodies: 6If you include extended_keymap_common.h instead of keymap_common.h at the top of your file, you'll have access to a bunch of goodies:t
7 7
8- Use `LSFT()`, `LCTL()`, et. al. (listed in extended_keymap_common.h) as modifiers for keys (daisy-chain-able) 8- Use `LSFT()`, `LCTL()`, et. al. (listed in extended_keymap_common.h) as modifiers for keys (daisy-chain-able)
9- Use `FUNC(1)` instead of `FN1` (etc.) to access the function layers beyond the 32 function layer limit 9- Use `FUNC(1)` instead of `FN1` (etc.) to access the function layers beyond the 32 function layer limit
diff --git a/keyboard/atomic_old/Makefile b/keyboard/atomic_old/Makefile
new file mode 100644
index 000000000..c4e0cb45d
--- /dev/null
+++ b/keyboard/atomic_old/Makefile
@@ -0,0 +1,135 @@
1#----------------------------------------------------------------------------
2# On command line:
3#
4# make all = Make software.
5#
6# make clean = Clean out built project files.
7#
8# make coff = Convert ELF to AVR COFF.
9#
10# make extcoff = Convert ELF to AVR Extended COFF.
11#
12# make program = Download the hex file to the device.
13# Please customize your programmer settings(PROGRAM_CMD)
14#
15# make teensy = Download the hex file to the device, using teensy_loader_cli.
16# (must have teensy_loader_cli installed).
17#
18# make dfu = Download the hex file to the device, using dfu-programmer (must
19# have dfu-programmer installed).
20#
21# make flip = Download the hex file to the device, using Atmel FLIP (must
22# have Atmel FLIP installed).
23#
24# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
25# (must have dfu-programmer installed).
26#
27# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
28# (must have Atmel FLIP installed).
29#
30# make debug = Start either simulavr or avarice as specified for debugging,
31# with avr-gdb or avr-insight as the front end for debugging.
32#
33# make filename.s = Just compile filename.c into the assembler code only.
34#
35# make filename.i = Create a preprocessed source file for use in submitting
36# bug reports to the GCC project.
37#
38# To rebuild project do "make clean" then "make all".
39#----------------------------------------------------------------------------
40
41# Target file name (without extension).
42TARGET = atomic_lufa
43
44# Directory common source filess exist
45TOP_DIR = ../..
46
47# Directory keyboard dependent files exist
48TARGET_DIR = .
49
50# project specific files
51SRC = keymap_common.c \
52 matrix.c \
53 led.c
54
55ifdef KEYMAP
56 SRC := keymap_$(KEYMAP).c $(SRC)
57else
58 SRC := keymap_vlad.c $(SRC)
59endif
60
61CONFIG_H = config.h
62
63
64# MCU name
65#MCU = at90usb1287
66MCU = atmega32u4
67
68# Processor frequency.
69# This will define a symbol, F_CPU, in all source code files equal to the
70# processor frequency in Hz. You can then use this symbol in your source code to
71# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
72# automatically to create a 32-bit value in your source code.
73#
74# This will be an integer division of F_USB below, as it is sourced by
75# F_USB after it has run through any CPU prescalers. Note that this value
76# does not *change* the processor frequency - it should merely be updated to
77# reflect the processor speed set externally so that the code can use accurate
78# software delays.
79F_CPU = 16000000
80
81
82#
83# LUFA specific
84#
85# Target architecture (see library "Board Types" documentation).
86ARCH = AVR8
87
88# Input clock frequency.
89# This will define a symbol, F_USB, in all source code files equal to the
90# input clock frequency (before any prescaling is performed) in Hz. This value may
91# differ from F_CPU if prescaling is used on the latter, and is required as the
92# raw input clock is fed directly to the PLL sections of the AVR for high speed
93# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
94# at the end, this will be done automatically to create a 32-bit value in your
95# source code.
96#
97# If no clock division is performed on the input clock inside the AVR (via the
98# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
99F_USB = $(F_CPU)
100
101# Interrupt driven control endpoint task(+60)
102OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
103
104
105# Boot Section Size in *bytes*
106# Teensy halfKay 512
107# Teensy++ halfKay 1024
108# Atmel DFU loader 4096
109# LUFA bootloader 4096
110# USBaspLoader 2048
111OPT_DEFS += -DBOOTLOADER_SIZE=4096
112
113
114# Build Options
115# comment out to disable the options.
116#
117BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
118MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
119EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
120CONSOLE_ENABLE = yes # Console for debug(+400)
121COMMAND_ENABLE = yes # Commands for debug and configuration
122#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
123NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
124
125
126# Optimize size but this may cause error "relocation truncated to fit"
127#EXTRALDFLAGS = -Wl,--relax
128
129# Search Path
130VPATH += $(TARGET_DIR)
131VPATH += $(TOP_DIR)
132
133include $(TOP_DIR)/protocol/lufa.mk
134include $(TOP_DIR)/common.mk
135include $(TOP_DIR)/rules.mk
diff --git a/keyboard/atomic_old/Makefile.pjrc b/keyboard/atomic_old/Makefile.pjrc
new file mode 100644
index 000000000..9655ff65a
--- /dev/null
+++ b/keyboard/atomic_old/Makefile.pjrc
@@ -0,0 +1,116 @@
1#----------------------------------------------------------------------------
2# On command line:
3#
4# make all = Make software.
5#
6# make clean = Clean out built project files.
7#
8# make coff = Convert ELF to AVR COFF.
9#
10# make extcoff = Convert ELF to AVR Extended COFF.
11#
12# make program = Download the hex file to the device.
13# Please customize your programmer settings(PROGRAM_CMD)
14#
15# make teensy = Download the hex file to the device, using teensy_loader_cli.
16# (must have teensy_loader_cli installed).
17#
18# make dfu = Download the hex file to the device, using dfu-programmer (must
19# have dfu-programmer installed).
20#
21# make flip = Download the hex file to the device, using Atmel FLIP (must
22# have Atmel FLIP installed).
23#
24# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
25# (must have dfu-programmer installed).
26#
27# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
28# (must have Atmel FLIP installed).
29#
30# make debug = Start either simulavr or avarice as specified for debugging,
31# with avr-gdb or avr-insight as the front end for debugging.
32#
33# make filename.s = Just compile filename.c into the assembler code only.
34#
35# make filename.i = Create a preprocessed source file for use in submitting
36# bug reports to the GCC project.
37#
38# To rebuild project do "make clean" then "make all".
39#----------------------------------------------------------------------------
40
41# Target file name (without extension).
42TARGET = gh60_pjrc
43
44# Directory common source filess exist
45TOP_DIR = ../..
46
47# Directory keyboard dependent files exist
48TARGET_DIR = .
49
50# project specific files
51SRC = keymap_common.c \
52 matrix.c \
53 led.c
54
55ifdef KEYMAP
56 SRC := keymap_$(KEYMAP).c $(SRC)
57else
58 SRC := keymap_poker.c $(SRC)
59endif
60
61CONFIG_H = config.h
62
63
64# MCU name, you MUST set this to match the board you are using
65# type "make clean" after changing this, so all files will be rebuilt
66MCU = atmega32u4
67#MCU = at90usb1286
68
69
70# Processor frequency.
71# Normally the first thing your program should do is set the clock prescaler,
72# so your program will run at the correct speed. You should also set this
73# variable to same clock speed. The _delay_ms() macro uses this, and many
74# examples use this variable to calculate timings. Do not add a "UL" here.
75F_CPU = 16000000
76
77
78# Boot Section Size in *bytes*
79# Teensy halfKay 512
80# Atmel DFU loader 4096
81# LUFA bootloader 4096
82OPT_DEFS += -DBOOTLOADER_SIZE=4096
83
84
85# Build Options
86# comment out to disable the options.
87#
88BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
89MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
90EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
91CONSOLE_ENABLE = yes # Console for debug
92COMMAND_ENABLE = yes # Commands for debug and configuration
93SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
94NKRO_ENABLE = yes # USB Nkey Rollover(+500)
95#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
96
97
98# Search Path
99VPATH += $(TARGET_DIR)
100VPATH += $(TOP_DIR)
101
102include $(TOP_DIR)/protocol/pjrc.mk
103include $(TOP_DIR)/common.mk
104include $(TOP_DIR)/rules.mk
105
106plain: OPT_DEFS += -DKEYMAP_PLAIN
107plain: all
108
109poker: OPT_DEFS += -DKEYMAP_POKER
110poker: all
111
112poker_set: OPT_DEFS += -DKEYMAP_POKER_SET
113poker_set: all
114
115poker_bit: OPT_DEFS += -DKEYMAP_POKER_BIT
116poker_bit: all
diff --git a/keyboard/atomic_old/README 2.md b/keyboard/atomic_old/README 2.md
new file mode 100644
index 000000000..510cb5c8b
--- /dev/null
+++ b/keyboard/atomic_old/README 2.md
@@ -0,0 +1,141 @@
1GH60 keyboard firmware
2======================
3DIY compact keyboard designed and run by komar007 and Geekhack community.
4
5- Both Rev.A and Rev.B PCB are supported by one firmware binary(issue #64)
6
7## GH60 Resources
8- [KOMAR's project page](http://blog.komar.be/projects/gh60-programmable-keyboard/)
9- [Prototyping](http://geekhack.org/index.php?topic=34959.0)
10- [Rev.A PCB test](http://geekhack.org/index.php?topic=37570.0)
11- [Rev.B PCB test](http://geekhack.org/index.php?topic=50685.0)
12- [Group buy](http://geekhack.org/index.php?topic=41464.0)
13
14
15## Build
16Move to this directory then just run `make` like:
17
18 $ make
19
20Use `make -f Makefile.pjrc` if you want to use PJRC stack but I find no reason to do so now.
21
22
23## Keymap
24Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `keymap_<name>.c` and see keymap document(you can find in top README.md) and existent keymap files.
25
26To build firmware binary hex file with a certain keymap just do `make` with `KEYMAP` option like:
27
28 $ make KEYMAP=[poker|poker_set|poker_bit|plain|hasu|spacefn|hhkb|<name>]
29
30
31### 1 Poker
32[keymap_poker.c](keymap_poker.c) emulates original Poker layers
33while both [keymap_poker_bit.c](keymap_poker_bit.c) and [keymap_poker_set.c](keymap_poker_set.c) implements same layout in different way and they fix a minor issue of original Poker and enhance arrow keys.
34
35 Fn + Esc = `
36 Fn + {left, down, up, right} = {home, pgdown, pgup, end}
37
38#### 1.0 Default layer
39 ,-----------------------------------------------------------.
40 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
41 |-----------------------------------------------------------|
42 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
43 |-----------------------------------------------------------|
44 |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |
45 |-----------------------------------------------------------|
46 |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
47 |-----------------------------------------------------------|
48 |Ctrl|Gui |Alt | Space |Fn |Gui |App |Ctrl|
49 `-----------------------------------------------------------'
50#### 1.1 Poker Fn layer
51 ,-----------------------------------------------------------.
52 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| |
53 |-----------------------------------------------------------|
54 | |FnQ| Up| | | | | | |Cal| |Hom|Ins| |
55 |-----------------------------------------------------------|
56 | |Lef|Dow|Rig| | |Psc|Slk|Pau| |Tsk|End| |
57 |-----------------------------------------------------------|
58 | |Del| |Web|Mut|VoU|VoD| |PgU|PgD|Del| Up |
59 |-----------------------------------------------------------|
60 | | | | FnS |Fn |Left|Down|Righ|
61 `-----------------------------------------------------------'
62
63
64### 2. Plain
65Without any Fn layer this will be useful if you want to use key remapping tool like AHK on host.
66See [keymap_plain.c](keymap_plain.c) for detail.
67
68#### 1.0 Plain Default layer
69 ,-----------------------------------------------------------.
70 |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
71 |-----------------------------------------------------------|
72 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
73 |-----------------------------------------------------------|
74 |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |
75 |-----------------------------------------------------------|
76 |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
77 |-----------------------------------------------------------|
78 |Ctrl|Gui |Alt | Space |Alt |Gui |App |Ctrl|
79 `-----------------------------------------------------------'
80
81
82### 3. Hasu
83This is my favorite keymap with HHKB Fn, Vi cursor and Mousekey layer. See [keymap_hasu.c](keymap_hasu.c) for detail.
84
85
86### 4. SpaceFN
87This layout proposed by spiceBar uses space bar to change layer with using Dual role key technique. See [keymap_spacefn.c](keymap_spacefn.c) and [SpaceFN discussion](http://geekhack.org/index.php?topic=51069.0).
88
89#### 4.0 Default layer
90 ,-----------------------------------------------------------.
91 |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
92 |-----------------------------------------------------------|
93 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
94 |-----------------------------------------------------------|
95 |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |
96 |-----------------------------------------------------------|
97 |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
98 |-----------------------------------------------------------|
99 |Ctrl|Gui |Alt | Space/Fn |Alt |Gui |App |Ctrl|
100 `-----------------------------------------------------------'
101#### 4.1 SpaceFN layer
102 ,-----------------------------------------------------------.
103 |` | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete |
104 |-----------------------------------------------------------|
105 | | | | | | | |Hom|Up |End|Psc|Slk|Pau|Ins |
106 |-----------------------------------------------------------|
107 | | | | | | |PgU|Lef|Dow|Rig| | | |
108 |-----------------------------------------------------------|
109 | | | | | |Spc|PgD|` |~ | | | |
110 |-----------------------------------------------------------|
111 | | | | Fn | | | | |
112 `-----------------------------------------------------------'
113
114
115### 5. HHKB
116[keymap_hhkb.c](keymap_hhkb.c) emulates original HHKB layers.
117#### 5.0: Default layer
118 ,-----------------------------------------------------------.
119 |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `|
120 |-----------------------------------------------------------|
121 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Bspc |
122 |-----------------------------------------------------------|
123 |Ctrl | A| S| D| F| G| H| J| K| L|Fn3| '|Return |
124 |-----------------------------------------------------------|
125 |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn |
126 |-----------------------------------------------------------|
127 | |Gui |Alt | Space | |Alt |Gui | |
128 `-----------------------------------------------------------'
129#### 5.1: HHKB Fn layer
130 ,-----------------------------------------------------------.
131 |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del|
132 |-----------------------------------------------------------|
133 |Caps | | | | | | | |Psc|Slk|Pus|Up | | |
134 |-----------------------------------------------------------|
135 | |VoD|VoU|Mut|Ejc| | *| /|Hom|PgU|Lef|Rig|Enter |
136 |-----------------------------------------------------------|
137 | | | | | | | +| -|End|PgD|Dow| | |
138 |-----------------------------------------------------------|
139 | | | | | | | | |
140 `-----------------------------------------------------------'
141
diff --git a/keyboard/atomic_old/config.h b/keyboard/atomic_old/config.h
new file mode 100644
index 000000000..5ea953805
--- /dev/null
+++ b/keyboard/atomic_old/config.h
@@ -0,0 +1,70 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21
22/* USB Device descriptor parameter */
23#define VENDOR_ID 0xFEED
24#define PRODUCT_ID 0x6060
25#define DEVICE_VER 0x0001
26#define MANUFACTURER Ortholinear Keyboards
27#define PRODUCT Atomic Keyboard
28#define DESCRIPTION t.m.k. keyboard firmware for Atomic
29
30/* key matrix size */
31#define MATRIX_ROWS 5
32#define MATRIX_COLS 15
33
34/* define if matrix has ghost */
35//#define MATRIX_HAS_GHOST
36
37/* Set 0 if debouncing isn't needed */
38#define DEBOUNCE 5
39
40/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
41#define LOCKING_SUPPORT_ENABLE
42/* Locking resynchronize hack */
43#define LOCKING_RESYNC_ENABLE
44
45/* key combination for command */
46#define IS_COMMAND() ( \
47 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
48)
49
50
51
52/*
53 * Feature disable options
54 * These options are also useful to firmware size reduction.
55 */
56
57/* disable debug print */
58//#define NO_DEBUG
59
60/* disable print */
61//#define NO_PRINT
62
63/* disable action features */
64//#define NO_ACTION_LAYER
65//#define NO_ACTION_TAPPING
66//#define NO_ACTION_ONESHOT
67//#define NO_ACTION_MACRO
68//#define NO_ACTION_FUNCTION
69
70#endif
diff --git a/keyboard/atomic_old/keymap_common.c b/keyboard/atomic_old/keymap_common.c
new file mode 100644
index 000000000..fdb1769e1
--- /dev/null
+++ b/keyboard/atomic_old/keymap_common.c
@@ -0,0 +1,30 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "keymap_common.h"
18
19
20/* translates key to keycode */
21uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
22{
23 return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
24}
25
26/* translates Fn keycode to action */
27action_t keymap_fn_to_action(uint8_t keycode)
28{
29 return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) };
30}
diff --git a/keyboard/atomic_old/keymap_common.h b/keyboard/atomic_old/keymap_common.h
new file mode 100644
index 000000000..c582c0135
--- /dev/null
+++ b/keyboard/atomic_old/keymap_common.h
@@ -0,0 +1,87 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#ifndef KEYMAP_COMMON_H
18#define KEYMAP_COMMON_H
19
20#include <stdint.h>
21#include <stdbool.h>
22#include <avr/pgmspace.h>
23#include "keycode.h"
24#include "action.h"
25#include "action_macro.h"
26#include "report.h"
27#include "host.h"
28#include "print.h"
29#include "debug.h"
30#include "keymap.h"
31
32
33extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
34extern const uint16_t fn_actions[];
35
36// JCK: Semi-Standard layout
37#define KEYMAP_JCK( \
38 K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0E, \
39 K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
40 K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, K2E, \
41 K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3C, K3D, K3E, \
42 K40, K41, K43, K46, K4A, K4B, K4C, K4D, K4E \
43) { \
44 { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_NO, KC_##K0E }, \
45 { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E }, \
46 { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_NO, KC_##K2D, KC_##K2E }, \
47 { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_NO, KC_##K3C, KC_##K3D, KC_##K3E }, \
48 { KC_##K40, KC_##K41, KC_NO, KC_##K43, KC_NO, KC_NO, KC_##K46, KC_NO, KC_NO, KC_NO, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E } \
49}
50
51// ASK: Short Space layout
52#define KEYMAP_ASK_MESSY( \
53 K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0E, \
54 K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
55 K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2D, K2E, \
56 K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3C, K3D, K3E, \
57 K40, K41, K43, K44, K46, K48, K49, K4A, K4B, K4C, K4D, K4E \
58) { \
59 { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_NO, KC_##K0E }, \
60 { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E }, \
61 { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_NO, KC_##K2D, KC_##K2E }, \
62 { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_NO, KC_##K3C, KC_##K3D, KC_##K3E }, \
63 { KC_##K40, KC_##K41, KC_NO, KC_##K43, KC_##K44, KC_NO, KC_##K46, KC_NO, KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E } \
64}
65
66#define KEYMAP_ASK( \
67 K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0E, \
68 K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
69 K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \
70 K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3D, K3E, \
71 K40, K41, K43, K44, K46, K47, K48, K4A, K4B, K4C, K4D, K4E \
72) { \
73 { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_NO, KC_##K0E }, \
74 { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E }, \
75 { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_NO, KC_##K2E }, \
76 { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_NO, KC_##K3D, KC_##K3E }, \
77 { KC_##K40, KC_##K41, KC_NO, KC_##K43, KC_##K44, KC_NO, KC_##K46, KC_##K47, KC_##K48, KC_NO, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E } \
78}
79
80
81// MLO: Semi-Grid layout
82
83// KLN: Grid layout
84
85// PKR: Standard layout
86
87#endif
diff --git a/keyboard/atomic_old/keymap_plain.c b/keyboard/atomic_old/keymap_plain.c
new file mode 100644
index 000000000..e7f53649f
--- /dev/null
+++ b/keyboard/atomic_old/keymap_plain.c
@@ -0,0 +1,46 @@
1#include "keymap_common.h"
2
3// JCK: Semi-Standard layout
4
5const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
6 /* 0: qwerty */
7 [0] = KEYMAP_JCK(GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSPC, \
8 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC, RBRC, BSLS, DEL, \
9 ESC, A, S, D, F, G, H, J, K, L, SCLN, QUOT, ENT, MPLY, \
10 LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT, VOLD, VOLU, \
11 LCTL, LALT, LGUI, SPC, FN1, LEFT, DOWN, UP, RGHT),
12 [1] = KEYMAP_JCK(GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSPC, \
13 TAB, Q, W, F, P, G, J, L, U, Y, SCLN, LBRC, RBRC, BSLS, DEL, \
14 ESC, A, R, S, T, D, H, N, E, I, O, QUOT, ENT, MPLY, \
15 LSFT, Z, X, C, V, B, K, M, COMM, DOT, SLSH, RSFT, VOLD, VOLU, \
16 LCTL, LALT, LGUI, SPC, FN1, LEFT, DOWN, UP, RGHT),
17 [2] = KEYMAP_JCK(GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BSPC, \
18 TAB, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, LBRC, RBRC, BSLS, DEL, \
19 ESC, FN3, FN4, TRNS, TRNS, TRNS, TRNS, MINS, EQL, LBRC, RBRC, BSLS, ENT, MPLY, \
20 LSFT, FN9, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT, VOLD, VOLU, \
21 LCTL, LALT, LGUI, SPC, TRNS, MNXT, VOLD, VOLU, MPLY),
22};
23const uint16_t PROGMEM fn_actions[] = {
24 [1] = ACTION_LAYER_MOMENTARY(2), // to Fn overlay
25 [3] = ACTION_DEFAULT_LAYER_SET(0),
26 [4] = ACTION_DEFAULT_LAYER_SET(1),
27
28 [9] = ACTION_MODS_KEY(MOD_LSFT | MOD_RSFT, KC_PAUSE),
29
30 [10] = ACTION_MODS_KEY(MOD_LSFT, KC_1),
31 [11] = ACTION_MODS_KEY(MOD_LSFT, KC_2),
32 [12] = ACTION_MODS_KEY(MOD_LSFT, KC_3),
33 [13] = ACTION_MODS_KEY(MOD_LSFT, KC_4),
34 [14] = ACTION_MODS_KEY(MOD_LSFT, KC_5),
35 [15] = ACTION_MODS_KEY(MOD_LSFT, KC_6),
36 [16] = ACTION_MODS_KEY(MOD_LSFT, KC_7),
37 [17] = ACTION_MODS_KEY(MOD_LSFT, KC_8),
38 [18] = ACTION_MODS_KEY(MOD_LSFT, KC_9),
39 [19] = ACTION_MODS_KEY(MOD_LSFT, KC_0),
40 [20] = ACTION_MODS_KEY(MOD_LSFT, KC_MINS),
41 [21] = ACTION_MODS_KEY(MOD_LSFT, KC_EQL),
42 [22] = ACTION_MODS_KEY(MOD_LSFT, KC_GRV),
43 [23] = ACTION_MODS_KEY(MOD_LSFT, KC_LBRC),
44 [24] = ACTION_MODS_KEY(MOD_LSFT, KC_RBRC),
45 [28] = ACTION_MODS_KEY(MOD_LSFT, KC_BSLS),
46};
diff --git a/keyboard/atomic_old/keymap_ricky.c b/keyboard/atomic_old/keymap_ricky.c
new file mode 100644
index 000000000..fcc91a1fa
--- /dev/null
+++ b/keyboard/atomic_old/keymap_ricky.c
@@ -0,0 +1,15 @@
1#include "keymap_common.h"
2
3// JCK: Semi-Standard layout
4
5const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
6 /* 0: qwerty */
7 [0] = KEYMAP_JCK(GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSPC, \
8 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC, RBRC, BSLS, PSCR, \
9 CAPS, A, S, D, F, G, H, J, K, L, SCLN, QUOT, ENT, INS, \
10 LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT, UP, DEL, \
11 LCTL, LGUI, LALT, SPC, RALT, RCTL, LEFT, DOWN, RGHT)
12};
13const uint16_t PROGMEM fn_actions[] = {
14};
15
diff --git a/keyboard/atomic_old/keymap_vlad.c b/keyboard/atomic_old/keymap_vlad.c
new file mode 100644
index 000000000..e56bcf161
--- /dev/null
+++ b/keyboard/atomic_old/keymap_vlad.c
@@ -0,0 +1,14 @@
1#include "keymap_common.h"
2
3// JCK: Semi-Standard layout
4
5const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
6 /* 0: qwerty */
7 [0] = KEYMAP_ASK(GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSPC, \
8 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC, RBRC, BSLS, DEL, \
9 CAPS, A, S, D, F, G, H, J, K, L, SCLN, QUOT, ENT, VOLU, \
10 LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT, UP, VOLD, \
11 LCTL, LGUI, LALT, LGUI, SPC, RGUI, RALT, RGUI, RCTL, LEFT, DOWN, RGHT)
12};
13const uint16_t PROGMEM fn_actions[] = {
14}; \ No newline at end of file
diff --git a/keyboard/atomic_old/led.c b/keyboard/atomic_old/led.c
new file mode 100644
index 000000000..2d52fbf1c
--- /dev/null
+++ b/keyboard/atomic_old/led.c
@@ -0,0 +1,25 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <avr/io.h>
19#include "stdint.h"
20#include "led.h"
21
22
23void led_set(uint8_t usb_led)
24{
25}
diff --git a/keyboard/atomic_old/matrix.c b/keyboard/atomic_old/matrix.c
new file mode 100644
index 000000000..98102cb69
--- /dev/null
+++ b/keyboard/atomic_old/matrix.c
@@ -0,0 +1,211 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18/*
19 * scan matrix
20 */
21#include <stdint.h>
22#include <stdbool.h>
23#include <avr/io.h>
24#include <util/delay.h>
25#include "action_layer.h"
26#include "print.h"
27#include "debug.h"
28#include "util.h"
29#include "matrix.h"
30
31
32#ifndef DEBOUNCE
33# define DEBOUNCE 10
34#endif
35static uint8_t debouncing = DEBOUNCE;
36
37/* matrix state(1:on, 0:off) */
38static matrix_row_t matrix[MATRIX_ROWS];
39static matrix_row_t matrix_debouncing[MATRIX_ROWS];
40
41static matrix_row_t read_cols(void);
42static void init_cols(void);
43static void unselect_rows(void);
44static void select_row(uint8_t row);
45
46
47inline
48uint8_t matrix_rows(void)
49{
50 return MATRIX_ROWS;
51}
52
53inline
54uint8_t matrix_cols(void)
55{
56 return MATRIX_COLS;
57}
58
59
60void matrix_init(void)
61{
62 // initialize row and col
63 unselect_rows();
64 init_cols();
65
66 // initialize matrix state: all keys off
67 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
68 matrix[i] = 0;
69 matrix_debouncing[i] = 0;
70 }
71}
72
73uint8_t matrix_scan(void)
74{
75 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
76 select_row(i);
77 _delay_us(30); // without this wait read unstable value.
78 matrix_row_t cols = read_cols();
79 if (matrix_debouncing[i] != cols) {
80 matrix_debouncing[i] = cols;
81 if (debouncing) {
82 debug("bounce!: "); debug_hex(debouncing); debug("\n");
83 }
84 debouncing = DEBOUNCE;
85 }
86 unselect_rows();
87 }
88
89 if (debouncing) {
90 if (--debouncing) {
91 _delay_ms(1);
92 } else {
93 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
94 matrix[i] = matrix_debouncing[i];
95 }
96 }
97 }
98
99
100 return 1;
101}
102
103bool matrix_is_modified(void)
104{
105 if (debouncing) return false;
106 return true;
107}
108
109inline
110bool matrix_is_on(uint8_t row, uint8_t col)
111{
112 return (matrix[row] & ((matrix_row_t)1<<col));
113}
114
115inline
116matrix_row_t matrix_get_row(uint8_t row)
117{
118 return matrix[row];
119}
120
121void matrix_print(void)
122{
123 print("\nr/c 0123456789ABCDEF\n");
124 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
125 phex(row); print(": ");
126 pbin_reverse16(matrix_get_row(row));
127 print("\n");
128 }
129}
130
131uint8_t matrix_key_count(void)
132{
133 uint8_t count = 0;
134 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
135 count += bitpop16(matrix[i]);
136 }
137 return count;
138}
139
140/* Column pin configuration
141 * col: 0 1 2 3 4 5 6 7 8 9 10 11
142 * pin: F0 F1 F4 F5 F6 F7 B6 B5 B4 D7 D5 D4
143 */
144
145static void init_cols(void)
146{
147 DDRC &= ~(1<<6 | 1<<7);
148 PORTC |= (1<<6 | 1<<7);
149 DDRD &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
150 PORTD |= (1<<4 | 1<<5 | 1<<6 | 1<<7);
151 DDRB &= ~(1<<4 | 1<<5 | 1<<6);
152 PORTB |= (1<<4 | 1<<5 | 1<<6);
153 DDRF &= ~(1<<0 | 1<<1 | 1<<4 | 1<<5 | 1<<6 | 1<<7);
154 PORTF |= (1<<0 | 1<<1 | 1<<4 | 1<<5 | 1<<6 | 1<<7);
155}
156
157static matrix_row_t read_cols(void)
158{
159 return (PINC&(1<<6) ? 0 : (1<< 0)) |
160 (PINC&(1<<7) ? 0 : (1<< 1)) |
161 (PIND&(1<<5) ? 0 : (1<< 2)) |
162 (PIND&(1<<4) ? 0 : (1<< 3)) |
163 (PIND&(1<<6) ? 0 : (1<< 4)) |
164 (PIND&(1<<7) ? 0 : (1<< 5)) |
165 (PINB&(1<<4) ? 0 : (1<< 6)) |
166 (PINB&(1<<5) ? 0 : (1<< 7)) |
167 (PINB&(1<<6) ? 0 : (1<< 8)) |
168 (PINF&(1<<7) ? 0 : (1<< 9)) |
169 (PINF&(1<<6) ? 0 : (1<<10)) |
170 (PINF&(1<<5) ? 0 : (1<<11)) |
171 (PINF&(1<<4) ? 0 : (1<<12)) |
172 (PINF&(1<<1) ? 0 : (1<<13)) |
173 (PINF&(1<<0) ? 0 : (1<<14));
174}
175
176/* Row pin configuration
177 * row: 0 1 2 3
178 * pin: B0 B1 B2 B3
179 */
180static void unselect_rows(void)
181{
182 // Hi-Z(DDR:0, PORT:0) to unselect
183 DDRB &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<7);
184 PORTB |= (1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<7);
185}
186
187static void select_row(uint8_t row)
188{
189 switch (row) {
190 case 0:
191 DDRB |= (1<<0);
192 PORTB &= ~(1<<0);
193 break;
194 case 1:
195 DDRB |= (1<<1);
196 PORTB &= ~(1<<1);
197 break;
198 case 2:
199 DDRB |= (1<<2);
200 PORTB &= ~(1<<2);
201 break;
202 case 3:
203 DDRB |= (1<<3);
204 PORTB &= ~(1<<3);
205 break;
206 case 4:
207 DDRB |= (1<<7);
208 PORTB &= ~(1<<7);
209 break;
210 }
211}
diff --git a/keyboard/planck/Config/LUFAConfig.h b/keyboard/planck/Config/LUFAConfig.h
new file mode 100755
index 000000000..fa9404498
--- /dev/null
+++ b/keyboard/planck/Config/LUFAConfig.h
@@ -0,0 +1,93 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2012.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29*/
30
31/** \file
32 * \brief LUFA Library Configuration Header File
33 *
34 * This header file is used to configure LUFA's compile time options,
35 * as an alternative to the compile time constants supplied through
36 * a makefile.
37 *
38 * For information on what each token does, refer to the LUFA
39 * manual section "Summary of Compile Tokens".
40 */
41
42#ifndef _LUFA_CONFIG_H_
43#define _LUFA_CONFIG_H_
44
45 #if (ARCH == ARCH_AVR8)
46
47 /* Non-USB Related Configuration Tokens: */
48// #define DISABLE_TERMINAL_CODES
49
50 /* USB Class Driver Related Tokens: */
51// #define HID_HOST_BOOT_PROTOCOL_ONLY
52// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
53// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
54// #define HID_MAX_COLLECTIONS {Insert Value Here}
55// #define HID_MAX_REPORTITEMS {Insert Value Here}
56// #define HID_MAX_REPORT_IDS {Insert Value Here}
57// #define NO_CLASS_DRIVER_AUTOFLUSH
58
59 /* General USB Driver Related Tokens: */
60// #define ORDERED_EP_CONFIG
61 #define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
62 #define USB_DEVICE_ONLY
63// #define USB_HOST_ONLY
64// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
65// #define NO_LIMITED_CONTROLLER_CONNECT
66// #define NO_SOF_EVENTS
67
68 /* USB Device Mode Driver Related Tokens: */
69// #define USE_RAM_DESCRIPTORS
70 #define USE_FLASH_DESCRIPTORS
71// #define USE_EEPROM_DESCRIPTORS
72// #define NO_INTERNAL_SERIAL
73 #define FIXED_CONTROL_ENDPOINT_SIZE 8
74// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
75 #define FIXED_NUM_CONFIGURATIONS 1
76// #define CONTROL_ONLY_DEVICE
77// #define INTERRUPT_CONTROL_ENDPOINT
78// #define NO_DEVICE_REMOTE_WAKEUP
79// #define NO_DEVICE_SELF_POWER
80
81 /* USB Host Mode Driver Related Tokens: */
82// #define HOST_STATE_AS_GPIOR {Insert Value Here}
83// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
84// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
85// #define NO_AUTO_VBUS_MANAGEMENT
86// #define INVERTED_VBUS_ENABLE_LINE
87
88 #else
89
90 #error Unsupported architecture for this LUFA configuration file.
91
92 #endif
93#endif
diff --git a/keyboard/planck/Makefile b/keyboard/planck/Makefile
index cd67c711b..ad25854e6 100644
--- a/keyboard/planck/Makefile
+++ b/keyboard/planck/Makefile
@@ -60,8 +60,7 @@ ifdef COMMON
60 SRC = keymap_common.c \ 60 SRC = keymap_common.c \
61 $(MATRIX) \ 61 $(MATRIX) \
62 led.c \ 62 led.c \
63 backlight.c \ 63 backlight.c
64 beeps.c
65 64
66ifdef KEYMAP 65ifdef KEYMAP
67 SRC := common_keymaps/keymap_$(KEYMAP).c $(SRC) 66 SRC := common_keymaps/keymap_$(KEYMAP).c $(SRC)
@@ -74,8 +73,7 @@ else
74SRC = extended_keymap_common.c \ 73SRC = extended_keymap_common.c \
75 $(MATRIX) \ 74 $(MATRIX) \
76 led.c \ 75 led.c \
77 backlight.c \ 76 backlight.c
78 beeps.c
79 77
80ifdef KEYMAP 78ifdef KEYMAP
81 SRC := extended_keymaps/extended_keymap_$(KEYMAP).c $(SRC) 79 SRC := extended_keymaps/extended_keymap_$(KEYMAP).c $(SRC)
diff --git a/keyboard/planck/config.h b/keyboard/planck/config.h
index 7e95afdde..47cf39a90 100644
--- a/keyboard/planck/config.h
+++ b/keyboard/planck/config.h
@@ -18,19 +18,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18#ifndef CONFIG_H 18#ifndef CONFIG_H
19#define CONFIG_H 19#define CONFIG_H
20 20
21#include "config_definitions.h"
21 22
22/* USB Device descriptor parameter */ 23/* USB Device descriptor parameter */
23#define VENDOR_ID 0xFEED 24#define VENDOR_ID 0xFEED
24#define PRODUCT_ID 0x6060 25#define PRODUCT_ID 0x6060
25#define DEVICE_VER 0x0001 26#define DEVICE_VER 0x0001
26#define MANUFACTURER Ortholinear Keyboards 27#define MANUFACTURER Ortholinear Keyboards
27#define PRODUCT Planck 28#define PRODUCT The Planck Keyboard
28#define DESCRIPTION A compact ortholinear keyboard 29#define DESCRIPTION A compact ortholinear keyboard
29 30
30/* key matrix size */ 31/* key matrix size */
31#define MATRIX_ROWS 4 32#define MATRIX_ROWS 4
32#define MATRIX_COLS 12 33#define MATRIX_COLS 12
33 34
35/* Planck PCB default pin-out */
36#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
37#define ROWS (int []){ D0, D5, B5, B6 }
38
34/* define if matrix has ghost */ 39/* define if matrix has ghost */
35//#define MATRIX_HAS_GHOST 40//#define MATRIX_HAS_GHOST
36 41
diff --git a/keyboard/planck/config_definitions.h b/keyboard/planck/config_definitions.h
new file mode 100644
index 000000000..fd138b884
--- /dev/null
+++ b/keyboard/planck/config_definitions.h
@@ -0,0 +1,50 @@
1#ifndef CONFIG_DEFINITIONS_H
2#define CONFIG_DEFINITIONS_H
3
4#define B0 0x20
5#define B1 0x21
6#define B2 0x22
7#define B3 0x23
8#define B4 0x24
9#define B5 0x25
10#define B6 0x26
11#define B7 0x27
12#define C0 0x30
13#define C1 0x31
14#define C2 0x32
15#define C3 0x33
16#define C4 0x34
17#define C5 0x35
18#define C6 0x36
19#define C7 0x37
20#define D0 0x40
21#define D1 0x41
22#define D2 0x42
23#define D3 0x43
24#define D4 0x44
25#define D5 0x45
26#define D6 0x46
27#define D7 0x47
28#define E0 0x50
29#define E1 0x51
30#define E2 0x52
31#define E3 0x53
32#define E4 0x54
33#define E5 0x55
34#define E6 0x56
35#define E7 0x57
36#define F0 0x60
37#define F1 0x61
38#define F2 0x62
39#define F3 0x63
40#define F4 0x64
41#define F5 0x65
42#define F6 0x66
43#define F7 0x67
44
45
46
47
48
49#endif
50
diff --git a/keyboard/planck/extended_keymap_common.h b/keyboard/planck/extended_keymap_common.h
index 2dce4a2fa..e6a7dac5b 100644
--- a/keyboard/planck/extended_keymap_common.h
+++ b/keyboard/planck/extended_keymap_common.h
@@ -48,6 +48,7 @@ typedef union {
48keymap_config_t keymap_config; 48keymap_config_t keymap_config;
49#endif 49#endif
50 50
51
51/* translates key to keycode */ 52/* translates key to keycode */
52uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); 53uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
53 54
diff --git a/keyboard/planck/extended_keymaps/extended_keymap_default.c b/keyboard/planck/extended_keymaps/extended_keymap_default.c
index 1d5ac4321..c75144bf4 100644
--- a/keyboard/planck/extended_keymaps/extended_keymap_default.c
+++ b/keyboard/planck/extended_keymaps/extended_keymap_default.c
@@ -1,5 +1,7 @@
1#include "extended_keymap_common.h" 1#include "extended_keymap_common.h"
2#include "backlight.h" 2#include "backlight.h"
3#include "lufa.h"
4#include "debug.h"
3 5
4const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 6const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
5[0] = { /* Qwerty */ 7[0] = { /* Qwerty */
@@ -51,9 +53,11 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
51 case 0: 53 case 0:
52 if (record->event.pressed) { 54 if (record->event.pressed) {
53 register_code(KC_RSFT); 55 register_code(KC_RSFT);
56 midi_send_noteon(&midi_device, 1, 64, 127);
54 backlight_step(); 57 backlight_step();
55 } else { 58 } else {
56 unregister_code(KC_RSFT); 59 unregister_code(KC_RSFT);
60 midi_send_noteoff(&midi_device, 1, 64, 127);
57 } 61 }
58 break; 62 break;
59 } 63 }
diff --git a/keyboard/planck/matrix.c b/keyboard/planck/matrix.c
new file mode 100644
index 000000000..58bd61f75
--- /dev/null
+++ b/keyboard/planck/matrix.c
@@ -0,0 +1,235 @@
1/*
2Copyright 2012 Jun Wako
3Generated by planckkeyboard.com (2014 Jack Humbert)
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/*
20 * scan matrix
21 */
22#include <stdint.h>
23#include <stdbool.h>
24#include <avr/io.h>
25#include <util/delay.h>
26#include "print.h"
27#include "debug.h"
28#include "util.h"
29#include "matrix.h"
30#include "backlight.h" // TODO fix this dependency
31
32#ifndef DEBOUNCE
33# define DEBOUNCE 10
34#endif
35static uint8_t debouncing = DEBOUNCE;
36
37/* matrix state(1:on, 0:off) */
38static matrix_row_t matrix[MATRIX_ROWS];
39static matrix_row_t matrix_debouncing[MATRIX_ROWS];
40
41static matrix_row_t read_cols(void);
42static void init_cols(void);
43static void unselect_rows(void);
44static void select_row(uint8_t row);
45
46inline
47uint8_t matrix_rows(void)
48{
49 return MATRIX_ROWS;
50}
51
52inline
53uint8_t matrix_cols(void)
54{
55 return MATRIX_COLS;
56}
57
58void matrix_init(void)
59{
60 // To use PORTF disable JTAG with writing JTD bit twice within four cycles.
61 MCUCR |= (1<<JTD);
62 MCUCR |= (1<<JTD);
63
64 backlight_init_ports();
65
66 // Turn status LED on
67 DDRE |= (1<<6);
68 PORTE |= (1<<6);
69
70 // initialize row and col
71 unselect_rows();
72 init_cols();
73
74 // initialize matrix state: all keys off
75 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
76 matrix[i] = 0;
77 matrix_debouncing[i] = 0;
78 }
79}
80
81
82uint8_t matrix_scan(void)
83{
84 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
85 select_row(i);
86 _delay_us(30); // without this wait read unstable value.
87 matrix_row_t cols = read_cols();
88 if (matrix_debouncing[i] != cols) {
89 matrix_debouncing[i] = cols;
90 if (debouncing) {
91 debug("bounce!: "); debug_hex(debouncing); debug("\n");
92 }
93 debouncing = DEBOUNCE;
94 }
95 unselect_rows();
96 }
97
98 if (debouncing) {
99 if (--debouncing) {
100 _delay_ms(1);
101 } else {
102 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
103 matrix[i] = matrix_debouncing[i];
104 }
105 }
106 }
107
108 return 1;
109}
110
111bool matrix_is_modified(void)
112{
113 if (debouncing) return false;
114 return true;
115}
116
117inline
118bool matrix_is_on(uint8_t row, uint8_t col)
119{
120 return (matrix[row] & ((matrix_row_t)1<col));
121}
122
123inline
124matrix_row_t matrix_get_row(uint8_t row)
125{
126 return matrix[row];
127}
128
129void matrix_print(void)
130{
131 print("\nr/c 0123456789ABCDEF\n");
132 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
133 phex(row); print(": ");
134 pbin_reverse16(matrix_get_row(row));
135 print("\n");
136 }
137}
138
139uint8_t matrix_key_count(void)
140{
141 uint8_t count = 0;
142 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
143 count += bitpop16(matrix[i]);
144 }
145 return count;
146}
147
148static void init_cols(void)
149{
150 int B = 0, C = 0, D = 0, E = 0, F = 0;
151 for(int x = 0; x < MATRIX_COLS; x++) {
152 int col = COLS[x];
153 if ((col & 0xF0) == 0x20) {
154 B |= (1<<(col & 0x0F));
155 } else if ((col & 0xF0) == 0x30) {
156 C |= (1<<(col & 0x0F));
157 } else if ((col & 0xF0) == 0x40) {
158 D |= (1<<(col & 0x0F));
159 } else if ((col & 0xF0) == 0x50) {
160 E |= (1<<(col & 0x0F));
161 } else if ((col & 0xF0) == 0x60) {
162 F |= (1<<(col & 0x0F));
163 }
164 }
165 DDRB &= ~(B); PORTB |= (B);
166 DDRC &= ~(C); PORTC |= (C);
167 DDRD &= ~(D); PORTD |= (D);
168 DDRE &= ~(E); PORTE |= (E);
169 DDRF &= ~(F); PORTF |= (F);
170}
171
172static matrix_row_t read_cols(void)
173{
174 matrix_row_t result = 0;
175 for(int x = 0; x < MATRIX_COLS; x++) {
176 int col = COLS[x];
177 if ((col & 0xF0) == 0x20) {
178 result |= (PINB&(1<<(col & 0x0F)) ? 0 : (1<<x));
179 } else if ((col & 0xF0) == 0x30) {
180 result |= (PINC&(1<<(col & 0x0F)) ? 0 : (1<<x));
181 } else if ((col & 0xF0) == 0x40) {
182 result |= (PIND&(1<<(col & 0x0F)) ? 0 : (1<<x));
183 } else if ((col & 0xF0) == 0x50) {
184 result |= (PINE&(1<<(col & 0x0F)) ? 0 : (1<<x));
185 } else if ((col & 0xF0) == 0x60) {
186 result |= (PINF&(1<<(col & 0x0F)) ? 0 : (1<<x));
187 }
188 }
189 return result;
190}
191
192static void unselect_rows(void)
193{
194 int B = 0, C = 0, D = 0, E = 0, F = 0;
195 for(int x = 0; x < MATRIX_ROWS; x++) {
196 int row = ROWS[x];
197 if ((row & 0xF0) == 0x20) {
198 B |= (1<<(row & 0x0F));
199 } else if ((row & 0xF0) == 0x30) {
200 C |= (1<<(row & 0x0F));
201 } else if ((row & 0xF0) == 0x40) {
202 D |= (1<<(row & 0x0F));
203 } else if ((row & 0xF0) == 0x50) {
204 E |= (1<<(row & 0x0F));
205 } else if ((row & 0xF0) == 0x60) {
206 F |= (1<<(row & 0x0F));
207 }
208 }
209 DDRB &= ~(B); PORTB |= (B);
210 DDRC &= ~(C); PORTC |= (C);
211 DDRD &= ~(D); PORTD |= (D);
212 DDRE &= ~(E); PORTE |= (E);
213 DDRF &= ~(F); PORTF |= (F);
214}
215
216static void select_row(uint8_t row)
217{
218 int row_pin = ROWS[row];
219 if ((row_pin & 0xF0) == 0x20) {
220 DDRB |= (1<<(row_pin & 0x0F));
221 PORTB &= ~(1<<(row_pin & 0x0F));
222 } else if ((row_pin & 0xF0) == 0x30) {
223 DDRC |= (1<<(row_pin & 0x0F));
224 PORTC &= ~(1<<(row_pin & 0x0F));
225 } else if ((row_pin & 0xF0) == 0x40) {
226 DDRD |= (1<<(row_pin & 0x0F));
227 PORTD &= ~(1<<(row_pin & 0x0F));
228 } else if ((row_pin & 0xF0) == 0x50) {
229 DDRE |= (1<<(row_pin & 0x0F));
230 PORTE &= ~(1<<(row_pin & 0x0F));
231 } else if ((row_pin & 0xF0) == 0x60) {
232 DDRF |= (1<<(row_pin & 0x0F));
233 PORTF &= ~(1<<(row_pin & 0x0F));
234 }
235} \ No newline at end of file
diff --git a/keyboard/planck/matrix_pcb.c b/keyboard/planck/matrix_pcb.c
index 6f6ccd5c1..2a9ec8fcd 100644
--- a/keyboard/planck/matrix_pcb.c
+++ b/keyboard/planck/matrix_pcb.c
@@ -78,6 +78,7 @@ void matrix_init(void)
78 } 78 }
79} 79}
80 80
81
81uint8_t matrix_scan(void) 82uint8_t matrix_scan(void)
82{ 83{
83 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 84 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
diff --git a/keyboard/preonic/Makefile b/keyboard/preonic/Makefile
new file mode 100644
index 000000000..5eb45fe1c
--- /dev/null
+++ b/keyboard/preonic/Makefile
@@ -0,0 +1,138 @@
1#----------------------------------------------------------------------------
2# On command line:
3#
4# make all = Make software.
5#
6# make clean = Clean out built project files.
7#
8# make coff = Convert ELF to AVR COFF.
9#
10# make extcoff = Convert ELF to AVR Extended COFF.
11#
12# make program = Download the hex file to the device.
13# Please customize your programmer settings(PROGRAM_CMD)
14#
15# make teensy = Download the hex file to the device, using teensy_loader_cli.
16# (must have teensy_loader_cli installed).
17#
18# make dfu = Download the hex file to the device, using dfu-programmer (must
19# have dfu-programmer installed).
20#
21# make flip = Download the hex file to the device, using Atmel FLIP (must
22# have Atmel FLIP installed).
23#
24# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
25# (must have dfu-programmer installed).
26#
27# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
28# (must have Atmel FLIP installed).
29#
30# make debug = Start either simulavr or avarice as specified for debugging,
31# with avr-gdb or avr-insight as the front end for debugging.
32#
33# make filename.s = Just compile filename.c into the assembler code only.
34#
35# make filename.i = Create a preprocessed source file for use in submitting
36# bug reports to the GCC project.
37#
38# To rebuild project do "make clean" then "make all".
39#----------------------------------------------------------------------------
40
41# Target file name (without extension).
42TARGET = preonic_lufa
43
44# Directory common source filess exist
45TOP_DIR = ../..
46
47# Directory keyboard dependent files exist
48TARGET_DIR = .
49
50# # project specific files
51SRC = extended_keymap_common.c \
52 matrix.c \
53 led.c \
54 backlight.c
55
56ifdef KEYMAP
57 SRC := extended_keymaps/extended_keymap_$(KEYMAP).c $(SRC)
58else
59 SRC := extended_keymaps/extended_keymap_default.c $(SRC)
60endif
61
62CONFIG_H = config.h
63
64# MCU name
65#MCU = at90usb1287
66MCU = atmega32u4
67
68# Processor frequency.
69# This will define a symbol, F_CPU, in all source code files equal to the
70# processor frequency in Hz. You can then use this symbol in your source code to
71# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
72# automatically to create a 32-bit value in your source code.
73#
74# This will be an integer division of F_USB below, as it is sourced by
75# F_USB after it has run through any CPU prescalers. Note that this value
76# does not *change* the processor frequency - it should merely be updated to
77# reflect the processor speed set externally so that the code can use accurate
78# software delays.
79F_CPU = 16000000
80
81
82#
83# LUFA specific
84#
85# Target architecture (see library "Board Types" documentation).
86ARCH = AVR8
87
88# Input clock frequency.
89# This will define a symbol, F_USB, in all source code files equal to the
90# input clock frequency (before any prescaling is performed) in Hz. This value may
91# differ from F_CPU if prescaling is used on the latter, and is required as the
92# raw input clock is fed directly to the PLL sections of the AVR for high speed
93# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
94# at the end, this will be done automatically to create a 32-bit value in your
95# source code.
96#
97# If no clock division is performed on the input clock inside the AVR (via the
98# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
99F_USB = $(F_CPU)
100
101# Interrupt driven control endpoint task(+60)
102OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
103
104
105# Boot Section Size in *bytes*
106# Teensy halfKay 512
107# Teensy++ halfKay 1024
108# Atmel DFU loader 4096
109# LUFA bootloader 4096
110# USBaspLoader 2048
111OPT_DEFS += -DBOOTLOADER_SIZE=4096
112
113
114# Build Options
115# comment out to disable the options.
116#
117BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
118MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
119EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
120CONSOLE_ENABLE = yes # Console for debug(+400)
121COMMAND_ENABLE = yes # Commands for debug and configuration
122# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
123#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
124NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
125BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
126MIDI_ENABLE = yes # MIDI controls
127BACKLIGHT_ENABLE = yes
128
129# Optimize size but this may cause error "relocation truncated to fit"
130#EXTRALDFLAGS = -Wl,--relax
131
132# Search Path
133VPATH += $(TARGET_DIR)
134VPATH += $(TOP_DIR)
135
136include $(TOP_DIR)/protocol/lufa.mk
137include $(TOP_DIR)/common.mk
138include $(TOP_DIR)/rules.mk
diff --git a/keyboard/preonic/Makefile.pjrc b/keyboard/preonic/Makefile.pjrc
new file mode 100644
index 000000000..be83ba18b
--- /dev/null
+++ b/keyboard/preonic/Makefile.pjrc
@@ -0,0 +1,116 @@
1#----------------------------------------------------------------------------
2# On command line:
3#
4# make all = Make software.
5#
6# make clean = Clean out built project files.
7#
8# make coff = Convert ELF to AVR COFF.
9#
10# make extcoff = Convert ELF to AVR Extended COFF.
11#
12# make program = Download the hex file to the device.
13# Please customize your programmer settings(PROGRAM_CMD)
14#
15# make teensy = Download the hex file to the device, using teensy_loader_cli.
16# (must have teensy_loader_cli installed).
17#
18# make dfu = Download the hex file to the device, using dfu-programmer (must
19# have dfu-programmer installed).
20#
21# make flip = Download the hex file to the device, using Atmel FLIP (must
22# have Atmel FLIP installed).
23#
24# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
25# (must have dfu-programmer installed).
26#
27# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
28# (must have Atmel FLIP installed).
29#
30# make debug = Start either simulavr or avarice as specified for debugging,
31# with avr-gdb or avr-insight as the front end for debugging.
32#
33# make filename.s = Just compile filename.c into the assembler code only.
34#
35# make filename.i = Create a preprocessed source file for use in submitting
36# bug reports to the GCC project.
37#
38# To rebuild project do "make clean" then "make all".
39#----------------------------------------------------------------------------
40
41# Target file name (without extension).
42TARGET = gh60_pjrc
43
44# Directory common source filess exist
45TOP_DIR = ../..
46
47# Directory keyboard dependent files exist
48TARGET_DIR = .
49
50# project specific files
51SRC = keymap_common.c \
52 matrix.c \
53 led.c
54
55ifdef KEYMAP
56 SRC := keymap_$(KEYMAP).c $(SRC)
57else
58 SRC := keymap_jack.c $(SRC)
59endif
60
61CONFIG_H = config.h
62
63
64# MCU name, you MUST set this to match the board you are using
65# type "make clean" after changing this, so all files will be rebuilt
66MCU = atmega32u4
67#MCU = at90usb1286
68
69
70# Processor frequency.
71# Normally the first thing your program should do is set the clock prescaler,
72# so your program will run at the correct speed. You should also set this
73# variable to same clock speed. The _delay_ms() macro uses this, and many
74# examples use this variable to calculate timings. Do not add a "UL" here.
75F_CPU = 16000000
76
77
78# Boot Section Size in *bytes*
79# Teensy halfKay 512
80# Atmel DFU loader 4096
81# LUFA bootloader 4096
82OPT_DEFS += -DBOOTLOADER_SIZE=4096
83
84
85# Build Options
86# comment out to disable the options.
87#
88BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
89MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
90EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
91CONSOLE_ENABLE = yes # Console for debug
92COMMAND_ENABLE = yes # Commands for debug and configuration
93SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
94NKRO_ENABLE = yes # USB Nkey Rollover(+500)
95#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
96
97
98# Search Path
99VPATH += $(TARGET_DIR)
100VPATH += $(TOP_DIR)
101
102include $(TOP_DIR)/protocol/pjrc.mk
103include $(TOP_DIR)/common.mk
104include $(TOP_DIR)/rules.mk
105
106plain: OPT_DEFS += -DKEYMAP_PLAIN
107plain: all
108
109poker: OPT_DEFS += -DKEYMAP_POKER
110poker: all
111
112poker_set: OPT_DEFS += -DKEYMAP_POKER_SET
113poker_set: all
114
115poker_bit: OPT_DEFS += -DKEYMAP_POKER_BIT
116poker_bit: all
diff --git a/keyboard/preonic/PCB_GUIDE.md b/keyboard/preonic/PCB_GUIDE.md
new file mode 100644
index 000000000..c3004c75a
--- /dev/null
+++ b/keyboard/preonic/PCB_GUIDE.md
@@ -0,0 +1,116 @@
1# Planck Firmware Guide
2
3## Setting up the environment
4
5### Windows
61. Install [WinAVR Tools](http://sourceforge.net/projects/winavr/) for AVR GCC compiler.
72. Install [DFU-Programmer][dfu-prog] (the -win one).
83. Start DFU bootloader on the chip first time you will see 'Found New Hardware Wizard' to install driver. If you install device driver properly you can find chip name like 'ATmega32U4' under 'LibUSB-Win32 Devices' tree on 'Device Manager'. If not you will need to update its driver on 'Device Manager' to the `dfu-programmer` driver.
9
10### Mac
111. Install [CrossPack](http://www.obdev.at/products/crosspack/index.html) or install Xcode from the App Store and install the Command Line Tools from `Xcode->Preferences->Downloads`.
122. Install [DFU-Programmer][dfu-prog].
13
14### Linux
151. Install AVR GCC with your favorite package manager.
162. Install [DFU-Programmer][dfu-prog].
17
18##Verify Your Installation
191. Clone the following repository: https://github.com/jackhumbert/tmk_keyboard
202. Open a Terminal and `cd` into `tmk_keyboard/keyboard/planck`
213. Run `make`. This should output a lot of information about the build process.
22
23## Using the built-in functions
24
25Here is a list of some of the functions available from the command line:
26
27* `make clean`: clean the environment - may be required in-between builds
28* `make`: compile the code
29* `make COMMON=true`: compile with the common (non-extended) keymap
30* `make MATRIX=<matrix_file>`: compile with the referenced matrix file. Default if unspecified is `matrix_pcb.c`. For handwired boards, use `matrix_handwired.c`.
31* `make KEYMAP=<keymap>`: compile with the extended keymap file `extended_keymaps/extended_keymap_<keymap>.c`
32* `make COMMON=true KEYMAP=<keymap>`: compile with the common keymap file `common_keymaps/keymap_<keymap>.c`
33* `make dfu`: build and flash the layout to the PCB
34* `make dfu-force`: build and force-flash the layout to the PCB (may be require for first flash)
35
36Generally, the instructions to flash the PCB are as follows:
37
381. Make changes to the appropriate keymap file
392. Save the file
403. `make clean`
414. Press the reset button on the PCB/press the key with the `RESET` keycode
425. `make <arguments> dfu` - use the necessary `KEYMAP=<keymap>` and/or `COMMON=true` arguments here.
43
44## Extended keymap
45
46### Keymap
47
48Unlike the common keymap, prefixing the keycodes with `KC_` is required. A full list of the keycodes is available [here](https://github.com/jackhumbert/tmk_keyboard/blob/master/doc/keycode.txt). For the keycodes available only in the extended keymap, see this [header file](https://github.com/jackhumbert/tmk_keyboard/blob/master/keyboard/planck/extended_keymap_common.h).
49
50You can use modifiers with keycodes like this:
51
52 LCTL(KC_C)
53
54Which will generate Ctrl+c. These are daisy-chainable, meaning you can do things like:
55
56 LCTL(LALT(KC_C))
57
58That will generate Ctrl+Alt+c. The entire list of these functions is here:
59
60* `LCTL()`: Left control
61* `LSFT()` / `S()`: Left shift
62* `LALT()`: Left alt/opt
63* `LGUI()`: Left win/cmd
64* `RCTL()`: Right control
65* `RSFT()`: Right shift
66* `RALT()`: Right alt/opt
67* `RGUI()`: Right win/cmd
68
69`S(KC_1)`-like entries are useful in writing keymaps for the Planck.
70
71### Other keycodes
72
73A number of other keycodes have been added that you may find useful:
74
75* `CM_<key>`: the Colemak equivalent of a key (in place of `KC_<key>`), when using Colemak in software (`CM_O` generates `KC_SCLN`)
76* `RESET`: jump to bootloader for flashing (same as press the reset button)
77* `BL_STEP`: step through the backlight brightnesses
78* `BL_<0-15>`: set backlight brightness to 0-15
79* `BL_DEC`: lower the backlight brightness
80* `BL_INC`: raise the backlight brightness
81* `BL_TOGG`: toggle the backlight on/off
82
83### Function layers
84
85The extended keymap extends the number of function layers from 32 to the near-infinite value of 256. Rather than using `FN<num>` notation (still available, but limited to `FN0`-`FN31`), you can use the `FUNC(<num>)` notation. `F(<num>)` is a shortcut for this.
86
87The function actions are unchanged, and you can see the full list of them [here](https://github.com/jackhumbert/tmk_keyboard/blob/master/common/action_code.h). They are explained in detail [here](https://github.com/jackhumbert/tmk_keyboard/blob/master/doc/keymap.md#2-action).
88
89### Macros
90
91Macros have been setup in the `extended_keymaps/extended_keymaps_default.c` file so that you can use `M(<num>)` to access a macro in the `action_get_macro` section on your keymap. The switch/case structure you see here is required, and is setup for `M(0)` - you'll need to copy and paste the code to look like this (e.g. to support `M(3)`):
92
93 switch(id) {
94 case 0:
95 return MACRODOWN(TYPE(KC_A), END);
96 break;
97 case 1:
98 return MACRODOWN(TYPE(KC_B), END);
99 break;
100 case 2:
101 return MACRODOWN(TYPE(KC_C), END);
102 break;
103 case 3:
104 return MACRODOWN(TYPE(KC_D), END);
105 break;
106 }
107 return MACRO_NONE;
108
109`MACRODOWN()` is a shortcut for `(record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)` which tells the macro to execute when the key is pressed. Without this, the macro will be executed on both the down and up stroke.
110
111[cygwin]: https://www.cygwin.com/
112[mingw]: http://www.mingw.org/
113[mhv]: https://infernoembedded.com/products/avr-tools
114[winavr]: http://winavr.sourceforge.net/
115[crosspack]: http://www.obdev.at/products/crosspack/index.html
116[dfu-prog]: http://dfu-programmer.sourceforge.net/
diff --git a/keyboard/preonic/README.md b/keyboard/preonic/README.md
new file mode 100644
index 000000000..ee824d26e
--- /dev/null
+++ b/keyboard/preonic/README.md
@@ -0,0 +1,56 @@
1Planck keyboard firmware
2======================
3DIY/Assembled compact ortholinear 40% keyboard by [Ortholinear Keyboards](http://ortholinearkeyboards.com).
4
5## Extended Keymap
6If you include extended_keymap_common.h instead of keymap_common.h at the top of your file, you'll have access to a bunch of goodies:
7
8- Use `LSFT()`, `LCTL()`, et. al. (listed in extended_keymap_common.h) as modifiers for keys (daisy-chain-able)
9- Use `FUNC(1)` instead of `FN1` (etc.) to access the function layers beyond the 32 function layer limit
10- Use `CM_F` instead of `KC_F` to get the ColeMak equivilent for shortcuts (maps backwards)
11- Use `MACRODOWN()` instead of `MACRO()` to easily make a keydown macro (`CM_*` works here too)
12
13### Some notes on usage:
14
15- The `KEYMAP()` macro is unable to be used due to the bitwise modifications that take place - refer to extended_keymap_jack.c to see how to set things up with the `KC_` prefix
16- Keep an eye on the Makefile - this needs to include the correct files to work
17- Don't forget to use `const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {` instead of the 8bit equivilent
18
19## Build
20
21Follow [this guide](http://deskthority.net/workshop-f7/how-to-build-your-very-own-keyboard-firmware-t7177.html) to setup your development environment before anything else. Abbreviated instructions are provide at the [bottom of this document](https://github.com/rswiernik/tmk_keyboard/tree/rswiernik_dev/keyboard/planck#environment-setup)
22
23Download the whole firmware [here](https://github.com/jackhumbert/tmk_keyboard/archive/master.zip) and navigate to the keyboard/planck folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex that you can load with the Teensy app onto your Planck (once you've hit reset/shorted GND & RST).
24
25Depending on which keymap you would like to use, you will have to compile slightly differently.
26
27####Default
28To build with the default keymap, simply move to the tmk\_keyboard/keyboard/planck/ and run `make` as follows:
29```
30$ make
31```
32
33## Keymap
34Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create file named `keymap_<name>.c` and see keymap document (you can find in top README.md) and existent keymap files.
35
36####**Extended Keymaps**
37
38To build the firmware binary hex file with an extended keymap just do `make` with `KEYMAP` option like:
39```
40$ make KEYMAP=[common|jack|<name>]
41```
42_The only applicable keymaps will work with this option._ Extended keymaps follow the format **__extended\_keymap\_\<name\>.c__**
43
44####**Common Keymaps**
45
46Building with a common keymap is as simple as adding the COMMON option. Note that only
47```
48$ make KEYMAP=[common|jack|<name>] COMMON=true
49```
50_The only applicable keymaps will work with this option._ Common keymaps follow the format **__keymap\_\<name\>.c__**
51
52## Notable TMK forks (which some of the keymap files are from)
53- [Shane's Fork](https://github.com/shanecelis/tmk_keyboard/tree/master/keyboard/planck)
54- [Pierre's Fork](https://github.com/pcarrier/tmk_keyboard/blob/pcarrier/planck/keyboard/gh60/keymap_planck.c)
55- [Nathan's Fork](https://github.com/nathanrosspowell/tmk_keyboard/tree/planck-jack/keyboard/planck)
56- [Matthew's Fork](https://github.com/pepers/tmk_keyboard/tree/master/keyboard/planck_grid)
diff --git a/keyboard/preonic/__avr_gdbinit b/keyboard/preonic/__avr_gdbinit
new file mode 100644
index 000000000..afc51e6d1
--- /dev/null
+++ b/keyboard/preonic/__avr_gdbinit
@@ -0,0 +1,6 @@
1define reset
2SIGNAL SIGHUP
3end
4file planck_lufa.elf
5target remote localhost:4242
6break main
diff --git a/keyboard/preonic/analog.c b/keyboard/preonic/analog.c
new file mode 100644
index 000000000..49b84ee0e
--- /dev/null
+++ b/keyboard/preonic/analog.c
@@ -0,0 +1,53 @@
1// Simple analog to digitial conversion
2
3#include <avr/io.h>
4#include <avr/pgmspace.h>
5#include <stdint.h>
6#include "analog.h"
7
8
9static uint8_t aref = (1<<REFS0); // default to AREF = Vcc
10
11
12void analogReference(uint8_t mode)
13{
14 aref = mode & 0xC0;
15}
16
17
18// Arduino compatible pin input
19int16_t analogRead(uint8_t pin)
20{
21#if defined(__AVR_ATmega32U4__)
22 static const uint8_t PROGMEM pin_to_mux[] = {
23 0x00, 0x01, 0x04, 0x05, 0x06, 0x07,
24 0x25, 0x24, 0x23, 0x22, 0x21, 0x20};
25 if (pin >= 12) return 0;
26 return adc_read(pgm_read_byte(pin_to_mux + pin));
27#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
28 if (pin >= 8) return 0;
29 return adc_read(pin);
30#else
31 return 0;
32#endif
33}
34
35// Mux input
36int16_t adc_read(uint8_t mux)
37{
38#if defined(__AVR_AT90USB162__)
39 return 0;
40#else
41 uint8_t low;
42
43 ADCSRA = (1<<ADEN) | ADC_PRESCALER; // enable ADC
44 ADCSRB = (1<<ADHSM) | (mux & 0x20); // high speed mode
45 ADMUX = aref | (mux & 0x1F); // configure mux input
46 ADCSRA = (1<<ADEN) | ADC_PRESCALER | (1<<ADSC); // start the conversion
47 while (ADCSRA & (1<<ADSC)) ; // wait for result
48 low = ADCL; // must read LSB first
49 return (ADCH << 8) | low; // must read MSB only once!
50#endif
51}
52
53
diff --git a/keyboard/preonic/analog.h b/keyboard/preonic/analog.h
new file mode 100644
index 000000000..9b95a93be
--- /dev/null
+++ b/keyboard/preonic/analog.h
@@ -0,0 +1,36 @@
1#ifndef _analog_h_included__
2#define _analog_h_included__
3
4#include <stdint.h>
5
6void analogReference(uint8_t mode);
7int16_t analogRead(uint8_t pin);
8int16_t adc_read(uint8_t mux);
9
10#define ADC_REF_POWER (1<<REFS0)
11#define ADC_REF_INTERNAL ((1<<REFS1) | (1<<REFS0))
12#define ADC_REF_EXTERNAL (0)
13
14// These prescaler values are for high speed mode, ADHSM = 1
15#if F_CPU == 16000000L
16#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS1))
17#elif F_CPU == 8000000L
18#define ADC_PRESCALER ((1<<ADPS2) | (1<<ADPS0))
19#elif F_CPU == 4000000L
20#define ADC_PRESCALER ((1<<ADPS2))
21#elif F_CPU == 2000000L
22#define ADC_PRESCALER ((1<<ADPS1) | (1<<ADPS0))
23#elif F_CPU == 1000000L
24#define ADC_PRESCALER ((1<<ADPS1))
25#else
26#define ADC_PRESCALER ((1<<ADPS0))
27#endif
28
29// some avr-libc versions do not properly define ADHSM
30#if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
31#if !defined(ADHSM)
32#define ADHSM (7)
33#endif
34#endif
35
36#endif
diff --git a/keyboard/preonic/backlight.c b/keyboard/preonic/backlight.c
new file mode 100644
index 000000000..f69364b2a
--- /dev/null
+++ b/keyboard/preonic/backlight.c
@@ -0,0 +1,61 @@
1
2#include <avr/io.h>
3#include "backlight.h"
4
5#define CHANNEL OCR1C
6
7void backlight_init_ports()
8{
9
10 // Setup PB7 as output and output low.
11 DDRB |= (1<<7);
12 PORTB &= ~(1<<7);
13
14 // Use full 16-bit resolution.
15 ICR1 = 0xFFFF;
16
17 // I could write a wall of text here to explain... but TL;DW
18 // Go read the ATmega32u4 datasheet.
19 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
20
21 // Pin PB7 = OCR1C (Timer 1, Channel C)
22 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
23 // (i.e. start high, go low when counter matches.)
24 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
25 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
26
27 TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
28 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
29
30 backlight_init();
31}
32
33void backlight_set(uint8_t level)
34{
35 if ( level == 0 )
36 {
37 // Turn off PWM control on PB7, revert to output low.
38 TCCR1A &= ~(_BV(COM1C1));
39 CHANNEL = 0x0;
40 // Prevent backlight blink on lowest level
41 PORTB &= ~(_BV(PORTB7));
42 }
43 else if ( level == BACKLIGHT_LEVELS )
44 {
45 // Prevent backlight blink on lowest level
46 PORTB &= ~(_BV(PORTB7));
47 // Turn on PWM control of PB7
48 TCCR1A |= _BV(COM1C1);
49 // Set the brightness
50 CHANNEL = 0xFFFF;
51 }
52 else
53 {
54 // Prevent backlight blink on lowest level
55 PORTB &= ~(_BV(PORTB7));
56 // Turn on PWM control of PB7
57 TCCR1A |= _BV(COM1C1);
58 // Set the brightness
59 CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
60 }
61} \ No newline at end of file
diff --git a/keyboard/preonic/beeps.c b/keyboard/preonic/beeps.c
new file mode 100644
index 000000000..13e46e1da
--- /dev/null
+++ b/keyboard/preonic/beeps.c
@@ -0,0 +1,238 @@
1#include "beeps.h"
2#include <math.h>
3#include <avr/pgmspace.h>
4#include <avr/interrupt.h>
5#include <avr/io.h>
6
7#define PI 3.14159265
8#define CHANNEL OCR1C
9
10volatile uint16_t sample;
11uint16_t lastSample;
12
13const int sounddata_length=200;
14
15const unsigned char sounddata_data[] PROGMEM = {128,
16128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
17128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
18128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
19128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
20128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
21128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
22128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
23128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
24128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
25128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 129, 127, 129, 128, 127, 133,
26117, 109, 125, 121, 116, 132, 140, 126, 114, 114, 116, 120, 114, 93, 73, 66, 76, 116, 142, 129,
27128, 129, 120, 119, 118, 104, 87, 123, 181, 194, 196, 198, 189, 176, 160, 162, 172, 164, 164, 183,
28197, 188, 168, 167, 170, 165, 185, 209, 206, 196, 196, 199, 185, 162, 156, 167, 176, 173, 170, 166,
29151, 142, 140, 134, 130, 127, 113, 86, 67, 66, 69, 75, 73, 75, 86, 90, 91, 84, 65, 48,
3041, 30, 26, 56, 91, 88, 72, 70, 73, 82, 89, 73, 57, 60, 74, 89, 92, 77, 63, 60,
3153, 47, 56, 64, 63, 61, 56, 54, 52, 36, 16, 22, 51, 66, 67, 70, 76, 88, 99, 92,
3277, 74, 85, 100, 106, 97, 83, 85, 96, 108, 133, 160, 164};
33
34void delay_us(int count) {
35 while(count--) {
36 _delay_us(1);
37 }
38}
39
40void beeps() {
41 // DDRB |= (1<<7);
42 // PORTB &= ~(1<<7);
43
44 // // Use full 16-bit resolution.
45 // ICR1 = 0xFFFF;
46
47 // // I could write a wall of text here to explain... but TL;DW
48 // // Go read the ATmega32u4 datasheet.
49 // // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
50
51 // // Pin PB7 = OCR1C (Timer 1, Channel C)
52 // // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
53 // // (i.e. start high, go low when counter matches.)
54 // // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
55 // // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
56
57 // TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
58 // TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
59
60
61 // // Turn off PWM control on PB7, revert to output low.
62 // // TCCR1A &= ~(_BV(COM1C1));
63 // // CHANNEL = ((1 << level) - 1);
64
65 // // Turn on PWM control of PB7
66 // TCCR1A |= _BV(COM1C1);
67 // // CHANNEL = level << OFFSET | 0x0FFF;
68 // // CHANNEL = 0b1010101010101010;
69
70 // float x = 12;
71 // float y = 24;
72 // float length = 50;
73 // float scale = 1;
74
75 // // int f1 = 1000000/440;
76 // // int f2 = 1000000/880;
77 // // for (uint32_t i = 0; i < length * 1000; i++) {
78 // // // int frequency = 1/((sin(PI*2*i*scale*pow(2, x/12.0))*.5+1 + sin(PI*2*i*scale*pow(2, y/12.0))*.5+1) / 2);
79
80 // // ICR1 = f1; // Set max to the period
81 // // OCR1C = f1 >> 1; // Set compare to half the period
82 // // // _delay_us(10);
83 // // }
84 // int frequency = 1000000/440;
85 // ICR1 = frequency; // Set max to the period
86 // OCR1C = frequency >> 1; // Set compare to half the period
87 // _delay_us(500000);
88
89 // TCCR1A &= ~(_BV(COM1C1));
90 // CHANNEL = 0;
91play_notes();
92
93
94 // play_note(55*pow(2, 0/12.0), 1);
95 // play_note(55*pow(2, 12/12.0), 1);
96 // play_note(55*pow(2, 24/12.0), 1);
97 // play_note(55*pow(2, 0/12.0), 1);
98 // play_note(55*pow(2, 12/12.0), 1);
99 // play_note(55*pow(2, 24/12.0), 1);
100
101 // play_note(0, 4);
102
103 // play_note(55*pow(2, 0/12.0), 8);
104 // play_note(55*pow(2, 12/12.0), 4);
105 // play_note(55*pow(2, 10/12.0), 4);
106 // play_note(55*pow(2, 12/12.0), 8);
107 // play_note(55*pow(2, 10/12.0), 4);
108 // play_note(55*pow(2, 7/12.0), 2);
109 // play_note(55*pow(2, 8/12.0), 2);
110 // play_note(55*pow(2, 7/12.0), 16);
111 // play_note(0, 4);
112 // play_note(55*pow(2, 3/12.0), 8);
113 // play_note(55*pow(2, 5/12.0), 4);
114 // play_note(55*pow(2, 7/12.0), 4);
115 // play_note(55*pow(2, 7/12.0), 8);
116 // play_note(55*pow(2, 5/12.0), 4);
117 // play_note(55*pow(2, 3/12.0), 4);
118 // play_note(55*pow(2, 2/12.0), 16);
119
120
121}
122
123void play_note(float freq, int length) {
124 DDRB |= (1<<7);
125 PORTB &= ~(1<<7);
126
127 if (freq > 0) {
128 int frequency = 1000000/freq;
129 ICR1 = frequency; // Set max to the period
130 OCR1C = frequency >> 1; // Set compare to half the period
131
132 TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
133 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
134 }
135
136 for (int i = 0; i < length; i++) {
137 _delay_us(50000);
138 }
139
140 TCCR1A &= ~(_BV(COM1C1));
141}
142
143// This is called at 8000 Hz to load the next sample.
144ISR(TIMER1_COMPA_vect) {
145 if (sample >= sounddata_length) {
146 if (sample == sounddata_length + lastSample) {
147 TIMSK1 &= ~_BV(OCIE1A);
148
149 // Disable the per-sample timer completely.
150 TCCR1B &= ~_BV(CS10);
151 }
152 else {
153 OCR1C = sounddata_length + lastSample - sample;
154 }
155 }
156 else {
157 OCR1C = pgm_read_byte(&sounddata_data[sample]);
158 }
159
160 ++sample;
161}
162
163void play_notes() {
164
165
166 // Set up Timer 2 to do pulse width modulation on the speaker
167 // pin.
168
169 DDRB |= (1<<7);
170 PORTB &= ~(1<<7);
171
172 // Use internal clock (datasheet p.160)
173 // ASSR &= ~(_BV(EXCLK) | _BV(AS2));
174
175 // Set fast PWM mode (p.157)
176 TCCR1A |= _BV(WGM21) | _BV(WGM20);
177 TCCR1B &= ~_BV(WGM22);
178
179 // Do non-inverting PWM on pin OC2A (p.155)
180 // On the Arduino this is pin 11.
181 TCCR1A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
182 TCCR1A &= ~(_BV(COM2B1) | _BV(COM2B0));
183 // No prescaler (p.158)
184 TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
185
186 // Set initial pulse width to the first sample.
187 OCR1A = pgm_read_byte(&sounddata_data[0]);
188
189
190
191
192 cli();
193
194 // Set CTC mode (Clear Timer on Compare Match) (p.133)
195 // Have to set OCR1A *after*, otherwise it gets reset to 0!
196 TCCR2B = (TCCR2B & ~_BV(WGM13)) | _BV(WGM12);
197 TCCR2A = TCCR2A & ~(_BV(WGM11) | _BV(WGM10));
198
199 // No prescaler (p.134)
200 TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
201
202 // Set the compare register (OCR1A).
203 // OCR1A is a 16-bit register, so we have to do this with
204 // interrupts disabled to be safe.
205 // OCR2A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
206 OCR2A = 2000;
207
208 // Enable interrupt when TCNT1 == OCR1A (p.136)
209 TIMSK1 |= _BV(OCIE2A);
210
211 sample = 0;
212 sei();
213}
214
215void note(int x, float length) {
216 DDRB |= (1<<1);
217 int t = (int)(440*pow(2,-x/12.0)); // starting note
218 for (int y = 0; y < length*1000/t; y++) { // note length
219 PORTB |= (1<<1);
220 delay_us(t);
221 PORTB &= ~(1<<1);
222 delay_us(t);
223 }
224 PORTB &= ~(1<<1);
225}
226
227void true_note(float x, float y, float length) {
228 for (uint32_t i = 0; i < length * 50; i++) {
229 uint32_t v = (uint32_t) (round(sin(PI*2*i*640000*pow(2, x/12.0))*.5+1 + sin(PI*2*i*640000*pow(2, y/12.0))*.5+1) / 2 * pow(2, 8));
230 for (int u = 0; u < 8; u++) {
231 if (v & (1 << u) && !(PORTB&(1<<1)))
232 PORTB |= (1<<1);
233 else if (PORTB&(1<<1))
234 PORTB &= ~(1<<1);
235 }
236 }
237 PORTB &= ~(1<<1);
238} \ No newline at end of file
diff --git a/keyboard/preonic/beeps.h b/keyboard/preonic/beeps.h
new file mode 100644
index 000000000..3e3c634ff
--- /dev/null
+++ b/keyboard/preonic/beeps.h
@@ -0,0 +1,9 @@
1#include <stdint.h>
2#include <stdbool.h>
3#include <avr/io.h>
4#include <util/delay.h>
5
6void note(int x, float length);
7void beeps();
8void true_note(float x, float y, float length);
9void play_note(float freq, int length); \ No newline at end of file
diff --git a/keyboard/preonic/config.h b/keyboard/preonic/config.h
new file mode 100644
index 000000000..00486c470
--- /dev/null
+++ b/keyboard/preonic/config.h
@@ -0,0 +1,76 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_definitions.h"
22
23/* USB Device descriptor parameter */
24#define VENDOR_ID 0xFEED
25#define PRODUCT_ID 0x6060
26#define DEVICE_VER 0x0001
27#define MANUFACTURER Ortholinear Keyboards
28#define PRODUCT The Preonic Keyboard
29#define DESCRIPTION A compact ortholinear keyboard
30
31/* key matrix size */
32#define MATRIX_ROWS 5
33#define MATRIX_COLS 12
34
35/* Planck PCB default pin-out */
36#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
37#define ROWS (int []){ D1, D0, D5, B5, B6 }
38
39/* define if matrix has ghost */
40//#define MATRIX_HAS_GHOST
41
42/* number of backlight levels */
43#define BACKLIGHT_LEVELS 3
44
45/* Set 0 if debouncing isn't needed */
46#define DEBOUNCE 5
47
48/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
49#define LOCKING_SUPPORT_ENABLE
50/* Locking resynchronize hack */
51#define LOCKING_RESYNC_ENABLE
52
53/* key combination for command */
54#define IS_COMMAND() ( \
55 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
56)
57
58/*
59 * Feature disable options
60 * These options are also useful to firmware size reduction.
61 */
62
63/* disable debug print */
64#define NO_DEBUG
65
66/* disable print */
67#define NO_PRINT
68
69/* disable action features */
70//#define NO_ACTION_LAYER
71//#define NO_ACTION_TAPPING
72//#define NO_ACTION_ONESHOT
73//#define NO_ACTION_MACRO
74//#define NO_ACTION_FUNCTION
75
76#endif
diff --git a/keyboard/preonic/config_definitions.h b/keyboard/preonic/config_definitions.h
new file mode 100644
index 000000000..fd138b884
--- /dev/null
+++ b/keyboard/preonic/config_definitions.h
@@ -0,0 +1,50 @@
1#ifndef CONFIG_DEFINITIONS_H
2#define CONFIG_DEFINITIONS_H
3
4#define B0 0x20
5#define B1 0x21
6#define B2 0x22
7#define B3 0x23
8#define B4 0x24
9#define B5 0x25
10#define B6 0x26
11#define B7 0x27
12#define C0 0x30
13#define C1 0x31
14#define C2 0x32
15#define C3 0x33
16#define C4 0x34
17#define C5 0x35
18#define C6 0x36
19#define C7 0x37
20#define D0 0x40
21#define D1 0x41
22#define D2 0x42
23#define D3 0x43
24#define D4 0x44
25#define D5 0x45
26#define D6 0x46
27#define D7 0x47
28#define E0 0x50
29#define E1 0x51
30#define E2 0x52
31#define E3 0x53
32#define E4 0x54
33#define E5 0x55
34#define E6 0x56
35#define E7 0x57
36#define F0 0x60
37#define F1 0x61
38#define F2 0x62
39#define F3 0x63
40#define F4 0x64
41#define F5 0x65
42#define F6 0x66
43#define F7 0x67
44
45
46
47
48
49#endif
50
diff --git a/keyboard/preonic/extended_keymap_common.c b/keyboard/preonic/extended_keymap_common.c
new file mode 100644
index 000000000..ade850844
--- /dev/null
+++ b/keyboard/preonic/extended_keymap_common.c
@@ -0,0 +1,210 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "extended_keymap_common.h"
19#include "report.h"
20#include "keycode.h"
21#include "action_layer.h"
22#include "action.h"
23#include "action_macro.h"
24#include "debug.h"
25#include "backlight.h"
26
27static action_t keycode_to_action(uint16_t keycode);
28
29
30/* converts key to action */
31action_t action_for_key(uint8_t layer, keypos_t key)
32{
33 // 16bit keycodes - important
34 uint16_t keycode = keymap_key_to_keycode(layer, key);
35
36 if (keycode >= 0x0100 && keycode < 0x2000) {
37 // Has a modifier
38 action_t action;
39 // Split it up
40 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF);
41 return action;
42 } else if (keycode >= 0x2000 && keycode < 0x3000) {
43 // Is a shortcut for function layer, pull last 12bits
44 return keymap_func_to_action(keycode & 0xFFF);
45 } else if (keycode >= 0x3000 && keycode < 0x4000) {
46 action_t action;
47 action.code = ACTION_MACRO(keycode & 0xFF);
48 return action;
49 } else if (keycode >= BL_0 & keycode <= BL_15) {
50 action_t action;
51 action.code = ACTION_BACKLIGHT_LEVEL(keycode & 0x000F);
52 return action;
53 } else if (keycode == BL_DEC) {
54 action_t action;
55 action.code = ACTION_BACKLIGHT_DECREASE();
56 return action;
57 } else if (keycode == BL_INC) {
58 action_t action;
59 action.code = ACTION_BACKLIGHT_INCREASE();
60 return action;
61 } else if (keycode == BL_TOGG) {
62 action_t action;
63 action.code = ACTION_BACKLIGHT_TOGGLE();
64 return action;
65 } else if (keycode == BL_STEP) {
66 action_t action;
67 action.code = ACTION_BACKLIGHT_STEP();
68 return action;
69 } else if (keycode == RESET) {
70 bootloader_jump();
71 return;
72 } else if (keycode > RESET) {
73 // MIDI
74 return;
75 }
76
77 switch (keycode) {
78 case KC_FN0 ... KC_FN31:
79 return keymap_fn_to_action(keycode);
80#ifdef BOOTMAGIC_ENABLE
81 case KC_CAPSLOCK:
82 case KC_LOCKING_CAPS:
83 if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
84 return keycode_to_action(KC_LCTL);
85 }
86 return keycode_to_action(keycode);
87 case KC_LCTL:
88 if (keymap_config.swap_control_capslock) {
89 return keycode_to_action(KC_CAPSLOCK);
90 }
91 return keycode_to_action(KC_LCTL);
92 case KC_LALT:
93 if (keymap_config.swap_lalt_lgui) {
94 if (keymap_config.no_gui) {
95 return keycode_to_action(ACTION_NO);
96 }
97 return keycode_to_action(KC_LGUI);
98 }
99 return keycode_to_action(KC_LALT);
100 case KC_LGUI:
101 if (keymap_config.swap_lalt_lgui) {
102 return keycode_to_action(KC_LALT);
103 }
104 if (keymap_config.no_gui) {
105 return keycode_to_action(ACTION_NO);
106 }
107 return keycode_to_action(KC_LGUI);
108 case KC_RALT:
109 if (keymap_config.swap_ralt_rgui) {
110 if (keymap_config.no_gui) {
111 return keycode_to_action(ACTION_NO);
112 }
113 return keycode_to_action(KC_RGUI);
114 }
115 return keycode_to_action(KC_RALT);
116 case KC_RGUI:
117 if (keymap_config.swap_ralt_rgui) {
118 return keycode_to_action(KC_RALT);
119 }
120 if (keymap_config.no_gui) {
121 return keycode_to_action(ACTION_NO);
122 }
123 return keycode_to_action(KC_RGUI);
124 case KC_GRAVE:
125 if (keymap_config.swap_grave_esc) {
126 return keycode_to_action(KC_ESC);
127 }
128 return keycode_to_action(KC_GRAVE);
129 case KC_ESC:
130 if (keymap_config.swap_grave_esc) {
131 return keycode_to_action(KC_GRAVE);
132 }
133 return keycode_to_action(KC_ESC);
134 case KC_BSLASH:
135 if (keymap_config.swap_backslash_backspace) {
136 return keycode_to_action(KC_BSPACE);
137 }
138 return keycode_to_action(KC_BSLASH);
139 case KC_BSPACE:
140 if (keymap_config.swap_backslash_backspace) {
141 return keycode_to_action(KC_BSLASH);
142 }
143 return keycode_to_action(KC_BSPACE);
144#endif
145 default:
146 return keycode_to_action(keycode);
147 }
148}
149
150
151/* Macro */
152__attribute__ ((weak))
153const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
154{
155 return MACRO_NONE;
156}
157
158/* Function */
159__attribute__ ((weak))
160void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
161{
162}
163
164/* translates keycode to action */
165static action_t keycode_to_action(uint16_t keycode)
166{
167 action_t action;
168 switch (keycode) {
169 case KC_A ... KC_EXSEL:
170 case KC_LCTRL ... KC_RGUI:
171 action.code = ACTION_KEY(keycode);
172 break;
173 case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
174 action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
175 break;
176 case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
177 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
178 break;
179 case KC_MS_UP ... KC_MS_ACCEL2:
180 action.code = ACTION_MOUSEKEY(keycode);
181 break;
182 case KC_TRNS:
183 action.code = ACTION_TRANSPARENT;
184 break;
185 default:
186 action.code = ACTION_NO;
187 break;
188 }
189 return action;
190}
191
192
193/* translates key to keycode */
194uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
195{
196 // Read entire word (16bits)
197 return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
198}
199
200/* translates Fn keycode to action */
201action_t keymap_fn_to_action(uint16_t keycode)
202{
203 return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) };
204}
205
206action_t keymap_func_to_action(uint16_t keycode)
207{
208 // For FUNC without 8bit limit
209 return (action_t){ .code = pgm_read_word(&fn_actions[(int)keycode]) };
210}
diff --git a/keyboard/preonic/extended_keymap_common.h b/keyboard/preonic/extended_keymap_common.h
new file mode 100644
index 000000000..e6a7dac5b
--- /dev/null
+++ b/keyboard/preonic/extended_keymap_common.h
@@ -0,0 +1,180 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef KEYMAP_H
19#define KEYMAP_H
20
21#include <stdint.h>
22#include <stdbool.h>
23#include "action.h"
24#include <avr/pgmspace.h>
25#include "keycode.h"
26#include "keymap.h"
27#include "action_macro.h"
28#include "report.h"
29#include "host.h"
30// #include "print.h"
31#include "debug.h"
32
33#ifdef BOOTMAGIC_ENABLE
34/* NOTE: Not portable. Bit field order depends on implementation */
35typedef union {
36 uint16_t raw;
37 struct {
38 bool swap_control_capslock:1;
39 bool capslock_to_control:1;
40 bool swap_lalt_lgui:1;
41 bool swap_ralt_rgui:1;
42 bool no_gui:1;
43 bool swap_grave_esc:1;
44 bool swap_backslash_backspace:1;
45 bool nkro:1;
46 };
47} keymap_config_t;
48keymap_config_t keymap_config;
49#endif
50
51
52/* translates key to keycode */
53uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
54
55/* translates Fn keycode to action */
56action_t keymap_fn_to_action(uint16_t keycode);
57
58/* translates Fn keycode to action */
59action_t keymap_func_to_action(uint16_t keycode);
60
61extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
62extern const uint16_t fn_actions[];
63
64// Ability to use mods in layouts
65#define LCTL(kc) kc | 0x0100
66#define LSFT(kc) kc | 0x0200
67#define LALT(kc) kc | 0x0400
68#define LGUI(kc) kc | 0x0800
69#define RCTL(kc) kc | 0x1100
70#define RSFT(kc) kc | 0x1200
71#define RALT(kc) kc | 0x1400
72#define RGUI(kc) kc | 0x1800
73
74// Alias for function layers than expand past FN31
75#define FUNC(kc) kc | 0x2000
76
77// Aliases
78#define S(kc) LSFT(kc)
79#define F(kc) FUNC(kc)
80
81// For software implementation of colemak
82#define CM_Q KC_Q
83#define CM_W KC_W
84#define CM_F KC_E
85#define CM_P KC_R
86#define CM_G KC_T
87#define CM_J KC_Y
88#define CM_L KC_U
89#define CM_U KC_I
90#define CM_Y KC_O
91#define CM_SCLN KC_P
92
93#define CM_A KC_A
94#define CM_R KC_S
95#define CM_S KC_D
96#define CM_T KC_F
97#define CM_D KC_G
98#define CM_H KC_H
99#define CM_N KC_J
100#define CM_E KC_K
101#define CM_I KC_L
102#define CM_O KC_SCLN
103
104#define CM_Z KC_Z
105#define CM_X KC_X
106#define CM_C KC_C
107#define CM_V KC_V
108#define CM_B KC_B
109#define CM_K KC_N
110#define CM_M KC_M
111#define CM_COMM KC_COMM
112#define CM_DOT KC_DOT
113#define CM_SLSH KC_SLSH
114
115// Make it easy to support these in macros
116#define KC_CM_Q CM_Q
117#define KC_CM_W CM_W
118#define KC_CM_F CM_F
119#define KC_CM_P CM_P
120#define KC_CM_G CM_G
121#define KC_CM_J CM_J
122#define KC_CM_L CM_L
123#define KC_CM_U CM_U
124#define KC_CM_Y CM_Y
125#define KC_CM_SCLN CM_SCLN
126
127#define KC_CM_A CM_A
128#define KC_CM_R CM_R
129#define KC_CM_S CM_S
130#define KC_CM_T CM_T
131#define KC_CM_D CM_D
132#define KC_CM_H CM_H
133#define KC_CM_N CM_N
134#define KC_CM_E CM_E
135#define KC_CM_I CM_I
136#define KC_CM_O CM_O
137
138#define KC_CM_Z CM_Z
139#define KC_CM_X CM_X
140#define KC_CM_C CM_C
141#define KC_CM_V CM_V
142#define KC_CM_B CM_B
143#define KC_CM_K CM_K
144#define KC_CM_M CM_M
145#define KC_CM_COMM CM_COMM
146#define KC_CM_DOT CM_DOT
147#define KC_CM_SLSH CM_SLSH
148
149#define M(kc) kc | 0x3000
150
151#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
152
153#define BL_ON 0x4009
154#define BL_OFF 0x4000
155#define BL_0 0x4000
156#define BL_1 0x4001
157#define BL_2 0x4002
158#define BL_3 0x4003
159#define BL_4 0x4004
160#define BL_5 0x4005
161#define BL_6 0x4006
162#define BL_7 0x4007
163#define BL_8 0x4008
164#define BL_9 0x4009
165#define BL_10 0x400A
166#define BL_11 0x400B
167#define BL_12 0x400C
168#define BL_13 0x400D
169#define BL_14 0x400E
170#define BL_15 0x400F
171#define BL_DEC 0x4010
172#define BL_INC 0x4011
173#define BL_TOGG 0x4012
174#define BL_STEP 0x4013
175
176#define RESET 0x5000
177
178#define MIDI(n) n | 0x6000
179
180#endif
diff --git a/keyboard/preonic/extended_keymaps/extended_keymap_default.c b/keyboard/preonic/extended_keymaps/extended_keymap_default.c
new file mode 100644
index 000000000..c75144bf4
--- /dev/null
+++ b/keyboard/preonic/extended_keymaps/extended_keymap_default.c
@@ -0,0 +1,65 @@
1#include "extended_keymap_common.h"
2#include "backlight.h"
3#include "lufa.h"
4#include "debug.h"
5
6const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
7[0] = { /* Qwerty */
8 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
9 {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
10 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT},
11 {M(0), KC_LCTL, KC_LALT, KC_LGUI, FUNC(2), KC_SPC, KC_SPC, FUNC(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
12 // Space is repeated to accommadate for both spacebar wiring positions
13},
14[1] = { /* Colemak */
15 {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
16 {KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
17 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT},
18 {KC_FN3, KC_LCTL, KC_LALT, KC_LGUI, FUNC(2), KC_SPC, KC_SPC, FUNC(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
19},
20[2] = { /* RAISE */
21 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
22 {KC_TRNS, FUNC(3), FUNC(4), RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
23 {KC_TRNS, KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
24 {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, FUNC(1), KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
25},
26[3] = { /* LOWER */
27 {S(KC_GRV), S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), S(KC_9), S(KC_0), KC_BSPC},
28 {KC_TRNS, FUNC(3), FUNC(4), RESET, KC_TRNS, KC_TRNS, KC_TRNS, S(KC_MINS), S(KC_EQL), S(KC_LBRC), S(KC_RBRC), S(KC_BSLS)},
29 {KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS},
30 {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, FUNC(2), KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
31},
32[4] = { /* TENKEY */
33 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_KP_7, KC_KP_8, KC_KP_9, KC_P, KC_BSPC},
34 {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_KP_4, KC_KP_5, KC_KP_6, KC_SCLN, KC_QUOT},
35 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_KP_1, KC_KP_2, KC_KP_3, KC_SLSH, KC_ENT},
36 {KC_TRNS, KC_LCTL, KC_LALT, KC_LGUI, KC_TRNS, KC_SPC, KC_SPC, KC_KP_0, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
37}
38};
39
40const uint16_t PROGMEM fn_actions[] = {
41 [1] = ACTION_LAYER_MOMENTARY(2), // to RAISE
42 [2] = ACTION_LAYER_MOMENTARY(3), // to LOWER
43
44 [3] = ACTION_DEFAULT_LAYER_SET(0),
45 [4] = ACTION_DEFAULT_LAYER_SET(1),
46
47};
48
49const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
50{
51 // MACRODOWN only works in this function
52 switch(id) {
53 case 0:
54 if (record->event.pressed) {
55 register_code(KC_RSFT);
56 midi_send_noteon(&midi_device, 1, 64, 127);
57 backlight_step();
58 } else {
59 unregister_code(KC_RSFT);
60 midi_send_noteoff(&midi_device, 1, 64, 127);
61 }
62 break;
63 }
64 return MACRO_NONE;
65};
diff --git a/keyboard/preonic/extended_keymaps/extended_keymap_lock.c b/keyboard/preonic/extended_keymaps/extended_keymap_lock.c
new file mode 100644
index 000000000..c35ca8a10
--- /dev/null
+++ b/keyboard/preonic/extended_keymaps/extended_keymap_lock.c
@@ -0,0 +1,73 @@
1#include "extended_keymap_common.h"
2#include "backlight.h"
3#include "action_layer.h"
4#include "lufa.h"
5
6const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
7[0] = { /* Qwerty */
8 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
9 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
10 {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
11 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT},
12 {M(0), KC_LCTL, KC_LALT, KC_LGUI, FUNC(2), KC_SPC, KC_SPC, FUNC(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
13 // Space is repeated to accommadate for both spacebar wiring positions
14},
15[1] = { /* Colemak */
16 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
17 {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
18 {KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
19 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT},
20 {KC_FN3, KC_LCTL, KC_LALT, KC_LGUI, FUNC(2), KC_SPC, KC_SPC, FUNC(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
21},
22[2] = { /* RAISE */
23 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
24 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
25 {KC_TRNS, FUNC(3), FUNC(4), RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
26 {KC_TRNS, KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
27 {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, FUNC(1), KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
28},
29[3] = { /* LOWER */
30 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
31 {S(KC_GRV), S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), S(KC_9), S(KC_0), KC_BSPC},
32 {KC_TRNS, FUNC(3), FUNC(4), RESET, KC_TRNS, KC_TRNS, KC_TRNS, S(KC_MINS), S(KC_EQL), S(KC_LBRC), S(KC_RBRC), S(KC_BSLS)},
33 {KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS},
34 {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, FUNC(2), KC_TRNS, KC_TRNS, KC_TRNS, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
35},
36[4] = { /* TENKEY */
37 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
38 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_KP_7, KC_KP_8, KC_KP_9, KC_P, KC_BSPC},
39 {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_KP_4, KC_KP_5, KC_KP_6, KC_SCLN, KC_QUOT},
40 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_KP_1, KC_KP_2, KC_KP_3, KC_SLSH, KC_ENT},
41 {KC_TRNS, KC_LCTL, KC_LALT, KC_LGUI, KC_TRNS, KC_SPC, KC_SPC, KC_KP_0, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
42}
43};
44
45const uint16_t PROGMEM fn_actions[] = {
46 [1] = ACTION_LAYER_MOMENTARY(2), // to RAISE
47 [2] = ACTION_LAYER_MOMENTARY(3), // to LOWER
48
49 [3] = ACTION_DEFAULT_LAYER_SET(0),
50 [4] = ACTION_DEFAULT_LAYER_SET(1),
51
52};
53
54const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
55{
56 // MACRODOWN only works in this function
57 switch(id) {
58 case 0:
59 if (record->event.pressed) {
60 // register_code(KC_RSFT);
61 backlight_set(BACKLIGHT_LEVELS);
62 midi_send_noteon(&midi_device, 1, 64, 127);
63 layer_on(4);
64 } else {
65 // unregister_code(KC_RSFT);
66 backlight_set(0);
67 midi_send_noteoff(&midi_device, 1, 64, 127);
68 layer_clear();
69 }
70 break;
71 }
72 return MACRO_NONE;
73};
diff --git a/keyboard/preonic/led.c b/keyboard/preonic/led.c
new file mode 100644
index 000000000..2c0574660
--- /dev/null
+++ b/keyboard/preonic/led.c
@@ -0,0 +1,38 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <avr/io.h>
19#include "stdint.h"
20#include "led.h"
21
22
23void led_set(uint8_t usb_led)
24{
25 // // Using PE6 Caps Lock LED
26 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
27 // {
28 // // Output high.
29 // DDRE |= (1<<6);
30 // PORTE |= (1<<6);
31 // }
32 // else
33 // {
34 // // Output low.
35 // DDRE &= ~(1<<6);
36 // PORTE &= ~(1<<6);
37 // }
38}
diff --git a/keyboard/preonic/matrix.c b/keyboard/preonic/matrix.c
new file mode 100644
index 000000000..98ef55ed6
--- /dev/null
+++ b/keyboard/preonic/matrix.c
@@ -0,0 +1,234 @@
1/*
2Copyright 2012 Jun Wako
3Generated by planckkeyboard.com (2014 Jack Humbert)
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/*
20 * scan matrix
21 */
22#include <stdint.h>
23#include <stdbool.h>
24#include <avr/io.h>
25#include <util/delay.h>
26#include "print.h"
27#include "debug.h"
28#include "util.h"
29#include "matrix.h"
30
31#ifndef DEBOUNCE
32# define DEBOUNCE 10
33#endif
34static uint8_t debouncing = DEBOUNCE;
35
36/* matrix state(1:on, 0:off) */
37static matrix_row_t matrix[MATRIX_ROWS];
38static matrix_row_t matrix_debouncing[MATRIX_ROWS];
39
40static matrix_row_t read_cols(void);
41static void init_cols(void);
42static void unselect_rows(void);
43static void select_row(uint8_t row);
44
45inline
46uint8_t matrix_rows(void)
47{
48 return MATRIX_ROWS;
49}
50
51inline
52uint8_t matrix_cols(void)
53{
54 return MATRIX_COLS;
55}
56
57void matrix_init(void)
58{
59 // To use PORTF disable JTAG with writing JTD bit twice within four cycles.
60 MCUCR |= (1<<JTD);
61 MCUCR |= (1<<JTD);
62
63 backlight_init_ports();
64
65 // Turn status LED on
66 DDRE |= (1<<6);
67 PORTE |= (1<<6);
68
69 // initialize row and col
70 unselect_rows();
71 init_cols();
72
73 // initialize matrix state: all keys off
74 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
75 matrix[i] = 0;
76 matrix_debouncing[i] = 0;
77 }
78}
79
80
81uint8_t matrix_scan(void)
82{
83 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
84 select_row(i);
85 _delay_us(30); // without this wait read unstable value.
86 matrix_row_t cols = read_cols();
87 if (matrix_debouncing[i] != cols) {
88 matrix_debouncing[i] = cols;
89 if (debouncing) {
90 debug("bounce!: "); debug_hex(debouncing); debug("\n");
91 }
92 debouncing = DEBOUNCE;
93 }
94 unselect_rows();
95 }
96
97 if (debouncing) {
98 if (--debouncing) {
99 _delay_ms(1);
100 } else {
101 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
102 matrix[i] = matrix_debouncing[i];
103 }
104 }
105 }
106
107 return 1;
108}
109
110bool matrix_is_modified(void)
111{
112 if (debouncing) return false;
113 return true;
114}
115
116inline
117bool matrix_is_on(uint8_t row, uint8_t col)
118{
119 return (matrix[row] & ((matrix_row_t)1<col));
120}
121
122inline
123matrix_row_t matrix_get_row(uint8_t row)
124{
125 return matrix[row];
126}
127
128void matrix_print(void)
129{
130 print("\nr/c 0123456789ABCDEF\n");
131 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
132 phex(row); print(": ");
133 pbin_reverse16(matrix_get_row(row));
134 print("\n");
135 }
136}
137
138uint8_t matrix_key_count(void)
139{
140 uint8_t count = 0;
141 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
142 count += bitpop16(matrix[i]);
143 }
144 return count;
145}
146
147static void init_cols(void)
148{
149 int B = 0, C = 0, D = 0, E = 0, F = 0;
150 for(int x = 0; x < MATRIX_COLS; x++) {
151 int col = COLS[x];
152 if ((col & 0xF0) == 0x20) {
153 B |= (1<<(col & 0x0F));
154 } else if ((col & 0xF0) == 0x30) {
155 C |= (1<<(col & 0x0F));
156 } else if ((col & 0xF0) == 0x40) {
157 D |= (1<<(col & 0x0F));
158 } else if ((col & 0xF0) == 0x50) {
159 E |= (1<<(col & 0x0F));
160 } else if ((col & 0xF0) == 0x60) {
161 F |= (1<<(col & 0x0F));
162 }
163 }
164 DDRB &= ~(B); PORTB |= (B);
165 DDRC &= ~(C); PORTC |= (C);
166 DDRD &= ~(D); PORTD |= (D);
167 DDRE &= ~(E); PORTE |= (E);
168 DDRF &= ~(F); PORTF |= (F);
169}
170
171static matrix_row_t read_cols(void)
172{
173 matrix_row_t result = 0;
174 for(int x = 0; x < MATRIX_COLS; x++) {
175 int col = COLS[x];
176 if ((col & 0xF0) == 0x20) {
177 result |= (PINB&(1<<(col & 0x0F)) ? 0 : (1<<x));
178 } else if ((col & 0xF0) == 0x30) {
179 result |= (PINC&(1<<(col & 0x0F)) ? 0 : (1<<x));
180 } else if ((col & 0xF0) == 0x40) {
181 result |= (PIND&(1<<(col & 0x0F)) ? 0 : (1<<x));
182 } else if ((col & 0xF0) == 0x50) {
183 result |= (PINE&(1<<(col & 0x0F)) ? 0 : (1<<x));
184 } else if ((col & 0xF0) == 0x60) {
185 result |= (PINF&(1<<(col & 0x0F)) ? 0 : (1<<x));
186 }
187 }
188 return result;
189}
190
191static void unselect_rows(void)
192{
193 int B = 0, C = 0, D = 0, E = 0, F = 0;
194 for(int x = 0; x < MATRIX_ROWS; x++) {
195 int row = ROWS[x];
196 if ((row & 0xF0) == 0x20) {
197 B |= (1<<(row & 0x0F));
198 } else if ((row & 0xF0) == 0x30) {
199 C |= (1<<(row & 0x0F));
200 } else if ((row & 0xF0) == 0x40) {
201 D |= (1<<(row & 0x0F));
202 } else if ((row & 0xF0) == 0x50) {
203 E |= (1<<(row & 0x0F));
204 } else if ((row & 0xF0) == 0x60) {
205 F |= (1<<(row & 0x0F));
206 }
207 }
208 DDRB &= ~(B); PORTB |= (B);
209 DDRC &= ~(C); PORTC |= (C);
210 DDRD &= ~(D); PORTD |= (D);
211 DDRE &= ~(E); PORTE |= (E);
212 DDRF &= ~(F); PORTF |= (F);
213}
214
215static void select_row(uint8_t row)
216{
217 int row_pin = ROWS[row];
218 if ((row_pin & 0xF0) == 0x20) {
219 DDRB |= (1<<(row_pin & 0x0F));
220 PORTB &= ~(1<<(row_pin & 0x0F));
221 } else if ((row_pin & 0xF0) == 0x30) {
222 DDRC |= (1<<(row_pin & 0x0F));
223 PORTC &= ~(1<<(row_pin & 0x0F));
224 } else if ((row_pin & 0xF0) == 0x40) {
225 DDRD |= (1<<(row_pin & 0x0F));
226 PORTD &= ~(1<<(row_pin & 0x0F));
227 } else if ((row_pin & 0xF0) == 0x50) {
228 DDRE |= (1<<(row_pin & 0x0F));
229 PORTE &= ~(1<<(row_pin & 0x0F));
230 } else if ((row_pin & 0xF0) == 0x60) {
231 DDRF |= (1<<(row_pin & 0x0F));
232 PORTF &= ~(1<<(row_pin & 0x0F));
233 }
234} \ No newline at end of file
diff --git a/protocol/lufa.mk b/protocol/lufa.mk
index ac70ac039..74a8bef3c 100644
--- a/protocol/lufa.mk
+++ b/protocol/lufa.mk
@@ -19,7 +19,12 @@ endif
19 19
20LUFA_SRC = $(LUFA_DIR)/lufa.c \ 20LUFA_SRC = $(LUFA_DIR)/lufa.c \
21 $(LUFA_DIR)/descriptor.c \ 21 $(LUFA_DIR)/descriptor.c \
22 $(LUFA_SRC_USB) 22 $(LUFA_SRC_USB) \
23 $(LUFA_DIR)/midi/midi.c \
24 $(LUFA_DIR)/midi/midi_device.c \
25 $(LUFA_DIR)/midi/bytequeue/bytequeue.c \
26 $(LUFA_DIR)/midi/bytequeue/interrupt_setting.c \
27 $(LUFA_DIR)/LUFA-git/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c
23 28
24SRC += $(LUFA_SRC) 29SRC += $(LUFA_SRC)
25 30
diff --git a/protocol/lufa/descriptor.c b/protocol/lufa/descriptor.c
index c13a81bda..8a14c5e09 100644
--- a/protocol/lufa/descriptor.c
+++ b/protocol/lufa/descriptor.c
@@ -486,6 +486,165 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
486 .PollingIntervalMS = 0x01 486 .PollingIntervalMS = 0x01
487 }, 487 },
488#endif 488#endif
489
490#ifdef MIDI_ENABLE
491 .Audio_ControlInterface =
492 {
493 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
494
495 .InterfaceNumber = MIDI_INTERFACE,
496 .AlternateSetting = 0,
497
498 .TotalEndpoints = 0,
499
500 .Class = AUDIO_CSCP_AudioClass,
501 .SubClass = AUDIO_CSCP_ControlSubclass,
502 .Protocol = AUDIO_CSCP_ControlProtocol,
503
504 .InterfaceStrIndex = NO_DESCRIPTOR
505 },
506
507 .Audio_ControlInterface_SPC =
508 {
509 .Header = {.Size = sizeof(USB_Audio_Descriptor_Interface_AC_t), .Type = DTYPE_CSInterface},
510 .Subtype = AUDIO_DSUBTYPE_CSInterface_Header,
511
512 .ACSpecification = VERSION_BCD(1,0,0),
513 .TotalLength = sizeof(USB_Audio_Descriptor_Interface_AC_t),
514
515 .InCollection = 1,
516 .InterfaceNumber = MIDI2_INTERFACE,
517 },
518
519 .Audio_StreamInterface =
520 {
521 .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
522
523 .InterfaceNumber = MIDI2_INTERFACE,
524 .AlternateSetting = 0,
525
526 .TotalEndpoints = 2,
527
528 .Class = AUDIO_CSCP_AudioClass,
529 .SubClass = AUDIO_CSCP_MIDIStreamingSubclass,
530 .Protocol = AUDIO_CSCP_StreamingProtocol,
531
532 .InterfaceStrIndex = NO_DESCRIPTOR
533 },
534
535 .Audio_StreamInterface_SPC =
536 {
537 .Header = {.Size = sizeof(USB_MIDI_Descriptor_AudioInterface_AS_t), .Type = DTYPE_CSInterface},
538 .Subtype = AUDIO_DSUBTYPE_CSInterface_General,
539
540 .AudioSpecification = VERSION_BCD(1,0,0),
541
542 .TotalLength = (sizeof(USB_Descriptor_Configuration_t) -
543 offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
544 },
545
546 .MIDI_In_Jack_Emb =
547 {
548 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
549 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
550
551 .JackType = MIDI_JACKTYPE_Embedded,
552 .JackID = 0x01,
553
554 .JackStrIndex = NO_DESCRIPTOR
555 },
556
557 .MIDI_In_Jack_Ext =
558 {
559 .Header = {.Size = sizeof(USB_MIDI_Descriptor_InputJack_t), .Type = DTYPE_CSInterface},
560 .Subtype = AUDIO_DSUBTYPE_CSInterface_InputTerminal,
561
562 .JackType = MIDI_JACKTYPE_External,
563 .JackID = 0x02,
564
565 .JackStrIndex = NO_DESCRIPTOR
566 },
567
568 .MIDI_Out_Jack_Emb =
569 {
570 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
571 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
572
573 .JackType = MIDI_JACKTYPE_Embedded,
574 .JackID = 0x03,
575
576 .NumberOfPins = 1,
577 .SourceJackID = {0x02},
578 .SourcePinID = {0x01},
579
580 .JackStrIndex = NO_DESCRIPTOR
581 },
582
583 .MIDI_Out_Jack_Ext =
584 {
585 .Header = {.Size = sizeof(USB_MIDI_Descriptor_OutputJack_t), .Type = DTYPE_CSInterface},
586 .Subtype = AUDIO_DSUBTYPE_CSInterface_OutputTerminal,
587
588 .JackType = MIDI_JACKTYPE_External,
589 .JackID = 0x04,
590
591 .NumberOfPins = 1,
592 .SourceJackID = {0x01},
593 .SourcePinID = {0x01},
594
595 .JackStrIndex = NO_DESCRIPTOR
596 },
597
598 .MIDI_In_Jack_Endpoint =
599 {
600 .Endpoint =
601 {
602 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
603
604 .EndpointAddress = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM),
605 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
606 .EndpointSize = MIDI_STREAM_EPSIZE,
607 .PollingIntervalMS = 0x05
608 },
609
610 .Refresh = 0,
611 .SyncEndpointNumber = 0
612 },
613
614 .MIDI_In_Jack_Endpoint_SPC =
615 {
616 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
617 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
618
619 .TotalEmbeddedJacks = 0x01,
620 .AssociatedJackID = {0x01}
621 },
622
623 .MIDI_Out_Jack_Endpoint =
624 {
625 .Endpoint =
626 {
627 .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint},
628
629 .EndpointAddress = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
630 .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
631 .EndpointSize = MIDI_STREAM_EPSIZE,
632 .PollingIntervalMS = 0x05
633 },
634
635 .Refresh = 0,
636 .SyncEndpointNumber = 0
637 },
638
639 .MIDI_Out_Jack_Endpoint_SPC =
640 {
641 .Header = {.Size = sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t), .Type = DTYPE_CSEndpoint},
642 .Subtype = AUDIO_DSUBTYPE_CSEndpoint_General,
643
644 .TotalEmbeddedJacks = 0x01,
645 .AssociatedJackID = {0x03}
646 }
647#endif
489}; 648};
490 649
491 650
diff --git a/protocol/lufa/descriptor.h b/protocol/lufa/descriptor.h
index 42af07917..0471ef31d 100644
--- a/protocol/lufa/descriptor.h
+++ b/protocol/lufa/descriptor.h
@@ -85,6 +85,25 @@ typedef struct
85 USB_HID_Descriptor_HID_t NKRO_HID; 85 USB_HID_Descriptor_HID_t NKRO_HID;
86 USB_Descriptor_Endpoint_t NKRO_INEndpoint; 86 USB_Descriptor_Endpoint_t NKRO_INEndpoint;
87#endif 87#endif
88
89#ifdef MIDI_ENABLE
90 // MIDI Audio Control Interface
91 USB_Descriptor_Interface_t Audio_ControlInterface;
92 USB_Audio_Descriptor_Interface_AC_t Audio_ControlInterface_SPC;
93
94 // MIDI Audio Streaming Interface
95 USB_Descriptor_Interface_t Audio_StreamInterface;
96 USB_MIDI_Descriptor_AudioInterface_AS_t Audio_StreamInterface_SPC;
97 USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Emb;
98 USB_MIDI_Descriptor_InputJack_t MIDI_In_Jack_Ext;
99 USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Emb;
100 USB_MIDI_Descriptor_OutputJack_t MIDI_Out_Jack_Ext;
101 USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
102 USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_In_Jack_Endpoint_SPC;
103 USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
104 USB_MIDI_Descriptor_Jack_Endpoint_t MIDI_Out_Jack_Endpoint_SPC;
105#endif
106
88} USB_Descriptor_Configuration_t; 107} USB_Descriptor_Configuration_t;
89 108
90 109
@@ -115,9 +134,15 @@ typedef struct
115# define NKRO_INTERFACE CONSOLE_INTERFACE 134# define NKRO_INTERFACE CONSOLE_INTERFACE
116#endif 135#endif
117 136
137#ifdef MIDI_ENABLE
138# define MIDI_INTERFACE (NKRO_INTERFACE + 1)
139# define MIDI2_INTERFACE (NKRO_INTERFACE + 2)
140#else
141# define MIDI2_INTERFACE NKRO_INTERFACE
142#endif
118 143
119/* nubmer of interfaces */ 144/* nubmer of interfaces */
120#define TOTAL_INTERFACES (NKRO_INTERFACE + 1) 145#define TOTAL_INTERFACES MIDI2_INTERFACE + 1
121 146
122 147
123// Endopoint number and size 148// Endopoint number and size
@@ -150,12 +175,21 @@ typedef struct
150# endif 175# endif
151#endif 176#endif
152 177
178#ifdef MIDI_ENABLE
179# define MIDI_STREAM_IN_EPNUM (NKRO_IN_EPNUM + 1)
180# define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 1)
181#else
182# define MIDI_STREAM_IN_EPNUM NKRO_IN_EPNUM
183# define MIDI_STREAM_OUT_EPNUM NKRO_IN_EPNUM
184#endif
185
153 186
154#define KEYBOARD_EPSIZE 8 187#define KEYBOARD_EPSIZE 8
155#define MOUSE_EPSIZE 8 188#define MOUSE_EPSIZE 8
156#define EXTRAKEY_EPSIZE 8 189#define EXTRAKEY_EPSIZE 8
157#define CONSOLE_EPSIZE 32 190#define CONSOLE_EPSIZE 32
158#define NKRO_EPSIZE 16 191#define NKRO_EPSIZE 16
192#define MIDI_STREAM_EPSIZE 64
159 193
160 194
161uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, 195uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index cdfc7bc6a..03b13f404 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -52,6 +52,7 @@
52#include "descriptor.h" 52#include "descriptor.h"
53#include "lufa.h" 53#include "lufa.h"
54 54
55
55uint8_t keyboard_idle = 0; 56uint8_t keyboard_idle = 0;
56uint8_t keyboard_protocol = 1; 57uint8_t keyboard_protocol = 1;
57static uint8_t keyboard_led_stats = 0; 58static uint8_t keyboard_led_stats = 0;
@@ -65,14 +66,60 @@ static void send_keyboard(report_keyboard_t *report);
65static void send_mouse(report_mouse_t *report); 66static void send_mouse(report_mouse_t *report);
66static void send_system(uint16_t data); 67static void send_system(uint16_t data);
67static void send_consumer(uint16_t data); 68static void send_consumer(uint16_t data);
69
70#ifdef MIDI_ENABLE
71void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
72void usb_get_midi(MidiDevice * device);
73void midi_usb_init(MidiDevice * device);
74#endif
75
68host_driver_t lufa_driver = { 76host_driver_t lufa_driver = {
69 keyboard_leds, 77 keyboard_leds,
70 send_keyboard, 78 send_keyboard,
71 send_mouse, 79 send_mouse,
72 send_system, 80 send_system,
73 send_consumer 81 send_consumer,
82#ifdef MIDI_ENABLE
83 usb_send_func,
84 usb_get_midi,
85 midi_usb_init,
86#endif
87
88};
89
90void SetupHardware(void);
91
92
93USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
94{
95 .Config =
96 {
97 .StreamingInterfaceNumber = MIDI2_INTERFACE,
98 .DataINEndpoint =
99 {
100 .Address = (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM),
101 .Size = MIDI_STREAM_EPSIZE,
102 .Banks = 1,
103 },
104 .DataOUTEndpoint =
105 {
106 .Address = (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM),
107 .Size = MIDI_STREAM_EPSIZE,
108 .Banks = 1,
109 },
110 },
74}; 111};
75 112
113#define SYSEX_START_OR_CONT 0x40
114#define SYSEX_ENDS_IN_1 0x50
115#define SYSEX_ENDS_IN_2 0x60
116#define SYSEX_ENDS_IN_3 0x70
117
118#define SYS_COMMON_1 0x50
119#define SYS_COMMON_2 0x20
120#define SYS_COMMON_3 0x30
121
122
76 123
77/******************************************************************************* 124/*******************************************************************************
78 * Console 125 * Console
@@ -240,8 +287,20 @@ void EVENT_USB_Device_ConfigurationChanged(void)
240 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, 287 ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
241 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE); 288 NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
242#endif 289#endif
290
291#ifdef MIDI_ENABLE
292 ConfigSuccess &= MIDI_Device_ConfigureEndpoints(&USB_MIDI_Interface);
293
294 // ConfigSuccess &= ENDPOINT_CONFIG(MIDI_STREAM_IN_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN,
295 // MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
296 // ConfigSuccess &= ENDPOINT_CONFIG(MIDI_STREAM_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,
297 // MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
298#endif
299
243} 300}
244 301
302
303
245/* 304/*
246Appendix G: HID Request Support Requirements 305Appendix G: HID Request Support Requirements
247 306
@@ -263,6 +322,8 @@ void EVENT_USB_Device_ControlRequest(void)
263 uint8_t* ReportData = NULL; 322 uint8_t* ReportData = NULL;
264 uint8_t ReportSize = 0; 323 uint8_t ReportSize = 0;
265 324
325 MIDI_Device_ProcessControlRequest(&USB_MIDI_Interface);
326
266 /* Handle HID Class specific requests */ 327 /* Handle HID Class specific requests */
267 switch (USB_ControlRequest.bRequest) 328 switch (USB_ControlRequest.bRequest)
268 { 329 {
@@ -541,10 +602,117 @@ int8_t sendchar(uint8_t c)
541#endif 602#endif
542 603
543 604
605
606
607
608#ifdef MIDI_ENABLE
609void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
610 MIDI_EventPacket_t event;
611 event.Data1 = byte0;
612 event.Data2 = byte1;
613 event.Data3 = byte2;
614
615 uint8_t cable = 0;
616
617// Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
618
619 //if the length is undefined we assume it is a SYSEX message
620 if (midi_packet_length(byte0) == UNDEFINED) {
621 switch(cnt) {
622 case 3:
623 if (byte2 == SYSEX_END)
624 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
625 else
626 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
627 break;
628 case 2:
629 if (byte1 == SYSEX_END)
630 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
631 else
632 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
633 break;
634 case 1:
635 if (byte0 == SYSEX_END)
636 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
637 else
638 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
639 break;
640 default:
641 return; //invalid cnt
642 }
643 } else {
644 //deal with 'system common' messages
645 //TODO are there any more?
646 switch(byte0 & 0xF0){
647 case MIDI_SONGPOSITION:
648 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
649 break;
650 case MIDI_SONGSELECT:
651 case MIDI_TC_QUARTERFRAME:
652 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
653 break;
654 default:
655 event.Event = MIDI_EVENT(cable, byte0);
656 break;
657 }
658 }
659
660// Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
661// Endpoint_ClearIN();
662
663 MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
664 MIDI_Device_Flush(&USB_MIDI_Interface);
665 MIDI_Device_USBTask(&USB_MIDI_Interface);
666 USB_USBTask();
667}
668
669void usb_get_midi(MidiDevice * device) {
670 MIDI_EventPacket_t event;
671 while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
672
673 midi_packet_length_t length = midi_packet_length(event.Data1);
674 uint8_t input[3];
675 input[0] = event.Data1;
676 input[1] = event.Data2;
677 input[2] = event.Data3;
678 if (length == UNDEFINED) {
679 //sysex
680 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
681 length = 3;
682 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
683 length = 2;
684 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
685 length = 1;
686 } else {
687 //XXX what to do?
688 }
689 }
690
691 //pass the data to the device input function
692 if (length != UNDEFINED)
693 midi_device_input(device, length, input);
694 }
695 MIDI_Device_USBTask(&USB_MIDI_Interface);
696 USB_USBTask();
697}
698
699void midi_usb_init(MidiDevice * device){
700 midi_device_init(device);
701 midi_device_set_send_func(device, usb_send_func);
702 midi_device_set_pre_input_process_func(device, usb_get_midi);
703
704 SetupHardware();
705 sei();
706}
707#endif
708
709
710
711
544/******************************************************************************* 712/*******************************************************************************
545 * main 713 * main
546 ******************************************************************************/ 714 ******************************************************************************/
547static void SetupHardware(void) 715void SetupHardware(void)
548{ 716{
549 /* Disable watchdog if enabled by bootloader/fuses */ 717 /* Disable watchdog if enabled by bootloader/fuses */
550 MCUSR &= ~(1 << WDRF); 718 MCUSR &= ~(1 << WDRF);
@@ -563,12 +731,41 @@ static void SetupHardware(void)
563 print_set_sendchar(sendchar); 731 print_set_sendchar(sendchar);
564} 732}
565 733
734#ifdef MIDI_ENABLE
735void fallthrough_callback(MidiDevice * device,
736 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
737void cc_callback(MidiDevice * device,
738 uint8_t chan, uint8_t num, uint8_t val);
739void sysex_callback(MidiDevice * device,
740 uint16_t start, uint8_t length, uint8_t * data);
741#endif
742
566int main(void) __attribute__ ((weak)); 743int main(void) __attribute__ ((weak));
567int main(void) 744int main(void)
568{ 745{
746 //setup the device
747
748#ifdef MIDI_ENABLE
749 midi_device_init(&midi_device);
750 midi_device_set_send_func(&midi_device, usb_send_func);
751 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
752#endif
753
569 SetupHardware(); 754 SetupHardware();
570 sei(); 755 sei();
571 756
757#ifdef MIDI_ENABLE
758 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
759 midi_register_cc_callback(&midi_device, cc_callback);
760 midi_register_sysex_callback(&midi_device, sysex_callback);
761
762 midi_send_cc(&midi_device, 0, 1, 2);
763 midi_send_cc(&midi_device, 15, 1, 0);
764 midi_send_noteon(&midi_device, 0, 64, 127);
765 midi_send_noteoff(&midi_device, 0, 64, 127);
766#endif
767
768
572 /* wait for USB startup & debug output */ 769 /* wait for USB startup & debug output */
573 while (USB_DeviceState != DEVICE_STATE_Configured) { 770 while (USB_DeviceState != DEVICE_STATE_Configured) {
574#if defined(INTERRUPT_CONTROL_ENDPOINT) 771#if defined(INTERRUPT_CONTROL_ENDPOINT)
@@ -598,8 +795,33 @@ int main(void)
598 795
599 keyboard_task(); 796 keyboard_task();
600 797
798#ifdef MIDI_ENABLE
799 midi_device_process(&midi_device);
800#endif
801
601#if !defined(INTERRUPT_CONTROL_ENDPOINT) 802#if !defined(INTERRUPT_CONTROL_ENDPOINT)
602 USB_USBTask(); 803 USB_USBTask();
603#endif 804#endif
604 } 805 }
605} 806}
807
808#ifdef MIDI_ENABLE
809//echo data back
810void fallthrough_callback(MidiDevice * device,
811 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
812 //pass the data back to the device, using the general purpose send data
813 //function, any bytes after cnt are ignored
814}
815
816void cc_callback(MidiDevice * device,
817 uint8_t chan, uint8_t num, uint8_t val) {
818 //sending it back on the next channel
819 midi_send_cc(device, (chan + 1) % 16, num, val);
820}
821
822void sysex_callback(MidiDevice * device,
823 uint16_t start, uint8_t length, uint8_t * data) {
824 for (int i = 0; i < length; i++)
825 midi_send_cc(device, 15, 0x7F & data[i], 0x7F & (start + i));
826}
827#endif
diff --git a/protocol/lufa/lufa.h b/protocol/lufa/lufa.h
index 195123c0f..505cb3279 100644
--- a/protocol/lufa/lufa.h
+++ b/protocol/lufa/lufa.h
@@ -48,7 +48,7 @@
48#include <LUFA/Version.h> 48#include <LUFA/Version.h>
49#include <LUFA/Drivers/USB/USB.h> 49#include <LUFA/Drivers/USB/USB.h>
50#include "host.h" 50#include "host.h"
51 51#include "midi/midi.h"
52 52
53#ifdef __cplusplus 53#ifdef __cplusplus
54extern "C" { 54extern "C" {
@@ -66,6 +66,7 @@ typedef struct {
66 uint16_t usage; 66 uint16_t usage;
67} __attribute__ ((packed)) report_extra_t; 67} __attribute__ ((packed)) report_extra_t;
68 68
69MidiDevice midi_device;
69 70
70#if LUFA_VERSION_INTEGER < 0x120730 71#if LUFA_VERSION_INTEGER < 0x120730
71 /* old API 120219 */ 72 /* old API 120219 */
diff --git a/protocol/lufa/midi/Config/LUFAConfig.h b/protocol/lufa/midi/Config/LUFAConfig.h
new file mode 100755
index 000000000..fa9404498
--- /dev/null
+++ b/protocol/lufa/midi/Config/LUFAConfig.h
@@ -0,0 +1,93 @@
1/*
2 LUFA Library
3 Copyright (C) Dean Camera, 2012.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7*/
8
9/*
10 Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29*/
30
31/** \file
32 * \brief LUFA Library Configuration Header File
33 *
34 * This header file is used to configure LUFA's compile time options,
35 * as an alternative to the compile time constants supplied through
36 * a makefile.
37 *
38 * For information on what each token does, refer to the LUFA
39 * manual section "Summary of Compile Tokens".
40 */
41
42#ifndef _LUFA_CONFIG_H_
43#define _LUFA_CONFIG_H_
44
45 #if (ARCH == ARCH_AVR8)
46
47 /* Non-USB Related Configuration Tokens: */
48// #define DISABLE_TERMINAL_CODES
49
50 /* USB Class Driver Related Tokens: */
51// #define HID_HOST_BOOT_PROTOCOL_ONLY
52// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
53// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
54// #define HID_MAX_COLLECTIONS {Insert Value Here}
55// #define HID_MAX_REPORTITEMS {Insert Value Here}
56// #define HID_MAX_REPORT_IDS {Insert Value Here}
57// #define NO_CLASS_DRIVER_AUTOFLUSH
58
59 /* General USB Driver Related Tokens: */
60// #define ORDERED_EP_CONFIG
61 #define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
62 #define USB_DEVICE_ONLY
63// #define USB_HOST_ONLY
64// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
65// #define NO_LIMITED_CONTROLLER_CONNECT
66// #define NO_SOF_EVENTS
67
68 /* USB Device Mode Driver Related Tokens: */
69// #define USE_RAM_DESCRIPTORS
70 #define USE_FLASH_DESCRIPTORS
71// #define USE_EEPROM_DESCRIPTORS
72// #define NO_INTERNAL_SERIAL
73 #define FIXED_CONTROL_ENDPOINT_SIZE 8
74// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
75 #define FIXED_NUM_CONFIGURATIONS 1
76// #define CONTROL_ONLY_DEVICE
77// #define INTERRUPT_CONTROL_ENDPOINT
78// #define NO_DEVICE_REMOTE_WAKEUP
79// #define NO_DEVICE_SELF_POWER
80
81 /* USB Host Mode Driver Related Tokens: */
82// #define HOST_STATE_AS_GPIOR {Insert Value Here}
83// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
84// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
85// #define NO_AUTO_VBUS_MANAGEMENT
86// #define INVERTED_VBUS_ENABLE_LINE
87
88 #else
89
90 #error Unsupported architecture for this LUFA configuration file.
91
92 #endif
93#endif
diff --git a/protocol/lufa/midi/bytequeue/COPYING b/protocol/lufa/midi/bytequeue/COPYING
new file mode 100755
index 000000000..94a9ed024
--- /dev/null
+++ b/protocol/lufa/midi/bytequeue/COPYING
@@ -0,0 +1,674 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 3, 29 June 2007
3
4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The GNU General Public License is a free, copyleft license for
11software and other kinds of works.
12
13 The licenses for most software and other practical works are designed
14to take away your freedom to share and change the works. By contrast,
15the GNU General Public License is intended to guarantee your freedom to
16share and change all versions of a program--to make sure it remains free
17software for all its users. We, the Free Software Foundation, use the
18GNU General Public License for most of our software; it applies also to
19any other work released this way by its authors. You can apply it to
20your programs, too.
21
22 When we speak of free software, we are referring to freedom, not
23price. Our General Public Licenses are designed to make sure that you
24have the freedom to distribute copies of free software (and charge for
25them if you wish), that you receive source code or can get it if you
26want it, that you can change the software or use pieces of it in new
27free programs, and that you know you can do these things.
28
29 To protect your rights, we need to prevent others from denying you
30these rights or asking you to surrender the rights. Therefore, you have
31certain responsibilities if you distribute copies of the software, or if
32you modify it: responsibilities to respect the freedom of others.
33
34 For example, if you distribute copies of such a program, whether
35gratis or for a fee, you must pass on to the recipients the same
36freedoms that you received. You must make sure that they, too, receive
37or can get the source code. And you must show them these terms so they
38know their rights.
39
40 Developers that use the GNU GPL protect your rights with two steps:
41(1) assert copyright on the software, and (2) offer you this License
42giving you legal permission to copy, distribute and/or modify it.
43
44 For the developers' and authors' protection, the GPL clearly explains
45that there is no warranty for this free software. For both users' and
46authors' sake, the GPL requires that modified versions be marked as
47changed, so that their problems will not be attributed erroneously to
48authors of previous versions.
49
50 Some devices are designed to deny users access to install or run
51modified versions of the software inside them, although the manufacturer
52can do so. This is fundamentally incompatible with the aim of
53protecting users' freedom to change the software. The systematic
54pattern of such abuse occurs in the area of products for individuals to
55use, which is precisely where it is most unacceptable. Therefore, we
56have designed this version of the GPL to prohibit the practice for those
57products. If such problems arise substantially in other domains, we
58stand ready to extend this provision to those domains in future versions
59of the GPL, as needed to protect the freedom of users.
60
61 Finally, every program is threatened constantly by software patents.
62States should not allow patents to restrict development and use of
63software on general-purpose computers, but in those that do, we wish to
64avoid the special danger that patents applied to a free program could
65make it effectively proprietary. To prevent this, the GPL assures that
66patents cannot be used to render the program non-free.
67
68 The precise terms and conditions for copying, distribution and
69modification follow.
70
71 TERMS AND CONDITIONS
72
73 0. Definitions.
74
75 "This License" refers to version 3 of the GNU General Public License.
76
77 "Copyright" also means copyright-like laws that apply to other kinds of
78works, such as semiconductor masks.
79
80 "The Program" refers to any copyrightable work licensed under this
81License. Each licensee is addressed as "you". "Licensees" and
82"recipients" may be individuals or organizations.
83
84 To "modify" a work means to copy from or adapt all or part of the work
85in a fashion requiring copyright permission, other than the making of an
86exact copy. The resulting work is called a "modified version" of the
87earlier work or a work "based on" the earlier work.
88
89 A "covered work" means either the unmodified Program or a work based
90on the Program.
91
92 To "propagate" a work means to do anything with it that, without
93permission, would make you directly or secondarily liable for
94infringement under applicable copyright law, except executing it on a
95computer or modifying a private copy. Propagation includes copying,
96distribution (with or without modification), making available to the
97public, and in some countries other activities as well.
98
99 To "convey" a work means any kind of propagation that enables other
100parties to make or receive copies. Mere interaction with a user through
101a computer network, with no transfer of a copy, is not conveying.
102
103 An interactive user interface displays "Appropriate Legal Notices"
104to the extent that it includes a convenient and prominently visible
105feature that (1) displays an appropriate copyright notice, and (2)
106tells the user that there is no warranty for the work (except to the
107extent that warranties are provided), that licensees may convey the
108work under this License, and how to view a copy of this License. If
109the interface presents a list of user commands or options, such as a
110menu, a prominent item in the list meets this criterion.
111
112 1. Source Code.
113
114 The "source code" for a work means the preferred form of the work
115for making modifications to it. "Object code" means any non-source
116form of a work.
117
118 A "Standard Interface" means an interface that either is an official
119standard defined by a recognized standards body, or, in the case of
120interfaces specified for a particular programming language, one that
121is widely used among developers working in that language.
122
123 The "System Libraries" of an executable work include anything, other
124than the work as a whole, that (a) is included in the normal form of
125packaging a Major Component, but which is not part of that Major
126Component, and (b) serves only to enable use of the work with that
127Major Component, or to implement a Standard Interface for which an
128implementation is available to the public in source code form. A
129"Major Component", in this context, means a major essential component
130(kernel, window system, and so on) of the specific operating system
131(if any) on which the executable work runs, or a compiler used to
132produce the work, or an object code interpreter used to run it.
133
134 The "Corresponding Source" for a work in object code form means all
135the source code needed to generate, install, and (for an executable
136work) run the object code and to modify the work, including scripts to
137control those activities. However, it does not include the work's
138System Libraries, or general-purpose tools or generally available free
139programs which are used unmodified in performing those activities but
140which are not part of the work. For example, Corresponding Source
141includes interface definition files associated with source files for
142the work, and the source code for shared libraries and dynamically
143linked subprograms that the work is specifically designed to require,
144such as by intimate data communication or control flow between those
145subprograms and other parts of the work.
146
147 The Corresponding Source need not include anything that users
148can regenerate automatically from other parts of the Corresponding
149Source.
150
151 The Corresponding Source for a work in source code form is that
152same work.
153
154 2. Basic Permissions.
155
156 All rights granted under this License are granted for the term of
157copyright on the Program, and are irrevocable provided the stated
158conditions are met. This License explicitly affirms your unlimited
159permission to run the unmodified Program. The output from running a
160covered work is covered by this License only if the output, given its
161content, constitutes a covered work. This License acknowledges your
162rights of fair use or other equivalent, as provided by copyright law.
163
164 You may make, run and propagate covered works that you do not
165convey, without conditions so long as your license otherwise remains
166in force. You may convey covered works to others for the sole purpose
167of having them make modifications exclusively for you, or provide you
168with facilities for running those works, provided that you comply with
169the terms of this License in conveying all material for which you do
170not control copyright. Those thus making or running the covered works
171for you must do so exclusively on your behalf, under your direction
172and control, on terms that prohibit them from making any copies of
173your copyrighted material outside their relationship with you.
174
175 Conveying under any other circumstances is permitted solely under
176the conditions stated below. Sublicensing is not allowed; section 10
177makes it unnecessary.
178
179 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
181 No covered work shall be deemed part of an effective technological
182measure under any applicable law fulfilling obligations under article
18311 of the WIPO copyright treaty adopted on 20 December 1996, or
184similar laws prohibiting or restricting circumvention of such
185measures.
186
187 When you convey a covered work, you waive any legal power to forbid
188circumvention of technological measures to the extent such circumvention
189is effected by exercising rights under this License with respect to
190the covered work, and you disclaim any intention to limit operation or
191modification of the work as a means of enforcing, against the work's
192users, your or third parties' legal rights to forbid circumvention of
193technological measures.
194
195 4. Conveying Verbatim Copies.
196
197 You may convey verbatim copies of the Program's source code as you
198receive it, in any medium, provided that you conspicuously and
199appropriately publish on each copy an appropriate copyright notice;
200keep intact all notices stating that this License and any
201non-permissive terms added in accord with section 7 apply to the code;
202keep intact all notices of the absence of any warranty; and give all
203recipients a copy of this License along with the Program.
204
205 You may charge any price or no price for each copy that you convey,
206and you may offer support or warranty protection for a fee.
207
208 5. Conveying Modified Source Versions.
209
210 You may convey a work based on the Program, or the modifications to
211produce it from the Program, in the form of source code under the
212terms of section 4, provided that you also meet all of these conditions:
213
214 a) The work must carry prominent notices stating that you modified
215 it, and giving a relevant date.
216
217 b) The work must carry prominent notices stating that it is
218 released under this License and any conditions added under section
219 7. This requirement modifies the requirement in section 4 to
220 "keep intact all notices".
221
222 c) You must license the entire work, as a whole, under this
223 License to anyone who comes into possession of a copy. This
224 License will therefore apply, along with any applicable section 7
225 additional terms, to the whole of the work, and all its parts,
226 regardless of how they are packaged. This License gives no
227 permission to license the work in any other way, but it does not
228 invalidate such permission if you have separately received it.
229
230 d) If the work has interactive user interfaces, each must display
231 Appropriate Legal Notices; however, if the Program has interactive
232 interfaces that do not display Appropriate Legal Notices, your
233 work need not make them do so.
234
235 A compilation of a covered work with other separate and independent
236works, which are not by their nature extensions of the covered work,
237and which are not combined with it such as to form a larger program,
238in or on a volume of a storage or distribution medium, is called an
239"aggregate" if the compilation and its resulting copyright are not
240used to limit the access or legal rights of the compilation's users
241beyond what the individual works permit. Inclusion of a covered work
242in an aggregate does not cause this License to apply to the other
243parts of the aggregate.
244
245 6. Conveying Non-Source Forms.
246
247 You may convey a covered work in object code form under the terms
248of sections 4 and 5, provided that you also convey the
249machine-readable Corresponding Source under the terms of this License,
250in one of these ways:
251
252 a) Convey the object code in, or embodied in, a physical product
253 (including a physical distribution medium), accompanied by the
254 Corresponding Source fixed on a durable physical medium
255 customarily used for software interchange.
256
257 b) Convey the object code in, or embodied in, a physical product
258 (including a physical distribution medium), accompanied by a
259 written offer, valid for at least three years and valid for as
260 long as you offer spare parts or customer support for that product
261 model, to give anyone who possesses the object code either (1) a
262 copy of the Corresponding Source for all the software in the
263 product that is covered by this License, on a durable physical
264 medium customarily used for software interchange, for a price no
265 more than your reasonable cost of physically performing this
266 conveying of source, or (2) access to copy the
267 Corresponding Source from a network server at no charge.
268
269 c) Convey individual copies of the object code with a copy of the
270 written offer to provide the Corresponding Source. This
271 alternative is allowed only occasionally and noncommercially, and
272 only if you received the object code with such an offer, in accord
273 with subsection 6b.
274
275 d) Convey the object code by offering access from a designated
276 place (gratis or for a charge), and offer equivalent access to the
277 Corresponding Source in the same way through the same place at no
278 further charge. You need not require recipients to copy the
279 Corresponding Source along with the object code. If the place to
280 copy the object code is a network server, the Corresponding Source
281 may be on a different server (operated by you or a third party)
282 that supports equivalent copying facilities, provided you maintain
283 clear directions next to the object code saying where to find the
284 Corresponding Source. Regardless of what server hosts the
285 Corresponding Source, you remain obligated to ensure that it is
286 available for as long as needed to satisfy these requirements.
287
288 e) Convey the object code using peer-to-peer transmission, provided
289 you inform other peers where the object code and Corresponding
290 Source of the work are being offered to the general public at no
291 charge under subsection 6d.
292
293 A separable portion of the object code, whose source code is excluded
294from the Corresponding Source as a System Library, need not be
295included in conveying the object code work.
296
297 A "User Product" is either (1) a "consumer product", which means any
298tangible personal property which is normally used for personal, family,
299or household purposes, or (2) anything designed or sold for incorporation
300into a dwelling. In determining whether a product is a consumer product,
301doubtful cases shall be resolved in favor of coverage. For a particular
302product received by a particular user, "normally used" refers to a
303typical or common use of that class of product, regardless of the status
304of the particular user or of the way in which the particular user
305actually uses, or expects or is expected to use, the product. A product
306is a consumer product regardless of whether the product has substantial
307commercial, industrial or non-consumer uses, unless such uses represent
308the only significant mode of use of the product.
309
310 "Installation Information" for a User Product means any methods,
311procedures, authorization keys, or other information required to install
312and execute modified versions of a covered work in that User Product from
313a modified version of its Corresponding Source. The information must
314suffice to ensure that the continued functioning of the modified object
315code is in no case prevented or interfered with solely because
316modification has been made.
317
318 If you convey an object code work under this section in, or with, or
319specifically for use in, a User Product, and the conveying occurs as
320part of a transaction in which the right of possession and use of the
321User Product is transferred to the recipient in perpetuity or for a
322fixed term (regardless of how the transaction is characterized), the
323Corresponding Source conveyed under this section must be accompanied
324by the Installation Information. But this requirement does not apply
325if neither you nor any third party retains the ability to install
326modified object code on the User Product (for example, the work has
327been installed in ROM).
328
329 The requirement to provide Installation Information does not include a
330requirement to continue to provide support service, warranty, or updates
331for a work that has been modified or installed by the recipient, or for
332the User Product in which it has been modified or installed. Access to a
333network may be denied when the modification itself materially and
334adversely affects the operation of the network or violates the rules and
335protocols for communication across the network.
336
337 Corresponding Source conveyed, and Installation Information provided,
338in accord with this section must be in a format that is publicly
339documented (and with an implementation available to the public in
340source code form), and must require no special password or key for
341unpacking, reading or copying.
342
343 7. Additional Terms.
344
345 "Additional permissions" are terms that supplement the terms of this
346License by making exceptions from one or more of its conditions.
347Additional permissions that are applicable to the entire Program shall
348be treated as though they were included in this License, to the extent
349that they are valid under applicable law. If additional permissions
350apply only to part of the Program, that part may be used separately
351under those permissions, but the entire Program remains governed by
352this License without regard to the additional permissions.
353
354 When you convey a copy of a covered work, you may at your option
355remove any additional permissions from that copy, or from any part of
356it. (Additional permissions may be written to require their own
357removal in certain cases when you modify the work.) You may place
358additional permissions on material, added by you to a covered work,
359for which you have or can give appropriate copyright permission.
360
361 Notwithstanding any other provision of this License, for material you
362add to a covered work, you may (if authorized by the copyright holders of
363that material) supplement the terms of this License with terms:
364
365 a) Disclaiming warranty or limiting liability differently from the
366 terms of sections 15 and 16 of this License; or
367
368 b) Requiring preservation of specified reasonable legal notices or
369 author attributions in that material or in the Appropriate Legal
370 Notices displayed by works containing it; or
371
372 c) Prohibiting misrepresentation of the origin of that material, or
373 requiring that modified versions of such material be marked in
374 reasonable ways as different from the original version; or
375
376 d) Limiting the use for publicity purposes of names of licensors or
377 authors of the material; or
378
379 e) Declining to grant rights under trademark law for use of some
380 trade names, trademarks, or service marks; or
381
382 f) Requiring indemnification of licensors and authors of that
383 material by anyone who conveys the material (or modified versions of
384 it) with contractual assumptions of liability to the recipient, for
385 any liability that these contractual assumptions directly impose on
386 those licensors and authors.
387
388 All other non-permissive additional terms are considered "further
389restrictions" within the meaning of section 10. If the Program as you
390received it, or any part of it, contains a notice stating that it is
391governed by this License along with a term that is a further
392restriction, you may remove that term. If a license document contains
393a further restriction but permits relicensing or conveying under this
394License, you may add to a covered work material governed by the terms
395of that license document, provided that the further restriction does
396not survive such relicensing or conveying.
397
398 If you add terms to a covered work in accord with this section, you
399must place, in the relevant source files, a statement of the
400additional terms that apply to those files, or a notice indicating
401where to find the applicable terms.
402
403 Additional terms, permissive or non-permissive, may be stated in the
404form of a separately written license, or stated as exceptions;
405the above requirements apply either way.
406
407 8. Termination.
408
409 You may not propagate or modify a covered work except as expressly
410provided under this License. Any attempt otherwise to propagate or
411modify it is void, and will automatically terminate your rights under
412this License (including any patent licenses granted under the third
413paragraph of section 11).
414
415 However, if you cease all violation of this License, then your
416license from a particular copyright holder is reinstated (a)
417provisionally, unless and until the copyright holder explicitly and
418finally terminates your license, and (b) permanently, if the copyright
419holder fails to notify you of the violation by some reasonable means
420prior to 60 days after the cessation.
421
422 Moreover, your license from a particular copyright holder is
423reinstated permanently if the copyright holder notifies you of the
424violation by some reasonable means, this is the first time you have
425received notice of violation of this License (for any work) from that
426copyright holder, and you cure the violation prior to 30 days after
427your receipt of the notice.
428
429 Termination of your rights under this section does not terminate the
430licenses of parties who have received copies or rights from you under
431this License. If your rights have been terminated and not permanently
432reinstated, you do not qualify to receive new licenses for the same
433material under section 10.
434
435 9. Acceptance Not Required for Having Copies.
436
437 You are not required to accept this License in order to receive or
438run a copy of the Program. Ancillary propagation of a covered work
439occurring solely as a consequence of using peer-to-peer transmission
440to receive a copy likewise does not require acceptance. However,
441nothing other than this License grants you permission to propagate or
442modify any covered work. These actions infringe copyright if you do
443not accept this License. Therefore, by modifying or propagating a
444covered work, you indicate your acceptance of this License to do so.
445
446 10. Automatic Licensing of Downstream Recipients.
447
448 Each time you convey a covered work, the recipient automatically
449receives a license from the original licensors, to run, modify and
450propagate that work, subject to this License. You are not responsible
451for enforcing compliance by third parties with this License.
452
453 An "entity transaction" is a transaction transferring control of an
454organization, or substantially all assets of one, or subdividing an
455organization, or merging organizations. If propagation of a covered
456work results from an entity transaction, each party to that
457transaction who receives a copy of the work also receives whatever
458licenses to the work the party's predecessor in interest had or could
459give under the previous paragraph, plus a right to possession of the
460Corresponding Source of the work from the predecessor in interest, if
461the predecessor has it or can get it with reasonable efforts.
462
463 You may not impose any further restrictions on the exercise of the
464rights granted or affirmed under this License. For example, you may
465not impose a license fee, royalty, or other charge for exercise of
466rights granted under this License, and you may not initiate litigation
467(including a cross-claim or counterclaim in a lawsuit) alleging that
468any patent claim is infringed by making, using, selling, offering for
469sale, or importing the Program or any portion of it.
470
471 11. Patents.
472
473 A "contributor" is a copyright holder who authorizes use under this
474License of the Program or a work on which the Program is based. The
475work thus licensed is called the contributor's "contributor version".
476
477 A contributor's "essential patent claims" are all patent claims
478owned or controlled by the contributor, whether already acquired or
479hereafter acquired, that would be infringed by some manner, permitted
480by this License, of making, using, or selling its contributor version,
481but do not include claims that would be infringed only as a
482consequence of further modification of the contributor version. For
483purposes of this definition, "control" includes the right to grant
484patent sublicenses in a manner consistent with the requirements of
485this License.
486
487 Each contributor grants you a non-exclusive, worldwide, royalty-free
488patent license under the contributor's essential patent claims, to
489make, use, sell, offer for sale, import and otherwise run, modify and
490propagate the contents of its contributor version.
491
492 In the following three paragraphs, a "patent license" is any express
493agreement or commitment, however denominated, not to enforce a patent
494(such as an express permission to practice a patent or covenant not to
495sue for patent infringement). To "grant" such a patent license to a
496party means to make such an agreement or commitment not to enforce a
497patent against the party.
498
499 If you convey a covered work, knowingly relying on a patent license,
500and the Corresponding Source of the work is not available for anyone
501to copy, free of charge and under the terms of this License, through a
502publicly available network server or other readily accessible means,
503then you must either (1) cause the Corresponding Source to be so
504available, or (2) arrange to deprive yourself of the benefit of the
505patent license for this particular work, or (3) arrange, in a manner
506consistent with the requirements of this License, to extend the patent
507license to downstream recipients. "Knowingly relying" means you have
508actual knowledge that, but for the patent license, your conveying the
509covered work in a country, or your recipient's use of the covered work
510in a country, would infringe one or more identifiable patents in that
511country that you have reason to believe are valid.
512
513 If, pursuant to or in connection with a single transaction or
514arrangement, you convey, or propagate by procuring conveyance of, a
515covered work, and grant a patent license to some of the parties
516receiving the covered work authorizing them to use, propagate, modify
517or convey a specific copy of the covered work, then the patent license
518you grant is automatically extended to all recipients of the covered
519work and works based on it.
520
521 A patent license is "discriminatory" if it does not include within
522the scope of its coverage, prohibits the exercise of, or is
523conditioned on the non-exercise of one or more of the rights that are
524specifically granted under this License. You may not convey a covered
525work if you are a party to an arrangement with a third party that is
526in the business of distributing software, under which you make payment
527to the third party based on the extent of your activity of conveying
528the work, and under which the third party grants, to any of the
529parties who would receive the covered work from you, a discriminatory
530patent license (a) in connection with copies of the covered work
531conveyed by you (or copies made from those copies), or (b) primarily
532for and in connection with specific products or compilations that
533contain the covered work, unless you entered into that arrangement,
534or that patent license was granted, prior to 28 March 2007.
535
536 Nothing in this License shall be construed as excluding or limiting
537any implied license or other defenses to infringement that may
538otherwise be available to you under applicable patent law.
539
540 12. No Surrender of Others' Freedom.
541
542 If conditions are imposed on you (whether by court order, agreement or
543otherwise) that contradict the conditions of this License, they do not
544excuse you from the conditions of this License. If you cannot convey a
545covered work so as to satisfy simultaneously your obligations under this
546License and any other pertinent obligations, then as a consequence you may
547not convey it at all. For example, if you agree to terms that obligate you
548to collect a royalty for further conveying from those to whom you convey
549the Program, the only way you could satisfy both those terms and this
550License would be to refrain entirely from conveying the Program.
551
552 13. Use with the GNU Affero General Public License.
553
554 Notwithstanding any other provision of this License, you have
555permission to link or combine any covered work with a work licensed
556under version 3 of the GNU Affero General Public License into a single
557combined work, and to convey the resulting work. The terms of this
558License will continue to apply to the part which is the covered work,
559but the special requirements of the GNU Affero General Public License,
560section 13, concerning interaction through a network will apply to the
561combination as such.
562
563 14. Revised Versions of this License.
564
565 The Free Software Foundation may publish revised and/or new versions of
566the GNU General Public License from time to time. Such new versions will
567be similar in spirit to the present version, but may differ in detail to
568address new problems or concerns.
569
570 Each version is given a distinguishing version number. If the
571Program specifies that a certain numbered version of the GNU General
572Public License "or any later version" applies to it, you have the
573option of following the terms and conditions either of that numbered
574version or of any later version published by the Free Software
575Foundation. If the Program does not specify a version number of the
576GNU General Public License, you may choose any version ever published
577by the Free Software Foundation.
578
579 If the Program specifies that a proxy can decide which future
580versions of the GNU General Public License can be used, that proxy's
581public statement of acceptance of a version permanently authorizes you
582to choose that version for the Program.
583
584 Later license versions may give you additional or different
585permissions. However, no additional obligations are imposed on any
586author or copyright holder as a result of your choosing to follow a
587later version.
588
589 15. Disclaimer of Warranty.
590
591 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
600 16. Limitation of Liability.
601
602 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610SUCH DAMAGES.
611
612 17. Interpretation of Sections 15 and 16.
613
614 If the disclaimer of warranty and limitation of liability provided
615above cannot be given local legal effect according to their terms,
616reviewing courts shall apply local law that most closely approximates
617an absolute waiver of all civil liability in connection with the
618Program, unless a warranty or assumption of liability accompanies a
619copy of the Program in return for a fee.
620
621 END OF TERMS AND CONDITIONS
622
623 How to Apply These Terms to Your New Programs
624
625 If you develop a new program, and you want it to be of the greatest
626possible use to the public, the best way to achieve this is to make it
627free software which everyone can redistribute and change under these terms.
628
629 To do so, attach the following notices to the program. It is safest
630to attach them to the start of each source file to most effectively
631state the exclusion of warranty; and each file should have at least
632the "copyright" line and a pointer to where the full notice is found.
633
634 <one line to give the program's name and a brief idea of what it does.>
635 Copyright (C) <year> <name of author>
636
637 This program is free software: you can redistribute it and/or modify
638 it under the terms of the GNU General Public License as published by
639 the Free Software Foundation, either version 3 of the License, or
640 (at your option) any later version.
641
642 This program is distributed in the hope that it will be useful,
643 but WITHOUT ANY WARRANTY; without even the implied warranty of
644 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 GNU General Public License for more details.
646
647 You should have received a copy of the GNU General Public License
648 along with this program. If not, see <http://www.gnu.org/licenses/>.
649
650Also add information on how to contact you by electronic and paper mail.
651
652 If the program does terminal interaction, make it output a short
653notice like this when it starts in an interactive mode:
654
655 <program> Copyright (C) <year> <name of author>
656 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 This is free software, and you are welcome to redistribute it
658 under certain conditions; type `show c' for details.
659
660The hypothetical commands `show w' and `show c' should show the appropriate
661parts of the General Public License. Of course, your program's commands
662might be different; for a GUI interface, you would use an "about box".
663
664 You should also get your employer (if you work as a programmer) or school,
665if any, to sign a "copyright disclaimer" for the program, if necessary.
666For more information on this, and how to apply and follow the GNU GPL, see
667<http://www.gnu.org/licenses/>.
668
669 The GNU General Public License does not permit incorporating your program
670into proprietary programs. If your program is a subroutine library, you
671may consider it more useful to permit linking proprietary applications with
672the library. If this is what you want to do, use the GNU Lesser General
673Public License instead of this License. But first, please read
674<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/protocol/lufa/midi/bytequeue/bytequeue.c b/protocol/lufa/midi/bytequeue/bytequeue.c
new file mode 100755
index 000000000..e43495632
--- /dev/null
+++ b/protocol/lufa/midi/bytequeue/bytequeue.c
@@ -0,0 +1,65 @@
1//this is a single reader [maybe multiple writer?] byte queue
2//Copyright 2008 Alex Norman
3//writen by Alex Norman
4//
5//This file is part of avr-bytequeue.
6//
7//avr-bytequeue is free software: you can redistribute it and/or modify
8//it under the terms of the GNU General Public License as published by
9//the Free Software Foundation, either version 3 of the License, or
10//(at your option) any later version.
11//
12//avr-bytequeue is distributed in the hope that it will be useful,
13//but WITHOUT ANY WARRANTY; without even the implied warranty of
14//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15//GNU General Public License for more details.
16//
17//You should have received a copy of the GNU General Public License
18//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
19
20#include "bytequeue.h"
21#include "interrupt_setting.h"
22
23void bytequeue_init(byteQueue_t * queue, uint8_t * dataArray, byteQueueIndex_t arrayLen){
24 queue->length = arrayLen;
25 queue->data = dataArray;
26 queue->start = queue->end = 0;
27}
28
29bool bytequeue_enqueue(byteQueue_t * queue, uint8_t item){
30 interrupt_setting_t setting = store_and_clear_interrupt();
31 //full
32 if(((queue->end + 1) % queue->length) == queue->start){
33 restore_interrupt_setting(setting);
34 return false;
35 } else {
36 queue->data[queue->end] = item;
37 queue->end = (queue->end + 1) % queue->length;
38 restore_interrupt_setting(setting);
39 return true;
40 }
41}
42
43byteQueueIndex_t bytequeue_length(byteQueue_t * queue){
44 byteQueueIndex_t len;
45 interrupt_setting_t setting = store_and_clear_interrupt();
46 if(queue->end >= queue->start)
47 len = queue->end - queue->start;
48 else
49 len = (queue->length - queue->start) + queue->end;
50 restore_interrupt_setting(setting);
51 return len;
52}
53
54//we don't need to avoid interrupts if there is only one reader
55uint8_t bytequeue_get(byteQueue_t * queue, byteQueueIndex_t index){
56 return queue->data[(queue->start + index) % queue->length];
57}
58
59//we just update the start index to remove elements
60void bytequeue_remove(byteQueue_t * queue, byteQueueIndex_t numToRemove){
61 interrupt_setting_t setting = store_and_clear_interrupt();
62 queue->start = (queue->start + numToRemove) % queue->length;
63 restore_interrupt_setting(setting);
64}
65
diff --git a/protocol/lufa/midi/bytequeue/bytequeue.h b/protocol/lufa/midi/bytequeue/bytequeue.h
new file mode 100755
index 000000000..e4a286134
--- /dev/null
+++ b/protocol/lufa/midi/bytequeue/bytequeue.h
@@ -0,0 +1,59 @@
1//this is a single reader [maybe multiple writer?] byte queue
2//Copyright 2008 Alex Norman
3//writen by Alex Norman
4//
5//This file is part of avr-bytequeue.
6//
7//avr-bytequeue is free software: you can redistribute it and/or modify
8//it under the terms of the GNU General Public License as published by
9//the Free Software Foundation, either version 3 of the License, or
10//(at your option) any later version.
11//
12//avr-bytequeue is distributed in the hope that it will be useful,
13//but WITHOUT ANY WARRANTY; without even the implied warranty of
14//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15//GNU General Public License for more details.
16//
17//You should have received a copy of the GNU General Public License
18//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
19
20#ifndef BYTEQUEUE_H
21#define BYTEQUEUE_H
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27#include <inttypes.h>
28#include <stdbool.h>
29
30typedef uint8_t byteQueueIndex_t;
31
32typedef struct {
33 byteQueueIndex_t start;
34 byteQueueIndex_t end;
35 byteQueueIndex_t length;
36 uint8_t * data;
37} byteQueue_t;
38
39//you must have a queue, an array of data which the queue will use, and the length of that array
40void bytequeue_init(byteQueue_t * queue, uint8_t * dataArray, byteQueueIndex_t arrayLen);
41
42//add an item to the queue, returns false if the queue is full
43bool bytequeue_enqueue(byteQueue_t * queue, uint8_t item);
44
45//get the length of the queue
46byteQueueIndex_t bytequeue_length(byteQueue_t * queue);
47
48//this grabs data at the index given [starting at queue->start]
49uint8_t bytequeue_get(byteQueue_t * queue, byteQueueIndex_t index);
50
51//update the index in the queue to reflect data that has been dealt with
52void bytequeue_remove(byteQueue_t * queue, byteQueueIndex_t numToRemove);
53
54#ifdef __cplusplus
55}
56#endif
57
58#endif
59
diff --git a/protocol/lufa/midi/bytequeue/interrupt_setting.c b/protocol/lufa/midi/bytequeue/interrupt_setting.c
new file mode 100755
index 000000000..eafef527c
--- /dev/null
+++ b/protocol/lufa/midi/bytequeue/interrupt_setting.c
@@ -0,0 +1,36 @@
1//Copyright 20010 Alex Norman
2//writen by Alex Norman
3//
4//This file is part of avr-bytequeue.
5//
6//avr-bytequeue is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-bytequeue is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
18
19
20//AVR specific code
21//should be able to port to other systems by simply providing chip specific
22//implementations of the typedef and these functions
23
24#include "interrupt_setting.h"
25#include <avr/interrupt.h>
26
27interrupt_setting_t store_and_clear_interrupt(void) {
28 uint8_t sreg = SREG;
29 cli();
30 return sreg;
31}
32
33void restore_interrupt_setting(interrupt_setting_t setting) {
34 SREG = setting;
35}
36
diff --git a/protocol/lufa/midi/bytequeue/interrupt_setting.h b/protocol/lufa/midi/bytequeue/interrupt_setting.h
new file mode 100755
index 000000000..053d02c9d
--- /dev/null
+++ b/protocol/lufa/midi/bytequeue/interrupt_setting.h
@@ -0,0 +1,39 @@
1//Copyright 20010 Alex Norman
2//writen by Alex Norman
3//
4//This file is part of avr-bytequeue.
5//
6//avr-bytequeue is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-bytequeue is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
18
19#ifndef INTERRUPT_SETTING_H
20#define INTERRUPT_SETTING_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26#include <inttypes.h>
27
28//AVR specific typedef
29typedef uint8_t interrupt_setting_t;
30
31interrupt_setting_t store_and_clear_interrupt(void);
32void restore_interrupt_setting(interrupt_setting_t setting);
33
34#ifdef __cplusplus
35}
36#endif
37
38#endif
39
diff --git a/protocol/lufa/midi/midi.c b/protocol/lufa/midi/midi.c
new file mode 100755
index 000000000..11a589078
--- /dev/null
+++ b/protocol/lufa/midi/midi.c
@@ -0,0 +1,277 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19#include "midi.h"
20#include <string.h> //for memcpy
21
22#define MIN(x,y) (((x) < (y)) ? (x) : (y))
23
24#ifndef NULL
25#define NULL 0
26#endif
27
28bool midi_is_statusbyte(uint8_t theByte){
29 return (bool)(theByte & MIDI_STATUSMASK);
30}
31
32bool midi_is_realtime(uint8_t theByte){
33 return (theByte >= MIDI_CLOCK);
34}
35
36midi_packet_length_t midi_packet_length(uint8_t status){
37 switch(status & 0xF0){
38 case MIDI_CC:
39 case MIDI_NOTEON:
40 case MIDI_NOTEOFF:
41 case MIDI_AFTERTOUCH:
42 case MIDI_PITCHBEND:
43 return THREE;
44 case MIDI_PROGCHANGE:
45 case MIDI_CHANPRESSURE:
46 case MIDI_SONGSELECT:
47 return TWO;
48 case 0xF0:
49 switch(status) {
50 case MIDI_CLOCK:
51 case MIDI_TICK:
52 case MIDI_START:
53 case MIDI_CONTINUE:
54 case MIDI_STOP:
55 case MIDI_ACTIVESENSE:
56 case MIDI_RESET:
57 case MIDI_TUNEREQUEST:
58 return ONE;
59 case MIDI_SONGPOSITION:
60 return THREE;
61 case MIDI_TC_QUARTERFRAME:
62 case MIDI_SONGSELECT:
63 return TWO;
64 case SYSEX_END:
65 case SYSEX_BEGIN:
66 default:
67 return UNDEFINED;
68 }
69 default:
70 return UNDEFINED;
71 }
72}
73
74void midi_send_cc(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val){
75 //CC Status: 0xB0 to 0xBF where the low nibble is the MIDI channel.
76 //CC Data: Controller Num, Controller Val
77 device->send_func(device, 3,
78 MIDI_CC | (chan & MIDI_CHANMASK),
79 num & 0x7F,
80 val & 0x7F);
81}
82
83void midi_send_noteon(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t vel){
84 //Note Data: Note Num, Note Velocity
85 device->send_func(device, 3,
86 MIDI_NOTEON | (chan & MIDI_CHANMASK),
87 num & 0x7F,
88 vel & 0x7F);
89}
90
91void midi_send_noteoff(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t vel){
92 //Note Data: Note Num, Note Velocity
93 device->send_func(device, 3,
94 MIDI_NOTEOFF | (chan & MIDI_CHANMASK),
95 num & 0x7F,
96 vel & 0x7F);
97}
98
99void midi_send_aftertouch(MidiDevice * device, uint8_t chan, uint8_t note_num, uint8_t amt){
100 device->send_func(device, 3,
101 MIDI_AFTERTOUCH | (chan & MIDI_CHANMASK),
102 note_num & 0x7F,
103 amt & 0x7F);
104}
105
106//XXX does this work right?
107//amt in range -0x2000, 0x1fff
108//uAmt should be in range..
109//0x0000 to 0x3FFF
110void midi_send_pitchbend(MidiDevice * device, uint8_t chan, int16_t amt){
111 uint16_t uAmt;
112 //check range
113 if(amt > 0x1fff){
114 uAmt = 0x3FFF;
115 } else if(amt < -0x2000){
116 uAmt = 0;
117 } else {
118 uAmt = amt + 0x2000;
119 }
120 device->send_func(device, 3,
121 MIDI_PITCHBEND | (chan & MIDI_CHANMASK),
122 uAmt & 0x7F,
123 (uAmt >> 7) & 0x7F);
124}
125
126void midi_send_programchange(MidiDevice * device, uint8_t chan, uint8_t num){
127 device->send_func(device, 2,
128 MIDI_PROGCHANGE | (chan & MIDI_CHANMASK),
129 num & 0x7F,
130 0);
131}
132
133void midi_send_channelpressure(MidiDevice * device, uint8_t chan, uint8_t amt){
134 device->send_func(device, 2,
135 MIDI_CHANPRESSURE | (chan & MIDI_CHANMASK),
136 amt & 0x7F,
137 0);
138}
139
140void midi_send_clock(MidiDevice * device){
141 device->send_func(device, 1, MIDI_CLOCK, 0, 0);
142}
143
144void midi_send_tick(MidiDevice * device){
145 device->send_func(device, 1, MIDI_TICK, 0, 0);
146}
147
148void midi_send_start(MidiDevice * device){
149 device->send_func(device, 1, MIDI_START, 0, 0);
150}
151
152void midi_send_continue(MidiDevice * device){
153 device->send_func(device, 1, MIDI_CONTINUE, 0, 0);
154}
155
156void midi_send_stop(MidiDevice * device){
157 device->send_func(device, 1, MIDI_STOP, 0, 0);
158}
159
160void midi_send_activesense(MidiDevice * device){
161 device->send_func(device, 1, MIDI_ACTIVESENSE, 0, 0);
162}
163
164void midi_send_reset(MidiDevice * device){
165 device->send_func(device, 1, MIDI_RESET, 0, 0);
166}
167
168void midi_send_tcquarterframe(MidiDevice * device, uint8_t time){
169 device->send_func(device, 2,
170 MIDI_TC_QUARTERFRAME,
171 time & 0x7F,
172 0);
173}
174
175//XXX is this right?
176void midi_send_songposition(MidiDevice * device, uint16_t pos){
177 device->send_func(device, 3,
178 MIDI_SONGPOSITION,
179 pos & 0x7F,
180 (pos >> 7) & 0x7F);
181}
182
183void midi_send_songselect(MidiDevice * device, uint8_t song){
184 device->send_func(device, 2,
185 MIDI_SONGSELECT,
186 song & 0x7F,
187 0);
188}
189
190void midi_send_tunerequest(MidiDevice * device){
191 device->send_func(device, 1, MIDI_TUNEREQUEST, 0, 0);
192}
193
194void midi_send_byte(MidiDevice * device, uint8_t b){
195 device->send_func(device, 1, b, 0, 0);
196}
197
198void midi_send_data(MidiDevice * device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2){
199 //ensure that the count passed along is always 3 or lower
200 if (count > 3) {
201 //TODO how to do this correctly?
202 }
203 device->send_func(device, count, byte0, byte1, byte2);
204}
205
206void midi_send_array(MidiDevice * device, uint16_t count, uint8_t * array) {
207 uint16_t i;
208 for (i = 0; i < count; i += 3) {
209 uint8_t b[3] = { 0, 0, 0 };
210 uint16_t to_send = count - i;
211 to_send = (to_send > 3) ? 3 : to_send;
212 memcpy(b, array + i, to_send);
213 midi_send_data(device, to_send, b[0], b[1], b[2]);
214 }
215}
216
217
218void midi_register_cc_callback(MidiDevice * device, midi_three_byte_func_t func){
219 device->input_cc_callback = func;
220}
221
222void midi_register_noteon_callback(MidiDevice * device, midi_three_byte_func_t func){
223 device->input_noteon_callback = func;
224}
225
226void midi_register_noteoff_callback(MidiDevice * device, midi_three_byte_func_t func){
227 device->input_noteoff_callback = func;
228}
229
230void midi_register_aftertouch_callback(MidiDevice * device, midi_three_byte_func_t func){
231 device->input_aftertouch_callback = func;
232}
233
234void midi_register_pitchbend_callback(MidiDevice * device, midi_three_byte_func_t func){
235 device->input_pitchbend_callback = func;
236}
237
238void midi_register_songposition_callback(MidiDevice * device, midi_three_byte_func_t func){
239 device->input_songposition_callback = func;
240}
241
242void midi_register_progchange_callback(MidiDevice * device, midi_two_byte_func_t func) {
243 device->input_progchange_callback = func;
244}
245
246void midi_register_chanpressure_callback(MidiDevice * device, midi_two_byte_func_t func) {
247 device->input_chanpressure_callback = func;
248}
249
250void midi_register_songselect_callback(MidiDevice * device, midi_two_byte_func_t func) {
251 device->input_songselect_callback = func;
252}
253
254void midi_register_tc_quarterframe_callback(MidiDevice * device, midi_two_byte_func_t func) {
255 device->input_tc_quarterframe_callback = func;
256}
257
258void midi_register_realtime_callback(MidiDevice * device, midi_one_byte_func_t func){
259 device->input_realtime_callback = func;
260}
261
262void midi_register_tunerequest_callback(MidiDevice * device, midi_one_byte_func_t func){
263 device->input_tunerequest_callback = func;
264}
265
266void midi_register_sysex_callback(MidiDevice * device, midi_sysex_func_t func) {
267 device->input_sysex_callback = func;
268}
269
270void midi_register_fallthrough_callback(MidiDevice * device, midi_var_byte_func_t func){
271 device->input_fallthrough_callback = func;
272}
273
274void midi_register_catchall_callback(MidiDevice * device, midi_var_byte_func_t func){
275 device->input_catchall_callback = func;
276}
277
diff --git a/protocol/lufa/midi/midi.h b/protocol/lufa/midi/midi.h
new file mode 100755
index 000000000..1a36737df
--- /dev/null
+++ b/protocol/lufa/midi/midi.h
@@ -0,0 +1,498 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19/**
20 * @file
21 * @brief The main midi functions
22 *
23 * This file includes all of the functions you need to set up and process a
24 * midi device, send midi, and register midi callbacks.
25 *
26 */
27
28#ifndef XNOR_MIDI_H
29#define XNOR_MIDI_H
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#include "midi_device.h"
36#include "midi_function_types.h"
37
38/**
39 * @defgroup midi_device_setup_process Device initialization and processing
40 * @brief These are method that you must use to initialize and run a device
41 *
42 * @{
43 */
44
45/**
46 * @brief Initialize a device
47 *
48 * You must call this before using the device in question.
49 *
50 * @param device the device to initialize
51*/
52void midi_device_init(MidiDevice * device); // [implementation in midi_device.c]
53
54/**
55 * @brief Process input data
56 *
57 * This method drives the input processing, you must call this method frequently
58 * if you expect to have your input callbacks called.
59 *
60 * @param device the device to process
61*/
62void midi_device_process(MidiDevice * device); // [implementation in midi_device.c]
63
64/**@}*/
65
66/**
67 * @defgroup send_functions Midi send functions
68 * @brief These are the functions you use to send midi data through a device.
69 * @{
70 */
71
72/**
73 * @brief Send a control change message (cc) via the given device.
74 *
75 * @param device the device to use for sending
76 * @param chan the channel to send on, 0-15
77 * @param num the cc num
78 * @param val the value of that cc num
79*/
80void midi_send_cc(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t val);
81
82/**
83 * @brief Send a note on message via the given device.
84 *
85 * @param device the device to use for sending
86 * @param chan the channel to send on, 0-15
87 * @param num the note number
88 * @param vel the note velocity
89*/
90void midi_send_noteon(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t vel);
91
92/**
93 * @brief Send a note off message via the given device.
94 *
95 * @param device the device to use for sending
96 * @param chan the channel to send on, 0-15
97 * @param num the note number
98 * @param vel the note velocity
99*/
100void midi_send_noteoff(MidiDevice * device, uint8_t chan, uint8_t num, uint8_t vel);
101
102/**
103 * @brief Send an after touch message via the given device.
104 *
105 * @param device the device to use for sending
106 * @param chan the channel to send on, 0-15
107 * @param note_num the note number
108 * @param amt the after touch amount
109*/
110void midi_send_aftertouch(MidiDevice * device, uint8_t chan, uint8_t note_num, uint8_t amt);
111
112/**
113 * @brief Send a pitch bend message via the given device.
114 *
115 * @param device the device to use for sending
116 * @param chan the channel to send on, 0-15
117 * @param amt the bend amount range: -8192..8191, 0 means no bend
118*/
119void midi_send_pitchbend(MidiDevice * device, uint8_t chan, int16_t amt); //range -8192, 8191
120
121/**
122 * @brief Send a program change message via the given device.
123 *
124 * @param device the device to use for sending
125 * @param chan the channel to send on, 0-15
126 * @param num the program to change to
127*/
128void midi_send_programchange(MidiDevice * device, uint8_t chan, uint8_t num);
129
130/**
131 * @brief Send a channel pressure message via the given device.
132 *
133 * @param device the device to use for sending
134 * @param chan the channel to send on, 0-15
135 * @param amt the amount of channel pressure
136*/
137void midi_send_channelpressure(MidiDevice * device, uint8_t chan, uint8_t amt);
138
139/**
140 * @brief Send a clock message via the given device.
141 *
142 * @param device the device to use for sending
143 */
144void midi_send_clock(MidiDevice * device);
145
146/**
147 * @brief Send a tick message via the given device.
148 *
149 * @param device the device to use for sending
150 */
151void midi_send_tick(MidiDevice * device);
152
153/**
154 * @brief Send a start message via the given device.
155 *
156 * @param device the device to use for sending
157 */
158void midi_send_start(MidiDevice * device);
159
160/**
161 * @brief Send a continue message via the given device.
162 *
163 * @param device the device to use for sending
164 */
165void midi_send_continue(MidiDevice * device);
166
167/**
168 * @brief Send a stop message via the given device.
169 *
170 * @param device the device to use for sending
171 */
172void midi_send_stop(MidiDevice * device);
173
174/**
175 * @brief Send an active sense message via the given device.
176 *
177 * @param device the device to use for sending
178 */
179void midi_send_activesense(MidiDevice * device);
180
181/**
182 * @brief Send a reset message via the given device.
183 *
184 * @param device the device to use for sending
185 */
186void midi_send_reset(MidiDevice * device);
187
188
189/**
190 * @brief Send a tc quarter frame message via the given device.
191 *
192 * @param device the device to use for sending
193 * @param time the time of this quarter frame, range 0..16383
194 */
195void midi_send_tcquarterframe(MidiDevice * device, uint8_t time);
196
197/**
198 * @brief Send a song position message via the given device.
199 *
200 * @param device the device to use for sending
201 * @param pos the song position
202 */
203void midi_send_songposition(MidiDevice * device, uint16_t pos);
204
205/**
206 * @brief Send a song select message via the given device.
207 *
208 * @param device the device to use for sending
209 * @param song the song to select
210 */
211void midi_send_songselect(MidiDevice * device, uint8_t song);
212
213/**
214 * @brief Send a tune request message via the given device.
215 *
216 * @param device the device to use for sending
217 */
218void midi_send_tunerequest(MidiDevice * device);
219
220/**
221 * @brief Send a byte via the given device.
222 *
223 * This is a generic method for sending data via the given midi device.
224 * This would be useful for sending sysex data or messages that are not
225 * implemented in this API, if there are any. Please contact the author
226 * if you find some so we can add them.
227 *
228 * @param device the device to use for sending
229 * @param b the byte to send
230 */
231void midi_send_byte(MidiDevice * device, uint8_t b);
232
233/**
234 * @brief Send up to 3 bytes of data
235 *
236 * % 4 is applied to count so that you can use this to pass sysex through
237 *
238 * @param device the device to use for sending
239 * @param count the count of bytes to send, %4 is applied
240 * @param byte0 the first byte
241 * @param byte1 the second byte, ignored if cnt % 4 != 2
242 * @param byte2 the third byte, ignored if cnt % 4 != 3
243 */
244void midi_send_data(MidiDevice * device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2);
245
246/**
247 * @brief Send an array of formatted midi data.
248 *
249 * Can be used for sysex.
250 *
251 * @param device the device to use for sending
252 * @param count the count of bytes to send
253 * @param array the array of bytes
254 */
255void midi_send_array(MidiDevice * device, uint16_t count, uint8_t * array);
256
257/**@}*/
258
259
260/**
261 * @defgroup input_callback_reg Input callback registration functions
262 *
263 * @brief These are the functions you use to register your input callbacks.
264 *
265 * The functions are called when the appropriate midi message is matched on the
266 * associated device's input.
267 *
268 * @{
269 */
270
271//three byte funcs
272
273/**
274 * @brief Register a control change message (cc) callback.
275 *
276 * @param device the device associate with
277 * @param func the callback function to register
278 */
279void midi_register_cc_callback(MidiDevice * device, midi_three_byte_func_t func);
280
281/**
282 * @brief Register a note on callback.
283 *
284 * @param device the device associate with
285 * @param func the callback function to register
286 */
287void midi_register_noteon_callback(MidiDevice * device, midi_three_byte_func_t func);
288
289/**
290 * @brief Register a note off callback.
291 *
292 * @param device the device associate with
293 * @param func the callback function to register
294 */
295void midi_register_noteoff_callback(MidiDevice * device, midi_three_byte_func_t func);
296
297/**
298 * @brief Register an after touch callback.
299 *
300 * @param device the device associate with
301 * @param func the callback function to register
302 */
303
304void midi_register_aftertouch_callback(MidiDevice * device, midi_three_byte_func_t func);
305
306/**
307 * @brief Register a pitch bend callback.
308 *
309 * @param device the device associate with
310 * @param func the callback function to register
311 */
312void midi_register_pitchbend_callback(MidiDevice * device, midi_three_byte_func_t func);
313
314/**
315 * @brief Register a song position callback.
316 *
317 * @param device the device associate with
318 * @param func the callback function to register
319 */
320void midi_register_songposition_callback(MidiDevice * device, midi_three_byte_func_t func);
321
322//two byte funcs
323
324/**
325 * @brief Register a program change callback.
326 *
327 * @param device the device associate with
328 * @param func the callback function to register
329 */
330void midi_register_progchange_callback(MidiDevice * device, midi_two_byte_func_t func);
331
332/**
333 * @brief Register a channel pressure callback.
334 *
335 * @param device the device associate with
336 * @param func the callback function to register
337 */
338void midi_register_chanpressure_callback(MidiDevice * device, midi_two_byte_func_t func);
339
340/**
341 * @brief Register a song select callback.
342 *
343 * @param device the device associate with
344 * @param func the callback function to register
345 */
346void midi_register_songselect_callback(MidiDevice * device, midi_two_byte_func_t func);
347
348/**
349 * @brief Register a tc quarter frame callback.
350 *
351 * @param device the device associate with
352 * @param func the callback function to register
353 */
354void midi_register_tc_quarterframe_callback(MidiDevice * device, midi_two_byte_func_t func);
355
356//one byte funcs
357
358/**
359 * @brief Register a realtime callback.
360 *
361 * The callback will be called for all of the real time message types.
362 *
363 * @param device the device associate with
364 * @param func the callback function to register
365 */
366void midi_register_realtime_callback(MidiDevice * device, midi_one_byte_func_t func);
367
368/**
369 * @brief Register a tune request callback.
370 *
371 * @param device the device associate with
372 * @param func the callback function to register
373 */
374void midi_register_tunerequest_callback(MidiDevice * device, midi_one_byte_func_t func);
375
376/**
377 * @brief Register a sysex callback.
378 *
379 * @param device the device associate with
380 * @param func the callback function to register
381 */
382void midi_register_sysex_callback(MidiDevice * device, midi_sysex_func_t func);
383
384/**
385 * @brief Register fall through callback.
386 *
387 * This is only called if a more specific callback is not matched and called.
388 * For instance, if you don't register a note on callback but you get a note on message
389 * the fall through callback will be called, if it is registered.
390 *
391 * @param device the device associate with
392 * @param func the callback function to register
393 */
394void midi_register_fallthrough_callback(MidiDevice * device, midi_var_byte_func_t func);
395
396
397/**
398 * @brief Register a catch all callback.
399 *
400 * If registered, the catch all callback is called for every message that is
401 * matched, even if a more specific or the fallthrough callback is registered.
402 *
403 * @param device the device associate with
404 * @param func the callback function to register
405 */
406void midi_register_catchall_callback(MidiDevice * device, midi_var_byte_func_t func);
407
408/**@}*/
409
410/**
411 * @defgroup midi_util Device independent utility functions.
412 * @{
413 */
414
415/**
416 * \enum midi_packet_length_t
417 *
418 * An enumeration of the possible packet length values.
419 */
420typedef enum {
421 UNDEFINED = 0,
422 ONE = 1,
423 TWO = 2,
424 THREE = 3} midi_packet_length_t;
425
426/**
427 * @brief Test to see if the byte given is a status byte
428 * @param theByte the byte to test
429 * @return true if the byte given is a midi status byte
430 */
431bool midi_is_statusbyte(uint8_t theByte);
432
433/**
434 * @brief Test to see if the byte given is a realtime message
435 * @param theByte the byte to test
436 * @return true if it is a realtime message, false otherwise
437 */
438bool midi_is_realtime(uint8_t theByte);
439
440/**
441 * @brief Find the length of the packet associated with the status byte given
442 * @param status the status byte
443 * @return the length of the packet, will return UNDEFINED if the byte is not
444 * a status byte or if it is a sysex status byte
445 */
446midi_packet_length_t midi_packet_length(uint8_t status);
447
448/**@}*/
449
450/**
451 * @defgroup defines Midi status and miscellaneous utility #defines
452 *
453 * @{
454 */
455
456#define SYSEX_BEGIN 0xF0
457#define SYSEX_END 0xF7
458
459//if you and this with a byte and you get anything non-zero
460//it is a status message
461#define MIDI_STATUSMASK 0x80
462//if you and this with a status message that contains channel info,
463//you'll get the channel
464#define MIDI_CHANMASK 0x0F
465
466#define MIDI_CC 0xB0
467#define MIDI_NOTEON 0x90
468#define MIDI_NOTEOFF 0x80
469#define MIDI_AFTERTOUCH 0xA0
470#define MIDI_PITCHBEND 0xE0
471#define MIDI_PROGCHANGE 0xC0
472#define MIDI_CHANPRESSURE 0xD0
473
474//midi realtime
475#define MIDI_CLOCK 0xF8
476#define MIDI_TICK 0xF9
477#define MIDI_START 0xFA
478#define MIDI_CONTINUE 0xFB
479#define MIDI_STOP 0xFC
480#define MIDI_ACTIVESENSE 0xFE
481#define MIDI_RESET 0xFF
482
483#define MIDI_TC_QUARTERFRAME 0xF1
484#define MIDI_SONGPOSITION 0xF2
485#define MIDI_SONGSELECT 0xF3
486#define MIDI_TUNEREQUEST 0xF6
487
488//This ID is for educational or development use only
489#define SYSEX_EDUMANUFID 0x7D
490
491/**@}*/
492
493#ifdef __cplusplus
494}
495#endif
496
497#endif
498
diff --git a/protocol/lufa/midi/midi_device.c b/protocol/lufa/midi/midi_device.c
new file mode 100755
index 000000000..3215a007d
--- /dev/null
+++ b/protocol/lufa/midi/midi_device.c
@@ -0,0 +1,291 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19#include "midi_device.h"
20#include "midi.h"
21
22#ifndef NULL
23#define NULL 0
24#endif
25
26//forward declarations, internally used to call the callbacks
27void midi_input_callbacks(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
28void midi_process_byte(MidiDevice * device, uint8_t input);
29
30void midi_device_init(MidiDevice * device){
31 device->input_state = IDLE;
32 device->input_count = 0;
33 bytequeue_init(&device->input_queue, device->input_queue_data, MIDI_INPUT_QUEUE_LENGTH);
34
35 //three byte funcs
36 device->input_cc_callback = NULL;
37 device->input_noteon_callback = NULL;
38 device->input_noteoff_callback = NULL;
39 device->input_aftertouch_callback = NULL;
40 device->input_pitchbend_callback = NULL;
41 device->input_songposition_callback = NULL;
42
43 //two byte funcs
44 device->input_progchange_callback = NULL;
45 device->input_chanpressure_callback = NULL;
46 device->input_songselect_callback = NULL;
47 device->input_tc_quarterframe_callback = NULL;
48
49 //one byte funcs
50 device->input_realtime_callback = NULL;
51 device->input_tunerequest_callback = NULL;
52
53 //var byte functions
54 device->input_sysex_callback = NULL;
55 device->input_fallthrough_callback = NULL;
56 device->input_catchall_callback = NULL;
57
58 device->pre_input_process_callback = NULL;
59}
60
61void midi_device_input(MidiDevice * device, uint8_t cnt, uint8_t * input) {
62 uint8_t i;
63 for (i = 0; i < cnt; i++)
64 bytequeue_enqueue(&device->input_queue, input[i]);
65}
66
67void midi_device_set_send_func(MidiDevice * device, midi_var_byte_func_t send_func){
68 device->send_func = send_func;
69}
70
71void midi_device_set_pre_input_process_func(MidiDevice * device, midi_no_byte_func_t pre_process_func){
72 device->pre_input_process_callback = pre_process_func;
73}
74
75void midi_device_process(MidiDevice * device) {
76 //call the pre_input_process_callback if there is one
77 if(device->pre_input_process_callback)
78 device->pre_input_process_callback(device);
79
80 //pull stuff off the queue and process
81 byteQueueIndex_t len = bytequeue_length(&device->input_queue);
82 uint16_t i;
83 //TODO limit number of bytes processed?
84 for(i = 0; i < len; i++) {
85 uint8_t val = bytequeue_get(&device->input_queue, 0);
86 midi_process_byte(device, val);
87 bytequeue_remove(&device->input_queue, 1);
88 }
89}
90
91void midi_process_byte(MidiDevice * device, uint8_t input) {
92 if (midi_is_realtime(input)) {
93 //call callback, store and restore state
94 input_state_t state = device->input_state;
95 device->input_state = ONE_BYTE_MESSAGE;
96 midi_input_callbacks(device, 1, input, 0, 0);
97 device->input_state = state;
98 } else if (midi_is_statusbyte(input)) {
99 //store the byte
100 if (device->input_state != SYSEX_MESSAGE) {
101 device->input_buffer[0] = input;
102 device->input_count = 1;
103 }
104 switch (midi_packet_length(input)) {
105 case ONE:
106 device->input_state = ONE_BYTE_MESSAGE;;
107 midi_input_callbacks(device, 1, input, 0, 0);
108 device->input_state = IDLE;
109 break;
110 case TWO:
111 device->input_state = TWO_BYTE_MESSAGE;
112 break;
113 case THREE:
114 device->input_state = THREE_BYTE_MESSAGE;
115 break;
116 case UNDEFINED:
117 switch(input) {
118 case SYSEX_BEGIN:
119 device->input_state = SYSEX_MESSAGE;
120 device->input_buffer[0] = input;
121 device->input_count = 1;
122 break;
123 case SYSEX_END:
124 //send what is left in the input buffer, set idle
125 device->input_buffer[device->input_count % 3] = input;
126 device->input_count += 1;
127 //call the callback
128 midi_input_callbacks(device, device->input_count,
129 device->input_buffer[0], device->input_buffer[1], device->input_buffer[2]);
130 device->input_state = IDLE;
131 break;
132 default:
133 device->input_state = IDLE;
134 device->input_count = 0;
135 }
136
137 break;
138 default:
139 device->input_state = IDLE;
140 device->input_count = 0;
141 break;
142 }
143 } else {
144 if (device->input_state != IDLE) {
145 //store the byte
146 device->input_buffer[device->input_count % 3] = input;
147 //increment count
148 uint16_t prev = device->input_count;
149 device->input_count += 1;
150
151 switch(prev % 3) {
152 case 2:
153 //call callback
154 midi_input_callbacks(device, device->input_count,
155 device->input_buffer[0], device->input_buffer[1], device->input_buffer[2]);
156 if (device->input_state != SYSEX_MESSAGE) {
157 //set to 1, keeping status byte, allowing for running status
158 device->input_count = 1;
159 }
160 break;
161 case 1:
162 if (device->input_state == TWO_BYTE_MESSAGE) {
163 //call callback
164 midi_input_callbacks(device, device->input_count,
165 device->input_buffer[0], device->input_buffer[1], 0);
166 if (device->input_state != SYSEX_MESSAGE) {
167 //set to 1, keeping status byte, allowing for running status
168 device->input_count = 1;
169 }
170 }
171 break;
172 case 0:
173 default:
174 //one byte messages are dealt with directly
175 break;
176 }
177 }
178 }
179}
180
181void midi_input_callbacks(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
182 //did we end up calling a callback?
183 bool called = false;
184 if (device->input_state == SYSEX_MESSAGE) {
185 if (device->input_sysex_callback) {
186 const uint16_t start = ((cnt - 1) / 3) * 3;
187 const uint8_t length = (cnt - start);
188 uint8_t data[3];
189 data[0] = byte0;
190 data[1] = byte1;
191 data[2] = byte2;
192 device->input_sysex_callback(device, start, length, data);
193 called = true;
194 }
195 } else {
196 switch (cnt) {
197 case 3:
198 {
199 midi_three_byte_func_t func = NULL;
200 switch (byte0 & 0xF0) {
201 case MIDI_CC:
202 func = device->input_cc_callback;
203 break;
204 case MIDI_NOTEON:
205 func = device->input_noteon_callback;
206 break;
207 case MIDI_NOTEOFF:
208 func = device->input_noteoff_callback;
209 break;
210 case MIDI_AFTERTOUCH:
211 func = device->input_aftertouch_callback;
212 break;
213 case MIDI_PITCHBEND:
214 func = device->input_pitchbend_callback;
215 break;
216 case 0xF0:
217 if (byte0 == MIDI_SONGPOSITION)
218 func = device->input_songposition_callback;
219 break;
220 default:
221 break;
222 }
223 if(func) {
224 //mask off the channel for non song position functions
225 if (byte0 == MIDI_SONGPOSITION)
226 func(device, byte0, byte1, byte2);
227 else
228 func(device, byte0 & 0x0F, byte1, byte2);
229 called = true;
230 }
231 }
232 break;
233 case 2:
234 {
235 midi_two_byte_func_t func = NULL;
236 switch (byte0 & 0xF0) {
237 case MIDI_PROGCHANGE:
238 func = device->input_progchange_callback;
239 break;
240 case MIDI_CHANPRESSURE:
241 func = device->input_chanpressure_callback;
242 break;
243 case 0xF0:
244 if (byte0 == MIDI_SONGSELECT)
245 func = device->input_songselect_callback;
246 else if (byte0 == MIDI_TC_QUARTERFRAME)
247 func = device->input_tc_quarterframe_callback;
248 break;
249 default:
250 break;
251 }
252 if(func) {
253 //mask off the channel
254 if (byte0 == MIDI_SONGSELECT || byte0 == MIDI_TC_QUARTERFRAME)
255 func(device, byte0, byte1);
256 else
257 func(device, byte0 & 0x0F, byte1);
258 called = true;
259 }
260 }
261 break;
262 case 1:
263 {
264 midi_one_byte_func_t func = NULL;
265 if (midi_is_realtime(byte0))
266 func = device->input_realtime_callback;
267 else if (byte0 == MIDI_TUNEREQUEST)
268 func = device->input_tunerequest_callback;
269 if (func) {
270 func(device, byte0);
271 called = true;
272 }
273 }
274 break;
275 default:
276 //just in case
277 if (cnt > 3)
278 cnt = 0;
279 break;
280 }
281 }
282
283 //if there is fallthrough default callback and we haven't called a more specific one,
284 //call the fallthrough
285 if (!called && device->input_fallthrough_callback)
286 device->input_fallthrough_callback(device, cnt, byte0, byte1, byte2);
287 //always call the catch all if it exists
288 if (device->input_catchall_callback)
289 device->input_catchall_callback(device, cnt, byte0, byte1, byte2);
290}
291
diff --git a/protocol/lufa/midi/midi_device.h b/protocol/lufa/midi/midi_device.h
new file mode 100755
index 000000000..088995286
--- /dev/null
+++ b/protocol/lufa/midi/midi_device.h
@@ -0,0 +1,156 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19/**
20 * @file
21 * @brief Device implementation functions
22 */
23
24#ifndef MIDI_DEVICE_H
25#define MIDI_DEVICE_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/**
32 * @defgroup midi_device Functions used when implementing your own midi device.
33 *
34 * You use the functions when you are implementing your own midi device.
35 *
36 * You set a send function to actually send bytes via your device, this method
37 * is called when you call a send function with this device, for instance
38 * midi_send_cc
39 *
40 * You use the midi_device_input to process input data from the device and pass
41 * it through the device's associated callbacks.
42 *
43 * You use the midi_device_set_pre_input_process_func if you want to have a
44 * function called at the beginning of the device's process function, generally
45 * to poll for input and pass that into midi_device_input
46 *
47 * @{
48 */
49
50#include "midi_function_types.h"
51#include "bytequeue/bytequeue.h"
52#define MIDI_INPUT_QUEUE_LENGTH 192
53
54typedef enum {
55 IDLE,
56 ONE_BYTE_MESSAGE = 1,
57 TWO_BYTE_MESSAGE = 2,
58 THREE_BYTE_MESSAGE = 3,
59 SYSEX_MESSAGE} input_state_t;
60
61typedef void (* midi_no_byte_func_t)(MidiDevice * device);
62
63/**
64 * \struct _midi_device
65 *
66 * @brief This structure represents the input and output functions and
67 * processing data for a midi device.
68 *
69 * A device can represent an actual physical device [serial port, usb port] or
70 * something virtual.
71 * You should not need to modify this structure directly.
72 */
73struct _midi_device {
74 //output send function
75 midi_var_byte_func_t send_func;
76
77 //********input callbacks
78 //three byte funcs
79 midi_three_byte_func_t input_cc_callback;
80 midi_three_byte_func_t input_noteon_callback;
81 midi_three_byte_func_t input_noteoff_callback;
82 midi_three_byte_func_t input_aftertouch_callback;
83 midi_three_byte_func_t input_pitchbend_callback;
84 midi_three_byte_func_t input_songposition_callback;
85 //two byte funcs
86 midi_two_byte_func_t input_progchange_callback;
87 midi_two_byte_func_t input_chanpressure_callback;
88 midi_two_byte_func_t input_songselect_callback;
89 midi_two_byte_func_t input_tc_quarterframe_callback;
90 //one byte funcs
91 midi_one_byte_func_t input_realtime_callback;
92 midi_one_byte_func_t input_tunerequest_callback;
93
94 //sysex
95 midi_sysex_func_t input_sysex_callback;
96
97 //only called if more specific callback is not matched
98 midi_var_byte_func_t input_fallthrough_callback;
99 //called if registered, independent of other callbacks
100 midi_var_byte_func_t input_catchall_callback;
101
102 //pre input processing function
103 midi_no_byte_func_t pre_input_process_callback;
104
105 //for internal input processing
106 uint8_t input_buffer[3];
107 input_state_t input_state;
108 uint16_t input_count;
109
110 //for queueing data between the input and the processing functions
111 uint8_t input_queue_data[MIDI_INPUT_QUEUE_LENGTH];
112 byteQueue_t input_queue;
113};
114
115/**
116 * @brief Process input bytes. This function parses bytes and calls the
117 * appropriate callbacks associated with the given device. You use this
118 * function if you are creating a custom device and you want to have midi
119 * input.
120 *
121 * @param device the midi device to associate the input with
122 * @param cnt the number of bytes you are processing
123 * @param input the bytes to process
124 */
125void midi_device_input(MidiDevice * device, uint8_t cnt, uint8_t * input);
126
127/**
128 * @brief Set the callback function that will be used for sending output
129 * data bytes. This is only used if you're creating a custom device.
130 * You'll most likely want the callback function to disable interrupts so
131 * that you can call the various midi send functions without worrying about
132 * locking.
133 *
134 * \param device the midi device to associate this callback with
135 * \param send_func the callback function that will do the sending
136 */
137void midi_device_set_send_func(MidiDevice * device, midi_var_byte_func_t send_func);
138
139/**
140 * @brief Set a callback which is called at the beginning of the
141 * midi_device_process call. This can be used to poll for input
142 * data and send the data through the midi_device_input function.
143 * You'll probably only use this if you're creating a custom device.
144 *
145 * \param device the midi device to associate this callback with
146 * \param midi_no_byte_func_t the actual callback function
147 */
148void midi_device_set_pre_input_process_func(MidiDevice * device, midi_no_byte_func_t pre_process_func);
149
150/**@}*/
151
152#ifdef __cplusplus
153}
154#endif
155
156#endif
diff --git a/protocol/lufa/midi/midi_function_types.h b/protocol/lufa/midi/midi_function_types.h
new file mode 100755
index 000000000..35c4601b2
--- /dev/null
+++ b/protocol/lufa/midi/midi_function_types.h
@@ -0,0 +1,50 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19/**
20 * @file
21 * @brief Function signature definitions
22 */
23
24#ifndef MIDI_FUNCTION_TYPES_H
25#define MIDI_FUNCTION_TYPES_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <inttypes.h>
32#include <stdbool.h>
33
34//forward declaration
35typedef struct _midi_device MidiDevice;
36
37typedef void (* midi_one_byte_func_t)(MidiDevice * device, uint8_t byte);
38typedef void (* midi_two_byte_func_t)(MidiDevice * device, uint8_t byte0, uint8_t byte1);
39typedef void (* midi_three_byte_func_t)(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2);
40//all bytes after count bytes should be ignored
41typedef void (* midi_var_byte_func_t)(MidiDevice * device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2);
42
43//the start byte tells you how far into the sysex message you are, the data_length tells you how many bytes data is
44typedef void (* midi_sysex_func_t)(MidiDevice * device, uint16_t start_byte, uint8_t data_length, uint8_t *data);
45
46#ifdef __cplusplus
47}
48#endif
49
50#endif
diff --git a/protocol/lufa/midi/sysex_tools.c b/protocol/lufa/midi/sysex_tools.c
new file mode 100755
index 000000000..7563a3e2a
--- /dev/null
+++ b/protocol/lufa/midi/sysex_tools.c
@@ -0,0 +1,99 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19#include "sysex_tools.h"
20
21uint16_t sysex_encoded_length(uint16_t decoded_length){
22 uint8_t remainder = decoded_length % 7;
23 if (remainder)
24 return (decoded_length / 7) * 8 + remainder + 1;
25 else
26 return (decoded_length / 7) * 8;
27}
28
29uint16_t sysex_decoded_length(uint16_t encoded_length){
30 uint8_t remainder = encoded_length % 8;
31 if (remainder)
32 return (encoded_length / 8) * 7 + remainder - 1;
33 else
34 return (encoded_length / 8) * 7;
35}
36
37uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, const uint16_t length){
38 uint16_t encoded_full = length / 7; //number of full 8 byte sections from 7 bytes of input
39 uint16_t i,j;
40
41 //fill out the fully encoded sections
42 for(i = 0; i < encoded_full; i++) {
43 uint16_t encoded_msb_idx = i * 8;
44 uint16_t input_start_idx = i * 7;
45 encoded[encoded_msb_idx] = 0;
46 for(j = 0; j < 7; j++){
47 uint8_t current = source[input_start_idx + j];
48 encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j);
49 encoded[encoded_msb_idx + 1 + j] = 0x7F & current;
50 }
51 }
52
53 //fill out the rest if there is any more
54 uint8_t remainder = length % 7;
55 if (remainder) {
56 uint16_t encoded_msb_idx = encoded_full * 8;
57 uint16_t input_start_idx = encoded_full * 7;
58 encoded[encoded_msb_idx] = 0;
59 for(j = 0; j < remainder; j++){
60 uint8_t current = source[input_start_idx + j];
61 encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j);
62 encoded[encoded_msb_idx + 1 + j] = 0x7F & current;
63 }
64 return encoded_msb_idx + remainder + 1;
65 } else {
66 return encoded_full * 8;
67 }
68}
69
70uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, const uint16_t length){
71 uint16_t decoded_full = length / 8;
72 uint16_t i,j;
73
74 if (length < 2)
75 return 0;
76
77 //fill out the fully encoded sections
78 for(i = 0; i < decoded_full; i++) {
79 uint16_t encoded_msb_idx = i * 8;
80 uint16_t output_start_index = i * 7;
81 for(j = 0; j < 7; j++){
82 decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
83 decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
84 }
85 }
86 uint8_t remainder = length % 8;
87 if (remainder) {
88 uint16_t encoded_msb_idx = decoded_full * 8;
89 uint16_t output_start_index = decoded_full * 7;
90 for(j = 0; j < (remainder - 1); j++) {
91 decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
92 decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
93 }
94 return decoded_full * 7 + remainder - 1;
95 } else {
96 return decoded_full * 7;
97 }
98}
99
diff --git a/protocol/lufa/midi/sysex_tools.h b/protocol/lufa/midi/sysex_tools.h
new file mode 100755
index 000000000..3654d0114
--- /dev/null
+++ b/protocol/lufa/midi/sysex_tools.h
@@ -0,0 +1,95 @@
1//midi for embedded chips,
2//Copyright 2010 Alex Norman
3//
4//This file is part of avr-midi.
5//
6//avr-midi is free software: you can redistribute it and/or modify
7//it under the terms of the GNU General Public License as published by
8//the Free Software Foundation, either version 3 of the License, or
9//(at your option) any later version.
10//
11//avr-midi is distributed in the hope that it will be useful,
12//but WITHOUT ANY WARRANTY; without even the implied warranty of
13//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14//GNU General Public License for more details.
15//
16//You should have received a copy of the GNU General Public License
17//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
18
19#ifndef SYSEX_TOOLS_H
20#define SYSEX_TOOLS_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26#include <inttypes.h>
27
28/**
29 * @file
30 * @brief Sysex utility functions
31 *
32 * These functions are for converting data to and from a "midi-safe" format,
33 * which can be use to send data with sysex messages. Sysex messages may only
34 * contain data where the to bit is not set.
35 *
36 * An "encoded" midi message is one that contains all of the data from its
37 * original state, but does not have any of the top bits set.
38 *
39 * Every 7 bytes of decoded data is converted into 8 bytes of encoded data and
40 * visa-versa. If you'd like to operate on small segments, make sure that you
41 * encode in 7 byte increments and decode in 8 byte increments.
42 *
43 */
44
45/** @defgroup sysex_tools Sysex utility functions
46 * @{
47 */
48
49/**
50 * @brief Compute the length of a message after it is encoded.
51 *
52 * @param decoded_length The length, in bytes, of the message to encode.
53 *
54 * @return The length, in bytes, of the message after encodeing.
55 */
56uint16_t sysex_encoded_length(uint16_t decoded_length);
57
58/**
59 * @brief Compute the length of a message after it is decoded.
60 *
61 * @param encoded_length The length, in bytes, of the encoded message.
62 *
63 * @return The length, in bytes, of the message after it is decoded.
64 */
65uint16_t sysex_decoded_length(uint16_t encoded_length);
66
67/**
68 * @brief Encode data so that it can be transmitted safely in a sysex message.
69 *
70 * @param encoded The output data buffer, must be at least sysex_encoded_length(length) bytes long.
71 * @param source The input buffer of data to be encoded.
72 * @param length The number of bytes from the input buffer to encode.
73 *
74 * @return number of bytes encoded.
75 */
76uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, uint16_t length);
77
78/**
79 * @brief Decode encoded data.
80 *
81 * @param decoded The output data buffer, must be at least sysex_decoded_length(length) bytes long.
82 * @param source The input buffer of data to be decoded.
83 * @param length The number of bytes from the input buffer to decode.
84 *
85 * @return number of bytes decoded.
86 */
87uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, uint16_t length);
88
89/**@}*/
90
91#ifdef __cplusplus
92}
93#endif
94
95#endif