Merge branch 'pc98_update'

This commit is contained in:
tmk 2018-06-07 22:22:04 +09:00
commit 9977fd5140
6 changed files with 100 additions and 102 deletions

View file

@ -10,7 +10,6 @@ TARGET_DIR = .
# keyboard dependent files
SRC = keymap.c \
matrix.c \
led.c \
protocol/serial_uart.c
# protocol/serial_soft.c
@ -20,9 +19,10 @@ 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 = atmega32u4 # Teensy 2.0
#MCU = at90usb646 # Teensy++ 1.0
#MCU = at90usb1286 # Teensy++ 2.0
MCU = atmega32u2 # TMK Converter
# Processor frequency.
@ -62,6 +62,7 @@ OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
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

View file

@ -1,6 +1,6 @@
PC98 to USB keyboard protocol converter
=======================================
Target MCU is ATMega32u4 but other USB capable AVR will also work.
Target MCU is ATMega32u2 but other USB capable AVR will also work.
Connector
@ -12,7 +12,7 @@ Connector
/ 8 7 6 \
| 5 4 3 |
\_ 2 1 _/
\_____/
\_____/
(receptacle)
@ -25,8 +25,8 @@ Wiring: You can change this with editing config.h.
3 ~RDY PD4
4 RXD PD2
5 ~RTY PD5
6 NC
7 NC
6 NC
7 NC
8 5V VCC
@ -59,9 +59,31 @@ PC98 to PS/2
http://www.tsp.ne.jp/~sawada/mago/c_gka98at.htm
http://www.tsp.ne.jp/~sawada/mago/src/gka98at.asm
scan code:
http://ixsvr.dyndns.org/usb2pc98
NEC PC-9801-98-S02 - raku raku keyboard:
https://deskthority.net/photos-f62/nec-pc-9801-98-s02-t5212.html
PC98 keyboard commands
----------------------
http://www.webtech.co.jp/company/doc/undocumented_mem/io_kb.txt
response from keyboard:
FAh: ACK
FCh: NACK
Inhibit repeating key:
0x9C, 0x70
0x9C, 0x70
LED control:
9Dh 7xh
second byte:
0111 xxxx
|||`- NumLock
||`-- ?
|`--- CapsLock
`---- Kana

View file

@ -32,10 +32,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() ( \
host_get_first_key() == KC_CANCEL \
keyboard_report->keys[0] == KC_STOP || \
keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) \
)
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* Control LED indicatiors, which doesn't work well with locking support */
//#define PC98_LED_CONTROL
/* PC98 Reset Port shared with TXD */
#define PC98_RST_DDR DDRD
#define PC98_RST_PORT PORTD
@ -47,7 +57,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* PC98 Retry Port */
#define PC98_RTY_DDR DDRD
#define PC98_RTY_PORT PORTD
#define PC98_RTY_BIT 5
#define PC98_RTY_BIT 1
/*
* PC98 Serial(USART) configuration
@ -101,7 +111,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/*
* Hardware Serial(UART)
*/
#ifdef __AVR_ATmega32U4__
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__)
#define SERIAL_UART_BAUD 19200
#define SERIAL_UART_DATA UDR1
#define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1)
@ -113,6 +123,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); /* RX interrupt, RX: enable */ \
UCSR1B |= (0<<TXCIE1) | (1<<TXEN1); /* TX interrupt, TX: enable */ \
UCSR1C |= (1<<UPM11) | (1<<UPM10); /* parity: none(00), even(01), odd(11) */ \
DDRD &= ~(1<<2); PORTD |= (1<<2); /* Pull-up RXD pin */ \
sei(); \
} while(0)
#else

View file

