Merge remote-tracking branch 'tmk/master' into cub_layout
This commit is contained in:
commit
8ecb3e9e44
54 changed files with 2772 additions and 243 deletions
|
|
@ -53,12 +53,6 @@ SRC += keymap_common.c \
|
|||
matrix.c \
|
||||
led.c
|
||||
|
||||
ifdef KEYMAP
|
||||
SRC := keymap_$(KEYMAP).c $(SRC)
|
||||
else
|
||||
SRC := keymap_hhkb.c $(SRC)
|
||||
endif
|
||||
|
||||
CONFIG_H = config.h
|
||||
|
||||
|
||||
|
|
@ -123,7 +117,27 @@ EXTRAKEY_ENABLE = yes # Audio control and System control
|
|||
CONSOLE_ENABLE = yes # Console for debug
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||
KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
|
||||
#KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
|
||||
#HHKB_JP = yes # HHKB JP support
|
||||
|
||||
|
||||
ifdef HHKB_JP
|
||||
OPT_DEFS += -DHHKB_JP
|
||||
endif
|
||||
|
||||
|
||||
#
|
||||
# Keymap file
|
||||
#
|
||||
ifdef KEYMAP
|
||||
SRC := keymap_$(KEYMAP).c $(SRC)
|
||||
else
|
||||
ifdef HHKB_JP
|
||||
SRC := keymap_jp.c $(SRC)
|
||||
else
|
||||
SRC := keymap_hhkb.c $(SRC)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# Search Path
|
||||
|
|
@ -138,4 +152,5 @@ debug-on: EXTRAFLAGS += -DDEBUG -DDEBUG_ACTION
|
|||
debug-on: all
|
||||
|
||||
debug-off: EXTRAFLAGS += -DNO_DEBUG -DNO_PRINT
|
||||
debug-off: OPT_DEFS := $(filter-out -DCONSOLE_ENABLE,$(OPT_DEFS))
|
||||
debug-off: all
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ Alternative Controller for HHKB Pro
|
|||
===================================
|
||||
I wanted to add some features like vi cursor and mouse keys to my [HHKB][HHKB] but its controller is not programmable and firmware source code is not open, of course. This means customizing this keyboard needs to replace original controller with programmable one.
|
||||
|
||||
This controller can work with HHKB **Professional**, **Professional** 2 and **Type-S**.
|
||||
This controller can work with HHKB **Professional**, **Professional** 2, **JP** and **Type-S**.
|
||||
|
||||
See [this thread][AltController] in geekhack.org.
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ See [doc/HHKB.txt](doc/HHKB.txt) and files under [doc/](doc/) for internal of HH
|
|||
See [this document](../../doc/build.md) first.
|
||||
|
||||
### Configuration
|
||||
Set `MCU`, `BOOTLOADER_SIZE` and other build options in `Makefile` and `config.h`.
|
||||
Set `MCU`, `BOOTLOADER_SIZE` and other build options in `Makefile` and `config.h`. If your target is **HHKB JP** you need to set `HHKB_JP` build option in `Makefile`.
|
||||
|
||||
### Build
|
||||
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. Just `make` with `KEYMAP` option like:
|
||||
|
|
@ -66,37 +66,22 @@ Use [Teensy Loader] if your controller is Teensy/Teensy++.
|
|||
|
||||
|
||||
##Keymap
|
||||
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.
|
||||
To define your own keymap create file named `keymap_<name>.c` and see [keymap document](../../doc/keymap.md) and existent keymap files.
|
||||
|
||||
|
||||
##Hardware
|
||||
You have some options for hardware. Development boards with USB AVR family(ATMega32U4, AT90USB1286) like Teensy will work while MegaAVR with [V-USB] library is also cheaper option for DIY.
|
||||
|
||||
###1. TMK Alt Controller Board
|
||||
TMK designed [Keyboard Controller Board for HHKB Pro2(KiCad project)](https://github.com/tmk/HHKB_controller).
|
||||
See [this post](http://geekhack.org/index.php?topic=12047.msg948923#msg948923).
|
||||
Design files are available at [Keyboard Controller Board for HHKB(KiCad project)](https://github.com/tmk/HHKB_controller) and see [Controller Distribution thread](http://geekhack.org/index.php?topic=56494.0) if you get an assembled one.
|
||||
|
||||
|
||||
###2. PJRC Teensy++ 2.0 version
|
||||
+---------------+
|
||||
| Teensy++ |
|
||||
| |
|
||||
| | HHKB pro HHKB pro2
|
||||
| | ~~~~~~~~ ~~~~~~~~~
|
||||
| PB0-2|------->ROW (6-8) (5-7)
|
||||
| PB3-5|------->COL (9-11) (8-10)
|
||||
| PB6|------->ENABLE (12) (11)
|
||||
| PE6|<-------KEY (4) (3)
|
||||
| PE7|------->PREV (5) (4)
|
||||
| |
|
||||
| | 5V--- (1-3) (1-2)
|
||||
| | GND--- (13-14) (12-13)
|
||||
+---------------+
|
||||
###2. PJRC Teensy
|
||||
See [this thread](http://geekhack.org/index.php?topic=57008.0).
|
||||
|
||||
- NOTE: PJRC [Teensy](http://www.pjrc.com/teensy/)
|
||||
|
||||
###3. V-USB version
|
||||
See [V-USB controller for HHKB](doc/V-USB.md)
|
||||
See [V-USB controller for HHKB](doc/V-USB.md).
|
||||
|
||||
|
||||
[LUFA]: http://www.fourwalledcubicle.com/LUFA.php
|
||||
|
|
|
|||
|
|
@ -28,7 +28,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 8
|
||||
#ifdef HHKB_JP
|
||||
# define MATRIX_ROWS 16
|
||||
#else
|
||||
# define MATRIX_ROWS 8
|
||||
#endif
|
||||
#define MATRIX_COLS 8
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ Controller PCB
|
|||
Keyswitch PCB
|
||||
-------------
|
||||
HC4051 Analog Multiplexer: select a row line.
|
||||
http://www.alldatasheet.com/datasheet-pdf/pdf/203989/KODENSHI/KK74HC4051A.html
|
||||
http://www.ti.com/lit/ds/schs122j/schs122j.pdf
|
||||
LS145 BCD Decoder: select a column line.
|
||||
http://www.alldatasheet.com/datasheet-pdf/pdf/27373/TI/SN74LS145D.html
|
||||
http://www.ti.com/lit/ds/symlink/sn74ls145.pdf
|
||||
BU9831 Non-volatile electronic potentiometer: for calibration?
|
||||
http://www.alldatasheet.com/datasheet-pdf/pdf/36387/ROHM/BU9831.html
|
||||
https://www.spezial.com/doc/rohm-a/bu9831.pdf
|
||||
TP1683/4 Capacitive Sensing controller: no datasheet available.
|
||||
|
||||
(HHKB_keyswitch.jpg)
|
||||
|
|
@ -28,37 +28,41 @@ Keyswitch PCB
|
|||
Connector Cable
|
||||
---------------
|
||||
Two PCBs are connected by 15 lines(13 in case of Pro2).
|
||||
Vcc and GND use 3(2) lines each, other 9 lines are for keyboard signaling.
|
||||
Vcc and GND use 3(2) lines each, other lines are for keyboard signaling.
|
||||
|
||||
Keyswitch connector
|
||||
pro pro2 Description Teensy++ pins
|
||||
HHKB connector lines:
|
||||
JP Pro2 Pro Function Description Teensy++ pins
|
||||
--------------------------------------------------------------------------------------------
|
||||
1 Vcc(5V) Not exist on Pro2 5V
|
||||
2 1 Vcc(5V) 5V
|
||||
3 2 Vcc(5V) 5V
|
||||
4 3 TP1684 KEY: Low(0) when key pressed PE6 input(with pullup)
|
||||
5 4 TP1684 KEY_PREV: make threshold PE7 output
|
||||
6 5 HC4051 A(bit0)\ PB0 output
|
||||
7 6 HC4051 B(bit1) > select row(0 to 7) PB1 output
|
||||
8 7 HC4051 C(bit2)/ PB2 output
|
||||
9 8 LS145 A(bit0)\ PB3 output
|
||||
10 9 LS145 B(bit1) > select column(0 to 7) PB4 output
|
||||
11 10 LS145 C(bit2)/ PB5 output
|
||||
12 11 LS145 D(enable) Low(0) enables selected column PB6 output
|
||||
13 12 GND GND
|
||||
14 13 GND GND
|
||||
15 GND Not exist on Pro2 GND
|
||||
1 Vcc(5V) 5V
|
||||
1 1 2 Vcc(5V) 5V
|
||||
2 2 3 Vcc(5V) 5V
|
||||
3 3 4 TP1684 KEY: Low(0) when key pressed PE6 input(with pullup)
|
||||
4 4 5 TP1684 KEY_PREV: make threshold PE7 output
|
||||
5 5 6 HC4051 A(bit0)\ PB0 output
|
||||
6 6 7 HC4051 B(bit1) > select row 0-7 PB1 output
|
||||
7 7 8 HC4051 C(bit2)/ PB2 output
|
||||
8 8 9 LS145 A(bit0)\ PB3 output
|
||||
9 9 10 LS145 B(bit1) > select column 0-7 PB4 output
|
||||
10 10 11 LS145 C(bit2)/ PB5 output
|
||||
11 11 12 LS145 D(enable) Low(0) enables selected column PB6 output
|
||||
12 12 13 GND GND
|
||||
13 13 14 GND GND
|
||||
15 GND
|
||||
14 HC4051(Z2) ~Enable of Z2 row0-7
|
||||
15 HC4051(Z3) ~Enable of Z3 row8-15
|
||||
|
||||
NOTE: guessing pin5(KEY_PREV) may work for hysteresis of capacitive sensing.
|
||||
NOTE: 1KOhm didn't work as pullup resistor on KEY. AVR internal pullup or 10KOhm resistor was OK.
|
||||
NOTE: JP has two HC4051(Z2,Z3) and line 5, 6 and 7 are connected to both of them.
|
||||
|
||||
(HHKB_connector.jpg)
|
||||
|
||||
|
||||
Keyswitch matrix
|
||||
----------------
|
||||
60 keyswitches in 8*8 matrix. It is ghost-free and bounce-free.
|
||||
HHKB switch matrix is ghost-free and bounce-free.
|
||||
|
||||
Pro/Pro2(8x8):
|
||||
COL 0 1 2 3 4 5 6 7
|
||||
ROW ---------------------------------------------------------------
|
||||
0| 2 q w s a z x c
|
||||
|
|
@ -71,8 +75,30 @@ Keyswitch matrix
|
|||
7| - + ] [ ' / . _NONE_
|
||||
|
||||
|
||||
JP(16x8):
|
||||
COL 0 1 2 3 4 5 6 7
|
||||
ROW ---------------------------------------------------------------
|
||||
0| ESC TAB LFn LShift LCtrl
|
||||
1| 4 E MuHKN C D
|
||||
2| 3 W LAlt X S
|
||||
3| 1 HHK
|
||||
4|
|
||||
5| 5 R V F
|
||||
6| 2 Q LGui Z A
|
||||
7| 6 T Space B G
|
||||
8| 9 I Kana , K
|
||||
9| 8 U Henkan M J
|
||||
A| 7 Y N H
|
||||
B| 0 O RAlt . L
|
||||
C| BS Right RShift Enter
|
||||
D| \ [ Down Up ]
|
||||
E| - P RFn / ;
|
||||
F| ~ @ Left Ro :
|
||||
|
||||
|
||||
Matrix diagram:
|
||||
|
||||
Pro/Pro2:
|
||||
+-------------------------+-+-+-+-+-+-+-+ Vcc
|
||||
|bias control? - - - - - - - - ---
|
||||
| 3.9K*8 R R R R R R R R |
|
||||
|
|
@ -89,18 +115,54 @@ Matrix diagram:
|
|||
KEY PREV | A B C +-----------------+
|
||||
| | +-^----+ | | | | LS145 |
|
||||
Vcc | | |BU9831| | | | +-^--^--^--^------+
|
||||
--- | | +------+ | | | A B C D +------+
|
||||
| | | | | | | | | | | |
|
||||
1-3 4 5 6 7 8 9 10 11 12 13-15 |
|
||||
+--------------------------------------------------+ |
|
||||
| connector | ---
|
||||
+--------------------------------------------------+ GND
|
||||
to controller
|
||||
--- | | +------+ | | | A B C D +-------+
|
||||
| | | | | | | | | | | |
|
||||
1-3 4 5 6 7 8 9 10 11 12 13-15 Pro |
|
||||
1-2 3 4 5 6 7 8 9 10 11 12-13 Pro2|
|
||||
+--------------------------------------------------+ |
|
||||
| connector | ---
|
||||
+--------------------------------------------------+ GND
|
||||
|
||||
|
||||
JP:
|
||||
+-----------------------------+-+-+-+-+ Vcc
|
||||
|bias control? - - - - - ---
|
||||
| 3.9K*5 R R R R R |
|
||||
+--------^+ +--------+ - - - - - |
|
||||
| | | HC4051 <0-----------|-|-|-|-|----|R|-+
|
||||
| |capa. | Z2 <1-----------|-|-|-|-|----|R|-+
|
||||
| TP1684 |sense | <2-----------|-|-|-|-|----|R|-+
|
||||
| <---+--| <3-----------|-|-|-|-|----|R|-+
|
||||
| | | | <4-----------|-|-|-|-|----|R|-+
|
||||
| | ~En| <5-----------|-|-|-|-|----|R|-+
|
||||
| | +----> <6-----------|-|-|-|-|----|R|-+
|
||||
| | | | | A B C <7-----------|-|-|-|-|----|R|-+
|
||||
+---V---^-+ | | +-^-^-^--+ | | | | | |
|
||||
KEY PREV | | | | | | | | | | |
|
||||
| | | | +--------+ | | | | | |
|
||||
| | | | | HC4051 <8-----------|-|-|-|-|----|R|-+
|
||||
| | | | | Z3 <9-----------|-|-|-|-|----|R|-+
|
||||
| | | +--| <A-----------|-|-|-|-|----|R|-+
|
||||
| | | | <B-----------|-|-|-|-|----|R|-+
|
||||
| | | | <C-----------|-|-|-|-|----|R|-+
|
||||
| | | ~En| <D-----------|-|-|-|-|----|R|-+
|
||||
| | | +-> <E-----------|-|-|-|-|----|R|-+
|
||||
| | | | | A B C <F-----------|-|-|-|-|----|R|-+
|
||||
| | | | +-^-^-^--+ 0 1 2 3 4 5 6 7 33K*8
|
||||
| | | | | | | +-----------------+
|
||||
| | | | | | | | LS145 |
|
||||
Vcc | | | | | | | +-^--^--^--^------+
|
||||
--- | | | | | | | A B C D +-------+
|
||||
| | | | | | | | | | | | | |
|
||||
1-2 3 4 14 15 5 6 7 8 9 10 11 12-13 |
|
||||
+--------------------------------------------------+ |
|
||||
| connector | ---
|
||||
+--------------------------------------------------+ GND
|
||||
|
||||
|
||||
Signals charts
|
||||
--------------
|
||||
While pressing space bar, watched HHKB original controller signals by logic analyzer.
|
||||
While pressing space bar, watched HHKB Pro original controller signals by logic analyzer.
|
||||
Row and column is looping between 0-7 each for selecting a key.
|
||||
A key is scaned every about 15ms, so scan rate is 66Hz.
|
||||
|
||||
|
|
@ -109,44 +171,32 @@ Signals charts
|
|||
Space bar locate at ROW:3 COL:7. A key is selected by HC4051(C,B,A) and LS145(C,B,A).
|
||||
Key state can be read on TP1684(4/KEY) while asserting low on LS145(D).
|
||||
|
||||
Usage of TP1684(5) is not clear. Controller seemed to output previous key state on this line.
|
||||
However key state can be read without using this signal.
|
||||
|
||||
(HHKB_chart2.jpg)
|
||||
|
||||
|
||||
Matrix scan pseudo code
|
||||
-----------------------
|
||||
for (row: 0-7) {
|
||||
SELECT_ROW(row); // set HC4051(A,B,C)
|
||||
Signal of JP:
|
||||
|
||||
for (col: 0-7) {
|
||||
SELECT_COL(col); // set LS145(A,B,C)
|
||||
1) Select row
|
||||
rowC ____~~~~____~~~~ 3.8/3.8ms(JP) 7.7/7.7ms(Pro) S2 of HC4051
|
||||
rowB __~~__~~__~~__~~ 1.9/1.9ms(JP) 3.8/3.8ms(Pro) S1 of HC4051
|
||||
rowA _~_~_~_~_~_~_~_~ 1.0/1.0ms(JP) 1.9/1.9ms(Pro) S0 of HC4051
|
||||
0123456701234567 selected row(Pro)
|
||||
0123456789ABCDEF selected row(JP)
|
||||
rowEn0 ________~~~~~~~~ 7.7/7.7ms(JP only) ~Enable of Z2 HC4051(JP only)
|
||||
rowEn1 ~~~~~~~~________ 7.7/7.7ms(JP only) ~Enable of Z3 HC4051(JP only)
|
||||
|
||||
_delay_us(40);
|
||||
2) Select column
|
||||
colC ____~~~~____~~~~ 550/410us(JP) / us(Pro)
|
||||
colB __~~__~~__~~__~~ 200/210us(JP) 450/460us(Pro)
|
||||
colA _~_~_~_~_~_~_~_~ 100/110us(JP) 220/230us(Pro)
|
||||
0123456701234567 selected column
|
||||
|
||||
if (prev_key_state(row, col)) {
|
||||
KEY_PREV_ON;
|
||||
}
|
||||
3) Wait 5us after column select, then set prev, strobe colD to spit out key status and read it.
|
||||
prev _~~~~_____ 20us if previous key state is low
|
||||
colD ~~~__~~~~~ 10us strobe
|
||||
key ~~~____~~~ 22us indicates current state of the key
|
||||
|
||||
_delay_us(7);
|
||||
|
||||
ENALBLE_COL(); // set LS145(D) to low
|
||||
|
||||
_delay_us(10);
|
||||
|
||||
if (KEY == 0) { // read TP1684(KEY)
|
||||
// key pressed
|
||||
} else {
|
||||
// not pressed
|
||||
}
|
||||
|
||||
KEY_PREV_OFF;
|
||||
UNALBLE_COL(); // set LS145(D) to high
|
||||
|
||||
_delay_us(150);
|
||||
}
|
||||
}
|
||||
NOTE: JP scans twice fast as Pro/Pro2 does. So Pro/Pro2 scans 8x8 matrix in 15.4ms while JP scans 16x8 in that time.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
149
keyboard/hhkb/hhkb_avr.h
Normal file
149
keyboard/hhkb/hhkb_avr.h
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#ifndef HHKB_AVR_H
|
||||
#define HHKB_AVR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
|
||||
// Timer resolution check
|
||||
#if (1000000/TIMER_RAW_FREQ > 20)
|
||||
# error "Timer resolution(>20us) is not enough for HHKB matrix scan tweak on V-USB."
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* HHKB Matrix I/O
|
||||
*
|
||||
* row: HC4051[A,B,C] selects scan row0-7
|
||||
* row-ext: [En0,En1] row extention for JP
|
||||
* col: LS145[A,B,C,D] selects scan col0-7 and enable(D)
|
||||
* key: on: 0/off: 1
|
||||
* prev: hysteresis control: assert(1) when previous key state is on
|
||||
*/
|
||||
|
||||
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
/*
|
||||
* For TMK HHKB alt controller(ATMega32U4)
|
||||
*
|
||||
* row: PB0-2
|
||||
* col: PB3-5,6
|
||||
* key: PD7(pull-uped)
|
||||
* prev: PB7
|
||||
* power: PD4(L:off/H:on)
|
||||
* row-ext: PC6,7 for HHKB JP(active low)
|
||||
*/
|
||||
static inline void KEY_ENABLE(void) { (PORTB &= ~(1<<6)); }
|
||||
static inline void KEY_UNABLE(void) { (PORTB |= (1<<6)); }
|
||||
static inline bool KEY_STATE(void) { return (PIND & (1<<7)); }
|
||||
static inline void KEY_PREV_ON(void) { (PORTB |= (1<<7)); }
|
||||
static inline void KEY_PREV_OFF(void) { (PORTB &= ~(1<<7)); }
|
||||
static inline void KEY_POWER_ON(void) {}
|
||||
static inline void KEY_POWER_OFF(void) {}
|
||||
static inline void KEY_INIT(void)
|
||||
{
|
||||
DDRB = 0xFF;
|
||||
PORTB = 0x00;
|
||||
DDRD &= ~0x80;
|
||||
PORTD |= 0x80;
|
||||
/* keyswitch board power on */
|
||||
DDRD |= (1<<4);
|
||||
PORTD |= (1<<4);
|
||||
#ifdef HHKB_JP
|
||||
/* row extention for HHKB JP */
|
||||
DDRC |= (1<<6|1<<7);
|
||||
PORTC |= (1<<6|1<<7);
|
||||
#endif
|
||||
KEY_UNABLE();
|
||||
KEY_PREV_OFF();
|
||||
}
|
||||
static inline void KEY_SELECT(uint8_t ROW, uint8_t COL)
|
||||
{
|
||||
PORTB = (PORTB & 0xC0) | (((COL) & 0x07)<<3) | ((ROW) & 0x07);
|
||||
#ifdef HHKB_JP
|
||||
if ((ROW) & 0x08) PORTC = (PORTC & ~(1<<6|1<<7)) | (1<<6);
|
||||
else PORTC = (PORTC & ~(1<<6|1<<7)) | (1<<7);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
/*
|
||||
* For Teensy++(AT90USB1286)
|
||||
*
|
||||
* HHKB pro HHKB pro2
|
||||
* row: PB0-2 (6-8) (5-7)
|
||||
* col: PB3-5,6 (9-12) (8-11)
|
||||
* key: PE6(pull-uped) (4) (3)
|
||||
* prev: PE7 (5) (4)
|
||||
*
|
||||
* TODO: convert into 'staitc inline' function
|
||||
*/
|
||||
#define KEY_INIT() do { \
|
||||
DDRB |= 0x7F; \
|
||||
DDRE |= (1<<7); \
|
||||
DDRE &= ~(1<<6); \
|
||||
PORTE |= (1<<6); \
|
||||
} while (0)
|
||||
#define KEY_SELECT(ROW, COL) (PORTB = (PORTB & 0xC0) | \
|
||||
(((COL) & 0x07)<<3) | \
|
||||
((ROW) & 0x07))
|
||||
#define KEY_ENABLE() (PORTB &= ~(1<<6))
|
||||
#define KEY_UNABLE() (PORTB |= (1<<6))
|
||||
#define KEY_STATE() (PINE & (1<<6))
|
||||
#define KEY_PREV_ON() (PORTE |= (1<<7))
|
||||
#define KEY_PREV_OFF() (PORTE &= ~(1<<7))
|
||||
#define KEY_POWER_ON()
|
||||
#define KEY_POWER_OFF()
|
||||
|
||||
|
||||
#else
|
||||
# error "define code for matrix scan"
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
// For ATMega328P with V-USB
|
||||
//
|
||||
// #elif defined(__AVR_ATmega328P__)
|
||||
// Ports for V-USB
|
||||
// key: PB0(pull-uped)
|
||||
// prev: PB1
|
||||
// row: PB2-4
|
||||
// col: PC0-2,3
|
||||
// power: PB5(Low:on/Hi-z:off)
|
||||
#define KEY_INIT() do { \
|
||||
DDRB |= 0x3E; \
|
||||
DDRB &= ~(1<<0); \
|
||||
PORTB |= 1<<0; \
|
||||
DDRC |= 0x0F; \
|
||||
KEY_UNABLE(); \
|
||||
KEY_PREV_OFF(); \
|
||||
} while (0)
|
||||
#define KEY_SELECT(ROW, COL) do { \
|
||||
PORTB = (PORTB & 0xE3) | ((ROW) & 0x07)<<2; \
|
||||
PORTC = (PORTC & 0xF8) | ((COL) & 0x07); \
|
||||
} while (0)
|
||||
#define KEY_ENABLE() (PORTC &= ~(1<<3))
|
||||
#define KEY_UNABLE() (PORTC |= (1<<3))
|
||||
#define KEY_STATE() (PINB & (1<<0))
|
||||
#define KEY_PREV_ON() (PORTB |= (1<<1))
|
||||
#define KEY_PREV_OFF() (PORTB &= ~(1<<1))
|
||||
// Power supply switching
|
||||
#define KEY_POWER_ON() do { \
|
||||
KEY_INIT(); \
|
||||
PORTB &= ~(1<<5); \
|
||||
_delay_ms(1); \
|
||||
} while (0)
|
||||
#define KEY_POWER_OFF() do { \
|
||||
DDRB &= ~0x3F; \
|
||||
PORTB &= ~0x3F; \
|
||||
DDRC &= ~0x0F; \
|
||||
PORTC &= ~0x0F; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -54,4 +54,31 @@ extern const uint16_t fn_actions[];
|
|||
{ KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_NO } \
|
||||
}
|
||||
|
||||
|
||||
#define KEYMAP_JP( \
|
||||
K02, K32, K62, K22, K12, K52, K72, KA2, K92, K82, KB2, KE2, KF2, KD2, KC2, \
|
||||
K03, K63, K23, K13, K53, K73, KA3, K93, K83, KB3, KE3, KF3, KD3, \
|
||||
K06, K66, K26, K16, K56, K76, KA6, K96, K86, KB6, KE6, KF6, KD6, KC6, \
|
||||
K05, K65, K25, K15, K55, K75, KA5, K95, K85, KB5, KE5, KF5, KD5, KC5, \
|
||||
K04, K34, K64, K24, K14, K74, K94, K84, KB4, KE4, KF4, KD4, KC4 \
|
||||
) \
|
||||
{ \
|
||||
{ KC_NO, KC_NO, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K32, KC_NO, KC_##K34, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K52, KC_##K53, KC_NO, KC_##K55, KC_##K56, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K82, KC_##K83, KC_##K84, KC_##K85, KC_##K86, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##K92, KC_##K93, KC_##K94, KC_##K95, KC_##K96, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##KA2, KC_##KA3, KC_NO, KC_##KA5, KC_##KA6, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##KB2, KC_##KB3, KC_##KB4, KC_##KB5, KC_##KB6, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##KC2, KC_NO, KC_##KC4, KC_##KC5, KC_##KC6, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##KD2, KC_##KD3, KC_##KD4, KC_##KD5, KC_##KD6, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##KE2, KC_##KE3, KC_##KE4, KC_##KE5, KC_##KE6, KC_NO }, \
|
||||
{ KC_NO, KC_NO, KC_##KF2, KC_##KF3, KC_##KF4, KC_##KF5, KC_##KF6, KC_NO } \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
50
keyboard/hhkb/keymap_jp.c
Normal file
50
keyboard/hhkb/keymap_jp.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* HHKB JP Layout
|
||||
*/
|
||||
#include "keymap_common.h"
|
||||
|
||||
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
|
||||
#else
|
||||
const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
|
||||
#endif
|
||||
/* Layer 0: Default Layer */
|
||||
KEYMAP_JP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, \
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, \
|
||||
LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT,BSLS,ENT, \
|
||||
LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RO, UP, RSFT, \
|
||||
FN0, ZKHK,LGUI,LALT,MHEN, SPC, HENK,KANA,RALT,FN0, LEFT,DOWN,RGHT),
|
||||
|
||||
/* Layer 1: HHKB mode (HHKB Fn)
|
||||
* ,-----------------------------------------------------------.
|
||||
* |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del|
|
||||
* |-----------------------------------------------------------|
|
||||
* |Caps | | | | | | | |Psc|Slk|Pus|Up | | |
|
||||
* |------------------------------------------------------` |
|
||||
* | |VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig| | |
|
||||
* |-----------------------------------------------------------|
|
||||
* | | | | | | | +| -|End|PgD|Dow| | | |
|
||||
* |-----------------------------------------------------------|
|
||||
* | || | | | | | | | | || | | |
|
||||
* `-----------------------------------------------------------'
|
||||
*/
|
||||
KEYMAP_JP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
|
||||
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS, UP, TRNS, \
|
||||
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,TRNS,PENT, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,TRNS,TRNS,TRNS, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS),
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Fn action definition
|
||||
*/
|
||||
#ifdef KEYMAP_SECTION_ENABLE
|
||||
const uint16_t fn_actions[] __attribute__ ((section (".keymap.fn_actions"))) = {
|
||||
#else
|
||||
const uint16_t fn_actions[] PROGMEM = {
|
||||
#endif
|
||||
[0] = ACTION_LAYER_MOMENTARY(1),
|
||||
};
|
||||
|
|
@ -20,20 +20,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "timer.h"
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
// Timer resolution check
|
||||
#if (1000000/TIMER_RAW_FREQ > 20)
|
||||
# error "Timer resolution(>20us) is not enough for HHKB matrix scan tweak on V-USB."
|
||||
#endif
|
||||
#include "hhkb_avr.h"
|
||||
|
||||
|
||||
// matrix state buffer(1:on, 0:off)
|
||||
|
|
@ -43,122 +36,6 @@ static matrix_row_t _matrix0[MATRIX_ROWS];
|
|||
static matrix_row_t _matrix1[MATRIX_ROWS];
|
||||
|
||||
|
||||
// Matrix I/O ports
|
||||
//
|
||||
// row: HC4051[A,B,C] selects scan row0-7
|
||||
// col: LS145[A,B,C,D] selects scan col0-7 and enable(D)
|
||||
// key: on: 0/off: 1
|
||||
// prev: unknown: output previous key state(negated)?
|
||||
|
||||
#if defined(__AVR_AT90USB1286__)
|
||||
// Ports for Teensy++
|
||||
// row: PB0-2
|
||||
// col: PB3-5,6
|
||||
// key: PE6(pull-uped)
|
||||
// prev: PE7
|
||||
#define KEY_INIT() do { \
|
||||
DDRB |= 0x7F; \
|
||||
DDRE |= (1<<7); \
|
||||
DDRE &= ~(1<<6); \
|
||||
PORTE |= (1<<6); \
|
||||
} while (0)
|
||||
#define KEY_SELECT(ROW, COL) (PORTB = (PORTB & 0xC0) | \
|
||||
(((COL) & 0x07)<<3) | \
|
||||
((ROW) & 0x07))
|
||||
#define KEY_ENABLE() (PORTB &= ~(1<<6))
|
||||
#define KEY_UNABLE() (PORTB |= (1<<6))
|
||||
#define KEY_STATE() (PINE & (1<<6))
|
||||
#define KEY_PREV_ON() (PORTE |= (1<<7))
|
||||
#define KEY_PREV_OFF() (PORTE &= ~(1<<7))
|
||||
#define KEY_POWER_ON()
|
||||
#define KEY_POWER_OFF()
|
||||
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
// Ports for my designed Alt Controller PCB
|
||||
// row: PB0-2
|
||||
// col: PB3-5,6
|
||||
// key: PD7(pull-uped)
|
||||
// prev: PB7
|
||||
// power: PD4(L:off/H:on)
|
||||
#define KEY_INIT() do { \
|
||||
DDRB = 0xFF; \
|
||||
PORTB = 0x00; \
|
||||
DDRD &= ~0x80; \
|
||||
PORTD |= 0x80; \
|
||||
/* keyswitch board power on */ \
|
||||
DDRD |= (1<<4); \
|
||||
PORTD |= (1<<4); \
|
||||
KEY_UNABLE(); \
|
||||
KEY_PREV_OFF(); \
|
||||
} while (0)
|
||||
#define KEY_SELECT(ROW, COL) (PORTB = (PORTB & 0xC0) | \
|
||||
(((COL) & 0x07)<<3) | \
|
||||
((ROW) & 0x07))
|
||||
#define KEY_ENABLE() (PORTB &= ~(1<<6))
|
||||
#define KEY_UNABLE() (PORTB |= (1<<6))
|
||||
#define KEY_STATE() (PIND & (1<<7))
|
||||
#define KEY_PREV_ON() (PORTB |= (1<<7))
|
||||
#define KEY_PREV_OFF() (PORTB &= ~(1<<7))
|
||||
#define KEY_POWER_ON()
|
||||
#define KEY_POWER_OFF()
|
||||
/*
|
||||
#define KEY_POWER_ON() do { \
|
||||
KEY_INIT(); \
|
||||
PORTD |= (1<<4); \
|
||||
_delay_ms(1); \
|
||||
} while (0)
|
||||
#define KEY_POWER_OFF() do { \
|
||||
PORTD &= ~(1<<4); \
|
||||
DDRB &= ~0xFF; \
|
||||
PORTB &= ~0xFF; \
|
||||
DDRB &= ~0x80; \
|
||||
PORTB &= ~0x80; \
|
||||
} while (0)
|
||||
*/
|
||||
|
||||
|
||||
#elif defined(__AVR_ATmega328P__)
|
||||
// Ports for V-USB
|
||||
// key: PB0(pull-uped)
|
||||
// prev: PB1
|
||||
// row: PB2-4
|
||||
// col: PC0-2,3
|
||||
// power: PB5(Low:on/Hi-z:off)
|
||||
#define KEY_INIT() do { \
|
||||
DDRB |= 0x3E; \
|
||||
DDRB &= ~(1<<0); \
|
||||
PORTB |= 1<<0; \
|
||||
DDRC |= 0x0F; \
|
||||
KEY_UNABLE(); \
|
||||
KEY_PREV_OFF(); \
|
||||
} while (0)
|
||||
#define KEY_SELECT(ROW, COL) do { \
|
||||
PORTB = (PORTB & 0xE3) | ((ROW) & 0x07)<<2; \
|
||||
PORTC = (PORTC & 0xF8) | ((COL) & 0x07); \
|
||||
} while (0)
|
||||
#define KEY_ENABLE() (PORTC &= ~(1<<3))
|
||||
#define KEY_UNABLE() (PORTC |= (1<<3))
|
||||
#define KEY_STATE() (PINB & (1<<0))
|
||||
#define KEY_PREV_ON() (PORTB |= (1<<1))
|
||||
#define KEY_PREV_OFF() (PORTB &= ~(1<<1))
|
||||
// Power supply switching
|
||||
#define KEY_POWER_ON() do { \
|
||||
KEY_INIT(); \
|
||||
PORTB &= ~(1<<5); \
|
||||
_delay_ms(1); \
|
||||
} while (0)
|
||||
#define KEY_POWER_OFF() do { \
|
||||
DDRB &= ~0x3F; \
|
||||
PORTB &= ~0x3F; \
|
||||
DDRC &= ~0x0F; \
|
||||
PORTC &= ~0x0F; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
# error "define code for matrix scan"
|
||||
#endif
|
||||
|
||||
|
||||
inline
|
||||
uint8_t matrix_rows(void)
|
||||
{
|
||||
|
|
@ -199,13 +76,13 @@ uint8_t matrix_scan(void)
|
|||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
|
||||
KEY_SELECT(row, col);
|
||||
_delay_us(40);
|
||||
_delay_us(5);
|
||||
|
||||
// Not sure this is needed. This just emulates HHKB controller's behaviour.
|
||||
if (matrix_prev[row] & (1<<col)) {
|
||||
KEY_PREV_ON();
|
||||
}
|
||||
_delay_us(7);
|
||||
_delay_us(10);
|
||||
|
||||
// NOTE: KEY_STATE is valid only in 20us after KEY_ENABLE.
|
||||
// If V-USB interrupts in this section we could lose 40us or so
|
||||
|
|
@ -241,11 +118,13 @@ uint8_t matrix_scan(void)
|
|||
matrix[row] = matrix_prev[row];
|
||||
}
|
||||
|
||||
_delay_us(5);
|
||||
KEY_PREV_OFF();
|
||||
KEY_UNABLE();
|
||||
|
||||
// NOTE: KEY_STATE keep its state in 20us after KEY_ENABLE.
|
||||
// This takes 25us or more to make sure KEY_STATE returns to idle state.
|
||||
_delay_us(150);
|
||||
_delay_us(75);
|
||||
}
|
||||
}
|
||||
KEY_POWER_OFF();
|
||||
|
|
|
|||
117
keyboard/kitten_paw/Makefile.lufa
Normal file
117
keyboard/kitten_paw/Makefile.lufa
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device.
|
||||
# Please customize your programmer settings(PROGRAM_CMD)
|
||||
#
|
||||
# make teensy = Download the hex file to the device, using teensy_loader_cli.
|
||||
# (must have teensy_loader_cli installed).
|
||||
#
|
||||
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
||||
# have dfu-programmer installed).
|
||||
#
|
||||
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
||||
# have Atmel FLIP installed).
|
||||
#
|
||||
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
||||
# (must have dfu-programmer installed).
|
||||
#
|
||||
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
||||
# (must have Atmel FLIP installed).
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = kittenpaw_lufa
|
||||
|
||||
# Directory common source filess exist
|
||||
TOP_DIR = ../..
|
||||
|
||||
# Directory keyboard dependent files exist
|
||||
TARGET_DIR = .
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = keymap.c \
|
||||
matrix.c \
|
||||
led.c
|
||||
|
||||
CONFIG_H = config.h
|
||||
|
||||
# MCU name
|
||||
MCU = atmega32u2
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency in Hz. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
#
|
||||
# This will be an integer division of F_USB below, as it is sourced by
|
||||
# F_USB after it has run through any CPU prescalers. Note that this value
|
||||
# does not *change* the processor frequency - it should merely be updated to
|
||||
# reflect the processor speed set externally so that the code can use accurate
|
||||
# software delays.
|
||||
F_CPU = 16000000
|
||||
|
||||
#
|
||||
# LUFA specific
|
||||
#
|
||||
# Target architecture (see library "Board Types" documentation).
|
||||
ARCH = AVR8
|
||||
|
||||
# Input clock frequency.
|
||||
# This will define a symbol, F_USB, in all source code files equal to the
|
||||
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
||||
# at the end, this will be done automatically to create a 32-bit value in your
|
||||
# source code.
|
||||
#
|
||||
# If no clock division is performed on the input clock inside the AVR (via the
|
||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
||||
F_USB = $(F_CPU)
|
||||
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
|
||||
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
#CONSOLE_ENABLE = yes # Console for debug(+400)
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
|
||||
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
|
||||
|
||||
|
||||
# Boot Section Size in bytes
|
||||
# Teensy halfKay 512
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TOP_DIR)
|
||||
|
||||
include $(TOP_DIR)/protocol/lufa.mk
|
||||
include $(TOP_DIR)/common.mk
|
||||
include $(TOP_DIR)/rules.mk
|
||||
20
keyboard/kitten_paw/README.md
Normal file
20
keyboard/kitten_paw/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Kitten Paw controller firmware
|
||||
======================
|
||||
Custom controller for the Costar Majestouch keyboard designed by bpiphany.
|
||||
|
||||
*Note that this is not the official firmware*
|
||||
|
||||
Build
|
||||
-----
|
||||
Move to this directory then just run `make` like:
|
||||
|
||||
$ make -f Makefile.lufa
|
||||
|
||||
At the moment only the LUFA stack is supported.
|
||||
|
||||
|
||||
Bootloader
|
||||
---------
|
||||
To enter bootloader by hardware use a magnet above the controller before connecting the usb cable.
|
||||
|
||||
It is still possible to use Boot Magic and Command (LSFT+RSFT+PAUS) to access the bootloader though.
|
||||
43
keyboard/kitten_paw/config.h
Normal file
43
keyboard/kitten_paw/config.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6050
|
||||
#define DEVICE_VER 0x0104
|
||||
#define MANUFACTURER Costar
|
||||
#define PRODUCT Majestouch
|
||||
|
||||
/* message strings */
|
||||
#define DESCRIPTION t.m.k. keyboard firmware for Majestouch
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 8
|
||||
#define MATRIX_COLS 18
|
||||
|
||||
/* Set 0 if need no debouncing */
|
||||
#define DEBOUNCE 5
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
#endif
|
||||
102
keyboard/kitten_paw/keymap.c
Normal file
102
keyboard/kitten_paw/keymap.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "keycode.h"
|
||||
#include "action.h"
|
||||
#include "action_macro.h"
|
||||
#include "report.h"
|
||||
#include "host.h"
|
||||
#include "debug.h"
|
||||
#include "keymap.h"
|
||||
|
||||
/*
|
||||
Matrix col/row mapping
|
||||
|
||||
,----. ,-------------------. ,-------------------. ,-------------------. ,--------------.
|
||||
|06/6| |07/4|08/4|08/2|08/6| |15/5|11/6|12/2|12/4| |14/4|14/5|14/6|14/0| |13/5|13/7|15/7|
|
||||
`----' `-------------------' `-------------------' `-------------------' `--------------'
|
||||
,-------------------------------------------------------------------------. ,--------------. ,-------------------.
|
||||
|06/4|06/5|07/5|08/5|09/5|09/4|10/4|10/5|11/5|12/5|05/5|05/4|11/4| 14/2| |17/4|02/4|04/4| |16/1|17/1|04/1|04/0|
|
||||
|-------------------------------------------------------------------------| |--------------| |-------------------|
|
||||
|06/2 |06/7|07/7|08/7|09/7|09/2|10/2|10/7|11/7|12/7|05/7|05/2|11/2| 14/3| |16/4|02/5|04/5| |16/7|17/7|04/7| |
|
||||
|-------------------------------------------------------------------------| '--------------' |-------------- 02/7|
|
||||
|02/7 |06/3|07/3|08/3|09/3|09/6|10/6|10/3|11/3|12/3|05/3|05/6| 14/1| |16/2|17/2|04/2| |
|
||||
|-------------------------------------------------------------------------| ,----. |-------------------|
|
||||
|01/2 |06/1|07/1|08/1|09/1|09/0|10/0|10/1|11/1|12/1|05/0| 01/3| |02/6| |16/3|17/3|04/3| |
|
||||
|-------------------------------------------------------------------------| ,--------------. |-------------- 02/3|
|
||||
|15/4|03/2|13/6| 16/6 |13/0|0/3|12/0|15/1| |02/0|16/0|17/0| | 17/6 |04/6| |
|
||||
`-------------------------------------------------------------------------' `--------------' `-------------------'
|
||||
*/
|
||||
|
||||
#define KEYMAP( \
|
||||
KG6, KH4, KI4, KI2, KI6, KP5, KL6, KM2, KM4, KO4, KO5, KO6, KO0, KN5, KN7, KP7, \
|
||||
KG4, KG5, KH5, KI5, KJ5, KJ4, KK4, KK5, KL5, KM5, KF5, KF4, KL4, KO2, KR4, KC4, KE4, KQ1, KR1, KE1, KE0, \
|
||||
KG2, KG7, KH7, KI7, KJ7, KJ2, KK2, KK7, KL7, KM7, KF7, KF2, KL2, KO3, KQ4, KC5, KE5, KQ7, KR7, KE7, KC7, \
|
||||
KH2, KG3, KH3, KI3, KJ3, KJ6, KK6, KK3, KL3, KM3, KF3, KF6, KO1, KQ2, KR2, KE2, \
|
||||
KB2, KH6, KG1, KH1, KI1, KJ1, KJ0, KK0, KK1, KL1, KM1, KF0, KB3, KC6, KQ3, KR3, KE3, KC3, \
|
||||
KP4, KD2, KN6, KQ6, KN0, KA3, KM0, KP1, KC0, KQ0, KR0, KR6, KE6 \
|
||||
) { \
|
||||
/* 0 1 2 3 4 5 6 7 */ \
|
||||
/* A 0 */ {KC_NO, KC_NO, KC_NO, KC_##KA3, KC_NO, KC_NO, KC_NO, KC_NO },\
|
||||
/* B 1 */ {KC_NO, KC_NO, KC_##KB2, KC_##KB3, KC_NO, KC_NO, KC_NO, KC_NO },\
|
||||
/* C 2 */ {KC_##KC0, KC_NO, KC_NO, KC_##KC3, KC_##KC4, KC_##KC5, KC_##KC6, KC_##KC7},\
|
||||
/* D 3 */ {KC_NO, KC_NO, KC_##KD2, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO },\
|
||||
/* E 4 */ {KC_##KE0, KC_##KE1, KC_##KE2, KC_##KE3, KC_##KE4, KC_##KE5, KC_##KE6, KC_##KE7},\
|
||||
/* F 5 */ {KC_##KF0, KC_NO, KC_##KF2, KC_##KF3, KC_##KF4, KC_##KF5, KC_##KF6, KC_##KF7},\
|
||||
/* G 6 */ {KC_NO, KC_##KG1, KC_##KG2, KC_##KG3, KC_##KG4, KC_##KG5, KC_##KG6, KC_##KG7},\
|
||||
/* H 7 */ {KC_NO, KC_##KH1, KC_##KH2, KC_##KH3, KC_##KH4, KC_##KH5, KC_##KH6, KC_##KH7},\
|
||||
/* I 8 */ {KC_NO, KC_##KI1, KC_##KI2, KC_##KI3, KC_##KI4, KC_##KI5, KC_##KI6, KC_##KI7},\
|
||||
/* J 9 */ {KC_##KJ0, KC_##KJ1, KC_##KJ2, KC_##KJ3, KC_##KJ4, KC_##KJ5, KC_##KJ6, KC_##KJ7},\
|
||||
/* K 10 */ {KC_##KK0, KC_##KK1, KC_##KK2, KC_##KK3, KC_##KK4, KC_##KK5, KC_##KK6, KC_##KK7},\
|
||||
/* L 11 */ {KC_NO, KC_##KL1, KC_##KL2, KC_##KL3, KC_##KL4, KC_##KL5, KC_##KL6, KC_##KL7},\
|
||||
/* M 12 */ {KC_##KM0, KC_##KM1, KC_##KM2, KC_##KM3, KC_##KM4, KC_##KM5, KC_NO, KC_##KM7},\
|
||||
/* N 13 */ {KC_##KN0, KC_NO, KC_NO, KC_NO, KC_NO, KC_##KN5, KC_##KN6, KC_##KN7},\
|
||||
/* O 14 */ {KC_##KO0, KC_##KO1, KC_##KO2, KC_##KO3, KC_##KO4, KC_##KO5, KC_##KO6, KC_NO },\
|
||||
/* P 15 */ {KC_NO, KC_##KP1, KC_NO, KC_NO, KC_##KP4, KC_##KP5, KC_NO, KC_##KP7},\
|
||||
/* Q 16 */ {KC_##KQ0, KC_##KQ1, KC_##KQ2, KC_##KQ3, KC_##KQ4, KC_NO, KC_##KQ6, KC_##KQ7},\
|
||||
/* R 17 */ {KC_##KR0, KC_##KR1, KC_##KR2, KC_##KR3, KC_##KR4, KC_NO, KC_##KR6, KC_##KR7} \
|
||||
}
|
||||
|
||||
#include "keymap_ansi.h"
|
||||
|
||||
#define KEYMAPS_SIZE (sizeof(keymaps) / sizeof(keymaps[0]))
|
||||
#define FN_ACTIONS_SIZE (sizeof(fn_actions) / sizeof(fn_actions[0]))
|
||||
|
||||
/* translates key to keycode */
|
||||
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
|
||||
{
|
||||
if (layer < KEYMAPS_SIZE) {
|
||||
return pgm_read_byte(&keymaps[(layer)][(key.col)][(key.row)]);
|
||||
} else {
|
||||
return pgm_read_byte(&keymaps[0][(key.col)][(key.row)]);
|
||||
}
|
||||
}
|
||||
|
||||
/* translates Fn keycode to action */
|
||||
action_t keymap_fn_to_action(uint8_t keycode)
|
||||
{
|
||||
action_t action;
|
||||
if (FN_INDEX(keycode) < FN_ACTIONS_SIZE) {
|
||||
action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
|
||||
} else {
|
||||
action.code = ACTION_NO;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
23
keyboard/kitten_paw/keymap_ansi.h
Normal file
23
keyboard/kitten_paw/keymap_ansi.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
static const uint8_t PROGMEM keymaps[][MATRIX_COLS][MATRIX_ROWS] = {
|
||||
/* Layer 0: Standard ANSI layer */
|
||||
KEYMAP(\
|
||||
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, \
|
||||
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS, \
|
||||
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9, PPLS, \
|
||||
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, \
|
||||
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, PENT, \
|
||||
LCTL,LGUI,LALT, SPC, RALT,RGUI, FN0,RCTL, LEFT,DOWN,RGHT, P0, PDOT), \
|
||||
/* Layer 1: Function layer */
|
||||
KEYMAP(\
|
||||
CALC,MYCM,WSCH,WHOM,MAIL,VOLD,VOLU,MSEL,MSTP,MPLY,MPRV,MNXT,TRNS, WAKE, PWR,SLEP, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS, \
|
||||
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS, TRNS,TRNS,TRNS,TRNS, \
|
||||
TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS)
|
||||
};
|
||||
|
||||
static const uint16_t PROGMEM fn_actions[] = {
|
||||
[0] = ACTION_LAYER_MOMENTARY(1)
|
||||
};
|
||||
60
keyboard/kitten_paw/led.c
Normal file
60
keyboard/kitten_paw/led.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "stdint.h"
|
||||
#include "led.h"
|
||||
|
||||
/* LED pin configuration
|
||||
*
|
||||
* Scroll Lock PB7
|
||||
* CAPS PC6
|
||||
* NUMLOCK PC5
|
||||
*
|
||||
*/
|
||||
void led_set(uint8_t usb_led)
|
||||
{
|
||||
DDRB |= (1<<7);
|
||||
DDRC |= (1<<5) | (1<<6);
|
||||
|
||||
if (usb_led & (1<<USB_LED_CAPS_LOCK))
|
||||
{
|
||||
PORTC &= ~(1<<6);
|
||||
}
|
||||
else
|
||||
{
|
||||
PORTC |= (1<<6);
|
||||
}
|
||||
|
||||
if (usb_led & (1<<USB_LED_NUM_LOCK))
|
||||
{
|
||||
PORTC &= ~(1<<5);
|
||||
}
|
||||
else
|
||||
{
|
||||
PORTC |= (1<<5);
|
||||
}
|
||||
|
||||
if (usb_led & (1<<USB_LED_SCROLL_LOCK))
|
||||
{
|
||||
PORTB &= ~(1<<7);
|
||||
}
|
||||
else
|
||||
{
|
||||
PORTB |= (1<<7);
|
||||
}
|
||||
}
|
||||
239
keyboard/kitten_paw/matrix.c
Normal file
239
keyboard/kitten_paw/matrix.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 0
|
||||
#endif
|
||||
static uint8_t debouncing = DEBOUNCE;
|
||||
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
|
||||
|
||||
static uint8_t read_rows(void);
|
||||
static void init_rows(void);
|
||||
static void unselect_cols(void);
|
||||
static void select_col(uint8_t col);
|
||||
|
||||
inline uint8_t matrix_rows(void)
|
||||
{
|
||||
return MATRIX_ROWS;
|
||||
}
|
||||
|
||||
inline uint8_t matrix_cols(void)
|
||||
{
|
||||
return MATRIX_COLS;
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
unselect_cols();
|
||||
init_rows();
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
matrix_debouncing[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
|
||||
select_col(col);
|
||||
_delay_us(3);
|
||||
uint8_t rows = read_rows();
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
|
||||
bool curr_bit = rows & (1<<row);
|
||||
if (prev_bit != curr_bit) {
|
||||
matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
|
||||
debouncing = DEBOUNCE;
|
||||
}
|
||||
}
|
||||
unselect_cols();
|
||||
}
|
||||
|
||||
if (debouncing) {
|
||||
if (--debouncing) {
|
||||
_delay_ms(1);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = matrix_debouncing[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool matrix_is_modified(void)
|
||||
{
|
||||
if (debouncing) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool matrix_is_on(uint8_t row, uint8_t col)
|
||||
{
|
||||
return (matrix[row] & ((matrix_row_t)1<<col));
|
||||
}
|
||||
|
||||
inline matrix_row_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
void matrix_print(void)
|
||||
{
|
||||
print("\nr/c 0123456789ABCDEF\n");
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_key_count(void)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += bitpop32(matrix[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Row pin configuration
|
||||
*
|
||||
* row: 0 1 2 3 4 5 6 7
|
||||
* pin: PC2 PB1 PB2 PB3 PC7 PB4 PB5 PB6
|
||||
*
|
||||
*/
|
||||
static void init_rows(void)
|
||||
{
|
||||
DDRC &= ~0b10000100;
|
||||
DDRB &= ~0b01111110;
|
||||
PORTC |= 0b10000100;
|
||||
PORTB |= 0b01111110;
|
||||
}
|
||||
|
||||
static uint8_t read_rows(void)
|
||||
{
|
||||
return (PINC&(1<<2) ? 0 : (1<<0)) |
|
||||
(PINB&(1<<1) ? 0 : (1<<1)) |
|
||||
(PINB&(1<<2) ? 0 : (1<<2)) |
|
||||
(PINB&(1<<3) ? 0 : (1<<3)) |
|
||||
(PINC&(1<<7) ? 0 : (1<<4)) |
|
||||
(PINB&(1<<4) ? 0 : (1<<5)) |
|
||||
(PINB&(1<<5) ? 0 : (1<<6)) |
|
||||
(PINB&(1<<6) ? 0 : (1<<7));
|
||||
}
|
||||
|
||||
/* These columns uses two 74HC42 4 to 10 bit demultiplexers (low active).
|
||||
*
|
||||
* COL PD1 PD0 PD2 PD6 PD5 PD4
|
||||
* 12 1 1 0 0 0 0
|
||||
* 11 1 1 0 0 0 1
|
||||
* 10 1 1 0 0 1 0
|
||||
* 9 1 1 0 0 1 1
|
||||
* 8 1 1 0 1 0 0
|
||||
* 7 1 1 0 1 0 1
|
||||
* 6 1 1 0 1 1 0
|
||||
* 5 1 1 0 1 1 1
|
||||
* 4 1 1 1 0 0 0
|
||||
* 3 1 1 1 0 0 1
|
||||
|
||||
* COL PD2 PD6 PD1 PD0 PD5 PD4
|
||||
* 2 1 1 0 0 0 0
|
||||
* 1 1 1 0 0 0 1
|
||||
* 0 1 1 0 0 1 0
|
||||
* 17 1 1 0 0 1 1
|
||||
* 16 1 1 0 1 0 0
|
||||
* 1 1 0 1 0 1
|
||||
* 1 1 0 1 1 0
|
||||
* 15 1 1 0 1 1 1
|
||||
* 14 1 1 1 0 0 0
|
||||
* 13 1 1 1 0 0 1
|
||||
*/
|
||||
static void unselect_cols(void)
|
||||
{
|
||||
DDRD |= 0b01110111;
|
||||
PORTD &= ~0b01110111;
|
||||
}
|
||||
|
||||
static void select_col(uint8_t col)
|
||||
{
|
||||
switch (col) {
|
||||
case 0:
|
||||
PORTD |= (1<<5) | (1<<6) | (1<<2);
|
||||
break;
|
||||
case 1:
|
||||
PORTD |= (1<<4) | (1<<6) | (1<<2);
|
||||
break;
|
||||
case 2:
|
||||
PORTD |= (1<<6) | (1<<2);
|
||||
break;
|
||||
case 3:
|
||||
PORTD |= (1<<4) | (1<<2) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 4:
|
||||
PORTD |= (1<<2) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 5:
|
||||
PORTD |= (1<<4) | (1<<5) | (1<<6) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 6:
|
||||
PORTD |= (1<<5) | (1<<6) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 7:
|
||||
PORTD |= (1<<4) | (1<<6) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 8:
|
||||
PORTD |= (1<<6) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 9:
|
||||
PORTD |= (1<<4) | (1<<5) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 10:
|
||||
PORTD |= (1<<5) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 11:
|
||||
PORTD |= (1<<4) | (1<<0) | (1<<1);
|
||||
break;
|
||||
case 12:
|
||||
PORTD |= (1<<0) | (1<<1);
|
||||
break;
|
||||
case 13:
|
||||
PORTD |= (1<<4) | (1<<1) | (1<<6) | (1<<2);
|
||||
break;
|
||||
case 14:
|
||||
PORTD |= (1<<1) | (1<<6) | (1<<2);
|
||||
break;
|
||||
case 15:
|
||||
PORTD |= (1<<4) | (1<<5) | (1<<0) | (1<<6) | (1<<2);
|
||||
break;
|
||||
case 16:
|
||||
PORTD |= (1<<0) | (1<<6) | (1<<2);
|
||||
break;
|
||||
case 17:
|
||||
PORTD |= (1<<4) | (1<<5) | (1<<6) | (1<<2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
117
keyboard/lightpad/Makefile.lufa
Normal file
117
keyboard/lightpad/Makefile.lufa
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device.
|
||||
# Please customize your programmer settings(PROGRAM_CMD)
|
||||
#
|
||||
# make teensy = Download the hex file to the device, using teensy_loader_cli.
|
||||
# (must have teensy_loader_cli installed).
|
||||
#
|
||||
# make dfu = Download the hex file to the device, using dfu-programmer (must
|
||||
# have dfu-programmer installed).
|
||||
#
|
||||
# make flip = Download the hex file to the device, using Atmel FLIP (must
|
||||
# have Atmel FLIP installed).
|
||||
#
|
||||
# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
|
||||
# (must have dfu-programmer installed).
|
||||
#
|
||||
# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
|
||||
# (must have Atmel FLIP installed).
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = lightpad_lufa
|
||||
|
||||
# Directory common source filess exist
|
||||
TOP_DIR = ../..
|
||||
|
||||
# Directory keyboard dependent files exist
|
||||
TARGET_DIR = .
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = keymap.c \
|
||||
matrix.c \
|
||||
led.c \
|
||||
backlight.c
|
||||
|
||||
CONFIG_H = config.h
|
||||
|
||||
# MCU name
|
||||
MCU = atmega32u4
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency in Hz. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
#
|
||||
# This will be an integer division of F_USB below, as it is sourced by
|
||||
# F_USB after it has run through any CPU prescalers. Note that this value
|
||||
# does not *change* the processor frequency - it should merely be updated to
|
||||
# reflect the processor speed set externally so that the code can use accurate
|
||||
# software delays.
|
||||
F_CPU = 8000000
|
||||
|
||||
#
|
||||
# LUFA specific
|
||||
#
|
||||
# Target architecture (see library "Board Types" documentation).
|
||||
ARCH = AVR8
|
||||
|
||||
# Input clock frequency.
|
||||
# This will define a symbol, F_USB, in all source code files equal to the
|
||||
# input clock frequency (before any prescaling is performed) in Hz. This value may
|
||||
# differ from F_CPU if prescaling is used on the latter, and is required as the
|
||||
# raw input clock is fed directly to the PLL sections of the AVR for high speed
|
||||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
|
||||
# at the end, this will be done automatically to create a 32-bit value in your
|
||||
# source code.
|
||||
#
|
||||
# If no clock division is performed on the input clock inside the AVR (via the
|
||||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
|
||||
F_USB = $(F_CPU)
|
||||
|
||||
# Build Options
|
||||
# comment out to disable the options.
|
||||
#
|
||||
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
|
||||
#MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
|
||||
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
#CONSOLE_ENABLE = yes # Console for debug(+400)
|
||||
#COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
|
||||
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
|
||||
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
|
||||
|
||||
# Boot Section Size in bytes
|
||||
# Teensy halfKay 512
|
||||
# Atmel DFU loader 4096
|
||||
# LUFA bootloader 4096
|
||||
OPT_DEFS += -DBOOTLOADER_SIZE=4096
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TOP_DIR)
|
||||
|
||||
include $(TOP_DIR)/protocol/lufa.mk
|
||||
include $(TOP_DIR)/common.mk
|
||||
include $(TOP_DIR)/rules.mk
|
||||
24
keyboard/lightpad/README.md
Normal file
24
keyboard/lightpad/README.md
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Lightpad keypad firmware
|
||||
======================
|
||||
Korean custom keypad designed by Duck.
|
||||
|
||||
*Note that this is not the official firmware*
|
||||
|
||||
|
||||
Supported models
|
||||
----------------
|
||||
All pcb options are supported.
|
||||
|
||||
|
||||
Build
|
||||
-----
|
||||
Move to this directory then just run `make` like:
|
||||
|
||||
$ make -f Makefile.lufa
|
||||
|
||||
|
||||
Bootloader
|
||||
---------
|
||||
The PCB is hardwired to run the bootloader if the key at the `top left` position is held down when connecting the keyboard.
|
||||
|
||||
It is still possible to use Boot Magic and Command to access the bootloader though.
|
||||
129
keyboard/lightpad/backlight.c
Normal file
129
keyboard/lightpad/backlight.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "backlight.h"
|
||||
|
||||
/* Backlight pin configuration
|
||||
*
|
||||
* FN1 PB0 (low)
|
||||
* FN2 PB5 (low)
|
||||
* FN3 PB4 (low)
|
||||
* FN4 PD7 (low)
|
||||
* REAR PD6 (high)
|
||||
* NUMPAD PB2 (high)
|
||||
* NUMLOCK PB1 (low)
|
||||
*/
|
||||
void backlight_init_ports() {
|
||||
DDRB |= (1<<0) | (1<<1) | (1<<2) | (1<<4) | (1<<5);
|
||||
DDRD |= (1<<6) | (1<<7);
|
||||
|
||||
backlight_disable_numlock();
|
||||
}
|
||||
|
||||
void backlight_set(uint8_t level) {
|
||||
(level & BACKLIGHT_FN1) ? backlight_enable_fn1() : backlight_disable_fn1();
|
||||
(level & BACKLIGHT_FN2) ? backlight_enable_fn2() : backlight_disable_fn2();
|
||||
(level & BACKLIGHT_FN3) ? backlight_enable_fn3() : backlight_disable_fn3();
|
||||
(level & BACKLIGHT_FN4) ? backlight_enable_fn4() : backlight_disable_fn4();
|
||||
(level & BACKLIGHT_NUMPAD) ? backlight_enable_numpad() : backlight_disable_numpad();
|
||||
(level & BACKLIGHT_REAR) ? backlight_enable_rear() : backlight_disable_rear();
|
||||
}
|
||||
|
||||
void backlight_enable_fn1() {
|
||||
PORTB &= ~(1<<0);
|
||||
}
|
||||
|
||||
void backlight_disable_fn1() {
|
||||
PORTB |= (1<<0);
|
||||
}
|
||||
|
||||
void backlight_invert_fn1() {
|
||||
PORTB ^= (1<<0);
|
||||
}
|
||||
|
||||
void backlight_enable_fn2() {
|
||||
PORTB &= ~(1<<5);
|
||||
}
|
||||
|
||||
void backlight_disable_fn2() {
|
||||
PORTB |= (1<<5);
|
||||
}
|
||||
|
||||
void backlight_invert_fn2() {
|
||||
PORTB ^= (1<<5);
|
||||
}
|
||||
|
||||
void backlight_enable_fn3() {
|
||||
PORTB &= ~(1<<4);
|
||||
}
|
||||
|
||||
void backlight_disable_fn3() {
|
||||
PORTB |= (1<<4);
|
||||
}
|
||||
|
||||
void backlight_invert_fn3() {
|
||||
PORTB ^= (1<<4);
|
||||
}
|
||||
|
||||
void backlight_enable_fn4() {
|
||||
PORTD &= ~(1<<7);
|
||||
}
|
||||
|
||||
void backlight_disable_fn4() {
|
||||
PORTD |= (1<<7);
|
||||
}
|
||||
|
||||
void backlight_invert_fn4() {
|
||||
PORTD ^= (1<<7);
|
||||
}
|
||||
|
||||
void backlight_enable_numpad() {
|
||||
PORTB |= (1<<2);
|
||||
}
|
||||
|
||||
void backlight_disable_numpad() {
|
||||
PORTB &= ~(1<<2);
|
||||
}
|
||||
|
||||
void backlight_invert_numpad() {
|
||||
PORTB ^= (1<<2);
|
||||
}
|
||||
|
||||
void backlight_enable_numlock() {
|
||||
PORTB &= ~(1<<1);
|
||||
}
|
||||
|
||||
void backlight_disable_numlock() {
|
||||
PORTB |= (1<<1);
|
||||
}
|
||||
|
||||
void backlight_invert_numlock() {
|
||||
PORTB ^= (1<<1);
|
||||
}
|
||||
|
||||
void backlight_enable_rear() {
|
||||
PORTD |= (1<<6);
|
||||
}
|
||||
|
||||
void backlight_disable_rear() {
|
||||
PORTD &= ~(1<<6);
|
||||
}
|
||||
|
||||
void backlight_invert_rear() {
|
||||
PORTD ^= (1<<6);
|
||||
}
|
||||
39
keyboard/lightpad/backlight.h
Normal file
39
keyboard/lightpad/backlight.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
enum backlight_level {
|
||||
BACKLIGHT_FN1 = 0b0000001,
|
||||
BACKLIGHT_FN2 = 0b0000010,
|
||||
BACKLIGHT_FN3 = 0b0000100,
|
||||
BACKLIGHT_FN4 = 0b0001000,
|
||||
BACKLIGHT_NUMPAD = 0b0010000,
|
||||
BACKLIGHT_REAR = 0b0100000,
|
||||
};
|
||||
|
||||
void backlight_init_ports(void);
|
||||
|
||||
void backlight_invert_fn1(void);
|
||||
void backlight_enable_fn1(void);
|
||||
void backlight_disable_fn1(void);
|
||||
|
||||
void backlight_invert_fn2(void);
|
||||
void backlight_enable_fn2(void);
|
||||
void backlight_disable_fn2(void);
|
||||
|
||||
void backlight_invert_fn3(void);
|
||||
void backlight_enable_fn3(void);
|
||||
void backlight_disable_fn3(void);
|
||||
|
||||
void backlight_invert_fn4(void);
|
||||
void backlight_enable_fn4(void);
|
||||
void backlight_disable_fn4(void);
|
||||
|
||||
void backlight_invert_numlock(void);
|
||||
void backlight_enable_numlock(void);
|
||||
void backlight_disable_numlock(void);
|
||||
|
||||
void backlight_enable_numpad(void);
|
||||
void backlight_disable_numpad(void);
|
||||
void backlight_invert_numpad(void);
|
||||
|
||||
void backlight_enable_rear(void);
|
||||
void backlight_disable_rear(void);
|
||||
void backlight_invert_rear(void);
|
||||
46
keyboard/lightpad/config.h
Normal file
46
keyboard/lightpad/config.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/* USB Device descriptor parameter */
|
||||
#define VENDOR_ID 0xFEED
|
||||
#define PRODUCT_ID 0x6050
|
||||
#define DEVICE_VER 0x0104
|
||||
#define MANUFACTURER Duck
|
||||
#define PRODUCT Lightpad
|
||||
|
||||
/* message strings */
|
||||
#define DESCRIPTION t.m.k. keyboard firmware for Lightpad
|
||||
|
||||
/* matrix size */
|
||||
#define MATRIX_ROWS 6
|
||||
#define MATRIX_COLS 4
|
||||
|
||||
/* number of backlight levels */
|
||||
#define BACKLIGHT_LEVELS 1
|
||||
|
||||
/* Set 0 if need no debouncing */
|
||||
#define DEBOUNCE 5
|
||||
|
||||
/* key combination for command */
|
||||
#define IS_COMMAND() ( \
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
#endif
|
||||
73
keyboard/lightpad/keymap.c
Normal file
73
keyboard/lightpad/keymap.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "keycode.h"
|
||||
#include "action.h"
|
||||
#include "action_macro.h"
|
||||
#include "report.h"
|
||||
#include "host.h"
|
||||
#include "debug.h"
|
||||
#include "keymap.h"
|
||||
|
||||
/* Map physical keyboard layout to matrix array */
|
||||
#define KEYMAP( \
|
||||
K5A, K5B, K5C, K5D, \
|
||||
K4A, K4B, K4C, K4D, \
|
||||
K3A, K3B, K3C, K3D, \
|
||||
K2A, K2B, K2C, \
|
||||
K1A, K1B, K1C, K1D, \
|
||||
K0A, K0B, K0C \
|
||||
) { \
|
||||
/* 0 1 2 3 */ \
|
||||
/* 5 */ { KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D}, \
|
||||
/* 4 */ { KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D}, \
|
||||
/* 3 */ { KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D}, \
|
||||
/* 2 */ { KC_##K2A, KC_##K2B, KC_##K2C, KC_NO}, \
|
||||
/* 1 */ { KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D}, \
|
||||
/* 0 */ { KC_##K0A, KC_##K0B, KC_##K0C, KC_NO, } \
|
||||
}
|
||||
|
||||
#include "keymap_lightpad.h"
|
||||
|
||||
#define KEYMAPS_SIZE (sizeof(keymaps) / sizeof(keymaps[0]))
|
||||
#define FN_ACTIONS_SIZE (sizeof(fn_actions) / sizeof(fn_actions[0]))
|
||||
|
||||
/* translates key to keycode */
|
||||
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
|
||||
{
|
||||
if (layer < KEYMAPS_SIZE) {
|
||||
return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
|
||||
} else {
|
||||
// fall back to layer 0
|
||||
return pgm_read_byte(&keymaps[0][(key.row)][(key.col)]);
|
||||
}
|
||||
}
|
||||
|
||||
/* translates Fn keycode to action */
|
||||
action_t keymap_fn_to_action(uint8_t keycode)
|
||||
{
|
||||
action_t action;
|
||||
if (FN_INDEX(keycode) < FN_ACTIONS_SIZE) {
|
||||
action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
|
||||
} else {
|
||||
action.code = ACTION_NO;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
29
keyboard/lightpad/keymap_lightpad.h
Normal file
29
keyboard/lightpad/keymap_lightpad.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "backlight.h"
|
||||
|
||||
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
KEYMAP(\
|
||||
FN0, F1, DEL, BSPC, \
|
||||
NLCK,PSLS,PAST,PMNS, \
|
||||
P7, P8, P9, PPLS, \
|
||||
P4, P5, P6, \
|
||||
P1, P2, P3, PENT, \
|
||||
P0, NO, PDOT), \
|
||||
KEYMAP(\
|
||||
TRNS,PGDN,PGUP,MUTE, \
|
||||
MSEL,MPRV,MNXT,VOLD, \
|
||||
P7, P8, P9, VOLU, \
|
||||
FN4, FN5, FN6, \
|
||||
FN1, FN2, FN3, MPLY, \
|
||||
FN7, NO, MSTP)
|
||||
};
|
||||
|
||||
static const uint16_t PROGMEM fn_actions[] = {
|
||||
[0] = ACTION_LAYER_MOMENTARY(1),
|
||||
[1] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_FN1),
|
||||
[2] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_FN2),
|
||||
[3] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_FN3),
|
||||
[4] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_FN4),
|
||||
[5] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_NUMPAD),
|
||||
[6] = ACTION_BACKLIGHT_LEVEL(BACKLIGHT_REAR),
|
||||
[7] = ACTION_BACKLIGHT_TOGGLE()
|
||||
};
|
||||
24
keyboard/lightpad/led.c
Normal file
24
keyboard/lightpad/led.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "stdint.h"
|
||||
#include "led.h"
|
||||
|
||||
void led_set(uint8_t usb_led) {
|
||||
(usb_led & (1<<USB_LED_NUM_LOCK)) ? backlight_enable_numlock() : backlight_disable_numlock();
|
||||
}
|
||||
205
keyboard/lightpad/matrix.c
Normal file
205
keyboard/lightpad/matrix.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include "matrix.h"
|
||||
#include "eeconfig.h"
|
||||
#include "action_layer.h"
|
||||
#include "backlight.h"
|
||||
|
||||
#ifndef DEBOUNCE
|
||||
# define DEBOUNCE 0
|
||||
#endif
|
||||
static uint8_t debouncing = DEBOUNCE;
|
||||
|
||||
static matrix_row_t matrix[MATRIX_ROWS];
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
|
||||
|
||||
static uint8_t read_rows(void);
|
||||
static uint8_t read_fwkey(void);
|
||||
static void init_rows(void);
|
||||
static void unselect_cols(void);
|
||||
static void select_col(uint8_t col);
|
||||
|
||||
inline
|
||||
uint8_t matrix_rows(void)
|
||||
{
|
||||
return MATRIX_ROWS;
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t matrix_cols(void)
|
||||
{
|
||||
return MATRIX_COLS;
|
||||
}
|
||||
|
||||
void misc_init(void) {
|
||||
}
|
||||
|
||||
void matrix_init(void)
|
||||
{
|
||||
backlight_init_ports();
|
||||
unselect_cols();
|
||||
init_rows();
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = 0;
|
||||
matrix_debouncing[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_scan(void)
|
||||
{
|
||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
|
||||
select_col(col);
|
||||
_delay_us(3);
|
||||
uint8_t rows = read_rows();
|
||||
// Use the otherwise unused col: 0 row: 0 for firmware key
|
||||
if(col == 0) {
|
||||
rows |= read_fwkey();
|
||||
}
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
|
||||
bool curr_bit = rows & (1<<row);
|
||||
if (prev_bit != curr_bit) {
|
||||
matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
|
||||
if (debouncing) {
|
||||
dprint("bounce!: "); dprintf("%02X", debouncing); dprintln();
|
||||
}
|
||||
debouncing = DEBOUNCE;
|
||||
}
|
||||
}
|
||||
unselect_cols();
|
||||
}
|
||||
|
||||
if (debouncing) {
|
||||
if (--debouncing) {
|
||||
_delay_ms(1);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
matrix[i] = matrix_debouncing[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool matrix_is_modified(void)
|
||||
{
|
||||
if (debouncing) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool matrix_is_on(uint8_t row, uint8_t col)
|
||||
{
|
||||
return (matrix[row] & ((matrix_row_t)1<<col));
|
||||
}
|
||||
|
||||
inline
|
||||
matrix_row_t matrix_get_row(uint8_t row)
|
||||
{
|
||||
return matrix[row];
|
||||
}
|
||||
|
||||
void matrix_print(void)
|
||||
{
|
||||
print("\nr/c 0123456789ABCDEF\n");
|
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||
xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t matrix_key_count(void)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||
count += bitpop32(matrix[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Row configuration
|
||||
*
|
||||
* row: 0 1 2 3 4 5
|
||||
* pin: PD0 PD1 PD2 PD3 PD5 PB7
|
||||
*
|
||||
* Firmware uses pin PE2
|
||||
*/
|
||||
static void init_rows(void)
|
||||
{
|
||||
DDRD &= ~0b00101111;
|
||||
PORTD |= 0b00101111;
|
||||
|
||||
DDRB &= ~0b10000000;
|
||||
PORTB |= 0b10000000;
|
||||
|
||||
DDRE &= ~0b00000100;
|
||||
PORTE |= 0b00000100;
|
||||
}
|
||||
|
||||
static uint8_t read_rows(void)
|
||||
{
|
||||
return (PIND&(1<<0) ? (1<<0) : 0) |
|
||||
(PIND&(1<<1) ? (1<<1) : 0) |
|
||||
(PIND&(1<<2) ? (1<<2) : 0) |
|
||||
(PIND&(1<<3) ? (1<<3) : 0) |
|
||||
(PIND&(1<<5) ? (1<<4) : 0) |
|
||||
(PINB&(1<<7) ? (1<<5) : 0);
|
||||
}
|
||||
|
||||
static uint8_t read_fwkey(void)
|
||||
{
|
||||
return PINE&(1<<2) ? 0 : (1<<0);
|
||||
}
|
||||
|
||||
/* Column configuration
|
||||
*
|
||||
* col: 0 1 2 3
|
||||
* pin: PF0 PF1 PC7 PC6
|
||||
*/
|
||||
static void unselect_cols(void)
|
||||
{
|
||||
DDRF |= 0b00000011;
|
||||
PORTF &= ~0b00000011;
|
||||
DDRC |= 0b11000000;
|
||||
PORTC &= ~0b11000000;
|
||||
}
|
||||
|
||||
static void select_col(uint8_t col)
|
||||
{
|
||||
switch (col) {
|
||||
case 0:
|
||||
PORTF |= (1<<0);
|
||||
break;
|
||||
case 1:
|
||||
PORTF |= (1<<1);
|
||||
break;
|
||||
case 2:
|
||||
PORTC |= (1<<7);
|
||||
break;
|
||||
case 3:
|
||||
PORTC |= (1<<6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue