- 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
#include "kaypro1.h" | #include "kaypro1.h" | ||||
#include "microswitch8304.h" | #include "microswitch8304.h" | ||||
#include "sonynews.h" | #include "sonynews.h" | ||||
#include "sonyoas3400.h" | |||||
#include "tandy1000.h" | #include "tandy1000.h" | ||||
#include "univacf3w9.h" | #include "univacf3w9.h" | ||||
/* 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 | |||||
/* 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; | |||||
} | |||||
/* 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 | |||||
###| 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 | |||||
) | |||||
}; | }; | ||||
static const uint8_t PROGMEM debug_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 | 0x09, 0x74, // Usage 0x74 | ||||
0xA1, 0x53, // Collection 0x53 | 0xA1, 0x53, // Collection 0x53 | ||||
0x75, 0x08, // report size = 8 bits | 0x75, 0x08, // report size = 8 bits |
#| Please the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones | #| 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 | ##| 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 | ##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code | ||||
set( MacroModule "buffer" ) | set( MacroModule "buffer" ) |