From 65366a4e7a4bdb204fcbc79271976461538cd45a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 7 May 2012 02:32:56 -0400 Subject: [PATCH] Adding initial version of Sony OA-S3400 converter. - Not fully reading for usage, but 90% of the way there for typing. - Some soldering is required for 2 keys to work properly (Shift and Shift Lock) - Even when complete, be careful when doing multiple key combos, as the key buffer is only cleared when all general keys are released (all except Shift, Shift Lock, and Code) --- Keymap/keymap.h | 1 + Keymap/sonyoas3400.h | 552 ++++++++++++++++++++++++++++++++++ Scan/SonyOA-S3400/scan_loop.c | 531 ++++++++++++++++++++++++++++++++ Scan/SonyOA-S3400/scan_loop.h | 67 +++++ Scan/SonyOA-S3400/setup.cmake | 47 +++ USB/pjrc/usb_keyboard_debug.c | 4 +- setup.cmake | 2 +- 7 files changed, 1201 insertions(+), 3 deletions(-) create mode 100644 Keymap/sonyoas3400.h create mode 100644 Scan/SonyOA-S3400/scan_loop.c create mode 100644 Scan/SonyOA-S3400/scan_loop.h create mode 100644 Scan/SonyOA-S3400/setup.cmake diff --git a/Keymap/keymap.h b/Keymap/keymap.h index 01dc197..121acae 100644 --- a/Keymap/keymap.h +++ b/Keymap/keymap.h @@ -48,6 +48,7 @@ #include "kaypro1.h" #include "microswitch8304.h" #include "sonynews.h" +#include "sonyoas3400.h" #include "tandy1000.h" #include "univacf3w9.h" diff --git a/Keymap/sonyoas3400.h b/Keymap/sonyoas3400.h new file mode 100644 index 0000000..aebf482 --- /dev/null +++ b/Keymap/sonyoas3400.h @@ -0,0 +1,552 @@ +/* Copyright (C) 2012 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __SONYOAS3400_H +#define __SONYOAS3400_H + +// This file contains various key layouts for the Sony OA-S3400 Word Processor Keyboard + + +// ----- Variables ----- +static uint8_t sonyoas3400_ModifierMask[] = { 0x90, 0x91, 0x92, 0xCE, 0xE0 }; + +static uint8_t sonyoas3400_DefaultMap[] = { + 0, // 0x00 + 0, // 0x01 + 0, // 0x02 + 0, // 0x03 + 0, // 0x04 + 0, // 0x05 + 0, // 0x06 + 0, // 0x07 + KEY_BACKSPACE, // 0x08 + 0, // 0x09 + 0, // 0x0A + 0, // 0x0B + 0, // 0x0C + KEY_ENTER, // 0x0D + 0, // 0x0E + 0, // 0x0F + 0, // 0x10 + 0, // 0x11 + 0, // 0x12 + 0, // 0x13 + 0, // 0x14 + 0, // 0x15 + 0, // 0x16 + 0, // 0x17 + 0, // 0x18 + 0, // 0x19 + 0, // 0x1A + 0, // 0x1B + 0, // 0x1C + 0, // 0x1D + 0, // 0x1E + 0, // 0x1F + KEY_SPACE, // 0x20 + 0, // 0x21 + 0, // 0x22 + 0, // 0x23 + 0, // 0x24 + 0, // 0x25 + 0, // 0x26 + KEY_QUOTE, // 0x27 + 0, // 0x28 + 0, // 0x29 + 0, // 0x2A + 0, // 0x2B + KEY_COMMA, // 0x2C + KEY_MINUS, // 0x2D + KEY_PERIOD, // 0x2E + KEY_SLASH, // 0x2F + KEY_0, // 0x30 + KEY_1, // 0x31 + KEY_2, // 0x32 + KEY_3, // 0x33 + KEY_4, // 0x34 + KEY_5, // 0x35 + KEY_6, // 0x36 + KEY_7, // 0x37 + KEY_8, // 0x38 + KEY_9, // 0x39 + 0, // 0x3A + KEY_SEMICOLON, // 0x3B + 0, // 0x3C + KEY_EQUAL, // 0x3D + 0, // 0x3E + 0, // 0x3F + 0, // 0x40 + KEY_A, // 0x41 + KEY_B, // 0x42 + KEY_C, // 0x43 + KEY_D, // 0x44 + KEY_E, // 0x45 + KEY_F, // 0x46 + KEY_G, // 0x47 + KEY_H, // 0x48 + KEY_I, // 0x49 + KEY_J, // 0x4A + KEY_K, // 0x4B + KEY_L, // 0x4C + KEY_M, // 0x4D + KEY_N, // 0x4E + KEY_O, // 0x4F + KEY_P, // 0x50 + KEY_Q, // 0x51 + KEY_R, // 0x52 + KEY_S, // 0x53 + KEY_T, // 0x54 + KEY_U, // 0x55 + KEY_V, // 0x56 + KEY_W, // 0x57 + KEY_X, // 0x58 + KEY_Y, // 0x59 + KEY_Z, // 0x5A + 0, // 0x5B + 0, // 0x5C + 0, // 0x5D + 0, // 0x5E + 0, // 0x5F + 0, // 0x60 + 0, // 0x61 + 0, // 0x62 + 0, // 0x63 + 0, // 0x64 + 0, // 0x65 + 0, // 0x66 + 0, // 0x67 + 0, // 0x68 + 0, // 0x69 + 0, // 0x6A + 0, // 0x6B + 0, // 0x6C + 0, // 0x6D + 0, // 0x6E + 0, // 0x6F + 0, // 0x70 + 0, // 0x71 + 0, // 0x72 + 0, // 0x73 + 0, // 0x74 + 0, // 0x75 + 0, // 0x76 + 0, // 0x77 + 0, // 0x78 + 0, // 0x79 + 0, // 0x7A + 0, // 0x7B + 0, // 0x7C + 0, // 0x7D + 0, // 0x7E + 0, // 0x7F + 0, // 0x80 + 0, // 0x81 + KEY_LEFT_BRACE, // 0x82 + 0, // 0x83 + 0, // 0x84 + 0, // 0x85 + 0, // 0x86 + 0, // 0x87 + 0, // 0x88 + 0, // 0x89 + 0, // 0x8A + 0, // 0x8B + 0, // 0x8C + 0, // 0x8D + 0, // 0x8E + 0, // 0x8F + KEY_LEFT_SHIFT, // 0x90 + KEY_LEFT_CTRL, // 0x91 + KEY_LEFT_ALT, // 0x92 + 0, // 0x93 + 0, // 0x94 + 0, // 0x95 + 0, // 0x96 + 0, // 0x97 + 0, // 0x98 + 0, // 0x99 + 0, // 0x9A + 0, // 0x9B + 0, // 0x9C + 0, // 0x9D + 0, // 0x9E + 0, // 0x9F + 0, // 0xA0 + KEY_TAB, // 0xA1 + 0, // 0xA2 + 0, // 0xA3 + 0, // 0xA4 + 0, // 0xA5 + 0, // 0xA6 + 0, // 0xA7 + 0, // 0xA8 + 0, // 0xA9 + 0, // 0xAA + 0, // 0xAB + 0, // 0xAC + 0, // 0xAD + 0, // 0xAE + 0, // 0xAF + 0, // 0xB0 + 0, // 0xB1 + 0, // 0xB2 + 0, // 0xB3 + 0, // 0xB4 + 0, // 0xB5 + 0, // 0xB6 + 0, // 0xB7 + 0, // 0xB8 + 0, // 0xB9 + 0, // 0xBA + 0, // 0xBB + 0, // 0xBC + 0, // 0xBD + 0, // 0xBE + 0, // 0xBF + 0, // 0xC0 + 0, // 0xC1 + 0, // 0xC2 + 0, // 0xC3 + 0, // 0xC4 + 0, // 0xC5 + 0, // 0xC6 + 0, // 0xC7 + 0, // 0xC8 + 0, // 0xC9 + 0, // 0xCA + 0, // 0xCB + 0, // 0xCC + 0, // 0xCD + KEY_LEFT_GUI, // 0xCE + KEY_RIGHT_BRACE, // 0xCF + KEY_ESC, // 0xD0 + KEY_TILDE, // 0xD1 + KEY_BACKSLASH, // 0xD2 + KEY_F11, // 0xD3 + KEY_F12, // 0xD4 + KEY_F10, // 0xD5 + KEY_UP, // 0xD6 + KEY_DOWN, // 0xD7 + KEY_LEFT, // 0xD8 + KEY_RIGHT, // 0xD9 + 0, // 0xDA + 0, // 0xDB + 0, // 0xDC + 0, // 0xDD + 0, // 0xDE + 0, // 0xDF + KEY_RIGHT_ALT, // 0xE0 + KEY_INSERT, // 0xE1 + KEY_HOME, // 0xE2 + KEY_PAGE_UP, // 0xE3 + KEY_DELETE, // 0xE4 + KEY_END, // 0xE5 + KEY_PAGE_DOWN, // 0xE6 + KEY_DOWN, // 0xE7 + KEY_F9, // 0xE8 + 0, // 0xE9 + 0, // 0xEA + 0, // 0xEB + 0, // 0xEC + 0, // 0xED + 0, // 0xEE + 0, // 0xEF + 0, // 0xF0 + 0, // 0xF1 + 0, // 0xF2 + 0, // 0xF3 + 0, // 0xF4 + 0, // 0xF5 + KEY_F1, // 0xF6 + KEY_F2, // 0xF7 + KEY_F3, // 0xF8 + KEY_F4, // 0xF9 + KEY_F5, // 0xFA + KEY_F6, // 0xFB + KEY_F7, // 0xFC + KEY_F8, // 0xFD + 0, // 0xFE + 0, // 0xFF +}; + +static uint8_t sonyoas3400_ColemakMap[] = { + 0, // 0x00 + 0, // 0x01 + 0, // 0x02 + 0, // 0x03 + 0, // 0x04 + 0, // 0x05 + 0, // 0x06 + 0, // 0x07 + KEY_BACKSPACE, // 0x08 + 0, // 0x09 + 0, // 0x0A + 0, // 0x0B + 0, // 0x0C + KEY_ENTER, // 0x0D + 0, // 0x0E + 0, // 0x0F + 0, // 0x10 + 0, // 0x11 + 0, // 0x12 + 0, // 0x13 + 0, // 0x14 + 0, // 0x15 + 0, // 0x16 + 0, // 0x17 + 0, // 0x18 + 0, // 0x19 + 0, // 0x1A + 0, // 0x1B + 0, // 0x1C + 0, // 0x1D + 0, // 0x1E + 0, // 0x1F + KEY_SPACE, // 0x20 + 0, // 0x21 + 0, // 0x22 + 0, // 0x23 + 0, // 0x24 + 0, // 0x25 + 0, // 0x26 + KEY_QUOTE, // 0x27 + 0, // 0x28 + 0, // 0x29 + 0, // 0x2A + 0, // 0x2B + KEY_COMMA, // 0x2C + KEY_MINUS, // 0x2D + KEY_PERIOD, // 0x2E + KEY_SLASH, // 0x2F + KEY_0, // 0x30 + KEY_1, // 0x31 + KEY_2, // 0x32 + KEY_3, // 0x33 + KEY_4, // 0x34 + KEY_5, // 0x35 + KEY_6, // 0x36 + KEY_7, // 0x37 + KEY_8, // 0x38 + KEY_9, // 0x39 + 0, // 0x3A + KEY_O, // 0x3B + 0, // 0x3C + KEY_EQUAL, // 0x3D + 0, // 0x3E + 0, // 0x3F + 0, // 0x40 + KEY_A, // 0x41 + KEY_B, // 0x42 + KEY_C, // 0x43 + KEY_S, // 0x44 + KEY_F, // 0x45 + KEY_T, // 0x46 + KEY_D, // 0x47 + KEY_H, // 0x48 + KEY_U, // 0x49 + KEY_N, // 0x4A + KEY_E, // 0x4B + KEY_I, // 0x4C + KEY_M, // 0x4D + KEY_K, // 0x4E + KEY_Y, // 0x4F + KEY_SEMICOLON, // 0x50 + KEY_Q, // 0x51 + KEY_P, // 0x52 + KEY_R, // 0x53 + KEY_G, // 0x54 + KEY_L, // 0x55 + KEY_V, // 0x56 + KEY_W, // 0x57 + KEY_X, // 0x58 + KEY_J, // 0x59 + KEY_Z, // 0x5A + 0, // 0x5B + 0, // 0x5C + 0, // 0x5D + 0, // 0x5E + 0, // 0x5F + 0, // 0x60 + 0, // 0x61 + 0, // 0x62 + 0, // 0x63 + 0, // 0x64 + 0, // 0x65 + 0, // 0x66 + 0, // 0x67 + 0, // 0x68 + 0, // 0x69 + 0, // 0x6A + 0, // 0x6B + 0, // 0x6C + 0, // 0x6D + 0, // 0x6E + 0, // 0x6F + 0, // 0x70 + 0, // 0x71 + 0, // 0x72 + 0, // 0x73 + 0, // 0x74 + 0, // 0x75 + 0, // 0x76 + 0, // 0x77 + 0, // 0x78 + 0, // 0x79 + 0, // 0x7A + 0, // 0x7B + 0, // 0x7C + 0, // 0x7D + 0, // 0x7E + 0, // 0x7F + 0, // 0x80 + 0, // 0x81 + KEY_LEFT_BRACE, // 0x82 + 0, // 0x83 + 0, // 0x84 + 0, // 0x85 + 0, // 0x86 + 0, // 0x87 + 0, // 0x88 + 0, // 0x89 + 0, // 0x8A + 0, // 0x8B + 0, // 0x8C + 0, // 0x8D + 0, // 0x8E + 0, // 0x8F + KEY_LEFT_SHIFT, // 0x90 + KEY_LEFT_CTRL, // 0x91 + KEY_LEFT_ALT, // 0x92 + 0, // 0x93 + 0, // 0x94 + 0, // 0x95 + 0, // 0x96 + 0, // 0x97 + 0, // 0x98 + 0, // 0x99 + 0, // 0x9A + 0, // 0x9B + 0, // 0x9C + 0, // 0x9D + 0, // 0x9E + 0, // 0x9F + 0, // 0xA0 + KEY_TAB, // 0xA1 + 0, // 0xA2 + 0, // 0xA3 + 0, // 0xA4 + 0, // 0xA5 + 0, // 0xA6 + 0, // 0xA7 + 0, // 0xA8 + 0, // 0xA9 + 0, // 0xAA + 0, // 0xAB + 0, // 0xAC + 0, // 0xAD + 0, // 0xAE + 0, // 0xAF + 0, // 0xB0 + 0, // 0xB1 + 0, // 0xB2 + 0, // 0xB3 + 0, // 0xB4 + 0, // 0xB5 + 0, // 0xB6 + 0, // 0xB7 + 0, // 0xB8 + 0, // 0xB9 + 0, // 0xBA + 0, // 0xBB + 0, // 0xBC + 0, // 0xBD + 0, // 0xBE + 0, // 0xBF + 0, // 0xC0 + 0, // 0xC1 + 0, // 0xC2 + 0, // 0xC3 + 0, // 0xC4 + 0, // 0xC5 + 0, // 0xC6 + 0, // 0xC7 + 0, // 0xC8 + 0, // 0xC9 + 0, // 0xCA + 0, // 0xCB + 0, // 0xCC + 0, // 0xCD + KEY_LEFT_GUI, // 0xCE + KEY_RIGHT_BRACE, // 0xCF + KEY_ESC, // 0xD0 + KEY_TILDE, // 0xD1 + KEY_BACKSLASH, // 0xD2 + KEY_F11, // 0xD3 + KEY_F12, // 0xD4 + KEY_F10, // 0xD5 + KEY_UP, // 0xD6 + KEY_DOWN, // 0xD7 + KEY_LEFT, // 0xD8 + KEY_RIGHT, // 0xD9 + 0, // 0xDA + 0, // 0xDB + 0, // 0xDC + 0, // 0xDD + 0, // 0xDE + 0, // 0xDF + KEY_RIGHT_ALT, // 0xE0 + KEY_INSERT, // 0xE1 + KEY_HOME, // 0xE2 + KEY_PAGE_UP, // 0xE3 + KEY_DELETE, // 0xE4 + KEY_END, // 0xE5 + KEY_PAGE_DOWN, // 0xE6 + KEY_DOWN, // 0xE7 + KEY_F9, // 0xE8 + 0, // 0xE9 + 0, // 0xEA + 0, // 0xEB + 0, // 0xEC + 0, // 0xED + 0, // 0xEE + 0, // 0xEF + 0, // 0xF0 + 0, // 0xF1 + 0, // 0xF2 + 0, // 0xF3 + 0, // 0xF4 + 0, // 0xF5 + KEY_F1, // 0xF6 + KEY_F2, // 0xF7 + KEY_F3, // 0xF8 + KEY_F4, // 0xF9 + KEY_F5, // 0xFA + KEY_F6, // 0xFB + KEY_F7, // 0xFC + KEY_F8, // 0xFD + 0, // 0xFE + 0, // 0xFF +}; + + + +#endif + diff --git a/Scan/SonyOA-S3400/scan_loop.c b/Scan/SonyOA-S3400/scan_loop.c new file mode 100644 index 0000000..a694fa4 --- /dev/null +++ b/Scan/SonyOA-S3400/scan_loop.c @@ -0,0 +1,531 @@ +/* Copyright (C) 2012 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// ----- Includes ----- + +// AVR Includes +#include +#include +#include + +// Project Includes +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Defines ----- + +// - Pinout Defines - + +// Scan Bit Pins (from keyboard) +// - Reads in the ASCII scancode +// - Shift and ShiftLock are handled internally +#define READSCAN_PORT PORTC +#define READSCAN_DDR DDRC +#define READSCAN_PIN PINC + + +// Interrupt Pins (from keyboard) +// - CODEINT (Code key signal interrupt/press) +// - Normally high, low when "Code" key is pressed; separate from all other key presses +// - PRESSINT (Press signal interrupt/press) +// - Normally high, low when any key (or multiple except "Code") is pressed, returns to high once all keys are released +// - Signal is changed BEFORE the Scan Bits are updated +// - PULSEINT (Key action pulse interrupt/press) +// - Normally high, low pulses of 147us on key presses (depending on the combination of mode control pins) +// - Pulse is guarranteed to sent after the Scan Bits are updated +#define CODEINT_PORT PORTE +#define CODEINT_DDR DDRE +#define CODEINT_PIN PINE +#define CODEINT_POS 7 + +#define PRESSINT_PORT PORTE +#define PRESSINT_DDR DDRE +#define PRESSINT_POS 6 + +#define PULSEINT_PORT PORTD +#define PULSEINT_DDR DDRD +#define PULSEINT_POS 3 + + +// LED Pins (to keyboard) +// - 1 disable LED +// - 1 enable LED +#define LED1_PORT PORTF // [Pin 19] +#define LED1_DDR DDRF +#define LED1_POS 6 + +#define LED2_PORT PORTF // [Pin 20] +#define LED2_DDR DDRF +#define LED2_POS 7 + + +// Mode Control Pins (to keyboard) +// - Repeat [Pin 14] +// - 1 Single pulse mode (PULSEINT) +// - 0 Repeated pulse mode (PULSEINT) (1 pulse, pause, then constant pulses) +// - Multi [Pin 15] +// - 1 1KRO mode (typewriter compatibility mode) +// - 0 NKRO mode (new pulse on each keypress - PULSEINT) +// - Signal [Pin 18] +// - 1 disables pulse interrupt (PULSEINT) +// - 0 enables pulse interrupt (PULSEINT) +#define REPEAT_PORT PORTF +#define REPEAT_DDR DDRF +#define REPEAT_POS 3 + +#define MULTI_PORT PORTF +#define MULTI_DDR DDRF +#define MULTI_POS 4 + +#define SIGNAL_PORT PORTF +#define SIGNAL_DDR DDRF +#define SIGNAL_POS 5 + + +// Manually Scanned Keys +// Keys that the controller screws up, requiring a separate wire to be brought to the controller +// Note: Safer to route these through a NOT gate to boost the signal strength +// Values below are AFTER NOT gate +// - Shift (both shift keys are on the same scan line) +// - 0 Released +// - 1 Pressed +// - Shift Lock +// - 0 Released +// - 1 Pressed +#define MANUAL_SCAN_KEYS 2 + +#define SHIFT_KEY 0 +#define SHIFT_PORT PORTF +#define SHIFT_DDR DDRF +#define SHIFT_PIN PINF +#define SHIFT_POS 0 + +#define SHIFTLOCK_KEY 1 +#define SHIFTLOCK_PORT PORTF +#define SHIFTLOCK_DDR DDRF +#define SHIFTLOCK_PIN PINF +#define SHIFTLOCK_POS 1 + + +// ----- Macros ----- + +// Make sure we haven't overflowed the buffer +#define bufferAdd(byte) \ + if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \ + KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte + + + +// ----- Variables ----- + +// Buffer used to inform the macro processing module which keys have been detected as pressed +volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER]; +volatile uint8_t KeyIndex_BufferUsed; +volatile uint8_t KeyIndex_Add_InputSignal; // Used to pass the (click/input value) to the keyboard for the clicker + +volatile uint8_t KeyScan_Table[MANUAL_SCAN_KEYS]; // Used for tracking key status of manually scanned keys +volatile uint8_t KeyScan_Prev [MANUAL_SCAN_KEYS]; // Keeps track of key state changes +volatile uint8_t KeyScan_Count; + + + +// ----- Functions ----- + +// Pre-declarations +void processKeyValue( uint8_t keyValue ); + + + +// Setup +inline void scan_setup() +{ + // Setup the external interrupts for + // - General keypresses (INT6/E6) -> rising edge (to detect key release) + // - "Code" key (INT7/E7) -> falling/rising edge (to detect key press/release) + // - General keypress pulse (INT3/D3) -> falling edge (to detect key press ) + EICRA = 0x80; + EICRB = 0x70; + EIMSK = 0xC8; + + + // Setup Interrupt Pins + CODEINT_PORT |= (1 << CODEINT_POS ); + CODEINT_DDR &= ~(1 << CODEINT_POS ); + + PRESSINT_PORT |= (1 << PRESSINT_POS); + PRESSINT_DDR &= ~(1 << PRESSINT_POS); + + PULSEINT_PORT |= (1 << PULSEINT_POS); + PULSEINT_DDR &= ~(1 << PULSEINT_POS); + + + // Setup LED Pins (default off) + LED1_PORT |= (1 << LED1_POS); + LED1_DDR |= (1 << LED1_POS); + + LED2_PORT |= (1 << LED2_POS); + LED2_DDR |= (1 << LED2_POS); + + + // Setup READSCAN pins to read out scancode + READSCAN_PORT = 0xFF; + READSCAN_DDR = 0x00; + + + // Setup Mode Control Pins + // Note: These can be changed at any time, but there is no real reason too for a USB converter + REPEAT_PORT |= (1 << REPEAT_POS); // Setting high for single press mode + REPEAT_DDR |= (1 << REPEAT_POS); + + MULTI_PORT &= ~(1 << MULTI_POS ); // Setting low for multi press mode (NKRO) + MULTI_DDR |= (1 << MULTI_POS ); + + SIGNAL_PORT &= ~(1 << SIGNAL_POS); // Setting low to enable PULSEINT + SIGNAL_DDR |= (1 << SIGNAL_POS); + + + // Setup Troublesome Key Pins + SHIFT_PORT &= ~(1 << SHIFT_POS ); + SHIFT_DDR &= ~(1 << SHIFT_POS ); + + SHIFTLOCK_PORT &= ~(1 << SHIFTLOCK_POS); + SHIFTLOCK_DDR &= ~(1 << SHIFTLOCK_POS); + + + // Reset the keyboard before scanning, we might be in a wierd state + scan_resetKeyboard(); +} + +// Main Detection Loop +// Not needed for the Sony OA-S3400 as signals are interrupt based, thus this is a busy loop +// XXX Function is used for scanning troublesome keys, technically this is not needed for a pure converter +// I just want proper use of the shift and shift lock keys, without having to do major rework to attach to the entire matrix +inline uint8_t scan_loop() +{ + // Loop through known keys + for ( uint8_t key = 0; key < MANUAL_SCAN_KEYS; key++ ) switch ( key ) + { + case SHIFT_KEY: + if ( SHIFT_PIN & (1 << SHIFT_POS) ) + { + KeyScan_Table[SHIFT_KEY]++; + } + break; + case SHIFTLOCK_KEY: + if ( SHIFTLOCK_PIN & (1 << SHIFTLOCK_POS) ) + { + KeyScan_Table[SHIFTLOCK_KEY]++; + } + break; + default: + erro_print("Invalid key scan index"); + break; + } + + // Increment vote instance + KeyScan_Count++; + + // Loop function again if not enough votes have been tallied + if ( KeyScan_Count < 255 ) + return 1; + + // Clear vote data + KeyScan_Count = 0; + + // Loop through known keys + for ( uint8_t key = 0; key < MANUAL_SCAN_KEYS; key++ ) + { + // Key scanned as pressed (might have been held from a previous vote) + if ( KeyScan_Table[key] > 127 ) + { + // Keypress detected + if ( !KeyScan_Prev[key] ) + { + processKeyValue( 0x90 + key ); // Arbitrary key mapping starts at 0x90 + KeyScan_Prev[key] = 1; + } + } + // Key scanned as released + else + { + // Keypress detected + if ( KeyScan_Prev[key] ) + { + processKeyValue( 0xA0 + key ); // Arbitrary key mapping release starts at 0xA0 + KeyScan_Prev[key] = 0; + } + } + + // Clear votes + KeyScan_Table[key] = 0; + } + + // End loop, process macros and USB data + return 0; +} + +void processKeyValue( uint8_t keyValue ) +{ + // - Convert Shifted Value to non-shifted ASCII code - + + // Alphabetic + if ( keyValue >= 0x61 && keyValue <= 0x7A ) + { + keyValue -= 0x20; + } + // Other keys with ASCII shift codes + else + { + switch ( keyValue ) + { + case 0x21: // 1 + case 0x23: // 3 + case 0x24: // 4 + case 0x25: // 5 + keyValue += 0x10; + break; + case 0x26: // 7 + case 0x28: // 9 + keyValue += 0x11; + break; + case 0x81: // 1/2 + case 0x3A: // ; + keyValue += 0x01; + break; + case 0x29: // 0 + keyValue = 0x30; + break; + case 0x40: // 2 + keyValue = 0x32; + break; + case 0x80: // 6 + keyValue = 0x36; + break; + case 0x2A: // 8 + keyValue = 0x38; + break; + case 0x5F: // - + keyValue = 0x2D; + break; + case 0x2B: // + + keyValue = 0x3D; + break; + case 0x22: // " + keyValue = 0x27; + break; + case 0x3F: // ? + keyValue = 0x2F; + break; + } + } + + // Scan code is now finalized, and ready to add to buffer + // Note: Scan codes come from 3 different interrupts and a manual key scan into this function + + // Debug + char tmpStr[6]; + hexToStr( keyValue, tmpStr ); + dPrintStrs( tmpStr, " " ); + + // Detect release condition + uint8_t release = 0; + switch ( keyValue ) + { + case 0xA0: + case 0xA1: + case 0xA2: + keyValue -= 0x10; + case 0xB0: + release = 1; + break; + } + + // Key Release + if ( release ) + { + // Check for the released key, and shift the other keys lower on the buffer + uint8_t c; + for ( c = 0; c < KeyIndex_BufferUsed; c++ ) + { + // General key buffer clear + if ( keyValue == 0xB0 ) + { + switch ( KeyIndex_Buffer[c] ) + { + // Ignore these keys on general key release (have their own release codes) + case 0x90: + case 0x91: + case 0x92: + break; + + // Remove key from buffer + default: + // Shift keys from c position + for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ ) + KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1]; + + // Decrement Buffer + KeyIndex_BufferUsed--; + + break; + } + } + // Key to release found + else if ( KeyIndex_Buffer[c] == keyValue ) + { + // Shift keys from c position + for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ ) + KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1]; + + // Decrement Buffer + KeyIndex_BufferUsed--; + + break; + } + } + + // Error case (no key to release) + if ( c == KeyIndex_BufferUsed + 1 ) + { + errorLED( 1 ); + char tmpStr[6]; + hexToStr( keyValue, tmpStr ); + erro_dPrint( "Could not find key to release: ", tmpStr ); + } + } + // Press or Repeated Key + else + { + // Make sure the key isn't already in the buffer + for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ ) + { + // Key isn't in the buffer yet + if ( c == KeyIndex_BufferUsed ) + { + bufferAdd( keyValue ); + break; + } + + // Key already in the buffer + if ( KeyIndex_Buffer[c] == keyValue ) + break; + } + } +} + +// Key Press Detected Interrupt +ISR(INT3_vect) +{ + cli(); // Disable Interrupts + + uint8_t keyValue = 0x00; + + // Bits are flipped coming in from the keyboard + keyValue = ~READSCAN_PIN; + + // Process the scancode + processKeyValue( keyValue ); + + sei(); // Re-enable Interrupts +} + +// Key Release Detected Interrupt +ISR(INT6_vect) +{ + cli(); // Disable Interrupts + + // Send release code for general keys, 0xB0 + processKeyValue( 0xB0 ); + + sei(); // Re-enable Interrupts +} + +// Code Key Interrupt +ISR(INT7_vect) +{ + cli(); // Disable Interrupts + + // Code Key Released (send scancode) + if ( CODEINT_PIN & (1 << CODEINT_POS) ) + { + processKeyValue( 0xA2 ); + } + // Code Key Pressed (send scancode) + else + { + processKeyValue( 0x92 ); + } + + sei(); // Re-enable Interrupts +} + + +// Send data to keyboard +// Sony OA-S3400 has no serial/parallel dataport to send data too... +uint8_t scan_sendData( uint8_t dataPayload ) +{ + return 0; +} + +// Signal KeyIndex_Buffer that it has been properly read +// Not needed as a signal is sent to remove key-presses +void scan_finishedWithBuffer( void ) +{ + return; +} + +// Reset/Hold keyboard +// Sony OA-S3400 has no locking signals +void scan_lockKeyboard( void ) +{ +} + +void scan_unlockKeyboard( void ) +{ +} + +// Reset Keyboard +void scan_resetKeyboard( void ) +{ + // Empty buffer, now that keyboard has been reset + KeyIndex_BufferUsed = 0; + + // Clear the KeyScan table and count + for ( uint8_t key = 0; key < MANUAL_SCAN_KEYS; key++ ) + { + KeyScan_Table[key] = 0; + KeyScan_Prev [key] = 0; + } + KeyScan_Count = 0; +} + +// USB module is finished with buffer +// Not needed as a signal is sent to remove key-presses +void scan_finishedWithUSBBuffer( void ) +{ + return; +} + diff --git a/Scan/SonyOA-S3400/scan_loop.h b/Scan/SonyOA-S3400/scan_loop.h new file mode 100644 index 0000000..41412b2 --- /dev/null +++ b/Scan/SonyOA-S3400/scan_loop.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2012 by Jacob Alexander + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __SCAN_LOOP_H +#define __SCAN_LOOP_H + +// ----- Includes ----- + +// Compiler Includes +#include + +// Local Includes + + + +// ----- Defines ----- + +#define KEYBOARD_SIZE 0xFF // 255 - Size of the array space for the keyboard(max index) +#define KEYBOARD_BUFFER 24 // Max number of key signals to buffer + + + +// ----- Variables ----- + +extern volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER]; +extern volatile uint8_t KeyIndex_BufferUsed; +extern volatile uint8_t KeyIndex_Add_InputSignal; + + + +// ----- Functions ----- + +// Functions used by main.c +void scan_setup( void ); +uint8_t scan_loop( void ); + + +// Functions available to macro.c +uint8_t scan_sendData( uint8_t dataPayload ); + +void scan_finishedWithUSBBuffer( void ); +void scan_finishedWithBuffer( void ); +void scan_lockKeyboard( void ); +void scan_unlockKeyboard( void ); +void scan_resetKeyboard( void ); + + +#endif // __SCAN_LOOP_H + diff --git a/Scan/SonyOA-S3400/setup.cmake b/Scan/SonyOA-S3400/setup.cmake new file mode 100644 index 0000000..286771e --- /dev/null +++ b/Scan/SonyOA-S3400/setup.cmake @@ -0,0 +1,47 @@ +###| CMake Kiibohd Controller Scan Module |### +# +# Written by Jacob Alexander in 2012 for the Kiibohd Controller +# +# Released into the Public Domain +# +# For the Sony Word Processor OA-S3400 keyboard +# +### + + +### +# Module C files +# + +set( SCAN_SRCS + scan_loop.c +) + + +### +# Module H files +# +set( SCAN_HDRS + scan_loop.h +) + + +### +# File Dependency Setup +# +ADD_FILE_DEPENDENCIES( scan_loop.c ${SCAN_HDRS} ) +#add_file_dependencies( scan_loop.c ${SCAN_HDRS} ) + + +### +# Module Specific Options +# +add_definitions( -I${HEAD_DIR}/Keymap ) + +#| Keymap Settings +add_definitions( + -DMODIFIER_MASK=sonyoas3400_ModifierMask + #-DKEYINDEX_MASK=sonyoas3400_ColemakMap + -DKEYINDEX_MASK=sonyoas3400_DefaultMap +) + diff --git a/USB/pjrc/usb_keyboard_debug.c b/USB/pjrc/usb_keyboard_debug.c index 6aec93f..1043e6a 100644 --- a/USB/pjrc/usb_keyboard_debug.c +++ b/USB/pjrc/usb_keyboard_debug.c @@ -135,8 +135,8 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = { }; static const uint8_t PROGMEM debug_hid_report_desc[] = { - 0x06, 0x30, 0xFF, // Usage Page 0xFF31 (vendor defined) - //0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) + //0x06, 0x30, 0xFF, // Usage Page 0xFF31 (vendor defined) + 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) 0x09, 0x74, // Usage 0x74 0xA1, 0x53, // Collection 0x53 0x75, 0x08, // report size = 8 bits diff --git a/setup.cmake b/setup.cmake index 9e710e0..5f74503 100644 --- a/setup.cmake +++ b/setup.cmake @@ -20,7 +20,7 @@ #| Please the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones ##| Deals with acquiring the keypress information and turning it into a key index -set( ScanModule "BETKB" ) +set( ScanModule "SonyOA-S3400" ) ##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code set( MacroModule "buffer" ) -- 2.39.2