aboutsummaryrefslogtreecommitdiff
path: root/converter
diff options
context:
space:
mode:
authortmk <wakojun@gmail.com>2013-11-27 23:23:08 -0800
committertmk <wakojun@gmail.com>2013-11-27 23:23:08 -0800
commitf3132adb33fd38e8d9d49845809ad5cb89f9c9c1 (patch)
tree1ec0e2caca6ea8cf99c3e1d49e3a279f78523d99 /converter
parentbc5b64d83259715667356770965a33aa620a8030 (diff)
parentf7db144959461d9b817752f7c6ca34b34d275cff (diff)
downloadqmk_firmware-f3132adb33fd38e8d9d49845809ad5cb89f9c9c1.tar.gz
qmk_firmware-f3132adb33fd38e8d9d49845809ad5cb89f9c9c1.zip
Merge pull request #81 from bgould/master
Add support for Adafruit's Bluefruit
Diffstat (limited to 'converter')
-rw-r--r--converter/terminal_bluefruit/Makefile113
-rw-r--r--converter/terminal_bluefruit/README37
-rw-r--r--converter/terminal_bluefruit/config.h112
-rw-r--r--converter/terminal_bluefruit/keymap.c227
-rw-r--r--converter/terminal_bluefruit/led.c35
-rw-r--r--converter/terminal_bluefruit/matrix.c262
6 files changed, 786 insertions, 0 deletions
diff --git a/converter/terminal_bluefruit/Makefile b/converter/terminal_bluefruit/Makefile
new file mode 100644
index 000000000..83d68fc25
--- /dev/null
+++ b/converter/terminal_bluefruit/Makefile
@@ -0,0 +1,113 @@
1# Target file name (without extension).
2TARGET = terminal_bluefruit
3
4# Directory common source filess exist
5TOP_DIR = ../..
6
7# Directory keyboard dependent files exist
8TARGET_DIR = .
9
10# keyboard dependent files
11SRC = keymap.c \
12 matrix.c \
13 led.c
14
15CONFIG_H = config.h
16
17BLUEFRUIT_TRACE_SERIAL=true
18
19# MCU name, you MUST set this to match the board you are using
20# type "make clean" after changing this, so all files will be rebuilt
21#MCU = at90usb162 # Teensy 1.0
22MCU = atmega32u4 # Teensy 2.0
23#MCU = at90usb646 # Teensy++ 1.0
24#MCU = at90usb1286 # Teensy++ 2.0
25
26
27# Processor frequency.
28# Normally the first thing your program should do is set the clock prescaler,
29# so your program will run at the correct speed. You should also set this
30# variable to same clock speed. The _delay_ms() macro uses this, and many
31# examples use this variable to calculate timings. Do not add a "UL" here.
32F_CPU = 16000000
33
34
35#
36# LUFA specific
37#
38# Target architecture (see library "Board Types" documentation).
39ARCH = AVR8
40
41# Input clock frequency.
42# This will define a symbol, F_USB, in all source code files equal to the
43# input clock frequency (before any prescaling is performed) in Hz. This value may
44# differ from F_CPU if prescaling is used on the latter, and is required as the
45# raw input clock is fed directly to the PLL sections of the AVR for high speed
46# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
47# at the end, this will be done automatically to create a 32-bit value in your
48# source code.
49#
50# If no clock division is performed on the input clock inside the AVR (via the
51# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
52F_USB = $(F_CPU)
53
54# Interrupt driven control endpoint task
55OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
56
57
58# Boot Section Size in bytes
59# Teensy halfKay 512
60# Atmel DFU loader 4096
61# LUFA bootloader 4096
62OPT_DEFS += -DBOOTLOADER_SIZE=4096
63
64
65# Build Options
66# comment out to disable the options.
67#
68BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
69MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
70EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
71CONSOLE_ENABLE = yes # Console for debug(+400)
72COMMAND_ENABLE = yes # Commands for debug and configuration
73#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
74#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
75
76
77#
78# PS/2 protocol implementations
79# USART is recommended if it is available, others are for reference purpose.
80# INT implementation will drop simultaneous key strokes.
81#
82#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
83PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
84#PS2_USE_BUSYWAIT = yes # uses primitive reference code
85
86ifdef PS2_USE_USART
87 SRC += protocol/ps2_usart.c
88 OPT_DEFS += -DPS2_USE_USART
89endif
90
91ifdef PS2_USE_INT
92 SRC += protocol/ps2.c
93 OPT_DEFS += -DPS2_USE_INT
94endif
95
96ifdef PS2_USE_BUSYWAIT
97 SRC += protocol/ps2.c
98 OPT_DEFS += -DPS2_USE_BUSYWAIT
99endif
100
101#---------------- Programming Options --------------------------
102PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
103
104
105# Search Path
106VPATH += $(TARGET_DIR)
107VPATH += $(TOP_DIR)
108
109
110include $(TOP_DIR)/protocol/bluefruit.mk
111include $(TOP_DIR)/protocol.mk
112include $(TOP_DIR)/common.mk
113include $(TOP_DIR)/rules.mk
diff --git a/converter/terminal_bluefruit/README b/converter/terminal_bluefruit/README
new file mode 100644
index 000000000..6ff1bc92f
--- /dev/null
+++ b/converter/terminal_bluefruit/README
@@ -0,0 +1,37 @@
1Keyboard converter for IBM terminal keyboard
2============================================
3It supports PS/2 Scan Code Set 3 and runs on USB AVR chips such like PJRC Teensy.
4I tested the converter on ATMega32U4 with 1392595(102keys) and 6110345(122keys).
5
6Source code: https://github.com/tmk/tmk_keyboard
7Article: http://geekhack.org/index.php?topic=27272.0
8
9
10CONNECTION
11----------
12Keyboard ATMega32U4
13----------------------
14Data: PD2
15Clock: PD5
16
17And VCC and GND, of course. See RESOURCE for keyboard connector pin assign.
18
19
20BUILD
21-----
22$ git clone https://github.com/tmk/tmk_keyboard.git
23$ cd converter/terminal_usb
24$ make
25
26
27RESOURCE
28--------
29Soarer's Converter: http://geekhack.org/index.php?topic=17458.0
30102keys(1392595): http://geekhack.org/index.php?topic=10737.0
31122keys(1390876): http://www.seasip.info/VintagePC/ibm_1390876.html
32KbdBabel: http://www.kbdbabel.org/
33RJ45 Connector: http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
34DIN Connector: http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
35WinAVR: http://winavr.sourceforge.net/
36
37EOF
diff --git a/converter/terminal_bluefruit/config.h b/converter/terminal_bluefruit/config.h
new file mode 100644
index 000000000..8bf139d35
--- /dev/null
+++ b/converter/terminal_bluefruit/config.h
@@ -0,0 +1,112 @@
1/*
2Converter for 70% IBM Terminal Keyboard
3Author: Benjamin Gould, 2013
4Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef CONFIG_H
21#define CONFIG_H
22
23
24#define VENDOR_ID 0xFEED
25#define PRODUCT_ID 0x6535
26#define DEVICE_VER 0x0100
27#define MANUFACTURER t.m.k.
28#define PRODUCT 70% IBM Terminal Keyboard Converter w/ Bluetooth
29#define DESCRIPTION USB converter for IBM Terminal Keyboard w/ Bluetooth
30
31
32/* matrix size */
33#define MATRIX_ROWS 17 // keycode bit: 3-0
34#define MATRIX_COLS 8 // keycode bit: 6-4
35
36
37/* legacy keymap support */
38// #define USE_LEGACY_KEYMAP
39
40
41/* key combination for command */
42#define IS_COMMAND() ( \
43 (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) || \
44 (keyboard_report->mods == (MOD_BIT(KC_RALT) | MOD_BIT(KC_RCTL))) \
45)
46
47/* USART configuration
48 * asynchronous, 9600baud, 8-data bit, non parity, 1-stop bit, no flow control
49 */
50#ifdef __AVR_ATmega32U4__
51 #define SERIAL_UART_BAUD 9600
52 #define SERIAL_UART_DATA UDR1
53 #define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1)
54 #define SERIAL_UART_RXD_VECT USART1_RX_vect
55 #define SERIAL_UART_TXD_READY (UCSR1A&(1<<UDRE1))
56 #define SERIAL_UART_INIT() do { \
57 UBRR1L = (uint8_t) SERIAL_UART_UBRR; /* baud rate */ \
58 UBRR1H = (uint8_t) (SERIAL_UART_UBRR>>8); /* baud rate */ \
59 UCSR1B = (1<<TXEN1); /* TX: enable */ \
60 UCSR1C = (0<<UPM11) | (0<<UPM10) | /* parity: none(00), even(01), odd(11) */ \
61 (0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10); /* data-8bit(011) */ \
62 sei(); \
63 } while(0)
64#else
65# error "USART configuration is needed."
66#endif
67
68/*
69 * PS/2 Interrupt configuration
70 */
71#ifdef PS2_USE_INT
72/* uses INT1 for clock line(ATMega32U4) */
73#define PS2_CLOCK_PORT PORTD
74#define PS2_CLOCK_PIN PIND
75#define PS2_CLOCK_DDR DDRD
76#define PS2_CLOCK_BIT 1
77
78#define PS2_DATA_PORT PORTD
79#define PS2_DATA_PIN PIND
80#define PS2_DATA_DDR DDRD
81#define PS2_DATA_BIT 0
82
83#define PS2_INT_INIT() do { \
84 EICRA |= ((1<<ISC11) | \
85 (0<<ISC10)); \
86} while (0)
87#define PS2_INT_ON() do { \
88 EIMSK |= (1<<INT1); \
89} while (0)
90#define PS2_INT_OFF() do { \
91 EIMSK &= ~(1<<INT1); \
92} while (0)
93#define PS2_INT_VECT INT1_vect
94#endif
95
96
97/*
98 * PS/2 Busywait configuration
99 */
100#ifdef PS2_USE_BUSYWAIT
101#define PS2_CLOCK_PORT PORTD
102#define PS2_CLOCK_PIN PIND
103#define PS2_CLOCK_DDR DDRD
104#define PS2_CLOCK_BIT 1
105
106#define PS2_DATA_PORT PORTD
107#define PS2_DATA_PIN PIND
108#define PS2_DATA_DDR DDRD
109#define PS2_DATA_BIT 0
110#endif
111
112#endif
diff --git a/converter/terminal_bluefruit/keymap.c b/converter/terminal_bluefruit/keymap.c
new file mode 100644
index 000000000..716590a45
--- /dev/null
+++ b/converter/terminal_bluefruit/keymap.c
@@ -0,0 +1,227 @@
1/*
2Converter for 70% IBM Terminal Keyboard
3Author: Benjamin Gould, 2013
4Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <stdint.h>
21#include <stdbool.h>
22#include <avr/pgmspace.h>
23#include "keycode.h"
24#include "print.h"
25#include "debug.h"
26#include "util.h"
27#include "keymap.h"
28
29
30
31
32/*
33 * IBM Terminal keyboard 6110345(122keys)/1392595(102keys)
34 * http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M
35 * http://www.seasip.info/VintagePC/ibm_1391406.html
36 *
37 * Keymap array:
38 * 8 bytes
39 * +---------+
40 * 0| |
41 * :| | 0x00-0x87
42 * ;| |
43 * 17| |
44 * +---------+
45 */
46#define KEYMAP( \
47 K08,K10,K18,K20,K28,K30,K38,K40,K48,K50,K57,K5F, \
48 K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, \
49 \
50 K05,K06, K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K5D,K66, K67,K6E,K6F, K76,K77,K7E,K84, \
51 K04,K0C, K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, K5C, K64,K65,K6D, K6C,K75,K7D,K7C, \
52 K03,K0B, K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K53,K5A, K63, K6B,K73,K74,K7B, \
53 K83,K0A, K12,K13,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K51,K59, K61,K62,K6A, K69,K72,K7A,K79, \
54 K01,K09, K11, K19, K29, K39, K58, K60, K68,K70,K71,K78 \
55) { \
56 { KC_NO, KC_##K01, KC_NO, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
57 { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \
58 { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
59 { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F }, \
60 { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
61 { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
62 { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
63 { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
64 { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47 }, \
65 { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F }, \
66 { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
67 { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_##K5E, KC_##K5F }, \
68 { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
69 { KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_##K6D, KC_##K6E, KC_##K6F }, \
70 { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
71 { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO }, \
72 { KC_NO, KC_NO, KC_NO, KC_##K83, KC_##K84, KC_NO, KC_NO, KC_NO, }, \
73}
74
75static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
76 /* 0: default
77 * ,---. ,---------------. ,---------------. ,---------------. ,-----------.
78 * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
79 * `---' `---------------' `---------------' `---------------' `-----------'
80 * ,-----------------------------------------------------------. ,-----------. ,---------------.
81 * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \|BS | |Ins|Hom|PgU| |NmL| /| *| -|
82 * |-----------------------------------------------------------| |-----------| |---------------|
83 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
84 * |-----------------------------------------------------------| `-----------' |-----------| +|
85 * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #|Retu| | 4| 5| 6| |
86 * |-----------------------------------------------------------| ,---. |---------------|
87 * |Shif| \| Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
88 * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
89 * |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 0| .| |
90 * `----' `---------------------------------------' `----' `-----------' `---------------'
91 */
92/*
93 KEYMAP(
94 F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
95 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
96
97 PSCR,ESC, GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
98 SLCK,INT4, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
99 PAUS,INT5, CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, UP, P4, P5, P6, PCMM,
100 APP, INT6, LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, LEFT,INT2,RGHT, P1, P2, P3, PENT,
101 RGUI,LGUI, LCTL, LALT, SPC, RALT, RCTL, DOWN, NO, P0, PDOT,NO
102 ),
103*/
104 /*
105 KEYMAP(
106 TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
107 TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
108
109 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
110 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
111 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,
112 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
113 TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,TRNS,TRNS,TRNS
114 ),
115 */
116 // pseudo ANSI
117
118 KEYMAP(
119 FN0, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO,
120 PSCR,PAUS,PGUP,PGDN,HOME,END, INS, DEL, LEFT,DOWN,UP, RGHT,
121
122 NO, NO, ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, BSPC, NO, NO, NO, NO, NO, NO, NO,
123 NO, NO, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, NO, NO, NO, NO, NO, NO, NO,
124 NO, NO, LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT, BSLS,ENT, NO, NO, NO, NO, NO,
125 NO, NO, LSFT,FN1 ,Z, X, C, V, B, N, M, COMM,DOT, SLSH, FN1, RSFT, NO, NO, NO, NO, NO, NO, NO,
126 NO, NO, LCTL, LALT, SPC, LGUI, APP, NO, NO, NO, NO, NO
127 ),
128
129 // Momentary Function Layer
130 KEYMAP(
131 TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
132 TRNS,MUTE,VOLD,VOLU,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
133
134 TRNS,TRNS, TRNS,F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
135 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,HOME,UP ,END, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
136 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,MS_L,MS_D,MS_U,MS_R,LEFT,DOWN, RGHT,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,
137 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PGUP,PGDN,TRNS, TRNS,RSFT, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
138 TRNS,TRNS, BTN2, TRNS, BTN1, RALT, RCTL, TRNS, TRNS,TRNS,TRNS,TRNS
139 ),
140
141 // Mouse Layer
142 KEYMAP(
143 FN0, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
144 TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
145
146 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
147 TRNS,TRNS, TRNS,NO, NO, MS_U,NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
148 TRNS,TRNS, BTN2,BTN1,MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,NO, NO, NO, ENT, NO, NO, NO, NO, NO,
149 TRNS,TRNS, TRNS,TRNS,NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, RSFT, NO, NO, NO, NO, NO, NO, NO,
150 TRNS,TRNS, TRNS, TRNS, BTN1, BTN2, TRNS, NO, NO, NO, NO, NO
151 ),
152
153 // vi Layer
154 KEYMAP(
155 FN0, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
156 TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
157
158 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
159 TRNS,TRNS, TRNS,HOME,PGDN,UP, PGUP,END, HOME,PGDN,PGUP,END, NO, NO, NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
160 TRNS,TRNS, TRNS,NO, LEFT,DOWN,RGHT,NO, LEFT,DOWN,UP, RGHT,NO, NO, NO, ENT, NO, NO, NO, NO, NO,
161 TRNS,TRNS, TRNS,TRNS,NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, RSFT, NO, NO, NO, NO, NO, NO, NO,
162 TRNS,TRNS, TRNS, TRNS, SPC, RALT, RCTL, NO, NO, NO, NO, NO
163 ),
164
165 // num lock layer
166 KEYMAP(
167 FN0, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
168 TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
169
170 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
171 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
172 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,
173 TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
174 TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,TRNS,TRNS,TRNS
175 ),
176
177};
178
179
180static const uint16_t fn_actions[] PROGMEM = {
181 [0] = ACTION_DEFAULT_LAYER_SET(0),
182 [1] = ACTION_LAYER_MOMENTARY(1),
183 [2] = ACTION_LAYER_MOMENTARY(2), //ACTION_LAYER_ON(2, ON_RELEASE),
184 [3] = KC_NO, //ACTION_LAYER_ON(3, ON_RELEASE),
185 [4] = KC_NO, //ACTION_LAYER_ON(4, ON_RELEASE),
186 [5] = KC_NO,
187 [6] = KC_NO,
188 [7] = KC_NO,
189};
190
191/*
192enum macro_id {
193 MS_UL,
194 MS_UR,
195 MS_DL,
196 MS_DR,
197};
198
199const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
200{
201 keyevent_t event = record->event;
202
203 switch (id) {
204 case MS_UL:
205 return (event.pressed ? MACRO( D(MS_L), D(MS_U), END ) : MACRO( U(MS_L), U(MS_U), END ) );
206 case MS_UR:
207 return (event.pressed ? MACRO( D(MS_R), D(MS_U), END ) : MACRO( U(MS_L), U(MS_U), END ) );
208 case MS_DL:
209 return (event.pressed ? MACRO( D(MS_L), D(MS_D), END ) : MACRO( U(MS_L), U(MS_U), END ) );
210 case MS_DR:
211 return (event.pressed ? MACRO( D(MS_R), D(MS_D), END ) : MACRO( U(MS_L), U(MS_U), END ) );
212 }
213 return MACRO_NONE;
214}
215*/
216
217uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
218{
219 return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
220}
221
222action_t keymap_fn_to_action(uint8_t keycode)
223{
224 action_t action;
225 action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
226 return action;
227}
diff --git a/converter/terminal_bluefruit/led.c b/converter/terminal_bluefruit/led.c
new file mode 100644
index 000000000..e5bf41d4a
--- /dev/null
+++ b/converter/terminal_bluefruit/led.c
@@ -0,0 +1,35 @@
1/*
2Converter for 70% IBM Terminal Keyboard
3Author: Benjamin Gould, 2013
4Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "stdint.h"
21#include "ps2.h"
22#include "led.h"
23
24
25void led_set(uint8_t usb_led)
26{
27 uint8_t ps2_led = 0;
28 if (usb_led & (1<<USB_LED_SCROLL_LOCK))
29 ps2_led |= (1<<PS2_LED_SCROLL_LOCK);
30 if (usb_led & (1<<USB_LED_NUM_LOCK))
31 ps2_led |= (1<<PS2_LED_NUM_LOCK);
32 if (usb_led & (1<<USB_LED_CAPS_LOCK))
33 ps2_led |= (1<<PS2_LED_CAPS_LOCK);
34 ps2_host_set_led(ps2_led);
35}
diff --git a/converter/terminal_bluefruit/matrix.c b/converter/terminal_bluefruit/matrix.c
new file mode 100644
index 000000000..36901536f
--- /dev/null
+++ b/converter/terminal_bluefruit/matrix.c
@@ -0,0 +1,262 @@
1/*
2Copyright 2011 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 <stdint.h>
19#include <stdbool.h>
20#include <avr/io.h>
21#include <util/delay.h>
22#include "print.h"
23#include "util.h"
24#include "debug.h"
25#include "ps2.h"
26#include "matrix.h"
27
28
29static void matrix_make(uint8_t code);
30static void matrix_break(uint8_t code);
31#ifdef MATRIX_HAS_GHOST
32static bool matrix_has_ghost_in_row(uint8_t row);
33#endif
34
35
36/*
37 * Matrix Array usage:
38 * 'Scan Code Set 3' is assigned into 17x8 cell matrix.
39 *
40 * 8bit wide
41 * +---------+
42 * 0| |
43 * :| | 0x00-0x87
44 * ;| |
45 * 17| |
46 * +---------+
47 */
48static uint8_t matrix[MATRIX_ROWS];
49#define ROW(code) (code>>3)
50#define COL(code) (code&0x07)
51
52static bool is_modified = false;
53
54
55inline
56uint8_t matrix_rows(void)
57{
58 return MATRIX_ROWS;
59}
60
61inline
62uint8_t matrix_cols(void)
63{
64 return MATRIX_COLS;
65}
66
67void matrix_init(void)
68{
69 debug_enable = true;
70 //debug_matrix = true;
71 //debug_keyboard = true;
72 //debug_mouse = false;
73
74 ps2_host_init();
75
76 // initialize matrix state: all keys off
77 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
78
79 return;
80}
81
82uint8_t matrix_scan(void)
83{
84
85 // scan code reading states
86 static enum {
87 RESET,
88 RESET_RESPONSE,
89 KBD_ID0,
90 KBD_ID1,
91 CONFIG,
92 READY,
93 F0,
94 } state = RESET;
95
96 is_modified = false;
97
98 uint8_t code;
99 if ((code = ps2_host_recv())) {
100 debug("r"); debug_hex(code); debug(" ");
101 }
102
103 switch (state) {
104 case RESET:
105 debug("wFF ");
106 if (ps2_host_send(0xFF) == 0xFA) {
107 debug("[ack]\nRESET_RESPONSE: ");
108 state = RESET_RESPONSE;
109 }
110 break;
111 case RESET_RESPONSE:
112 if (code == 0xAA) {
113 debug("[ok]\nKBD_ID: ");
114 state = KBD_ID0;
115 } else if (code) {
116 debug("err\nRESET: ");
117 state = RESET;
118 }
119 break;
120 // after reset receive keyboad ID(2 bytes)
121 case KBD_ID0:
122 if (code) {
123 state = KBD_ID1;
124 }
125 break;
126 case KBD_ID1:
127 if (code) {
128 debug("\nCONFIG: ");
129 state = CONFIG;
130 }
131 break;
132 case CONFIG:
133 debug("wF8 ");
134 if (ps2_host_send(0xF8) == 0xFA) {
135 debug("[ack]\nREADY\n");
136 state = READY;
137 }
138 break;
139 case READY:
140 switch (code) {
141 case 0x00:
142 break;
143 case 0xF0:
144 state = F0;
145 debug(" ");
146 break;
147 default: // normal key make
148 if (code < 0x88) {
149 matrix_make(code);
150 } else {
151 debug("unexpected scan code at READY: "); debug_hex(code); debug("\n");
152 }
153 state = READY;
154 debug("\n");
155 }
156 break;
157 case F0: // Break code
158 switch (code) {
159 case 0x00:
160 break;
161 default:
162 if (code < 0x88) {
163 matrix_break(code);
164 } else {
165 debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
166 }
167 state = READY;
168 debug("\n");
169 }
170 break;
171 }
172 return 1;
173}
174
175bool matrix_is_modified(void)
176{
177 return is_modified;
178}
179
180inline
181bool matrix_has_ghost(void)
182{
183#ifdef MATRIX_HAS_GHOST
184 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
185 if (matrix_has_ghost_in_row(i))
186 return true;
187 }
188#endif
189 return false;
190}
191
192inline
193bool matrix_is_on(uint8_t row, uint8_t col)
194{
195 return (matrix[row] & (1<<col));
196}
197
198inline
199uint8_t matrix_get_row(uint8_t row)
200{
201 return matrix[row];
202}
203
204void matrix_print(void)
205{
206 print("\nr/c 01234567\n");
207 for (uint8_t row = 0; row < matrix_rows(); row++) {
208 phex(row); print(": ");
209 pbin_reverse(matrix_get_row(row));
210#ifdef MATRIX_HAS_GHOST
211 if (matrix_has_ghost_in_row(row)) {
212 print(" <ghost");
213 }
214#endif
215 print("\n");
216 }
217}
218
219uint8_t matrix_key_count(void)
220{
221 uint8_t count = 0;
222 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
223 count += bitpop(matrix[i]);
224 }
225 return count;
226}
227
228#ifdef MATRIX_HAS_GHOST
229inline
230static bool matrix_has_ghost_in_row(uint8_t row)
231{
232 // no ghost exists in case less than 2 keys on
233 if (((matrix[row] - 1) & matrix[row]) == 0)
234 return false;
235
236 // ghost exists in case same state as other row
237 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
238 if (i != row && (matrix[i] & matrix[row]) == matrix[row])
239 return true;
240 }
241 return false;
242}
243#endif
244
245
246inline
247static void matrix_make(uint8_t code)
248{
249 if (!matrix_is_on(ROW(code), COL(code))) {
250 matrix[ROW(code)] |= 1<<COL(code);
251 is_modified = true;
252 }
253}
254
255inline
256static void matrix_break(uint8_t code)
257{
258 if (matrix_is_on(ROW(code), COL(code))) {
259 matrix[ROW(code)] &= ~(1<<COL(code));
260 is_modified = true;
261 }
262}