Browse Source

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)
simple
Jacob Alexander 12 years ago
parent
commit
65366a4e7a

+ 1
- 0
Keymap/keymap.h View File

@@ -48,6 +48,7 @@
#include "kaypro1.h"
#include "microswitch8304.h"
#include "sonynews.h"
#include "sonyoas3400.h"
#include "tandy1000.h"
#include "univacf3w9.h"


+ 552
- 0
Keymap/sonyoas3400.h View File

@@ -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


+ 531
- 0
Scan/SonyOA-S3400/scan_loop.c View File

@@ -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;
}


+ 67
- 0
Scan/SonyOA-S3400/scan_loop.h View File

@@ -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


+ 47
- 0
Scan/SonyOA-S3400/setup.cmake View File

@@ -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
)


+ 2
- 2
USB/pjrc/usb_keyboard_debug.c View File

@@ -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

+ 1
- 1
setup.cmake View File

@@ -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" )