Browse Source

Tandy 1000 Converter, basicly works, except for packet mismatches

- Caused by too much processing in the converter...
- Easy to fix if I remove the macro engine...
simple
Jacob Alexander 12 years ago
parent
commit
46916defa5

+ 2
- 2
Debug/led/led.c View File

@@ -31,14 +31,14 @@
// ----- Functions -----

// Error LED Setup
void init_errorLED()
inline void init_errorLED()
{
// Use pin D6 as an output (LED)
DDRD |= (1<<6);
}

// Error LED Control
void errorLED( uint8_t on )
inline void errorLED( uint8_t on )
{
// Error LED On (D6)
if ( on ) {

+ 198
- 6
Keymap/keymap.h View File

@@ -30,16 +30,208 @@

// ----- Defines -----

// Modifier Mask
#define MODIFIERS_KEYPAD 0
#define MODIFIERS_KEYBOARD 4



// ----- Variables -----

static uint8_t tandy1000_modifierMask[] = { 0x1D, 0x2A, 0x36, 0x38, 0x46 };

/*
static uint8_t tandy1000_map[] = { 0,
KEY_ESC,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_0,
KEY_MINUS,
KEY_EQUAL,
KEY_BACKSPACE,
KEY_TAB,
KEY_Q,
KEY_W,
KEY_E,
KEY_R,
KEY_T,
KEY_Y,
KEY_U,
KEY_I,
KEY_O,
KEY_P,
KEY_LEFT_BRACE,
KEY_RIGHT_BRACE,
KEY_ENTER,
KEY_CTRL, // 0x1D
KEY_A,
KEY_S,
KEY_D,
KEY_F,
KEY_G,
KEY_H,
KEY_J,
KEY_K,
KEY_L,
KEY_SEMICOLON,
KEY_QUOTE,
KEY_UP,
KEY_LEFT_SHIFT, // 0x2A
KEY_LEFT,
KEY_Z,
KEY_X,
KEY_C,
KEY_V,
KEY_B,
KEY_N,
KEY_M,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_RIGHT_SHIFT, // 0x36
KEY_PRINTSCREEN,
KEY_ALT, // 0x38
KEY_SPACE,
KEY_CAPS_LOCK,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_NUM_LOCK,
KEY_GUI, // Actually Hold... 0x48
KEY_BACKSLASH, // Also KEYPAD_7
KEY_TILDE, // Also KEYPAD_8
KEYPAD_9,
KEY_UP,
KEY_BACKSLASH, // Actually | and KEYPAD_4
KEYPAD_5,
KEYPAD_6,
KEY_RIGHT,
KEYPAD_1,
KEY_TILDE, // Actually ` and KEYPAD_2
KEYPAD_3,
KEYPAD_0,
KEY_DELETE,
KEY_PAUSE,
KEY_INSERT,
KEYPAD_PERIOD,
KEYPAD_ENTER,
KEY_HOME,
KEY_F11,
KEY_F12, // 0x5A
};
*/

static uint8_t tandy1000_colemak[] = { 0,
KEY_ESC,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_0,
KEY_MINUS,
KEY_EQUAL,
KEY_BACKSPACE,
KEY_TAB,
KEY_Q,
KEY_W,
KEY_F,
KEY_P,
KEY_G,
KEY_J,
KEY_L,
KEY_U,
KEY_Y,
KEY_SEMICOLON,
KEY_LEFT_BRACE,
KEY_RIGHT_BRACE,
KEY_ENTER,
KEY_CTRL, // 0x1D
KEY_A,
KEY_R,
KEY_S,
KEY_T,
KEY_D,
KEY_H,
KEY_N,
KEY_E,
KEY_I,
KEY_O,
KEY_QUOTE,
KEY_UP,
KEY_LEFT_SHIFT, // 0x2A
KEY_LEFT,
KEY_Z,
KEY_X,
KEY_C,
KEY_V,
KEY_B,
KEY_K,
KEY_M,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_RIGHT_SHIFT, // 0x36
KEY_PRINTSCREEN,
KEY_ALT, // 0x38
KEY_SPACE,
0, //KEY_CAPS_LOCK,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
0, //KEY_NUM_LOCK,
KEY_GUI, // Actually Hold... 0x48
KEY_BACKSLASH, // Also KEYPAD_7
KEY_TILDE, // Also KEYPAD_8
KEYPAD_9,
KEY_DOWN,
KEY_BACKSLASH, // Actually | and KEYPAD_4
KEYPAD_5,
KEYPAD_6,
KEY_RIGHT,
KEYPAD_1,
KEY_TILDE, // Actually ` and KEYPAD_2
KEYPAD_3,
KEYPAD_0,
KEY_DELETE,
KEY_PAUSE,
KEY_INSERT,
KEYPAD_PERIOD,
KEYPAD_ENTER,
KEY_HOME,
KEY_F11,
KEY_F12, // 0x5A
};







//static uint8_t keypad_modifierMask[] = {};
static uint8_t keyboard_modifierMask[] = { 1, 17, 33, 49 };
//static uint8_t keyboard_modifierMask[] = { 1, 17, 33, 49 };
//static uint8_t alternate_modifierMask[] = { 1, 17, 33, 49, 62 };

// Default 1-indexed key mappings
@@ -61,7 +253,6 @@ static uint8_t keypadDefaultMap[] = { 0,
KEYPAD_0,
KEYPAD_PERIOD,
KEYPAD_PLUS };
*/
static uint8_t defaultMap[] = { 0,
KEY_GUI,
KEY_1,
@@ -126,6 +317,7 @@ static uint8_t defaultMap[] = { 0,
KEY_LEFT,
KEY_RIGHT,
KEY_SPACE };
*/
/*
static uint8_t navigationMap[] = { 0,
KEY_GUI,

+ 26
- 14
Macro/basic/macro.c View File

@@ -24,6 +24,7 @@
// AVR Includes

// Project Includes
#include <led.h>
#include <print.h>
#include <scan_loop.h>
#include <usb_com.h>
@@ -41,11 +42,17 @@

// Given a sampling array, and the current number of detected keypress
// Add as many keypresses from the sampling array to the USB key send array as possible.
void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map )
void keyPressDetection( uint8_t *keys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map )
//void keyPressDetection( uint8_t *keys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map )
{
for ( uint8_t key = 0; key < numberOfKeys + 1; key++ ) {
if ( keys[key] & (1 << 7) ) {
// TODO Debug Out
USBKeys_Sent = 0;

for ( uint8_t key = 1; key < numberOfKeys + 1; key++ )
//for ( uint8_t key = 0; key < numberOfKeys + 1; key++ )
{
//if ( keys[key] & (1 << 7) )
if ( keys[key] )
{
uint8_t modFound = 0;

// Determine if the key is a modifier
@@ -57,30 +64,35 @@ void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys,
break;
}
}

// Modifier, already done this loop
if ( modFound )
continue;

// Too many keys
if ( *validKeys >= USBKeys_MaxSize )
if ( USBKeys_Sent >= USBKeys_MaxSize )
{
info_print("USB Key limit reached");
errorLED( 1 );
break;
}

// Allow ignoring keys with 0's
if ( map[key] != 0 )
USBKeys_Array[(*validKeys)++] = map[key];
USBKeys_Array[USBKeys_Sent++] = map[key];

/*
char tmpStr[3];
hexToStr_op( USBKeys_Array[0], tmpStr, 2 );
warn_dPrint("Found key: 0x", tmpStr );
*/
}
}
}

