aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-02-23 14:35:45 +0900
committertmk <nobody@nowhere>2013-02-23 14:35:45 +0900
commit79b1f129085425c72b72bee28ed065bf243c0a0b (patch)
treeda34ff0e2714c124c3ece6f8ea77257625cbdb07
parent0368936060fbc32395508b09c76b620828d36db1 (diff)
parent6215727b0bd827a18456b21a26d6175abe365ada (diff)
downloadqmk_firmware-79b1f129085425c72b72bee28ed065bf243c0a0b.tar.gz
qmk_firmware-79b1f129085425c72b72bee28ed065bf243c0a0b.zip
Merge branch 'pc98' of github.com:tmk/tmk_keyboard into overlays
-rw-r--r--converter/pc98_usb/Makefile83
-rw-r--r--converter/pc98_usb/README65
-rw-r--r--converter/pc98_usb/command_extra.c43
-rw-r--r--converter/pc98_usb/config.h100
-rw-r--r--converter/pc98_usb/keymap.c187
-rw-r--r--converter/pc98_usb/led.c33
-rw-r--r--converter/pc98_usb/matrix.c168
-rw-r--r--protocol/serial.h1
-rw-r--r--protocol/serial_soft.c52
9 files changed, 732 insertions, 0 deletions
diff --git a/converter/pc98_usb/Makefile b/converter/pc98_usb/Makefile
new file mode 100644
index 000000000..076371dbf
--- /dev/null
+++ b/converter/pc98_usb/Makefile
@@ -0,0 +1,83 @@
1# Target file name (without extension).
2TARGET = pc98_usb
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 command_extra.c \
15 protocol/serial_soft.c
16
17CONFIG_H = config.h
18
19
20# MCU name, you MUST set this to match the board you are using
21# type "make clean" after changing this, so all files will be rebuilt
22#MCU = at90usb162 # Teensy 1.0
23MCU = atmega32u4 # Teensy 2.0
24#MCU = at90usb646 # Teensy++ 1.0
25#MCU = at90usb1286 # Teensy++ 2.0
26
27
28# Processor frequency.
29# Normally the first thing your program should do is set the clock prescaler,
30# so your program will run at the correct speed. You should also set this
31# variable to same clock speed. The _delay_ms() macro uses this, and many
32# examples use this variable to calculate timings. Do not add a "UL" here.
33F_CPU = 16000000
34
35
36#
37# LUFA specific
38#
39# Target architecture (see library "Board Types" documentation).
40ARCH = AVR8
41
42# Input clock frequency.
43# This will define a symbol, F_USB, in all source code files equal to the
44# input clock frequency (before any prescaling is performed) in Hz. This value may
45# differ from F_CPU if prescaling is used on the latter, and is required as the
46# raw input clock is fed directly to the PLL sections of the AVR for high speed
47# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
48# at the end, this will be done automatically to create a 32-bit value in your
49# source code.
50#
51# If no clock division is performed on the input clock inside the AVR (via the
52# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
53F_USB = $(F_CPU)
54
55# Interrupt driven control endpoint task
56OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
57
58
59# Build Options
60# *Comment out* to disable the options.
61#
62MOUSEKEY_ENABLE = yes # Mouse keys
63EXTRAKEY_ENABLE = yes # Audio control and System control
64CONSOLE_ENABLE = yes # Console for debug
65#NKRO_ENABLE = yes # USB Nkey Rollover
66
67
68# Boot Section Size in bytes
69# Teensy halfKay 512
70# Atmel DFU loader 4096
71# LUFA bootloader 4096
72OPT_DEFS += -DBOOT_SIZE=4096
73
74
75# Search Path
76VPATH += $(TARGET_DIR)
77VPATH += $(TOP_DIR)
78
79
80include $(TOP_DIR)/protocol/lufa.mk
81include $(TOP_DIR)/protocol.mk
82include $(TOP_DIR)/common.mk
83include $(TOP_DIR)/rules.mk
diff --git a/converter/pc98_usb/README b/converter/pc98_usb/README
new file mode 100644
index 000000000..7d9547d50
--- /dev/null
+++ b/converter/pc98_usb/README
@@ -0,0 +1,65 @@
1PC98 to USB keyboard protocol converter
2=======================================
3Target MCU is ATMega32u4 but other USB capable AVR will also work.
4
5
6Connector
7---------
8
9 8Pin mini DIN
10 ___ ___
11 / |_| \
12 / 8 7 6 \
13 | 5 4 3 |
14 \_ 2 1 _/
15 \_____/
16 (receptacle)
17
18
19Wiring: You can change this with ediging config.h.
20
21 Pin mini DIN MCU
22 ----------------------------------
23 1 ~RST PD1
24 2 GND GND
25 3 ~RDY PD4
26 4 RXD PD2
27 5 ~RTY PD5
28 6 NC
29 7 NC
30 8 5V VCC
31
32
33
34
35Protocol
36--------
37Singnal: Asynchronous, Positive logic, 19200baud, Least bit first
38Frame format: 1-Start bit(Lo), 8-Data bits, Odd-Parity, 1-Stop bit
39
40This converter uses software method for testing purpose. AVR UART engine will work better.
41
42
43
44
45Build Firmware
46--------------
47Just use 'make'
48
49 $ cd pc98_usb
50 $ make
51
52Then, load the binary to MCU with your favorite programmer.
53
54
55
56Other PC98 converter projects and resource
57------------------------------------------
58PC98 to USB
59http://davy.nyacom.net/kbd98usb/
60
61PC98 to PS/2
62http://www.tsp.ne.jp/~sawada/mago/c_gka98at.htm
63
64PC98 keyboard commands
65http://www.webtech.co.jp/company/doc/undocumented_mem/io_kb.txt
diff --git a/converter/pc98_usb/command_extra.c b/converter/pc98_usb/command_extra.c
new file mode 100644
index 000000000..50389467e
--- /dev/null
+++ b/converter/pc98_usb/command_extra.c
@@ -0,0 +1,43 @@
1#include "stdbool.h"
2#include "stdint.h"
3#include "keycode.h"
4#include "serial.h"
5#include "print.h"
6#include "command.h"
7
8bool command_extra(uint8_t code)
9{
10 switch (code) {
11 case KC_H:
12 case KC_SLASH: /* ? */
13 print("\n\n----- Sun converter Help -----\n");
14 print("UP: Bell On\n");
15 print("DOWN: Bell Off\n");
16 print("LEFT: Click On\n");
17 print("RIGHT: Click Off\n");
18 return false;
19 case KC_UP:
20 print("Bell On\n");
21 serial_send(0x02);
22 break;
23 case KC_DOWN:
24 print("Bell Off\n");
25 serial_send(0x03);
26 break;
27 case KC_LEFT:
28 print("Click On\n");
29 serial_send(0x0A);
30 break;
31 case KC_RIGHT:
32 print("Click Off\n");
33 serial_send(0x0B);
34 break;
35 case KC_NUMLOCK:
36 print("layout\n");
37 serial_send(0x0F);
38 break;
39 default:
40 return false;
41 }
42 return true;
43}
diff --git a/converter/pc98_usb/config.h b/converter/pc98_usb/config.h
new file mode 100644
index 000000000..6ef2c6ac3
--- /dev/null
+++ b/converter/pc98_usb/config.h
@@ -0,0 +1,100 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#define VENDOR_ID 0xFEED
22#define PRODUCT_ID 0x9898
23#define DEVICE_VER 0x0100
24#define MANUFACTURER t.m.k.
25#define PRODUCT PC98 keyboard converter
26#define DESCRIPTION converts PC98 keyboard protocol into USB
27
28
29/* matrix size */
30#define MATRIX_ROWS 16
31#define MATRIX_COLS 8
32
33
34/* key combination for command */
35#define IS_COMMAND() ( \
36 keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) || \
37 keyboard_report->mods == (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) || \
38 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
39)
40
41
42/* PC98 Serial(USART) configuration
43 * asynchronous, positive logic, 19200baud, bit order: LSB first
44 * 1-start bit, 8-data bit, odd parity, 1-stop bit
45 */
46#define SERIAL_BAUD 19200
47#define SERIAL_PARITY_ODD
48#define SERIAL_BIT_ORDER_LSB
49
50/* PC98 Reset Port */
51#define PC98_RST_DDR DDRD
52#define PC98_RST_PORT PORTD
53#define PC98_RST_BIT 1
54/* PC98 Ready Port */
55#define PC98_RDY_DDR DDRD
56#define PC98_RDY_PORT PORTD
57#define PC98_RDY_BIT 4
58/* PC98 Retry Port */
59#define PC98_RTY_DDR DDRD
60#define PC98_RTY_PORT PORTD
61#define PC98_RTY_BIT 5
62
63/* RXD Port */
64#define SERIAL_RXD_DDR DDRD
65#define SERIAL_RXD_PORT PORTD
66#define SERIAL_RXD_PIN PIND
67#define SERIAL_RXD_BIT 2
68#define SERIAL_RXD_READ() (SERIAL_RXD_PIN&(1<<SERIAL_RXD_BIT))
69/* RXD Interupt */
70#define SERIAL_RXD_VECT INT2_vect
71#define SERIAL_RXD_INIT() do { \
72 /* pin configuration: input with pull-up */ \
73 SERIAL_RXD_DDR &= ~(1<<SERIAL_RXD_BIT); \
74 SERIAL_RXD_PORT |= (1<<SERIAL_RXD_BIT); \
75 /* enable interrupt: INT2(falling edge) */ \
76 EICRA |= ((1<<ISC21)|(0<<ISC20)); \
77 EIMSK |= (1<<INT2); \
78} while (0)
79#define SERIAL_RXD_INT_ENTER()
80#define SERIAL_RXD_INT_EXIT() do { \
81 /* clear interrupt flag */ \
82 EIFR = (1<<INTF2); \
83} while (0)
84
85/* TXD Port: Not used */
86#define SERIAL_TXD_DDR DDRD
87#define SERIAL_TXD_PORT PORTD
88#define SERIAL_TXD_PIN PIND
89#define SERIAL_TXD_BIT 3
90/* negative logic */
91#define SERIAL_TXD_ON() do { SERIAL_TXD_PORT &= ~(1<<SERIAL_TXD_BIT); } while (0)
92#define SERIAL_TXD_OFF() do { SERIAL_TXD_PORT |= (1<<SERIAL_TXD_BIT); } while (0)
93#define SERIAL_TXD_INIT() do { \
94 /* pin configuration: output */ \
95 SERIAL_TXD_DDR |= (1<<SERIAL_TXD_BIT); \
96 /* idle */ \
97 SERIAL_TXD_ON(); \
98} while (0)
99
100#endif
diff --git a/converter/pc98_usb/keymap.c b/converter/pc98_usb/keymap.c
new file mode 100644
index 000000000..1e2dd03d5
--- /dev/null
+++ b/converter/pc98_usb/keymap.c
@@ -0,0 +1,187 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <stdint.h>
19#include <stdbool.h>
20#include <avr/pgmspace.h>
21#include "keycode.h"
22#include "util.h"
23#include "keymap.h"
24
25
26
27
28/* PC-9801-98-S02 Raku Raku keyboard(Luckyboard) Normal Mode
29 ,---------------------------------------------------------------.
30 | 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 6A| 6B| 36| 37| 3F| 3E|
31 `---------------------------------------------------------------'
32 ,---------------------------------------------------------------.
33 | 00| 01| 02| 03| 04| 05| 58| 71| 06| 07| 08| 09| 0A| 0E|
34 |---------------------------------------------------------------|
35 | 0F| 10| 11| 12| 13| 14| 3A | 15| 16| 17| 18| 19| 1C|
36 |---------------------------------------------------------------|
37 | 74| 20| 21| 22| 23| 24| 3B | 3C | 25| 26| 27| 28| 29| |
38 |---------------------------------------------------------------|
39 | 70| 2A| 2B| 2C| 2D| 2E| 38| 3D | 39| 2F| 30| 31| 32| 33| 70|
40 `---------------------------------------------------------------'
41 | 73| 51| 5B| 59| 34| 5A| 35| xx|
42 `-----------------------------------------------'
43 xx: 74 35 F4 B5
44*/
45#define KEYMAP( \
46 K60, K61, K62, K63, K64, K65, K66, K67, K68, K69, K6A, K6B, K36, K37, K3F, K3E, \
47 K00, K01, K02, K03, K04, K05, K58, K71, K06, K07, K08, K09, K0A, K0E, \
48 K0F, K10, K11, K12, K13, K14, K3A, K15, K16, K17, K18, K19, K1C, \
49 K74, K20, K21, K22, K23, K24, K3B, K3C, K25, K26, K27, K28, K29, \
50 K70,K2A, K2B, K2C, K2D, K2E, K38, K3D, K39, K2F, K30, K31, K32, K33, \
51 K73, K51, K5B, K59, K34, K5A, K35 \
52) { \
53 { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
54 { KC_##K08, KC_##K09, KC_##K0A, KC_NO, KC_NO, KC_NO, KC_##K0E, KC_##K0F }, \
55 { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
56 { KC_##K18, KC_##K19, KC_NO, KC_NO, KC_##K1C, KC_NO, KC_NO, KC_NO }, \
57 { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
58 { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
59 { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
60 { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
61 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
62 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
63 { KC_NO, KC_##K51, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
64 { KC_NO, KC_NO, KC_##K5A, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
65 { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
66 { KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_NO, KC_NO, KC_NO, KC_NO }, \
67 { KC_##K70, KC_NO, KC_NO, KC_##K73, KC_##K74, KC_NO, KC_NO, KC_NO }, \
68 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO } \
69}
70
71
72
73
74// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed.
75static const uint8_t PROGMEM fn_layer[] = {
76 2, // Fn0
77 3, // Fn1
78 4, // Fn2
79 0, // Fn3
80 0, // Fn4
81 0, // Fn5
82 0, // Fn6
83 0 // Fn7
84};
85
86// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
87// See layer.c for details.
88static const uint8_t PROGMEM fn_keycode[] = {
89 KC_NO, // Fn0
90 KC_SCLN, // Fn1
91 KC_SLSH, // Fn2
92 KC_NO, // Fn3
93 KC_NO, // Fn4
94 KC_NO, // Fn5
95 KC_NO, // Fn6
96 KC_NO // Fn7
97};
98
99
100static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
101 /*
102 ,---------------------------------------------------------------.
103 | 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 6A| 6B| 36| 37| 3F| 3E|
104 `---------------------------------------------------------------'
105 ,---------------------------------------------------------------.
106 | 00| 01| 02| 03| 04| 05| 58| 71| 06| 07| 08| 09| 0A| 0E|
107 |---------------------------------------------------------------|
108 | 0F| 10| 11| 12| 13| 14| 3A | 15| 16| 17| 18| 19| 1C|
109 |---------------------------------------------------------------|
110 | 74| 20| 21| 22| 23| 24| MINS| EQL| 25| 26| 27| 28| 29| |
111 |---------------------------------------------------------------|
112 | 70| 2A| 2B| 2C| 2D| 2E| 38| 3D | 39| 2F| 30| 31| 32| 33| 70|
113 `---------------------------------------------------------------'
114 | 73| 51| 5B| 59| 34| 5A| 35| xx|
115 `-----------------------------------------------'
116 */
117 KEYMAP(
118 PAUS,COPY, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14,
119 ESC, 1, 2, 3, 4, 5, NO, NO, 6, 7, 8, 9, 0, BSPC,
120 TAB, Q, W, E, R, T, UP, Y, U, I, O, P, ENT,
121 LCTL, A, S, D, F, G, MINS, EQL, H, J, K, L,SCLN,
122 LSFT, Z, X, C, V, B, INS, DOWN, DEL, N, M,COMM, DOT,SLSH,
123 LGUI, LALT, LCTL, LSFT, SPC, SPC, RALT
124 ),
125};
126
127
128uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
129{
130 return pgm_read_byte(&keymaps[(layer)][(row)][(col)]);
131}
132
133uint8_t keymap_fn_layer(uint8_t index)
134{
135 return pgm_read_byte(&fn_layer[index]);
136}
137
138uint8_t keymap_fn_keycode(uint8_t index)
139{
140 return pgm_read_byte(&fn_keycode[index]);
141}
142
143
144#if 0
145/* PC-9801-98-S02 Raku Raku keyboard(Luckyboard) M-siki mode
146 ,---------------------------------------------------------------.
147 | 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 6A| 6B| 36| 37| 3F| 3E|
148 `---------------------------------------------------------------'
149 ,---------------------------------------------------------------.
150 | 00| 01| 02| 03| 04| 05| NUM|CAPS| 06| 07| 08| 09| 0A| 0E|
151 |---------------------------------------------------------------|
152 | 0F| 10| 25| 20| 23| 2B| 3A | 2F| 15| 13| 11| 19| 1C|
153 |---------------------------------------------------------------|
154 | 74| 12| 16| 17| 1D| 18| 3B | 3C | 24| 1E| 14| 2E| 22| |
155 |---------------------------------------------------------------|
156 | 70| xx| 2A| 2C| xx| xx| 38| 3D | 39| 21| 29| 1F| xx| 2D| 70|
157 `---------------------------------------------------------------'
158 | 73| 51| xx| xx| 34| xx| 35| xx|
159 `-----------------------------------------------'
160*/
161
162#define KEYMAP_M( \
163 K60, K61, K62, K63, K64, K65, K66, K67, K68, K69, K6A, K6B, K36, K37, K3F, K3E, \
164 K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0E, \
165 K0F, K10, K25, K23, K20, K2B, K3A, K2F, K15, K13, K11, K19, K1C, \
166 K74, K12, K16, K17, K1D, K18, K3B, K3C, K24, K1E, K14, K2E, K22, \
167 K70, K2A, K2C, K38, K3D, K39, K21, K29, K1F, K2D, \
168 K73, K51, K34, K35 \
169) { \
170 { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
171 { KC_##K08, KC_##K09, KC_##K0A, KC_NO, KC_NO, KC_NO, KC_##K0E, KC_##K0F }, \
172 { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
173 { KC_##K18, KC_##K19, KC_NO, KC_NO, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F }, \
174 { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_NO, KC_NO }, \
175 { KC_NO, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
176 { KC_NO, KC_NO, KC_NO, KC_NO, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
177 { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
178 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
179 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
180 { KC_NO, KC_##K51, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
181 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
182 { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
183 { KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_NO, KC_NO, KC_NO, KC_NO }, \
184 { KC_##K70, KC_NO, KC_NO, KC_##K73, KC_##K74, KC_NO, KC_NO, KC_NO }, \
185 { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO } \
186}
187#endif
diff --git a/converter/pc98_usb/led.c b/converter/pc98_usb/led.c
new file mode 100644
index 000000000..48c3f1c2b
--- /dev/null
+++ b/converter/pc98_usb/led.c
@@ -0,0 +1,33 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "stdint.h"
19#include "serial.h"
20#include "led.h"
21
22
23void led_set(uint8_t usb_led)
24{
25 uint8_t sun_led = 0;
26 if (usb_led & (1<<USB_LED_NUM_LOCK)) sun_led |= (1<<0);
27 if (usb_led & (1<<USB_LED_COMPOSE)) sun_led |= (1<<1);
28 if (usb_led & (1<<USB_LED_SCROLL_LOCK)) sun_led |= (1<<2);
29 if (usb_led & (1<<USB_LED_CAPS_LOCK)) sun_led |= (1<<3);
30
31 serial_send(0x0E);
32 serial_send(sun_led);
33}
diff --git a/converter/pc98_usb/matrix.c b/converter/pc98_usb/matrix.c
new file mode 100644
index 000000000..2f1e821c5
--- /dev/null
+++ b/converter/pc98_usb/matrix.c
@@ -0,0 +1,168 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <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 "matrix.h"
25#include "debug.h"
26#include "protocol/serial.h"
27
28
29/*
30 * Matrix Array usage:
31 *
32 * ROW: 16(4bits)
33 * COL: 8(3bits)
34 *
35 * 8bit wide
36 * +---------+
37 * 0|00 ... 07|
38 * 1|08 ... 0F|
39 * :| ... |
40 * :| ... |
41 * E|70 ... 77|
42 * F|78 ... 7F|
43 * +---------+
44 */
45static uint8_t matrix[MATRIX_ROWS];
46#define ROW(code) ((code>>3)&0xF)
47#define COL(code) (code&0x07)
48
49static bool is_modified = false;
50
51
52inline
53uint8_t matrix_rows(void)
54{
55 return MATRIX_ROWS;
56}
57
58inline
59uint8_t matrix_cols(void)
60{
61 return MATRIX_COLS;
62}
63
64void matrix_init(void)
65{
66 print_enable = true;
67 debug_enable = true;
68 //debug_matrix = true;
69
70 PC98_RST_DDR |= (1<<PC98_RST_BIT);
71 PC98_RDY_DDR |= (1<<PC98_RDY_BIT);
72 PC98_RTY_DDR |= (1<<PC98_RTY_BIT);
73 PC98_RST_PORT |= (1<<PC98_RST_BIT);
74 PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
75 PC98_RTY_PORT |= (1<<PC98_RTY_BIT);
76
77 DDRD |= 1<<7;
78
79
80 serial_init();
81
82 // PC98 reset
83 PC98_RST_PORT &= ~(1<<PC98_RST_BIT);
84 _delay_us(15);
85 PC98_RST_PORT |= (1<<PC98_RST_BIT);
86 _delay_us(13);
87 PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
88
89 // PC98 ready
90 PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
91
92 // initialize matrix state: all keys off
93 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
94
95 debug("init\n");
96 return;
97}
98
99uint8_t matrix_scan(void)
100{
101 is_modified = false;
102
103 uint16_t code;
104 PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
105 _delay_us(30);
106 code = serial_recv2();
107 PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
108 if (code == -1) return 0;
109
110 debug_hex(code); debug(" ");
111
112 if (code&0x80) {
113 // break code
114 if (matrix_is_on(ROW(code), COL(code))) {
115 matrix[ROW(code)] &= ~(1<<COL(code));
116 is_modified = true;
117 }
118 } else {
119 // make code
120 if (!matrix_is_on(ROW(code), COL(code))) {
121 matrix[ROW(code)] |= (1<<COL(code));
122 is_modified = true;
123 }
124 }
125 return code;
126}
127
128bool matrix_is_modified(void)
129{
130 return is_modified;
131}
132
133inline
134bool matrix_has_ghost(void)
135{
136 return false;
137}
138
139inline
140bool matrix_is_on(uint8_t row, uint8_t col)
141{
142 return (matrix[row] & (1<<col));
143}
144
145inline
146uint8_t matrix_get_row(uint8_t row)
147{
148 return matrix[row];
149}
150
151void matrix_print(void)
152{
153 print("\nr/c 01234567\n");
154 for (uint8_t row = 0; row < matrix_rows(); row++) {
155 phex(row); print(": ");
156 pbin_reverse(matrix_get_row(row));
157 print("\n");
158 }
159}
160
161uint8_t matrix_key_count(void)
162{
163 uint8_t count = 0;
164 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
165 count += bitpop(matrix[i]);
166 }
167 return count;
168}
diff --git a/protocol/serial.h b/protocol/serial.h
index bd071bec9..96913c867 100644
--- a/protocol/serial.h
+++ b/protocol/serial.h
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
41/* host role */ 41/* host role */
42void serial_init(void); 42void serial_init(void);
43uint8_t serial_recv(void); 43uint8_t serial_recv(void);
44int16_t serial_recv2(void);
44void serial_send(uint8_t data); 45void serial_send(uint8_t data);
45 46
46#endif 47#endif
diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c
index beddc353c..3c9c914ed 100644
--- a/protocol/serial_soft.c
+++ b/protocol/serial_soft.c
@@ -48,8 +48,20 @@ POSSIBILITY OF SUCH DAMAGE.
48 48
49#define WAIT_US (1000000/SERIAL_BAUD) 49#define WAIT_US (1000000/SERIAL_BAUD)
50 50
51/* debug for signal timing, see debug pin with oscilloscope */
52#ifdef SERIAL_SOFT_DEBUG
53 #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7)
54 #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7)
55#else
56 #define SERIAL_SOFT_DEBUG_INIT()
57 #define SERIAL_SOFT_DEBUG_TGL()
58#endif
59
60
51void serial_init(void) 61void serial_init(void)
52{ 62{
63 SERIAL_SOFT_DEBUG_INIT();
64
53 SERIAL_RXD_INIT(); 65 SERIAL_RXD_INIT();
54 SERIAL_TXD_INIT(); 66 SERIAL_TXD_INIT();
55} 67}
@@ -60,6 +72,7 @@ static uint8_t rbuf[RBUF_SIZE];
60static uint8_t rbuf_head = 0; 72static uint8_t rbuf_head = 0;
61static uint8_t rbuf_tail = 0; 73static uint8_t rbuf_tail = 0;
62 74
75
63uint8_t serial_recv(void) 76uint8_t serial_recv(void)
64{ 77{
65 uint8_t data = 0; 78 uint8_t data = 0;
@@ -72,6 +85,18 @@ uint8_t serial_recv(void)
72 return data; 85 return data;
73} 86}
74 87
88int16_t serial_recv2(void)
89{
90 uint8_t data = 0;
91 if (rbuf_head == rbuf_tail) {
92 return -1;
93 }
94
95 data = rbuf[rbuf_tail];
96 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
97 return data;
98}
99
75void serial_send(uint8_t data) 100void serial_send(uint8_t data)
76{ 101{
77 /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ 102 /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */
@@ -103,22 +128,36 @@ void serial_send(uint8_t data)
103/* detect edge of start bit */ 128/* detect edge of start bit */
104ISR(SERIAL_RXD_VECT) 129ISR(SERIAL_RXD_VECT)
105{ 130{
131 SERIAL_SOFT_DEBUG_TGL()
106 SERIAL_RXD_INT_ENTER() 132 SERIAL_RXD_INT_ENTER()
107 133
108 uint8_t data = 0; 134 uint8_t data = 0;
135
109#ifdef SERIAL_BIT_ORDER_MSB 136#ifdef SERIAL_BIT_ORDER_MSB
110 uint8_t mask = 0x80; 137 uint8_t mask = 0x80;
111#else 138#else
112 uint8_t mask = 0x01; 139 uint8_t mask = 0x01;
113#endif 140#endif
141
142#ifdef SERIAL_PARITY_ODD
143 uint8_t parity = 0;
144#elif defined(SERIAL_PARITY_EVEN)
145 uint8_t parity = 1;
146#endif
147
114 /* to center of start bit */ 148 /* to center of start bit */
115 _delay_us(WAIT_US/2); 149 _delay_us(WAIT_US/2);
150 SERIAL_SOFT_DEBUG_TGL()
116 do { 151 do {
117 /* to center of next bit */ 152 /* to center of next bit */
118 _delay_us(WAIT_US); 153 _delay_us(WAIT_US);
119 154
155 SERIAL_SOFT_DEBUG_TGL()
120 if (SERIAL_RXD_READ()) { 156 if (SERIAL_RXD_READ()) {
121 data |= mask; 157 data |= mask;
158#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
159 parity ^= 1;
160#endif
122 } 161 }
123#ifdef SERIAL_BIT_ORDER_MSB 162#ifdef SERIAL_BIT_ORDER_MSB
124 mask >>= 1; 163 mask >>= 1;
@@ -126,14 +165,27 @@ ISR(SERIAL_RXD_VECT)
126 mask <<= 1; 165 mask <<= 1;
127#endif 166#endif
128 } while (mask); 167 } while (mask);
168
169#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
170 /* to center of parity bit */
171 _delay_us(WAIT_US);
172 if (SERIAL_RXD_READ()) { parity ^= 1; }
173 SERIAL_SOFT_DEBUG_TGL()
174#endif
175
129 /* to center of stop bit */ 176 /* to center of stop bit */
130 _delay_us(WAIT_US); 177 _delay_us(WAIT_US);
131 178
132 uint8_t next = (rbuf_head + 1) % RBUF_SIZE; 179 uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
180#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
181 if (parity && next != rbuf_tail) {
182#else
133 if (next != rbuf_tail) { 183 if (next != rbuf_tail) {
184#endif
134 rbuf[rbuf_head] = data; 185 rbuf[rbuf_head] = data;
135 rbuf_head = next; 186 rbuf_head = next;
136 } 187 }
137 188
138 SERIAL_RXD_INT_EXIT(); 189 SERIAL_RXD_INT_EXIT();
190 SERIAL_SOFT_DEBUG_TGL()
139} 191}