Merge branch 'pc98_update'

This commit is contained in:
tmk 2018-09-08 21:25:41 +09:00
commit 4650d2e575
5 changed files with 100 additions and 170 deletions

View file

@ -1,26 +1,25 @@
# Target file name (without extension).
TARGET = pc98_usb
TARGET ?= pc98_usb
# Directory common source filess exist
TMK_DIR = ../../tmk_core
TMK_DIR ?= ../../tmk_core
# Directory keyboard dependent files exist
TARGET_DIR = .
TARGET_DIR ?= .
# keyboard dependent files
SRC = matrix.c \
# Add one of lines below to select serial protocol implementation
# protocol/serial_uart.c
# protocol/serial_soft.c
SRC ?= matrix.c \
protocol/serial_uart.c
CONFIG_H = config.h
CONFIG_H ?= config.h
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
#MCU = at90usb162 # Teensy 1.0
#MCU = atmega32u4 # Teensy 2.0
#MCU = at90usb646 # Teensy++ 1.0
#MCU = at90usb1286 # Teensy++ 2.0
MCU = atmega32u2 # TMK Converter
MCU ?= atmega32u2 # TMK Converter
# Processor frequency.
@ -28,14 +27,14 @@ MCU = atmega32u2 # TMK Converter
# so your program will run at the correct speed. You should also set this
# variable to same clock speed. The _delay_ms() macro uses this, and many
# examples use this variable to calculate timings. Do not add a "UL" here.
F_CPU = 16000000
F_CPU ?= 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
ARCH ?= AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
@ -48,7 +47,7 @@ ARCH = AVR8
#
# 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)
F_USB ?= $(F_CPU)
# Interrupt driven control endpoint task
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
@ -57,12 +56,12 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Build Options
# *Comment out* to disable the options.
#
MOUSEKEY_ENABLE = yes # Mouse keys
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
UNIMAP_ENABLE = yes
MOUSEKEY_ENABLE ?= yes # Mouse keys
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
UNIMAP_ENABLE ?= yes
# Boot Section Size in bytes

View file

@ -25,7 +25,7 @@ Wiring: You can change this with editing config.h.
2 GND GND
3 ~RDY PD4
4 RXD PD2
5 ~RTY PD5
5 ~RTY PD1
6 NC
7 NC
8 5V VCC
@ -42,7 +42,7 @@ Frame format: 1-Start bit(Lo), 8-Data bits, Odd-Parity, 1-Stop bit
Build Firmware
--------------
Just use 'make' to bild firmware
Just use 'make' to bild firmware for TMK PC98 converter.
$ make clean
$ make
@ -53,6 +53,12 @@ To flash firmware
then push button on converter to flash firmware.
If you are using ATMega32u4 based board instead of premade TMK PC98 converter(ATMega32u2) use following commands.
$ make -f Makefile.32u4 clean
$ make -f Makefile.32u4
$ make -f Makefile.32u4 dfu
PC98 Scan Codes
@ -140,6 +146,10 @@ Its scan code map is very different from standard types. This is not tested.
Other PC98 converter projects and resource
------------------------------------------
PC-9800シリーズ テクニカルデータブック HARDWARE 編 1993年 p139, p343
https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n151
https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n355
PC98 to USB
http://davy.nyacom.net/kbd98usb/
@ -149,3 +159,25 @@ http://www.tsp.ne.jp/~sawada/mago/src/gka98at.asm
scan code:
http://ixsvr.dyndns.org/usb2pc98
NOTES
-----
### Tested on
- PC-9801V
- DIGITAL WAVE Dboard
### RDY
Current firmware does not control RDY line and it is drived as low to receive data always. While sending command firmware drive the line high.
PC98 host keeps RDY line high to prevent keyboard from sending data while processing.
https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n359
### Inhibit key repeating
The command(9Ch, 70h) works with Raku Raku keybaord but not with Dboard.
### LED indicater
Dboard has LEDs but it seems to ignore LED control command.

View file