void process_macros(void)
{
// Layout Setup
uint8_t validKeys = 0;

uint8_t *keyboard_MODMASK = keyboard_modifierMask;
uint8_t keyboard_NUMMODS = MODIFIERS_KEYBOARD;
uint8_t *keyboard_MAP = defaultMap;

// Debounce Sampling Array to USB Data Array
keyPressDetection( KeyIndex_Array, &validKeys, KeyIndex_Size, keyboard_MODMASK, keyboard_NUMMODS, keyboard_MAP );
keyPressDetection( KeyIndex_Array, KeyIndex_Size, MODIFIER_MASK, sizeof(MODIFIER_MASK), KEYINDEX_MASK );
}


+ 1
- 1
Macro/basic/macro.h View File

@@ -31,7 +31,7 @@

// ----- Functions -----

void keyPressDetection( uint8_t *keys, uint8_t *validKeys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map );
void keyPressDetection( uint8_t *keys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map );
void process_macros(void);

#endif

+ 239
- 0
Scan/Tandy1000/scan_loop.c View File

@@ -0,0 +1,239 @@
/* Copyright (C) 2011 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>

// Project Includes
#include <led.h>
#include <print.h>

// Local Includes
#include "scan_loop.h"



// ----- Defines -----

// Pinout Defines
#define CLK_READ PIND
#define CLK_PORT PORTD
#define CLK_DDR DDRD
#define CLK_PIN 1

#define DATA_READ PIND
#define DATA_PORT PORTD
#define DATA_DDR DDRD
#define DATA_PIN 0

#define INTR_PORT PORTD
#define INTR_DDR DDRD
#define INTR_PIN 0



// ----- Macros -----
#define READ_CLK CLK_READ & (1 << CLK_PIN) ? 1 : 0
#define READ_DATA DATA_READ & (1 << DATA_PIN) ? 0 : 1

#define UNSET_INTR() INTR_DDR &= ~(1 << INTR_PIN)
#define SET_INTR() INTR_DDR |= (1 << INTR_PIN)



// ----- Variables -----

uint8_t KeyIndex_Array[KEYBOARD_SIZE + 1];

// Scan Code Retrieval Variables
uint8_t inputData = 0xFF;
uint8_t packet_index = 0;



// ----- Functions -----

// Setup
inline void scan_setup()
{
// Setup inputs
CLK_DDR &= ~(1 << CLK_PIN);
DATA_DDR &= ~(1 << DATA_PIN);

// Setup Pull-up's
CLK_PORT &= ~(1 << CLK_PIN); // (CLK)
DATA_PORT &= ~(1 << DATA_PIN); // (/DATA)

// Setup Keyboard Interrupt
INTR_DDR &= ~(1 << INTR_PIN);
INTR_PORT &= ~(1 << INTR_PIN);

/* Interrupt Style (Not working fully)
cli();
// Setup interrupt on the CLK pin TODO Better defines
EICRA |= 0x03; // Rising Edge Interrupt
EIMSK |= (1 << INT0);

// Setup interrupt on the DATA pin TODO Better defines
EICRA |= 0x08; // Falling Edge Interrupt
EIMSK |= (1 << INT1);
sei();
*/
}


