- 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)simple
@@ -48,6 +48,7 @@ | |||
#include "kaypro1.h" | |||
#include "microswitch8304.h" | |||
#include "sonynews.h" | |||
#include "sonyoas3400.h" | |||
#include "tandy1000.h" | |||
#include "univacf3w9.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 | |||
@@ -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 <avr/interrupt.h> | |||
#include <avr/io.h> | |||
#include <util/delay.h> | |||
// Project Includes | |||
#include <led.h> | |||
#include <print.h> | |||
// 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; | |||
} | |||
@@ -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 <stdint.h> | |||
// 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 | |||
@@ -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 | |||
) | |||
@@ -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 |
@@ -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" ) |