@ -89,28 +89,20 @@ const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
`-----------------------------------------------'
*/
KEYMAP(
CANCEL,COPY, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, FN6,
ESC, 1, 2, 3, 4, 5, FN4, FN5, 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, MINS, EQL, H, J, K, L, FN2,
LSFT, Z, X, C, V, B, GRV, BSLS, QUOT, N, M,COMM, DOT, FN1,
LGUI, LALT, LCTL, LSFT, SPC, SPC, RALT
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(
PAUS,COPY, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14,
GRV, F1, F2, F3, F4, F5, NO, NO, F6, F7, F8, F9, F10, DEL,
TAB, Q, W, E, R, T, UP, HOME,PGDN,PGUP, END, P, ENT,
LCTL, A, S, D, F, G, MINS, EQL, LEFT,DOWN, UP,RGHT,SCLN,
LSFT, Z, X, C, V, B, INS, DOWN, DEL,HOME,PGDN,PGUP, END,TRNS,
LGUI, LALT, LCTL, LSFT, SPC, SPC, RALT
),
KEYMAP(
PAUS,COPY, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14,
GRV, F1, F2, F3, F4, F5, NO, NO, F6, F7, F8, F9, F10, DEL,
TAB, Q, W, E, R, T, UP, WH_L,WH_D,WH_U,WH_R, P, ENT,
LCTL, A, S, D, F, G, MINS, EQL, MS_L,MS_D,MS_U,MS_R,TRNS,
LSFT, Z, X, C, V, B, INS, DOWN, BTN3,BTN2,BTN1,BTN4,BTN5,TRNS,
LGUI, LALT, LCTL, LSFT, SPC, SPC, RALT
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
),
};
@ -162,11 +154,5 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
* Fn actions
*/
const action_t PROGMEM fn_actions[] = {
ACTION_LAYER_TAP_TOGGLE(0), // FN0
ACTION_LAYER_TAP_KEY(1, KC_SLASH), // FN1
ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN2
ACTION_LAYER_MOMENTARY(2), // FN3
ACTION_MACRO(LBRACKET), // FN4
ACTION_MACRO(RBRACKET), // FN5
ACTION_MACRO(DUMMY), // FN6
ACTION_LAYER_MOMENTARY(1), // FN0
};

View file

@ -1,33 +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 "serial.h"
#include "led.h"
void led_set(uint8_t usb_led)
{
uint8_t sun_led = 0;
if (usb_led & (1<<USB_LED_NUM_LOCK)) sun_led |= (1<<0);
if (usb_led & (1<<USB_LED_COMPOSE)) sun_led |= (1<<1);
if (usb_led & (1<<USB_LED_SCROLL_LOCK)) sun_led |= (1<<2);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) sun_led |= (1<<3);
serial_send(0x0E);
serial_send(sun_led);
}

View file

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "print.h"
#include "util.h"
#include "matrix.h"
#include "led.h"
#include "debug.h"
#include "protocol/serial.h"
@ -47,38 +48,46 @@ static uint8_t matrix[MATRIX_ROWS];
#define COL(code) (code&0x07)
static void pc98_send(uint8_t data)
{
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
_delay_ms(1);
serial_send(data);
_delay_ms(1);
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
}
static int16_t pc98_wait_response(void)
{
int16_t code = -1;
uint8_t timeout = 255;
while (timeout-- && (code = serial_recv2()) == -1) _delay_ms(1);
return code;
}
static void pc98_inhibit_repeat(void)
{
uint8_t code;
uint16_t code;
// clear recv buffer
while (serial_recv()) ;
RETRY:
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
_delay_ms(500);
serial_send(0x9C);
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
_delay_ms(100);
while (!(code = serial_recv())) ;
print("PC98: send 9C: "); print_hex8(code); print("\n");
pc98_send(0x9C);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 9C: %02X\n", code);
if (code != 0xFA) goto RETRY;
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
_delay_ms(100);
serial_send(0x70);
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
_delay_ms(100);
//code = serial_recv();
while (!(code = serial_recv())) ;
print("PC98: send 70: "); print_hex8(code); print("\n");
pc98_send(0x70);
code = pc98_wait_response();
if (code != -1) xprintf("PC98: send 70: %02X\n", code);
if (code != 0xFA) goto RETRY;
}
void matrix_init(void)
{
debug_keyboard = true;
PC98_RST_DDR |= (1<<PC98_RST_BIT);
PC98_RDY_DDR |= (1<<PC98_RDY_BIT);
PC98_RTY_DDR |= (1<<PC98_RTY_BIT);
@ -116,24 +125,11 @@ uint8_t matrix_scan(void)
{
uint16_t code;
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
_delay_us(30);
//_delay_us(30);
code = serial_recv2();
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
if (code == -1) return 0;
if (code == 0x60) {
pc98_inhibit_repeat();
/*
PC98_RDY_PORT |= (1<<PC98_RDY_BIT);
_delay_ms(100);
serial_send(0x96);
PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT);
*/
return 0;
}
print_hex8(code); print(" ");
if (code&0x80) {
@ -155,3 +151,18 @@ uint8_t matrix_get_row(uint8_t row)
{
return matrix[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
}