// Main Detection Loop
inline uint8_t scan_loop()
{
/*
// Packet Read
if ( packet_index == 8 )
{
// Disable Error LED, proper key found
errorLED( 0 );

//#ifdef MAX_DEBUG
// Crazy Debug (Read the Scan Code)
char tmpStr[3];
hexToStr_op( inputData, tmpStr, 2 );
dPrintStrsNL( "Read Data: 0x", tmpStr );
//#endif
// - Map the scan code to the index array -
// If the 8th bit is high, remove the keypress, else, add the keypress
// The lower 7 bits are the array index
KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;

// Reset Containers
packet_index = 0;
inputData = 0xFF;
}
// Bad Packet
else if ( packet_index > 8 )
{
// Signal Error
errorLED( 1 );

char tmpStr[3];
int8ToStr( packet_index, tmpStr );
erro_dPrint( "Big packet? Mismatched... ", tmpStr );

packet_index = 0;
inputData = 0xFF;
}
*/

// Disable keyboard interrupt (does nothing if already off)
UNSET_INTR();

// Read the clock 8 times
if ( READ_CLK )
{
// Mis-read packet, set back to 0
if ( packet_index == -1 )
packet_index = 0;

// Append 1 bit of data
inputData &= ~(READ_DATA << packet_index);
packet_index++;

// 8 Bits have been read
if ( packet_index == 8 )
{
// Wait till clock edge falls
while ( READ_CLK );

// Sample both lines to make sure this is not a data value
// and definitely the end of packet data blip
uint16_t badDataCounter = 0;
while ( !( READ_DATA ) && !( READ_CLK ) )
badDataCounter++;

if ( badDataCounter < 25 )
{
//#ifdef MAX_DEBUG
// Crazy Debug (Read the Scan Code)
char tmpStr[3];
hexToStr_op( inputData, tmpStr, 2 );
dbug_dPrint( "Read Data: 0x", tmpStr );
//#endif
// - Map the scan code to the index array -
// If the 8th bit is high, remove the keypress, else, add the keypress
// The lower 7 bits are the array index
KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
}
// Even though this is a mis-read packet, we still know what the value is
else
{
// Signal Error
errorLED( 1 );
char tmpStr[3];
hexToStr_op( inputData, tmpStr, 2 );
erro_dPrint( "Bad packet? Mismatched... 0x", tmpStr );
}

// Reset Containers
inputData = 0xFF;
packet_index = 0;

// Interrupt the keyboard, so we don't get packet pieces...
SET_INTR();

// Do not wait for next clock, let USB do it's thing (if desired)
return packet_index;
}

// Wait till clock edge falls
while ( READ_CLK );
}

// Interrupt keyboard if there is no pending packet
SET_INTR();

return packet_index;
}

// Detection interrupt, signalled by a clock pulse from CLK_PIN
ISR(INT0_vect)
{
//cli(); // Disable Interrupts

// Append 1 bit of data
//inputData &= ~(READ_DATA << packet_index);
packet_index++;

//sei(); // Re-enable Interrupts
}

