]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Adding inital outline for Univac-Sperry F3W9 keyboard.
authorJacob Alexander <triplehaata@gmail.com>
Sun, 4 Mar 2012 02:16:41 +0000 (21:16 -0500)
committerJacob Alexander <triplehaata@gmail.com>
Sun, 4 Mar 2012 02:16:41 +0000 (21:16 -0500)
- Not tested yet
- Packet size is large so it's not possible to use Teensy hardware

CMakeLists.txt
Keymap/keymap.h
Keymap/univacf3w9.h [new file with mode: 0644]
Scan/UnivacF3W9/scan_loop.c [new file with mode: 0644]
Scan/UnivacF3W9/scan_loop.h [new file with mode: 0644]
Scan/UnivacF3W9/setup.cmake [new file with mode: 0644]
USB/pjrc/usb_keyboard_debug.c
setup.cmake

index 9b4e935b2efa776ca3bc56a2f842a84474c7792c..44b914121d507cfc581458ca7d12e5668f015477 100644 (file)
@@ -64,8 +64,8 @@ set( SRCS
 #| "atmega32u4"       # Teensy   2.0
 #| "at90usb646"       # Teensy++ 1.0
 #| "at90usb1286"      # Teensy++ 2.0
-set( MCU "atmega32u4" )
-#set( MCU "at90usb1286" )
+#set( MCU "atmega32u4" )
+set( MCU "at90usb1286" )
 
 
 #| Compiler flag to set the C Standard level.
index 113712648ad084597d0d758bd8caa467f707871f..c479644ff96d5fd5023f33d5aaf31c91922fc7f2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 by Jacob Alexander
+/* Copyright (C) 2011-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
@@ -48,6 +48,7 @@
 #include "microswitch8304.h"
 #include "sonynews.h"
 #include "tandy1000.h"
+#include "univacf3w9.h"
 
 
 
diff --git a/Keymap/univacf3w9.h b/Keymap/univacf3w9.h
new file mode 100644 (file)
index 0000000..be7df6e
--- /dev/null
@@ -0,0 +1,329 @@
+/* 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 __UNIVACF3W9_H
+#define __UNIVACF3W9_H
+
+// This file contains various key layouts for the Univac F3W9 keyboard
+
+
+
+// ----- Variables -----
+static uint8_t univacf3w9_ModifierMask[] = { 0x81, 0x83, 0x85, 0x87, 0x89, 0x8B, 0x8D, 0x8F };
+
+static uint8_t univacf3w9_DefaultMap[] = { 
+                               0x00, // 0x00
+                               KEY_F4, // 0x01
+                               0, // 0x02
+                               KEY_F5, // 0x03
+                               KEY_F6, // 0x04
+                               KEY_F7, // 0x05
+                               KEY_F8, // 0x06
+                               KEY_F9, // 0x07
+                               0, // 0x08
+                               KEY_F10, // 0x09
+                               KEY_F11, // 0x0A
+                               KEY_F12, // 0x0B
+                               KEY_F13, // 0x0C
+                               0, // 0x0D
+                               KEY_F14, // 0x0E
+                               KEY_F15, // 0x0F
+                               0, // 0x10
+                               0, // 0x11
+                               0, // 0x12
+                               0, // 0x13
+                               0, // 0x14
+                               KEYPAD_ENTER, // 0x15
+                               KEYPAD_PERIOD, // 0x16
+                               KEYPAD_0, // 0x17
+                               KEYPAD_EQUAL, // 0x18
+                               KEYPAD_6, // 0x19
+                               KEYPAD_5, // 0x1A
+                               KEYPAD_4, // 0x1B
+                               0, // 0x1C
+                               0, // 0x1D
+                               KEY_F17, // 0x1E
+                               KEY_F16, // 0x1F
+                               0, // 0x20
+                               0, // 0x21
+                               0, // 0x22
+                               0, // 0x23
+                               0, // 0x24
+                               KEYPAD_3, // 0x25
+                               KEYPAD_2, // 0x26
+                               KEYPAD_1, // 0x27
+                               KEYPAD_PLUS, // 0x28
+                               KEYPAD_9, // 0x29
+                               KEYPAD_8, // 0x2A
+                               KEYPAD_7, // 0x2B
+                               KEYPAD_MINUS, // 0x2C
+                               KEYPAD_ASTERIX, // 0x2D
+                               KEYPAD_SLASH, // 0x2E
+                               KEY_NUM_LOCK, // 0x2F
+                               0, // 0x30
+                               0, // 0x31
+                               KEY_SPACE, // 0x32
+                               KEY_Z, // 0x33
+                               KEY_X, // 0x34
+                               KEY_C, // 0x35
+                               KEY_V, // 0x36
+                               KEY_B, // 0x37
+                               KEY_N, // 0x38
+                               KEY_M, // 0x39
+                               KEY_COMMA, // 0x3A
+                               KEY_PERIOD, // 0x3B
+                               KEY_UP, // 0x3C
+                               KEY_LEFT, // 0x3D
+                               KEY_RIGHT, // 0x3E
+                               KEY_DOWN, // 0x3F
+                               0, // 0x40
+                               KEY_F19, // 0x41
+                               KEY_CAPS_LOCK, // 0x42
+                               KEY_A, // 0x43
+                               KEY_S, // 0x44
+                               KEY_D, // 0x45
+                               KEY_F, // 0x46
+                               KEY_G, // 0x47
+                               KEY_H, // 0x48
+                               KEY_J, // 0x49
+                               KEY_K, // 0x4A
+                               KEY_L, // 0x4B
+                               KEY_SEMICOLON, // 0x4C
+                               KEY_QUOTE, // 0x4D
+                               KEY_ENTER, // 0x4E
+                               KEY_SLASH, // 0x4F
+                               0, // 0x50
+                               KEY_Q, // 0x51
+                               KEY_W, // 0x52
+                               KEY_E, // 0x53
+                               KEY_R, // 0x54
+                               KEY_T, // 0x55
+                               KEY_Y, // 0x56
+                               KEY_U, // 0x57
+                               KEY_I, // 0x58
+                               KEY_O, // 0x59
+                               KEY_P, // 0x5A
+                               KEY_LEFT_BRACE, // 0x5B
+                               KEY_RIGHT_BRACE, // 0x5C
+                               KEY_BACKSLASH, // 0x5D
+                               KEY_INSERT, // 0x5E
+                               KEY_PAGE_DOWN, // 0x5F
+                               0, // 0x60
+                               KEY_2, // 0x61
+                               KEY_3, // 0x62
+                               KEY_4, // 0x63
+                               KEY_5, // 0x64
+                               KEY_6, // 0x65
+                               KEY_7, // 0x66
+                               KEY_8, // 0x67
+                               KEY_9, // 0x68
+                               KEY_0, // 0x69
+                               KEY_MINUS, // 0x6A
+                               KEY_EQUAL, // 0x6B
+                               KEY_TILDE, // 0x6C
+                               KEY_BACKSPACE, // 0x6D
+                               KEY_DELETE, // 0x6E
+                               KEY_PAGE_UP, // 0x6F
+                               0, // 0x70
+                               KEY_F3, // 0x71
+                               KEY_F2, // 0x72
+                               KEY_F1, // 0x73
+                               KEY_F18, // 0x74
+                               KEY_ESC, // 0x75
+                               KEY_1, // 0x76
+                               KEY_TAB, // 0x77
+                               KEY_F19, // 0x78
+                               0, // 0x79
+                               0, // 0x7A
+                               0, // 0x7B
+                               0, // 0x7C
+                               0, // 0x7D
+                               0, // 0x7E
+                               0, // 0x7F
+                               0, // 0x80
+                               0, // 0x81
+                               0, // 0x82
+                               0, // 0x83
+                               0, // 0x84
+                               KEY_RIGHT_SHIFT, // 0x85
+                               0, // 0x86
+                               KEY_LEFT_SHIFT, // 0x87
+                               0, // 0x88
+                               0, // 0x89
+                               0, // 0x8A
+                               KEY_LEFT_CTRL, // 0x8B
+                               0, // 0x8C
+                               KEY_GUI, // 0x8D
+                               0, // 0x8E
+                               KEY_RIGHT_CTRL, // 0x8F
+};
+
+static uint8_t univacf3w9_ColemakMap[] = {
+                               0x00, // 0x00
+                               KEY_F4, // 0x01
+                               0, // 0x02
+                               KEY_F5, // 0x03
+                               KEY_F6, // 0x04
+                               KEY_F7, // 0x05
+                               KEY_F8, // 0x06
+                               KEY_F9, // 0x07
+                               0, // 0x08
+                               KEY_F10, // 0x09
+                               KEY_F11, // 0x0A
+                               KEY_F12, // 0x0B
+                               KEY_F13, // 0x0C
+                               0, // 0x0D
+                               KEY_F14, // 0x0E
+                               KEY_F15, // 0x0F
+                               0, // 0x10
+                               0, // 0x11
+                               0, // 0x12
+                               0, // 0x13
+                               0, // 0x14
+                               KEYPAD_ENTER, // 0x15
+                               KEYPAD_PERIOD, // 0x16
+                               KEYPAD_0, // 0x17
+                               KEYPAD_EQUAL, // 0x18
+                               KEYPAD_6, // 0x19
+                               KEYPAD_5, // 0x1A
+                               KEYPAD_4, // 0x1B
+                               0, // 0x1C
+                               0, // 0x1D
+                               KEY_F17, // 0x1E
+                               KEY_F16, // 0x1F
+                               0, // 0x20
+                               0, // 0x21
+                               0, // 0x22
+                               0, // 0x23
+                               0, // 0x24
+                               KEYPAD_3, // 0x25
+                               KEYPAD_2, // 0x26
+                               KEYPAD_1, // 0x27
+                               KEYPAD_PLUS, // 0x28
+                               KEYPAD_9, // 0x29
+                               KEYPAD_8, // 0x2A
+                               KEYPAD_7, // 0x2B
+                               KEYPAD_MINUS, // 0x2C
+                               KEYPAD_ASTERIX, // 0x2D
+                               KEYPAD_SLASH, // 0x2E
+                               KEY_NUM_LOCK, // 0x2F
+                               0, // 0x30
+                               0, // 0x31
+                               KEY_SPACE, // 0x32
+                               KEY_Z, // 0x33
+                               KEY_X, // 0x34
+                               KEY_C, // 0x35
+                               KEY_V, // 0x36
+                               KEY_B, // 0x37
+                               KEY_K, // 0x38
+                               KEY_M, // 0x39
+                               KEY_COMMA, // 0x3A
+                               KEY_PERIOD, // 0x3B
+                               KEY_UP, // 0x3C
+                               KEY_LEFT, // 0x3D
+                               KEY_RIGHT, // 0x3E
+                               KEY_DOWN, // 0x3F
+                               0, // 0x40
+                               KEY_F19, // 0x41
+                               KEY_CAPS_LOCK, // 0x42
+                               KEY_A, // 0x43
+                               KEY_R, // 0x44
+                               KEY_S, // 0x45
+                               KEY_T, // 0x46
+                               KEY_D, // 0x47
+                               KEY_H, // 0x48
+                               KEY_N, // 0x49
+                               KEY_E, // 0x4A
+                               KEY_I, // 0x4B
+                               KEY_O, // 0x4C
+                               KEY_QUOTE, // 0x4D
+                               KEY_ENTER, // 0x4E
+                               KEY_SLASH, // 0x4F
+                               0, // 0x50
+                               KEY_Q, // 0x51
+                               KEY_W, // 0x52
+                               KEY_F, // 0x53
+                               KEY_P, // 0x54
+                               KEY_G, // 0x55
+                               KEY_J, // 0x56
+                               KEY_L, // 0x57
+                               KEY_U, // 0x58
+                               KEY_Y, // 0x59
+                               KEY_SEMICOLON, // 0x5A
+                               KEY_LEFT_BRACE, // 0x5B
+                               KEY_RIGHT_BRACE, // 0x5C
+                               KEY_BACKSLASH, // 0x5D
+                               KEY_INSERT, // 0x5E
+                               KEY_PAGE_DOWN, // 0x5F
+                               0, // 0x60
+                               KEY_2, // 0x61
+                               KEY_3, // 0x62
+                               KEY_4, // 0x63
+                               KEY_5, // 0x64
+                               KEY_6, // 0x65
+                               KEY_7, // 0x66
+                               KEY_8, // 0x67
+                               KEY_9, // 0x68
+                               KEY_0, // 0x69
+                               KEY_MINUS, // 0x6A
+                               KEY_EQUAL, // 0x6B
+                               KEY_TILDE, // 0x6C
+                               KEY_BACKSPACE, // 0x6D
+                               KEY_DELETE, // 0x6E
+                               KEY_PAGE_UP, // 0x6F
+                               0, // 0x70
+                               KEY_F3, // 0x71
+                               KEY_F2, // 0x72
+                               KEY_F1, // 0x73
+                               KEY_F18, // 0x74
+                               KEY_ESC, // 0x75
+                               KEY_1, // 0x76
+                               KEY_TAB, // 0x77
+                               KEY_F19, // 0x78
+                               0, // 0x79
+                               0, // 0x7A
+                               0, // 0x7B
+                               0, // 0x7C
+                               0, // 0x7D
+                               0, // 0x7E
+                               0, // 0x7F
+                               0, // 0x80
+                               0, // 0x81
+                               0, // 0x82
+                               0, // 0x83
+                               0, // 0x84
+                               KEY_RIGHT_SHIFT, // 0x85
+                               0, // 0x86
+                               KEY_LEFT_SHIFT, // 0x87
+                               0, // 0x88
+                               0, // 0x89
+                               0, // 0x8A
+                               KEY_LEFT_CTRL, // 0x8B
+                               0, // 0x8C
+                               KEY_GUI, // 0x8D
+                               0, // 0x8E
+                               KEY_ALT, // 0x8F
+};
+
+
+
+#endif
+
diff --git a/Scan/UnivacF3W9/scan_loop.c b/Scan/UnivacF3W9/scan_loop.c
new file mode 100644 (file)
index 0000000..ad78e92
--- /dev/null
@@ -0,0 +1,371 @@
+/* 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
+#define REQUEST_PORT PORTD
+#define REQUEST_DDR  DDRD
+#define REQUEST_PIN  3
+#define DATA_READ    PIND
+#define DATA_PORT    PORTD
+#define DATA_DDR     DDRD
+#define DATA_PIN     2
+
+#define MAX_SAMPLES    10
+#define MAX_FAILURES   3731
+#define PACKET_STORAGE 24   // At worst only 8 packets, but with you keypresses you can get more
+
+
+// ----- Macros -----
+
+#define READ_DATA         DATA_READ &   (1 << DATA_PIN) ? 0 : 1
+
+#define REQUEST_DATA()  REQUEST_DDR &= ~(1 << REQUEST_PIN) // Start incoming keyboard transfer
+#define    STOP_DATA()  REQUEST_DDR |=  (1 << REQUEST_PIN) // Stop incoming keyboard data
+
+// 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;
+
+
+
+// ----- Function Declarations -----
+
+void processPacketValue( uint16_t packetValue );
+
+
+
+// ----- Interrupt Functions -----
+
+// XXX - None Required
+
+
+
+// ----- Functions -----
+
+// Setup
+// This setup is very simple, as there is no extra hardware used in this scan module, other than GPIOs.
+// To be nice, we wait a little bit after powering on, and dump any of the pending keyboard data.
+// Afterwards (as long as no keys were being held), the keyboard should have a clean buffer, and be ready to go.
+// (Even if keys were held down, everything should probably still work...)
+inline void scan_setup()
+{
+       // Setup the DATA pin
+       DATA_DDR  &= ~(1 << DATA_PIN); // Set to input
+       DATA_PORT |=  (1 << DATA_PIN); // Set to pull-up resistor
+
+       // Setup the REQUEST pin
+       REQUEST_DDR |= (1 << REQUEST_PIN); // Set to output
+       STOP_DATA(); // Set the line high to stop incoming data
+
+       // Reset the keyboard before scanning, we might be in a wierd state
+       _delay_ms( 50 );
+       scan_resetKeyboard();
+}
+
+
+// Main Detection Loop
+// The Univac-Sperry F3W9 has a convenient feature, an internal 8 key buffer
+// This buffer is only emptied (i.e. sent over the bus) when the REQUEST line is held high
+// Because of this, we can utilize the scan_loop to do all of the critical processing,
+//  without having to resort to interrupts, giving the data reading 100% of the CPU.
+// This is because the USB interrupts can wait until the scan_loop is finished to continue.
+//
+// Normally, this approach isn't taken, as it's easier/faster/safer to use Teensy hardware shift registers
+//  for serial data transfers.
+// However, since the Univac-Sperry F3W9 sends 20 bit packets (including the start bit), the Teensy
+//  doesn't have a shift register large enough (9 bit max), to hold the data.
+// So the line must be polled manually using CPU cycles
+//
+// Another interesting feature is that there are 2 data lines.
+// Output and /Output (NOT'ted version).
+// Not really useful here, but could be used for error checking, or eliminating an external NOT gate if
+//  we were using (but can't...) a hardware decoder like a USART.
+inline uint8_t scan_loop()
+{
+       // Protocol Notes:
+       // - Packets are 20 bits long, including the start bit
+       // - Each bit is ~105 usecs in length
+       // - Thus the average packet length is 2.205 msecs
+       // - Each packet is separated by at least 240 usecs (during a buffer unload)
+       // - While holding the key down, each packet has a space of about 910 usecs
+       // - A max of 8 keys can be sent at once (note, the arrow keys seem use 2 packets each, and thus take up twice as much buffer)
+       // - There is no timing danger for holding the request line, just that data may come in when you don't want it
+
+       // Now that the scan loop has been entered, we don't have to worry about interrupts stealing
+       //  precious cycles.
+       REQUEST_DATA();
+
+       // = Delays =
+       //
+       // For these calculations to work out properly, then Teensy should be running at 16 MHz
+       // - 1 bit         : 105   usecs is 16 000 000 * 0.000105  =   1680 instructions
+       // - Bit centering :  52.5 usecs is 16 000 000 * 0.0000525 =    840 instructions
+       // - Delay         :   5   msecs is 16 000 000 * 0.005     = 80 000 instructions
+       // - Microsecond   :   1   usec  is 16 000 000 * 0.000001  =     16 instructions
+       //
+       // Now, either I can follow these exactly, or based upon the fact that I have >840 tries to find the
+       //  the start bit, and >1680 tries to read the subsequent bits, I have some "flex" time.
+       // Knowing this, I can make some assumptions that because I'm only reading a total of 20 bits, and will
+       //  be re-centering for each packet.
+       // This will allow for less worrying about compiler optimizations (and porting!).
+
+       // The basic idea is to find a "reliable" value for the start bit, e.g. read it ~10 times.
+       // Using a for-loop and some addition counters, this should eat up approximately 20-30 instructions per read
+       //  (very loose estimation).
+       // So reading 10 * 30 instructions = 300 instructions, which is much less than 840 instructions to where the
+       //  bit center is, but is close enough that further delays of ~>1680 instructions will put the next read
+       //  within the next bit period.
+       // This is all possible because interrupts are disabled at this point, otherwise, all of this reasoning
+       //  would fall apart.
+       // _delay_us is available to use, fortunately.
+
+       // Input Packet Storage (before being processed)
+       uint16_t incomingPacket[PACKET_STORAGE];
+       uint8_t  numberOfIncomingPackets = 0;
+
+       // Sample the data line for ~5 ms, looking for a start bit
+       //  - Sampling every 1 usecs, looking for 10 good samples
+       //  - Accumulated samples will dumped if a high is detected
+       uint8_t  samples  = 0;
+       uint16_t failures = 0;
+
+       // Continue waiting for a start bit until MAX_FAILURES has been reached (~5ms of nothing)
+       while ( failures <= MAX_FAILURES )
+       {
+               // Attempt to find the start bit
+               while ( samples < MAX_SAMPLES )
+               {
+                       // Delay first
+                       _delay_us( 1 );
+
+                       // If data is valid, increment
+                       if ( READ_DATA )
+                       {
+                               samples++;
+                       }
+                       // Reset
+                       else
+                       {
+                               samples = 0;
+                               failures++;
+
+                               // After ~5ms of failures, break the loop
+                               // Each failure is approx 5 instructions + 1 usec, or approximately 1.34 usec)
+                               // So ~3731 failures for ~5ms
+                               // Being exact doesn't matter, as this is just to let the other parts of the
+                               //  controller do some processing
+                               if ( failures > MAX_FAILURES )
+                                       break;
+                       }
+               }
+
+               // If 10 valid samples of the start bit were obtained, 
+               if ( samples >= MAX_SAMPLES )
+               {
+                       // Clean out the old packet memory
+                       incomingPacket[numberOfIncomingPackets] = 0;
+
+                       // Read the next 19 bits into memory (bit 0 is the start bit, which is always 0)
+                       for ( uint8_t c = 1; c < 20; c++ )
+                       {
+                               // Wait until the middle of the next bit
+                               _delay_us( 105 );
+
+                               // Append the current bit value
+                               incomingPacket[numberOfIncomingPackets] |= (READ_DATA << c);
+                       }
+
+                       // Packet finished, increment counter
+                       numberOfIncomingPackets++;
+               }
+       }
+
+       // Stop the keyboard input
+       STOP_DATA();
+
+       // Finished receiving data from keyboard, start packet processing
+       for ( uint8_t packet = 0; packet < numberOfIncomingPackets; packet++ )
+               processPacketValue( incomingPacket[packet] );
+
+       return 0;
+}
+
+// Read in the Packet Data, and decide what to do with it
+void processPacketValue( uint16_t packetValue )
+{
+       // = Packet Layout =
+       //
+       // A is the first bit received (bit 0), T is the last
+       //
+       //   |  Modifier?  |  ??   |   Scan Code   |
+       //  A B C D E F G H I J K L M N O P Q R S T
+       //
+       // A      - Start bit
+       //          - Always Low
+       // B -> H - Modifier enabled bits
+       //          - Each bit represents a different modifier "mode"
+       //          - B -> Shift/Lock
+       //          - C -> ??
+       //          - D -> Func
+       //          - E -> ??
+       //          - F -> ??
+       //          - G -> ??
+       //          - H -> ??
+       // I -> L - ?? No idea yet...
+       //          - The bits change for some combinations, but not pattern has been found yet...
+       //          - I -> ??
+       //          - J -> ??
+       //          - K -> ??
+       //          - L -> ??
+       // M -> T - Scan Code
+       //          - Bits are organized from low to high (8 bit value)
+       //          - M -> Bit 1
+       //          - N -> Bit 2
+       //          - O -> Bit 3
+       //          - P -> Bit 4
+       //          - Q -> Bit 5
+       //          - R -> Bit 6
+       //          - S -> Bit 7
+       //          - T -> Bit 8
+
+       // Separate packet into sections
+       uint8_t scanCode  = (packetValue & 0xFF000) << 12;
+       uint8_t modifiers = (packetValue & 0x000FE);
+       uint8_t extra     = (packetValue & 0x00F00) << 8;
+
+       // Debug Info
+       char tmpStr1[3];
+       char tmpStr2[3];
+       char tmpStr3[3];
+       hexToStr_op( scanCode, tmpStr1, 2 );
+       hexToStr_op( modifiers, tmpStr2, 2 );
+       hexToStr_op( extra, tmpStr3, 2 );
+       dbug_dPrint( "Scancode: 0x", tmpStr1, " Modifiers: 0x", tmpStr2, " Extra: 0x", tmpStr3 );
+       dbug_dPrint( "Packet: 0x", tmpStr2, tmpStr3, tmpStr1 );
+
+       // TODO List
+       // - Modifier keys
+       // - Key Release mechanism
+
+       // Compute Modifier keys
+       // TODO
+
+       // Deal with special scan codes
+       switch ( scanCode )
+       {
+       default:
+               //bufferAdd( scanCode ); TODO - Uncomment when ready for USB output
+               break;
+       }
+}
+
+// Send data
+// NOTE: Does nothing with the Univac-Sperry F3W9
+uint8_t scan_sendData( uint8_t dataPayload )
+{
+       return 0;
+}
+
+// Signal KeyIndex_Buffer that it has been properly read
+inline void scan_finishedWithBuffer( void )
+{
+       return;
+}
+
+// Signal that the keys have been properly sent over USB
+// TODO
+inline void scan_finishedWithUSBBuffer( void )
+{
+       /*
+       uint8_t foundModifiers = 0;
+
+       // Look for all of the modifiers present, there is a max of 8 (but only keys for 5 on the HASCI version)
+       for ( uint8_t c = 0; c < KeyIndex_BufferUsed; c++ )
+       {
+               // The modifier range is from 0x80 to 0x8F (well, the last bit is the ON/OFF signal, but whatever...)
+               if ( KeyIndex_Buffer[c] <= 0x8F && KeyIndex_Buffer[c] >= 0x80 )
+               {
+                       // Add the modifier back into the the Key Buffer
+                       KeyIndex_Buffer[foundModifiers] = KeyIndex_Buffer[c];
+                       foundModifiers++;
+               }
+       }
+
+       // Adjust the size of the new Key Buffer
+       KeyIndex_BufferUsed = foundModifiers;
+       */
+}
+
+// Reset/Hold keyboard
+// NOTE: Does nothing with the Univac-Sperry F3W9
+void scan_lockKeyboard( void )
+{
+}
+
+// NOTE: Does nothing with the Univac-Sperry F3W9
+void scan_unlockKeyboard( void )
+{
+}
+
+// Reset Keyboard
+// - Holds the input read line high to flush the buffer
+// - This does not actually reset the keyboard, but always seems brings it to a sane state
+// - Won't work fully if keys are being pressed done at the same time
+void scan_resetKeyboard( void )
+{
+       // Initiate data request line, but don't read the incoming data
+       REQUEST_DATA();
+
+       // We shouldn't be receiving more than 8 packets (and maybe +1 error signal)
+       // This is around 22 ms of data, so a delay of 50 ms should be sufficient.
+       _delay_ms( 50 );
+
+       // Stop request line
+       STOP_DATA();
+}
+
diff --git a/Scan/UnivacF3W9/scan_loop.h b/Scan/UnivacF3W9/scan_loop.h
new file mode 100644 (file)
index 0000000..00f318f
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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 0x68 // 104 - 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;
+
+
+
+// ----- 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_finishedWithBuffer( void );
+void scan_finishedWithUSBBuffer( void );
+void scan_lockKeyboard( void );
+void scan_unlockKeyboard( void );
+void scan_resetKeyboard( void );
+
+
+#endif // __SCAN_LOOP_H
+
diff --git a/Scan/UnivacF3W9/setup.cmake b/Scan/UnivacF3W9/setup.cmake
new file mode 100644 (file)
index 0000000..9fe47fd
--- /dev/null
@@ -0,0 +1,46 @@
+###| CMake Kiibohd Controller Scan Module |###
+#
+# Written by Jacob Alexander in 2012 for the Kiibohd Controller
+#
+# Released into the Public Domain
+#
+###
+
+
+###
+# 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} )
+#add_file_dependencies( macro.c keymap.h epsonqx10.h )
+
+
+###
+# Module Specific Options
+#
+add_definitions( -I${HEAD_DIR}/Keymap )
+
+#| Keymap Settings
+add_definitions(
+       -DMODIFIER_MASK=univacf3w9_ModifierMask
+       -DKEYINDEX_MASK=univacf3w9_ColemakMap
+       #-DKEYINDEX_MASK=univacf3w9_DefaultMap
+)
+
index 1043e6ac1ebcb7369e0347d9d5215b4a3b670f10..6aec93f98ea3197aac0d5857148bc3c9f436320b 100644 (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
index c3eb2a25c06d88048833bebe0e775db06cab1b73..0f71324c97ccce7a7cc9d1d3a08dcd6ff7da0ef2 100644 (file)
@@ -1,6 +1,6 @@
 ###| CMAKE Kiibohd Controller Source Configurator |###
 #
-# Written by Jacob Alexander in 2011 for the Kiibohd Controller
+# Written by Jacob Alexander in 2011-2012 for the Kiibohd Controller
 #
 # Released into the Public Domain
 #
@@ -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  "BudKeypad" )
+set(  ScanModule  "UnivacF3W9" )
 
 ##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code
 set( MacroModule  "buffer"  )