@ -43,7 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LOCKING_RESYNC_ENABLE
/* Control LED indicatiors, which doesn't work well with locking support */
//#define PC98_LED_CONTROL
#define PC98_LED_CONTROL
/* PC98 Reset Port shared with TXD */
@ -64,8 +64,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* asynchronous, positive logic, 19200baud, bit order: LSB first
* 1-start bit, 8-data bit, odd parity, 1-stop bit
*/
/*
* Software Serial
* Add protocol/serial_soft.c to SRC in Makefile
*/
#define SERIAL_SOFT_BAUD 19200
#define SERIAL_SOFT_PARITY_ODD
@ -110,6 +112,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/*
* Hardware Serial(UART)
* Add protocol/serial_uart.c to SRC in Makefile
*/
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__)
#define SERIAL_UART_BAUD 19200

View file

@ -1,115 +0,0 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
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 "keycode.h"
#include "action.h"
#include "action_macro.h"
#include "util.h"
#include "keymap.h"
/* PC-9801-98-S02 Raku Raku keyboard(Luckyboard) Normal Mode
,---------------------------------------------------------------.
| 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 6A| 6B| 36| 37| 3F| 3E|
`---------------------------------------------------------------'
,---------------------------------------------------------------.
| 00| 01| 02| 03| 04| 05| 58| 71| 06| 07| 08| 09| 0A| 0E|
|---------------------------------------------------------------|
| 0F| 10| 11| 12| 13| 14| 3A | 15| 16| 17| 18| 19| 1C|
|---------------------------------------------------------'. |
| 74| 20| 21| 22| 23| 24| 3B | 3C | 25| 26| 27| 28| 29| |
|---------------------------------------------------------------|
| 70| 2A| 2B| 2C| 2D| 2E| 38| 3D | 39| 2F| 30| 31| 32| 33| 70|
`---------------------------------------------------------------'
| 73| 51| 5B| 59| 34| 5A| 35| xx|
`-----------------------------------------------'
xx: 74 35 F4 B5
*/
#define KEYMAP( \
K60, K61, K62, K63, K64, K65, K66, K67, K68, K69, K6A, K6B, K36, K37, K3F, K3E, \
K00, K01, K02, K03, K04, K05, K58, K71, K06, K07, K08, K09, K0A, K0E, \
K0F, K10, K11, K12, K13, K14, K3A, K15, K16, K17, K18, K19, K1C, \
K74, K20, K21, K22, K23, K24, K3B, K3C, K25, K26, K27, K28, K29, \
K70,K2A, K2B, K2C, K2D, K2E, K38, K3D, K39, K2F, K30, K31, K32, K33, \
K73, K51, K5B, K59, K34, K5A, K35 \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
{ KC_##K08, KC_##K09, KC_##K0A, KC_NO, KC_NO, KC_NO, KC_##K0E, KC_##K0F }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
{ KC_##K18, KC_##K19, KC_NO, KC_NO, KC_##K1C, KC_NO, KC_NO, KC_NO }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
{ KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
{ KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
{ 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_NO, KC_NO, KC_NO }, \
{ KC_NO, KC_##K51, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
{ KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_NO, KC_NO, KC_NO, KC_NO }, \
{ KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
{ KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_NO, KC_NO, KC_NO, KC_NO }, \
{ KC_##K70, KC_##K71, KC_NO, KC_##K73, KC_##K74, KC_NO, KC_NO, KC_NO }, \
{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO } \
}
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
,---------------------------------------------------------------.
| 60| 61| 62| 63| 64| 65| 66| 67| 68| 69| 6A| 6B| 36| 37| 3F| 3E|
`---------------------------------------------------------------'
,---------------------------------------------------------------.
| 00| 01| 02| 03| 04| 05| 58| 71| 06| 07| 08| 09| 0A| 0E|
|---------------------------------------------------------------|
| 0F| 10| 11| 12| 13| 14| 3A | 15| 16| 17| 18| 19| 1C|
|---------------------------------------------------------------|
| 74| 20| 21| 22| 23| 24| MINS| EQL| 25| 26| 27| 28| 29| |
|---------------------------------------------------------------|
| 70| 2A| 2B| 2C| 2D| 2E| 38| 3D | 39| 2F| 30| 31| 32| 33| 70|
`---------------------------------------------------------------'
| 73| 51| 5B| 59| 34| 5A| 35| xx|
`-----------------------------------------------'
*/
KEYMAP(
STOP,PSCR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14,
ESC, 1, 2, 3, 4, 5, LNUM,LCAP, 6, 7, 8, 9, 0, BSPC,
TAB, Q, W, E, R, T, UP, Y, U, I, O, P, ENT,
LCTL, A, S, D, F, G, LEFT, RGHT, H, J, K, L,SCLN,
LSFT, Z, X, C, V, B, INS, DOWN, DEL, N, M,COMM, DOT,SLSH,
LGUI, LALT, LCTL, FN0, SPC, FN0, RALT
),
KEYMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,SLCK,PAUS,
GRV, TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS,TRNS,TRNS,MINS, EQL, BSLS,
TRNS, TRNS,TRNS,TRNS,TRNS,TRNS, PGUP, TRNS,TRNS,TRNS,LBRC,RBRC, TRNS,
TRNS, TRNS,TRNS,TRNS,TRNS,TRNS, HOME, END, TRNS,TRNS,TRNS,TRNS,QUOT,
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, PGDN, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS
),
};
/*
* Fn actions
*/
const action_t PROGMEM fn_actions[] = {
ACTION_LAYER_MOMENTARY(1), // FN0
};

View file

@ -68,23 +68,34 @@ static int16_t pc98_wait_response(void)
static void pc98_inhibit_repeat(void)
{
uint16_t code;
// clear recv buffer
while (serial_recv()) ;
RETRY:
_delay_ms(100);
pc98_send(0x9C);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 9C: %02X\n", code);
if (code != 0xFA) goto RETRY;
_delay_ms(100);
pc98_send(0x70);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 70: %02X\n", code);
if (code != 0xFA) goto RETRY;
}
static uint8_t pc98_led = 0;
static void pc98_led_set(void)
{
uint16_t code;
RETRY:
pc98_send(0x9D);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 9D: %02X\n", code);
if (code != 0xFA) goto RETRY;
pc98_send(pc98_led);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send %02X: %02X\n", pc98_led, code);
if (code != 0xFA) goto RETRY;
}
void matrix_init(void)
{
debug_keyboard = true;
@ -99,36 +110,40 @@ void matrix_init(void)
serial_init();
// PC98 reset
/*
PC98_RST_PORT &= ~(1<<PC98_RST_BIT);
_delay_us(15);
PC98_RST_PORT |= (1<<PC98_RST_BIT);
_delay_us(13);
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
*/
// https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n359
PC98_RDY_PORT |= (1<<PC98_RDY_BIT); // RDY: high
PC98_RST_PORT &= ~(1<<PC98_RST_BIT); // RST: low
_delay_us(15); // > 13us
PC98_RST_PORT |= (1<<PC98_RST_BIT); // RST: high
_delay_ms(500);
_delay_ms(50);
pc98_inhibit_repeat();
// PC98 ready
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
debug("init\n");
// ready to receive from keyboard
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); // RDY: low
print("matrix_init done.\n");
return;
}
uint8_t matrix_scan(void)
{
uint16_t code;
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
//_delay_us(30);
code = serial_recv2();
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
if (code == -1) return 0;
if (code == -1) {
#ifdef PC98_LED_CONTROL
// Before sending command we have to make sure that there is no unprocessed key in queue
// otherwise keys will be missed during sending command
if (pc98_led) {
pc98_led_set();
pc98_led = 0;
}
#endif
return 0;
}
print_hex8(code); print(" ");
@ -154,15 +169,11 @@ uint8_t matrix_get_row(uint8_t row)
void led_set(uint8_t usb_led)
{
#ifdef PC98_LED_CONTROL
uint8_t led_state = 0x70;
if (usb_led & (1<<USB_LED_NUM_LOCK)) led_state |= (1<<0);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) led_state |= (1<<2);
xprintf("led_set: %02X\n", led_state);
pc98_send(0x9D);
_delay_ms(100);
pc98_send(led_state);
// responses(FA or FC) will be ignored in matrix_scan()
#endif
// https://archive.org/stream/PC9800TechnicalDataBookHARDWARE1993/PC-9800TechnicalDataBook_HARDWARE1993#page/n161
// http://www.webtech.co.jp/company/doc/undocumented_mem/io_kb.txt
pc98_led = 0x70;
if (usb_led & (1<<USB_LED_NUM_LOCK)) pc98_led |= (1<<0);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) pc98_led |= (1<<2);
xprintf("usb_led: %02X\n", usb_led);
xprintf("pc98_led: %02X\n", pc98_led);
}