// Data Detected
ISR(INT1_vect)
{
// Append 1 bit of data
inputData &= ~(1 << packet_index);
packet_index++;

// Disable Clk Signal (Not needed if there's a data signal)
EIFR |= (1 << INTF0);
}




+ 55
- 0
Scan/Tandy1000/scan_loop.h View File

@@ -0,0 +1,55 @@
/* Copyright (C) 2011 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 0x5A // 90 - Size of the array space for the keyboardr(max index)



// ----- Variables -----

// NOTE: Highest Bit: Valid keypress (0x80 is valid keypress)
// Other Bits: Pressed state sample counter
extern uint8_t KeyIndex_Array [KEYBOARD_SIZE + 1];
static const uint8_t KeyIndex_Size = KEYBOARD_SIZE;



// ----- Functions -----

void scan_setup( void );
uint8_t scan_loop( void );

#endif // __SCAN_LOOP_H


+ 29
- 0
Scan/Tandy1000/setup.cmake View File

@@ -0,0 +1,29 @@
###| CMake Kiibohd Controller Scan Module |###
#
# Written by Jacob Alexander in 2011 for the Kiibohd Controller
#
# Released into the Public Domain
#
###


###
# Module C files
#

set( SCAN_SRCS
scan_loop.c
)


###
# Module Specific Options
#
add_definitions( -I${HEAD_DIR}/Keymap )

#| Keymap Settings
add_definitions(
-DMODIFIER_MASK=tandy1000_modifierMask
-DKEYINDEX_MASK=tandy1000_colemak
)


+ 6
- 2
Scan/matrix/scan_loop.c View File

@@ -55,11 +55,15 @@ uint8_t scan_count = 0;

// ----- Functions -----

// Main Detection Loop
void scan_loop()
// Setup
void scan_setup()
{
//matrix_pinSetup( matrix_pinout );
}

// Main Detection Loop
void scan_loop()
{
//matrix_scan( matrix_pinout, keyboardDetectArray );

// Check count to see if the sample threshold may have been reached, otherwise collect more data

+ 1
- 0
Scan/matrix/scan_loop.h View File

@@ -31,6 +31,7 @@

// ----- Functions -----

void scan_setup( void );
void scan_loop( void );

#endif // __SCAN_LOOP_H

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

@@ -55,7 +55,7 @@ volatile uint8_t USBKeys_LEDs = 0;
// ----- Functions -----

// USB Module Setup
void usb_setup(void)
inline void usb_setup(void)
{
// Initialize the USB, and then wait for the host to set configuration.
// If the Teensy is powered without a PC connected to the USB port,
@@ -70,7 +70,7 @@ void usb_setup(void)


// USB Data Send
void usb_send(void)
inline void usb_send(void)
{
// TODO undo potentially old keys
for ( uint8_t c = USBKeys_Sent; c < USBKeys_MaxSize; c++ )

+ 10
- 1
main.c View File

@@ -102,10 +102,16 @@ int main(void)
uint8_t ledTimer = 15; // Enable LED for a short time
while ( 1 )
{
// Setup the scanning module
scan_setup();

while ( 1 )
{
// Acquire Key Indices
scan_loop();
// Loop continuously until scan_loop returns 0
cli();
while ( scan_loop() );
sei();

// Send keypresses over USB if the ISR has signalled that it's time
if ( !sendKeypresses )
@@ -122,6 +128,9 @@ int main(void)

// Indicate Error, if valid
errorLED( ledTimer );

if ( ledTimer > 0 )
ledTimer--;
}

// Loop should never get here (indicate error)

+ 9
- 5
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 "matrix" )
set( ScanModule "Tandy1000" )

##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code
set( MacroModule "basic" )
@@ -104,8 +104,12 @@ PathPrepend( DEBUG_SRCS ${DebugModulePath} ${DEBUG_SRCS} )


#| Print list of all module sources
message( STATUS "Detected Scan Module Source Files: \n${SCAN_SRCS}")
message( STATUS "Detected Macro Module Source Files:\n${MACRO_SRCS}")
message( STATUS "Detected USB Module Source Files: \n${USB_SRCS}")
message( STATUS "Detected Debug Module Source Files:\n${DEBUG_SRCS}")
message( STATUS "Detected Scan Module Source Files:" )
message( "${SCAN_SRCS}" )
message( STATUS "Detected Macro Module Source Files:" )
message( "${MACRO_SRCS}" )
message( STATUS "Detected USB Module Source Files:" )
message( "${USB_SRCS}" )
message( STATUS "Detected Debug Module Source Files:" )
message( "${DEBUG_SRCS}" )