From 4ce6d34cd8dfbcc6fa51a69e42dce38b3416b736 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 13 Apr 2013 22:35:59 -0400 Subject: [PATCH] Adapting the avr-capsense code to the Kiibohd Controller API - Adding "template" keymap - Removed "stray" functions, variables - Cleaned up warnings - Now builds - Added buffered macro integration (rather than dealing with USB directly) - Updated the print messages to use the Kiibohd print header TODO - Add generic matrix integration (this will require some changes to the matrix code) - Add more comments...lots more - Clean up dead code --- CMakeLists.txt | 4 +- Debug/print/print.h | 7 +- Keymap/avrcapsense.h | 538 +++++++ Keymap/keymap.h | 1 + Scan/avr-capsense/scan_loop.c | 2514 +++++++++++++++------------------ Scan/avr-capsense/scan_loop.h | 54 + Scan/avr-capsense/setup.cmake | 31 +- setup.cmake | 2 +- 8 files changed, 1744 insertions(+), 1407 deletions(-) create mode 100644 Keymap/avrcapsense.h mode change 100755 => 100644 Scan/avr-capsense/scan_loop.c create mode 100644 Scan/avr-capsense/scan_loop.h mode change 100755 => 100644 Scan/avr-capsense/setup.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ce0210..a68fc2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,8 @@ include( AddFileDependencies ) #| "avr" # Teensy++ 1.0 #| "avr" # Teensy++ 2.0 #| "arm" # Teensy 3.0 -set( COMPILER_FAMILY "arm" ) -#set( COMPILER_FAMILY "avr" ) +#set( COMPILER_FAMILY "arm" ) +set( COMPILER_FAMILY "avr" ) message( STATUS "Compiler Family:" ) message( "${COMPILER_FAMILY}" ) diff --git a/Debug/print/print.h b/Debug/print/print.h index ee36203..801cca1 100644 --- a/Debug/print/print.h +++ b/Debug/print/print.h @@ -78,6 +78,7 @@ #define dbug_dPrint(...) dPrintMsg ("1;35", "DEBUG", __VA_ARGS__) // Debug Msg #define dbug_print(str) printMsg ("1;35", "DEBUG", str) // Debug Msg + // Static String Printing #define print(s) _print(PSTR(s)) @@ -97,9 +98,9 @@ void printHex_op( uint16_t in, uint8_t op ); // String Functions #define hexToStr(hex, out) hexToStr_op(hex, out, 1) -void int8ToStr ( uint8_t in, char* out ); -void int16ToStr ( uint16_t in, char* out ); -void hexToStr_op( uint16_t in, char* out, uint8_t op ); +void int8ToStr ( uint8_t in, char* out ); +void int16ToStr ( uint16_t in, char* out ); +void hexToStr_op( uint16_t in, char* out, uint8_t op ); void revsStr ( char* in ); uint16_t lenStr ( char* in ); diff --git a/Keymap/avrcapsense.h b/Keymap/avrcapsense.h new file mode 100644 index 0000000..9b76996 --- /dev/null +++ b/Keymap/avrcapsense.h @@ -0,0 +1,538 @@ +/* Copyright (C) 2013 by Jacob Alexander + * + * dfj, place whatever license you want here + */ + +#ifndef __AVRCAPSENSE_H +#define __AVRCAPSENSE_H + +// This file contains various key layouts for dfj's AVR Capsense Controller + + +// ----- Variables ----- + +static uint8_t avrcapsense_ModifierMask [] = { 0x34, 0x38, 0x3A, 0x40 }; + +// Default 1-indexed key mappings +static uint8_t avrcapsense_DefaultMap[] = { + 0, // 0x00 + 0, // 0x01 + 0, // 0x02 + 0, // 0x03 + 0, // 0x04 + 0, // 0x05 + 0, // 0x06 + 0, // 0x07 + KEY_BACKSPACE, // 0x08 + KEY_TAB, // 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 + KEY_ESC, // 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 + 0, // 0x41 + 0, // 0x42 + 0, // 0x43 + 0, // 0x44 + 0, // 0x45 + 0, // 0x46 + 0, // 0x47 + 0, // 0x48 + 0, // 0x49 + 0, // 0x4A + 0, // 0x4B + 0, // 0x4C + 0, // 0x4D + 0, // 0x4E + 0, // 0x4F + 0, // 0x50 + 0, // 0x51 + 0, // 0x52 + 0, // 0x53 + 0, // 0x54 + 0, // 0x55 + 0, // 0x56 + 0, // 0x57 + 0, // 0x58 + 0, // 0x59 + 0, // 0x5A + KEY_LEFT_BRACE, // 0x5B + KEY_BACKSLASH, // 0x5C + KEY_RIGHT_BRACE, // 0x5D + 0, // 0x5E + 0, // 0x5F + KEY_TILDE, // 0x60 + KEY_A, // 0x61 + KEY_B, // 0x62 + KEY_C, // 0x63 + KEY_D, // 0x64 + KEY_E, // 0x65 + KEY_F, // 0x66 + KEY_G, // 0x67 + KEY_H, // 0x68 + KEY_I, // 0x69 + KEY_J, // 0x6A + KEY_K, // 0x6B + KEY_L, // 0x6C + KEY_M, // 0x6D + KEY_N, // 0x6E + KEY_O, // 0x6F + KEY_P, // 0x70 + KEY_Q, // 0x71 + KEY_R, // 0x72 + KEY_S, // 0x73 + KEY_T, // 0x74 + KEY_U, // 0x75 + KEY_V, // 0x76 + KEY_W, // 0x77 + KEY_X, // 0x78 + KEY_Y, // 0x79 + KEY_Z, // 0x7A + 0, // 0x7B + 0, // 0x7C + 0, // 0x7D + 0, // 0x7E + KEY_DELETE, // 0x7F + 0, // 0x80 + 0, // 0x81 + 0, // 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 + 0, // 0x90 + 0, // 0x91 + 0, // 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 + 0, // 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 + KEYPAD_0, // 0xB1 + KEYPAD_PERIOD, // 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 + KEYPAD_1, // 0xC0 + KEYPAD_2, // 0xC1 + KEYPAD_3, // 0xC2 + KEYPAD_ENTER, // 0xC3 + 0, // 0xC4 + 0, // 0xC5 + 0, // 0xC6 + 0, // 0xC7 + 0, // 0xC8 + 0, // 0xC9 + 0, // 0xCA + 0, // 0xCB + 0, // 0xCC + 0, // 0xCD + 0, // 0xCE + 0, // 0xCF + KEYPAD_4, // 0xD0 + KEYPAD_5, // 0xD1 + KEYPAD_6, // 0xD2 + KEYPAD_COMMA, // 0xD3 + 0, // 0xD4 + 0, // 0xD5 + 0, // 0xD6 + 0, // 0xD7 + 0, // 0xD8 + 0, // 0xD9 + 0, // 0xDA + 0, // 0xDB + 0, // 0xDC + 0, // 0xDD + 0, // 0xDE + 0, // 0xDF + 0, // 0xE0 + KEYPAD_7, // 0xE1 + KEYPAD_8, // 0xE2 + KEYPAD_9, // 0xE3 + KEYPAD_MINUS, // 0xE4 + 0, // 0xE5 + 0, // 0xE6 + 0, // 0xE7 + 0, // 0xE8 + 0, // 0xE9 + 0, // 0xEA + 0, // 0xEB + 0, // 0xEC + 0, // 0xED + 0, // 0xEE + 0, // 0xEF + 0, // 0xF0 + KEY_UP, // 0xF1 + KEY_DOWN, // 0xF2 + KEY_LEFT, // 0xF3 + KEY_RIGHT, // 0xF4 + KEY_LEFT_SHIFT, // 0xF5 + KEY_CTRL, // 0xF6 + 0, // 0xF7 + 0, // 0xF8 + 0, // 0xF9 + 0, // 0xFA + 0, // 0xFB + 0, // 0xFC + 0, // 0xFD + 0, // 0xFE + 0, // 0xFF +}; + +static uint8_t avrcapsense_ColemakMap[] = { + 0, // 0x00 + 0, // 0x01 + 0, // 0x02 + 0, // 0x03 + 0, // 0x04 + 0, // 0x05 + 0, // 0x06 + 0, // 0x07 + KEY_BACKSPACE, // 0x08 + KEY_TAB, // 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 + KEY_ESC, // 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 + 0, // 0x41 + 0, // 0x42 + 0, // 0x43 + 0, // 0x44 + 0, // 0x45 + 0, // 0x46 + 0, // 0x47 + 0, // 0x48 + 0, // 0x49 + 0, // 0x4A + 0, // 0x4B + 0, // 0x4C + 0, // 0x4D + 0, // 0x4E + 0, // 0x4F + 0, // 0x50 + 0, // 0x51 + 0, // 0x52 + 0, // 0x53 + 0, // 0x54 + 0, // 0x55 + 0, // 0x56 + 0, // 0x57 + 0, // 0x58 + 0, // 0x59 + 0, // 0x5A + KEY_LEFT_BRACE, // 0x5B + KEY_BACKSLASH, // 0x5C + KEY_RIGHT_BRACE, // 0x5D + 0, // 0x5E + 0, // 0x5F + KEY_TILDE, // 0x60 + KEY_A, // 0x61 + KEY_B, // 0x62 + KEY_C, // 0x63 + KEY_S, // 0x64 + KEY_F, // 0x65 + KEY_T, // 0x66 + KEY_D, // 0x67 + KEY_H, // 0x68 + KEY_U, // 0x69 + KEY_N, // 0x6A + KEY_E, // 0x6B + KEY_I, // 0x6C + KEY_M, // 0x6D + KEY_K, // 0x6E + KEY_Y, // 0x6F + KEY_SEMICOLON, // 0x70 + KEY_Q, // 0x71 + KEY_P, // 0x72 + KEY_R, // 0x73 + KEY_G, // 0x74 + KEY_L, // 0x75 + KEY_V, // 0x76 + KEY_W, // 0x77 + KEY_X, // 0x78 + KEY_J, // 0x79 + KEY_Z, // 0x7A + 0, // 0x7B + 0, // 0x7C + 0, // 0x7D + 0, // 0x7E + KEY_DELETE, // 0x7F + 0, // 0x80 + 0, // 0x81 + 0, // 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 + 0, // 0x90 + 0, // 0x91 + 0, // 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 + 0, // 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 + KEYPAD_0, // 0xB1 + KEYPAD_PERIOD, // 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 + KEYPAD_1, // 0xC0 + KEYPAD_2, // 0xC1 + KEYPAD_3, // 0xC2 + KEYPAD_ENTER, // 0xC3 + 0, // 0xC4 + 0, // 0xC5 + 0, // 0xC6 + 0, // 0xC7 + 0, // 0xC8 + 0, // 0xC9 + 0, // 0xCA + 0, // 0xCB + 0, // 0xCC + 0, // 0xCD + 0, // 0xCE + 0, // 0xCF + KEYPAD_4, // 0xD0 + KEYPAD_5, // 0xD1 + KEYPAD_6, // 0xD2 + KEYPAD_COMMA, // 0xD3 + 0, // 0xD4 + 0, // 0xD5 + 0, // 0xD6 + 0, // 0xD7 + 0, // 0xD8 + 0, // 0xD9 + 0, // 0xDA + 0, // 0xDB + 0, // 0xDC + 0, // 0xDD + 0, // 0xDE + 0, // 0xDF + 0, // 0xE0 + KEYPAD_7, // 0xE1 + KEYPAD_8, // 0xE2 + KEYPAD_9, // 0xE3 + KEYPAD_MINUS, // 0xE4 + 0, // 0xE5 + 0, // 0xE6 + 0, // 0xE7 + 0, // 0xE8 + 0, // 0xE9 + 0, // 0xEA + 0, // 0xEB + 0, // 0xEC + 0, // 0xED + 0, // 0xEE + 0, // 0xEF + 0, // 0xF0 + KEY_UP, // 0xF1 + KEY_DOWN, // 0xF2 + KEY_LEFT, // 0xF3 + KEY_RIGHT, // 0xF4 + KEY_LEFT_SHIFT, // 0xF5 + KEY_CTRL, // 0xF6 + 0, // 0xF7 + 0, // 0xF8 + 0, // 0xF9 + 0, // 0xFA + 0, // 0xFB + 0, // 0xFC + 0, // 0xFD + 0, // 0xFE + 0, // 0xFF +}; + + + +#endif + diff --git a/Keymap/keymap.h b/Keymap/keymap.h index 4f12803..5ad706e 100644 --- a/Keymap/keymap.h +++ b/Keymap/keymap.h @@ -41,6 +41,7 @@ // See files for full layout descriptions +#include "avrcapsense.h" #include "betkb.h" #include "budkeypad.h" #include "epsonqx10.h" diff --git a/Scan/avr-capsense/scan_loop.c b/Scan/avr-capsense/scan_loop.c old mode 100755 new mode 100644 index 7ce472e..3d80c76 --- a/Scan/avr-capsense/scan_loop.c +++ b/Scan/avr-capsense/scan_loop.c @@ -1,1391 +1,1123 @@ -/* Keyboard example with debug channel, for Teensy USB Development Board - * http://www.pjrc.com/teensy/usb_keyboard.html - * Copyright (c) 2008 PJRC.COM, LLC - * - * 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. - */ - -#include -#include -#include -#include -#include "usb_keyboard_debug.h" -#include "print.h" - -#define LED_CONFIG (DDRD |= (1<<6)) -#define LED_ON (PORTD &= ~(1<<6)) -#define LED_OFF (PORTD |= (1<<6)) -#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) - -#define THRESHOLD 0x0a -#define BUMP_THRESHOLD 0x50 -//((THRESHOLD) * 3) -#define BUMP_REST_US 1200 - -#define HYST 1 -#define HYST_T 0x10 - -#define TEST_KEY_STROBE (0x05) -#define TEST_KEY_MASK (1 << 0) - -#define ADHSM 7 - -/** Whether to use all of D and C, vs using E0, E1 instead of D6, D7, - * or alternately all of D, and E0,E1 and C0,..5 */ -//#define ALL_D_C -//#define SHORT_D -#define SHORT_C - -// rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20 -//#define OFFSET_VOLTAGE 0x14 -#define OFFSET_VOLTAGE 0x28 - -volatile uint8_t idle_count=1; - -uint8_t blink=0; - -volatile uint16_t full_av = 0; - -#define RIGHT_JUSTIFY 0 -#define LEFT_JUSTIFY (0xff) - -// set left or right justification here: -#define JUSTIFY_ADC RIGHT_JUSTIFY - -#define ADLAR_MASK (1 << ADLAR) -#ifdef JUSTIFY_ADC -#define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC)) -#else // defaults to right justification. -#define ADLAR_BITS 0 -#endif - - -// full muxmask -#define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4)) - -// F0-f7 pins only muxmask. -#define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2)) - -#define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK)))) -#define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK)))) - -#define MUX_1_1 0x1e -#define MUX_GND 0x1f - - - // set ADC clock prescale -#define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2)) -#define PRESCALE_SHIFT (ADPS0) -#define PRESCALE 3 - - -/**/ uint8_t ze_strober = 0; - -#ifdef EXTENDED_STROBE - -#define STROBE_LINES 18 - -#else - -#define STROBE_LINES 16 - -#endif - -#define STROBE_LINES_XSHIFT 4 -#define STROBE_LINES_MASK 0x0f -#define MUXES_COUNT 8 -#define MUXES_COUNT_XSHIFT 3 -#define MUXES_MASK 0x7 - -#define WARMUP_LOOPS ( 1024 ) - -#define RECOVERY_US 6 - -#define SAMPLES 10 -int16_t samples [SAMPLES]; - -//int16_t gsamples [SAMPLES]; - -#define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT) -//#define SAMPLE_OFFSET 9 -#define STROBE_OFFSET 0 - -/**/ int16_t adc_mux_averages[MUXES_COUNT]; -/**/ int16_t adc_strobe_averages[STROBE_LINES]; - - -/**/ uint8_t cur_keymap[STROBE_LINES]; -// /**/ int8_t last_keymap[STROBE_LINES]; -/**/ uint8_t usb_keymap[STROBE_LINES]; -uint8_t dirty; -uint8_t unstable; -uint8_t usb_dirty; - -int16_t threshold = THRESHOLD; -uint16_t tests = 0; - -uint8_t col_a=0; -uint8_t col_b=0; -uint8_t col_c=0; - -uint8_t column=0; - -#define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT)) - -int16_t keys_averages_acc[KEY_COUNT]; -uint16_t keys_averages[KEY_COUNT]; - -uint8_t full_samples[KEY_COUNT]; - -/* viable starting biases for near 0.830V offset. and adc PRESCALE 3 -0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D -001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F -0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F -000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017 -001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D -001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021 -0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021 -0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018 -*/ - -/*** starting bias relative to fixed offset estimate of 820mV (0x50) - * 77 69 65 5B 50 4E 4C 45 66 53 4D 49 45 3F 3E 35 - * 68 54 4F 49 45 40 3F 34 74 66 5F 56 4E 4D 4C 3F - * 6D 5D 53 4C 49 46 45 38 6D 5A 53 4E 49 48 45 3E - * 6F 5D 56 4E 4B 48 48 3A 6D 5C 54 4E 48 48 45 37 - * 75 68 5F 57 4F 4D 4C 3F 60 4E 48 41 3C 3C 39 2F - * 65 53 4E 49 41 3F 3E 34 65 54 4E 49 43 3F 3E 34 - * 60 51 4A 45 3F 3E 3C 30 57 4C 45 3E 3B 37 37 2E - * 64 4E 48 44 3C 3B 39 2F 5D 4F 48 45 3E 3C 3B 30 - */ - -/*volatile*/ uint16_t count = 0; - - - -/*volatile*/ uint8_t error = 0; -uint16_t error_data = 0; - -void dump(void); -void dumpkeys(void); - -static const uint8_t PROGMEM matrix122F_to_set3[] = { -0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x84, // (), npenter, np3, (), np+, np9, np*, np- -0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // np0, np., np2, np5, np6, np8, numlck, np/ -0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, // -0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, -0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, -0x00, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 vanishes - is test key. -0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, // 0x48 vanishes - else roll back. -0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, -0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, -0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, -0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, -0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, -0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, -0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, -0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, -0x01, 0x83, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x02 is replaced with 0x83. -}; - -#define LX2FX - -static const uint8_t PROGMEM page3_2_USB[133] = { -0x0, // 00 00 // no key. - -#ifndef LX2FX - -0xe3, // 01 Enl Help -> windows. (e3) -0x0, // 02 // no key. -0x80, // 03 A4 ExSel SetUp print, -> paste 7d -> vol up 80 -0x46, // 04 A3 CrSel Properties -> copy 7c -> mute 7f-> prt-scrn -0x29, // 05 9A Attn SysRq // good place fer escape. (29) -0x47, // 06 9C Clear -> kp / 54 -> scroll-lock (47) -0x3a, // 07 3A F1 -0x68, // 08 68 F13 -0x65, // 09 Ctrl // record/pause // -> kb application (65) -0x74, // 0A Copy Test // play/test -> execute 74 -> kp + 57 -0x75, // 0B // no key. help (75) -> kp - 56 -0x48, // 0C Pause ErInp erase input. -> cut 7b -> kp * 55 -> pause 48 - -#else - -/* -0x42, // 01 L9 -0x0, // 02 // no key. -0x3e, // 03 L5 -0x3c, // 04 L3 -0x3a, // 05 L1 -0x3b, // 06 L2 -0x3a, // 07 3A F1 -0x68, // 08 68 F13 -0x43, // 09 L10 -0x41, // 0A L8 -0x3f, // 0B L6 -0x3d, // 0C L4 -*/ -0x61, // 01 L9 -> num 9 0x61 -0x0, // 02 // no key. -0x5d, // 03 L5 -> num 5 0x5d -0x5b, // 04 L3 -> num 3 0x5b -0x59, // 05 L1 -> num 1 0x59 -0x5a, // 06 L2 -> num 2 0x5a -0x3a, // 07 3A F1 -0x68, // 08 68 F13 -0x62, // 09 L10 -> num 0 0x62 -0x60, // 0A L8 -> num 8 0x60 -0x5e, // 0B L6 -> num 6 0x5e -0x5c, // 0C L4 -> num 4 0x5c -#endif - - -0x2b, // 0D 2B Tab -0x29, // 0E 35 ~ ` -> escape 29 -0x3b, // 0F 3B F2 -0x69, // 10 69 F14 -0xe0, // 11 E0 Ctrl L -0xe1, // 12 E1 Shift L -0xe1, // 13 64 left of z. -> l shift e1 -0x39, // 14 39 Caps Lock -0x14, // 15 14 Q -0x1e, // 16 1E ! 1 -0x3c, // 17 3C F3 -0x6a, // 18 6A F15 -0xe2, // 19 E2 Alt L -0x1d, // 1A 1D Z -0x16, // 1B 16 S -0x04, // 1C 04 A -0x1a, // 1D 1A W -0x1f, // 1E 1F @ 2 -0x3d, // 1F 3D F4 -0x6b, // 20 6B F16 -0x06, // 21 06 C -0x1b, // 22 1B X -0x07, // 23 07 D -0x08, // 24 08 E -0x21, // 25 21 $ 4 -0x20, // 26 20 # 3 -0x3e, // 27 3E F5 -0x6c, // 28 6C F17 -0x2c, // 29 2C Space -0x19, // 2A 19 V -0x09, // 2B 09 F -0x17, // 2C 17 T -0x15, // 2D 15 R -0x22, // 2E 22 % 5 -0x3f, // 2F 3F F6 -0x6d, // 30 6D F18 -0x11, // 31 11 N -0x05, // 32 05 B -0x0b, // 33 0B H -0x0a, // 34 0A G -0x1c, // 35 1C Y -0x23, // 36 23 ^ 6 -0x40, // 37 40 F7 -0x6e, // 38 6E F19 -0xe6, // 39 E6 Alt R -0x10, // 3A 10 M -0x0d, // 3B 0D J -0x18, // 3C 18 U -0x24, // 3D 24 & 7 -0x25, // 3E 25 * 8 -0x41, // 3F 41 F8 -0x6f, // 40 6F F20 -0x36, // 41 36 < , -0x0e, // 42 0E K -0x0c, // 43 0C I -0x12, // 44 12 O -0x27, // 45 27 ) 0 -0x26, // 46 26 ( 9 -0x42, // 47 42 F9 -0x70, // 48 70 F21 -0x37, // 49 37 > . -0x38, // 4A 38 ? / -0x0f, // 4B 0F L -0x33, // 4C 33 : ; -0x13, // 4D 13 P -0x2d, // 4E 2D _ - -0x43, // 4F 43 F10 -0x71, // 50 71 F22 -0xe5, // 51 87 likely a shift - e.g. kp shift -> e5 -0x34, // 52 34 " ' -0x31, // 53 (INT 2) -> keypad enter. 58 -> |/\ (31) -0x2f, // 54 2F { [ -0x2e, // 55 2E + = -0x44, // 56 44 F11 -0x72, // 57 72 F23 -> vol up. -0xe4, // 58 E4 Ctrl R -0xe5, // 59 E5 Shift R -0x28, // 5A 28 Enter -0x30, // 5B 30 } ] -0x31, // 5C 31 | '\' -0x35, // 5D -> kp = 67 -> ~` 35 -0x45, // 5E 45 F12 -0x73, // 5F 73 F24 -> vol down. -0x51, // 60 51 Down CP -0x50, // 61 50 Left CP -0x51, //0x0,// 62 Rule // centre cp. //62 48 Pause/Bk -0x52, // 63 52 Up CP -0x4c, // 64 4C Del CP -0x4d, // 65 4D End CP -0x2a, // 66 2A Back Space -0x49, // 67 49 Ins CP -0x48, // 68 // under kp0 => kp 0 (62) 48 -> pause (48) -0x59, // 69 59 1 End KP -0x4f, // 6A 4F Right CP -0x5c, // 6B 5C 4 Left KP -0x5f, // 6C 5F 7 Home KP -0x4e, // 6D 4E PgDn CP -0x4a, // 6E 4A Home CP -0x4b, // 6F 4B PgUp CP -0x62, // 70 62 0 Ins KP -> pause (+48) -> kp-0 (62) -0x63, // 71 63 . Del KP -0x5a, // 72 5A 2 Down KP -0x5d, // 73 97 5 KP -0x5e, // 74 5E 6 Right KP -0x60, // 75 60 8 Up KP -0x53, // 76 53 Num Lock -0x54, // 77 54 / KP -0x47, // 78 Undo // under enter -> scroll-lock 47 -0x58, // 79 58 Enter KP -> enter kp -0x5b, // 7A 5B 3 PgDn KP -0x46, // 7B (INT 5) // under + -> print screen (46 -0x57, // 7C 57 + KP -0x61, // 7D 61 9 PgUp KP -0x55, // 7E 55 * KP -0x0, // 7F no such key? -0x0, // 80 no such key -0x0, // 81 Paste? -0x0, // 82 Find? -#ifndef LX2FX -0x81, // 83 Print Ident -> undo 7a -> vol down 81 -#else -//0x40, // 83 L7 (f1) 3a -0x5f, // 83 L7 (f1) 3a -> num 7 0x5f -#endif -0x56 // 84 56 - KP -}; - -void -_delay_loop(uint8_t __count) -{ - __asm__ volatile ( - "1: dec %0" "\n\t" - "brne 1b" - : "=r" (__count) - : "0" (__count) - ); -} - - -void setup_ADC (void) { - // disable adc digital pins. - DIDR1 |= (1 << AIN0D) | (1< BUMP_THRESHOLD + delta) { - // ze horror. - return 1; - } else { - return 0; //all good. - }*/ - return 0; - -} - -int sampleColumn_k(uint8_t column, int16_t * buffer) { - // ensure all probe lines are driven low, and chill for recovery delay. - uint16_t sample; - - ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions - ADCSRA |= (1 << ADIF); // clear int flag by writing 1. - - // sync up with adc clock: - while (! (ADCSRA & (1 << ADIF))); // wait until ready. - sample = ADC; // throw it away. - - for(uint8_t mux=0; mux < 8; ++mux) { - - PORTC &= ~C_MASK; - PORTD &= ~D_MASK; - PORTE &= ~E_MASK; - - SET_FULL_MUX(mux); // our sample will use this - - for(uint8_t i=0; i < 2; ++i) { - ADCSRA |= (1 << ADIF); // clear int flag by writing 1. - //wait for last read to complete. - while (! (ADCSRA & (1 << ADIF))); - sample = ADC; // throw away strobe'd value. - } - - recovery(0); - strobe_w(column); - - ADCSRA |= (1 << ADIF); // clear int flag by writing 1. - //wait for last read to complete. - while (! (ADCSRA & (1 << ADIF))); - sample = ADC; // throw away strobe'd value. - - ADCSRA |= (1 << ADIF); // clear int flag by writing 1. - while (! (ADCSRA & (1 << ADIF))); - - // retrieve current read. - buffer[mux] = ADC - OFFSET_VOLTAGE; - recovery(1); - - } - - // turn off adc. - ADCSRA &= ~(1 << ADEN); - - // pull all columns' probe-lines low. - PORTC &= ~C_MASK; - PORTD &= ~D_MASK; - PORTE &= ~E_MASK; -// recovery(1); - - - return 0; -} - -int sampleColumn(uint8_t column) { - int rval = 0; - - /* - sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET); - sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 ); -*/ - - rval = sampleColumn_k(column, samples+SAMPLE_OFFSET); - - for(uint8_t i=0; i<8; ++i) { - if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) { - // was a hump - - _delay_us(BUMP_REST_US); - rval++; - error = 0x50; - error_data = samples[SAMPLE_OFFSET +i]; // | ((uint16_t)i << 8); - return rval; - } - } - - return rval; -} - - - -uint8_t testColumn(uint8_t strobe) { - uint8_t column = 0; - uint8_t bit = 1; - for (uint8_t i=0; i < MUXES_COUNT; ++i) { - uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i]; - if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) { - column |= bit; - } - bit <<= 1; - } - return column; -} - -int main(void) { - // set for 16 MHz clock - CPU_PRESCALE(0); - - // 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, - // this will wait forever. - usb_init(); - while (!usb_configured()) /* wait */ ; - - // Wait an extra second for the PC's operating system to load drivers - // and do whatever it does to actually be ready for input - _delay_ms(1000); - - LED_CONFIG; - - setup_ADC(); - - // Configure timer 0 to generate a timer overflow interrupt every - // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock - // This demonstrates how to use interrupts to implement a simple - // inactivity timeout. - //TCCR0A = 0x00; - //TCCR0B = 0x05; - //TIMSK0 = (1<= WARMUP_LOOPS) ) { - tests++; - - tries = 1; - while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop. - col_a = testColumn(strober); - - tries = 1; - while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop. - col_b = testColumn(strober); - - tries = 1; - while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop. - col_c = testColumn(strober); - - if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) { - cur_keymap[strober] = col_a; - usb_dirty = 1; - } - } - - if(error == 0x50) { - error_data |= (((uint16_t)strober) << 12); - } - - for(int i=0; i> 3; - adc_strobe_averages[strober] >>= 1; - - /** test if we went negative. */ - if ((adc_strobe_averages[strober] & 0xFF00) && (count - >= WARMUP_LOOPS)) { - //count = 0; // TODO : constrain properly. - error = 0xf; error_data = adc_strobe_averages[strober]; - } - - uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT; - for (int i = 0; i < MUXES_COUNT; ++i) { - keys_averages_acc[strobe_line + i] - += samples[SAMPLE_OFFSET + i]; - } - - } // for strober - - if (count < WARMUP_LOOPS) { - error = 0x0C; - error_data = count; - count++; - } - - // verify test key is not down. - if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) { - //count=0; - error = 0x05; - error_data = cur_keymap[TEST_KEY_STROBE] << 8; - error_data += full_samples[TEST_KEY_STROBE * 8]; - //threshold++; - } - - // calc mux averages. - if (count < WARMUP_LOOPS) { - full_av += (full_av_acc >> (7)); - full_av >>= 1; - //full_av = full_av_acc / count; - full_av_acc = 0; - for (int i=0; i < MUXES_COUNT; ++i) { - -// mix in 1/4 of the current average to the running average. -> (@mux_mix = 2) -#define MUX_MIX 2 - - adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i]; - adc_mux_averages[i] += (mux_averages[i] >> 4); - adc_mux_averages[i] >>= MUX_MIX; - - mux_averages[i] = 0; - } - - } - -#define IDLE_COUNT_MASK 0xff -#define MAX_ICS 8 - -#define IDLE_COUNT_SHIFT 4 -#define KEYS_AVERAGES_MIX 2 - - idle_count++; - idle_count &= IDLE_COUNT_MASK; - - if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) { - for (int i=0; i>= 2; - - keys_averages[i] = av; - keys_averages_acc[i] = 0; - } - } - - - if(!idle_count) { - - for (int i=0; i< KEY_COUNT; ++i) { - keys_averages_acc[i] = 0; - } - - sampleColumn(0x0); // to resync us if we dumped a mess 'o text. - } - } -} - - -void debug_println() { - usb_debug_putchar('\r'); - usb_debug_putchar('\n'); -} - - -// This interrupt routine is run approx 61 times per second. -// A very simple inactivity timeout is implemented, where we -// will send a space character and print a message to the -// hid_listen debug message window. -ISR(TIMER0_OVF_vect) { - //idle_count++; - /* - if (idle_count > 61) { - idle_count = 0; - }*/ - -} - -void dumpkeys(void) { - //print(" \n"); - if(error) { - for (uint8_t i=0; i < STROBE_LINES; ++i) { - phex(usb_keymap[i]); - usb_debug_putchar(' '); - - //print(" "); - } - if (count >= WARMUP_LOOPS && error) { - dump(); - } - - print(" : "); - phex(error); - error = 0; - print(" : "); - phex16(error_data); - error_data = 0; - print(" : "); - debug_println(); - } - - - for(uint8_t i = 0; i < 6; ++i) { - keyboard_keys[i] = 0; - } - keyboard_modifier_keys = 0; - uint8_t usbkeycount = 0; - for (uint8_t i=0; i < STROBE_LINES; ++i) { - for(uint8_t j=0; j= 0xe0) && (usbkey <= 0xe7)) { // metas - keyboard_modifier_keys |= (1 << (usbkey & 0x07)); - } else { - keyboard_keys[usbkeycount++] = usbkey; - } - } - if (usb_dirty) usb_debug_putchar(' '); - } - } - } - if(usb_dirty) { - debug_println(); - } - - /** shall we send actual keyboard events? */ -#if 0 - usb_keyboard_send(); -#endif - -} - -// taken from the datasheet. -uint8_t readEE(uint16_t offset) { - /* Wait for completion of previous write */ - while(EECR & (1<1ms/byte. -void writeEE(uint16_t offset, uint8_t data) { - /* Wait for completion of previous write */ - while(EECR & (1<> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]); - phex (keys_averages[i]); - } - - print("\n"); - - for(int i =0; i< KEY_COUNT; ++i) { - if(!(i & 0x0f)) { - print("\n"); - } else if (!(i & 0x07)) { - print(" "); - } - usb_debug_putchar(' '); - //phex16 (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]); - //phex16 (keys_averages_acc[i]); - phex(full_samples[i]); - } - } - - - //} - -// uint8_t cur_strober = 0xe; - uint8_t cur_strober = ze_strober; - print("\n"); - - phex(cur_strober); - //print(": "); - print(": "); -#if 1 - print("\n"); - for (uint8_t i=0; i < MUXES_COUNT; ++i) { - usb_debug_putchar(' '); - phex16(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]); - } - - print("\n"); -// phex(threshold); -// print(": "); - - for (uint8_t i=0; i < MUXES_COUNT; ++i) { - usb_debug_putchar(' '); - phex16(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]); - } - -#endif - /* - for (uint8_t i=0; i< SAMPLES; ++i) { - print(" "); - phex16(samples[i]); - //phex16(ADC); - }*/ - //print(" : "); - //usb_debug_putchar((was_active)?' ':'*'); - - //phex16(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK); - /*print(" "); */ - //phex(keymap[TEST_KEY_STROBE]); - - - //print("\n"); - //print(":"); - //phex(full_av); - //phex16(count); - //print(" : "); - print("\n"); - - for (uint8_t i=0; i < STROBE_LINES; ++i) { - phex(cur_keymap[i]); - usb_debug_putchar(' '); - - //print(" "); - } - - - //print(": "); - //phex(adc_strobe_averages[ze_strober]); - //usb_debug_putchar(' '); - - - - for (uint8_t i=0; i < MUXES_COUNT; ++i) { - usb_debug_putchar(' '); - //phex16(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av); - //phex16((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1); - //phex16((adc_mux_averages[i] * 3 + adc_strobe_averages[ze_strober]) >> 2); - //phex16(adc_mux_averages[i] + threshold); - //phex16(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100); - //phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold); - phex16(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]); - } - - if(error) { - usb_debug_putchar(' '); - phex (error); - usb_debug_putchar(' '); - phex16(error_data); - error = 0; - error_data = 0; - } - //print("\n"); - - ze_strober++; - ze_strober &= 0xf; - - - dump_count++; - dump_count &= 0x0f; - - - - //ze_strobe = (1 << (ze_strober ) ); - - - - //phex(ADCSRA); - //print(" "); - //print("\n"); - //usb_keyboard_press(KEY_SPACE, 0); - -// if(blink) { -// LED_ON; -// } else { -// LED_OFF; -// } -// blink ^= 1; -} - - -/* -int oldmain(void) { - uint8_t b, d, mask, i, reset_idle; - uint8_t b_prev=0xFF, d_prev=0xFF; - - // set for 16 MHz clock - CPU_PRESCALE(0); - - // Configure all port B and port D pins as inputs with pullup resistors. - // See the "Using I/O Pins" page for details. - // http://www.pjrc.com/teensy/pins.html - DDRD = 0x00; - DDRB = 0x00; - PORTB = 0xFF; - PORTD = 0xFF; - - // 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, - // this will wait forever. - usb_init(); - while (!usb_configured()) ; - - // Wait an extra second for the PC's operating system to load drivers - // and do whatever it does to actually be ready for input - _delay_ms(1000); - - // Configure timer 0 to generate a timer overflow interrupt every - // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock - // This demonstrates how to use interrupts to implement a simple - // inactivity timeout. - TCCR0A = 0x00; - TCCR0B = 0x05; - TIMSK0 = (1< + +// Project Includes +#include +#include + +// Local Includes +#include "scan_loop.h" + + + +// ----- Defines ----- + +// TODO dfj defines...needs cleaning up and commenting... +#define THRESHOLD 0x0a +#define BUMP_THRESHOLD 0x50 +//((THRESHOLD) * 3) +#define BUMP_REST_US 1200 + +#define HYST 1 +#define HYST_T 0x10 + +#define TEST_KEY_STROBE (0x05) +#define TEST_KEY_MASK (1 << 0) + +#define ADHSM 7 + +/** Whether to use all of D and C, vs using E0, E1 instead of D6, D7, + * or alternately all of D, and E0,E1 and C0,..5 */ +//#define ALL_D_C +//#define SHORT_D +#define SHORT_C + +// rough offset voltage: one diode drop, about 50mV = 0x3ff * 50/3560 = 20 +//#define OFFSET_VOLTAGE 0x14 +#define OFFSET_VOLTAGE 0x28 + + +#define RIGHT_JUSTIFY 0 +#define LEFT_JUSTIFY (0xff) + +// set left or right justification here: +#define JUSTIFY_ADC RIGHT_JUSTIFY + +#define ADLAR_MASK (1 << ADLAR) +#ifdef JUSTIFY_ADC +#define ADLAR_BITS ((ADLAR_MASK) & (JUSTIFY_ADC)) +#else // defaults to right justification. +#define ADLAR_BITS 0 +#endif + + +// full muxmask +#define FULL_MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2) | (1 << MUX3) | (1 << MUX4)) + +// F0-f7 pins only muxmask. +#define MUX_MASK ((1 << MUX0) | (1 << MUX1) | (1 << MUX2)) + +#define MUX_1_1 0x1e +#define MUX_GND 0x1f + + + // set ADC clock prescale +#define PRESCALE_MASK ((1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2)) +#define PRESCALE_SHIFT (ADPS0) +#define PRESCALE 3 + + +#ifdef EXTENDED_STROBE + +#define STROBE_LINES 18 + +#else + +#define STROBE_LINES 16 + +#endif + +#define STROBE_LINES_XSHIFT 4 +#define STROBE_LINES_MASK 0x0f +#define MUXES_COUNT 8 +#define MUXES_COUNT_XSHIFT 3 +#define MUXES_MASK 0x7 + +#define WARMUP_LOOPS ( 1024 ) + +#define RECOVERY_US 6 + +#define SAMPLES 10 + + +#define SAMPLE_OFFSET ((SAMPLES) - MUXES_COUNT) +//#define SAMPLE_OFFSET 9 +#define STROBE_OFFSET 0 + + +#define KEY_COUNT ((STROBE_LINES) * (MUXES_COUNT)) + +#define LX2FX + + +#define RECOVERY_CONTROL 1 + +#define RECOVERY_SOURCE 0 +#define RECOVERY_SINK 2 +#define RECOVERY_MASK 0x03 + + +// mix in 1/4 of the current average to the running average. -> (@mux_mix = 2) +#define MUX_MIX 2 + + +#define IDLE_COUNT_MASK 0xff +#define MAX_ICS 8 + +#define IDLE_COUNT_SHIFT 4 +#define KEYS_AVERAGES_MIX 2 + + +#ifdef ALL_D_C + +#define D_MASK (0xff) +#define D_SHIFT 0 + +#define E_MASK (0x00) +#define E_SHIFT 0 + +#define C_MASK (0xff) +#define C_SHIFT 8 + +#else +#if defined(SHORT_D) + +#define D_MASK (0x3f) +#define D_SHIFT 0 + +#define E_MASK (0x03) +#define E_SHIFT 6 + +#define C_MASK (0xff) +#define C_SHIFT 8 + +#else +#if defined(SHORT_C) + +#define D_MASK (0xff) +#define D_SHIFT 0 + +#define E_MASK (0x03) +#define E_SHIFT 6 + +#define C_MASK (0xff) +#define C_SHIFT 8 +#endif +#endif +#endif + + + + + +// ----- Macros ----- + +// Make sure we haven't overflowed the buffer +#define bufferAdd(byte) \ + if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \ + KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte + + +// TODO dfj macros...needs cleaning up and commenting... +#define STROBE_CASE(SC_CASE, SC_REG_A) case (SC_CASE): PORT##SC_REG_A = \ + (( (PORT##SC_REG_A) & ~(1 << (SC_CASE - SC_REG_A##_SHIFT)) ) | (1 << (SC_CASE - SC_REG_A##_SHIFT))) + +#define SET_MUX(X) ((ADMUX) = (((ADMUX) & ~(MUX_MASK)) | ((X) & (MUX_MASK)))) +#define SET_FULL_MUX(X) ((ADMUX) = (((ADMUX) & ~(FULL_MUX_MASK)) | ((X) & (FULL_MUX_MASK)))) + + + + + +// ----- 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; + + +// TODO dfj variables...needs cleaning up and commenting + uint8_t blink = 0; +volatile uint8_t idle_count = 1; +volatile uint16_t full_av = 0; + +/**/ uint8_t ze_strober = 0; + +int16_t samples [SAMPLES]; + +//int16_t gsamples [SAMPLES]; + +/**/ int16_t adc_mux_averages[MUXES_COUNT]; +/**/ int16_t adc_strobe_averages[STROBE_LINES]; + + +/**/ uint8_t cur_keymap[STROBE_LINES]; +// /**/ int8_t last_keymap[STROBE_LINES]; +/**/ uint8_t usb_keymap[STROBE_LINES]; +uint8_t dirty; +uint8_t unstable; +uint8_t usb_dirty; + +int16_t threshold = THRESHOLD; +uint16_t tests = 0; + +uint8_t col_a=0; +uint8_t col_b=0; +uint8_t col_c=0; + +uint8_t column=0; + + +int16_t keys_averages_acc[KEY_COUNT]; +uint16_t keys_averages[KEY_COUNT]; + +uint8_t full_samples[KEY_COUNT]; + +/* viable starting biases for near 0.830V offset. and adc PRESCALE 3 +0017 0016 001B 001A 0016 0016 000F 000E 001B 001E 001E 0018 0017 0015 000E 001D +001B 001A 0016 0016 000F 000E 001C 001B 001E 0018 0017 0015 000E 001D 0024 001F +0016 0016 000F 000E 001C 001B 001E 001E 0017 0015 000E 001D 0024 001F 0020 001F +000F 000E 001C 001B 001E 001E 0018 0017 000E 001D 0024 001F 0020 001F 0020 0017 +001C 001B 001E 001E 0018 0017 0015 000E 0024 001F 0020 001F 0020 0017 0010 001D +001E 001E 0018 0017 0015 000E 001D 0024 0020 001F 0020 0017 0010 001D 0024 0021 +0018 0017 0015 000E 001D 0024 001F 0020 0020 0017 0010 001D 0024 0021 0021 0021 +0015 000E 001D 0024 001F 0020 001F 0020 0010 001D 0024 0021 0021 0021 0021 0018 +*/ + +/*** starting bias relative to fixed offset estimate of 820mV (0x50) + * 77 69 65 5B 50 4E 4C 45 66 53 4D 49 45 3F 3E 35 + * 68 54 4F 49 45 40 3F 34 74 66 5F 56 4E 4D 4C 3F + * 6D 5D 53 4C 49 46 45 38 6D 5A 53 4E 49 48 45 3E + * 6F 5D 56 4E 4B 48 48 3A 6D 5C 54 4E 48 48 45 37 + * 75 68 5F 57 4F 4D 4C 3F 60 4E 48 41 3C 3C 39 2F + * 65 53 4E 49 41 3F 3E 34 65 54 4E 49 43 3F 3E 34 + * 60 51 4A 45 3F 3E 3C 30 57 4C 45 3E 3B 37 37 2E + * 64 4E 48 44 3C 3B 39 2F 5D 4F 48 45 3E 3C 3B 30 + */ + +/*volatile*/ uint16_t count = 0; + +/*volatile*/ uint8_t error = 0; +uint16_t error_data = 0; + + +int16_t mux_averages[MUXES_COUNT]; +int16_t strobe_averages[STROBE_LINES]; + +uint8_t dump_count = 0; + + + +// ----- Function Declarations ----- + +void dump ( void ); +void dumpkeys( void ); + +void recovery( uint8_t on ); + +int sampleColumn ( uint8_t column ); +int sampleColumn_i( uint8_t column, uint8_t muxes, int16_t * buffer); // XXX Not currently used +int sampleColumn_k( uint8_t column, int16_t *buffer ); + +void setup_ADC( void ); + +void strobe_w( uint8_t strobe_num ); + +uint8_t testColumn( uint8_t strobe ); + + + +// ----- Functions ----- + +// Initial setup for cap sense controller +inline void scan_setup() +{ + // TODO dfj code...needs cleanup + commenting... + setup_ADC(); + + // Configure timer 0 to generate a timer overflow interrupt every + // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock + // This demonstrates how to use interrupts to implement a simple + // inactivity timeout. + //TCCR0A = 0x00; + //TCCR0B = 0x05; + //TIMSK0 = (1<= WARMUP_LOOPS) ) { + tests++; + + tries = 1; + while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop. + col_a = testColumn(strober); + + tries = 1; + while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop. + col_b = testColumn(strober); + + tries = 1; + while (tries++ && sampleColumn(strober)) { tries &= 0x7; } // don't waste this one just because the last one was poop. + col_c = testColumn(strober); + + if( (col_a == col_b) && (col_b == col_c) && (cur_keymap[strober] != col_a) ) { + cur_keymap[strober] = col_a; + usb_dirty = 1; + } + } + + if(error == 0x50) { + error_data |= (((uint16_t)strober) << 12); + } + + for(int i=0; i> 3; + adc_strobe_averages[strober] >>= 1; + + /** test if we went negative. */ + if ((adc_strobe_averages[strober] & 0xFF00) && (count + >= WARMUP_LOOPS)) { + //count = 0; // TODO : constrain properly. + error = 0xf; error_data = adc_strobe_averages[strober]; + } + + uint8_t strobe_line = strober << MUXES_COUNT_XSHIFT; + for (int i = 0; i < MUXES_COUNT; ++i) { + keys_averages_acc[strobe_line + i] + += samples[SAMPLE_OFFSET + i]; + } + + } // for strober + + if (count < WARMUP_LOOPS) { + error = 0x0C; + error_data = count; + count++; + } + + // verify test key is not down. + if((cur_keymap[TEST_KEY_STROBE] & TEST_KEY_MASK) ) { + //count=0; + error = 0x05; + error_data = cur_keymap[TEST_KEY_STROBE] << 8; + error_data += full_samples[TEST_KEY_STROBE * 8]; + //threshold++; + } + + // calc mux averages. + if (count < WARMUP_LOOPS) { + full_av += (full_av_acc >> (7)); + full_av >>= 1; + //full_av = full_av_acc / count; + full_av_acc = 0; + for (int i=0; i < MUXES_COUNT; ++i) { + + adc_mux_averages[i] = (adc_mux_averages[i] << MUX_MIX) - adc_mux_averages[i]; + adc_mux_averages[i] += (mux_averages[i] >> 4); + adc_mux_averages[i] >>= MUX_MIX; + + mux_averages[i] = 0; + } + + } + + idle_count++; + idle_count &= IDLE_COUNT_MASK; + + if (/*usb_dirty &&*/ (count >= WARMUP_LOOPS) ) { + for (int i=0; i>= 2; + + keys_averages[i] = av; + keys_averages_acc[i] = 0; + } + } + + + if(!idle_count) { + + for (int i=0; i< KEY_COUNT; ++i) { + keys_averages_acc[i] = 0; + } + + sampleColumn(0x0); // to resync us if we dumped a mess 'o text. + } + + + // Return non-zero if macro and USB processing should be delayed + // Macro processing will always run if returning 0 + // USB processing only happens once the USB send timer expires, if it has not, scan_loop will be called + // after the macro processing has been completed + return 0; +} + + +// Reset Keyboard +void scan_resetKeyboard( void ) +{ + // Empty buffer, now that keyboard has been reset + KeyIndex_BufferUsed = 0; +} + + +// Send data to keyboard +// NOTE: Only used for converters, since the scan module shouldn't handle sending data in a controller +uint8_t scan_sendData( uint8_t dataPayload ) +{ + return 0; +} + + +// Reset/Hold keyboard +// NOTE: Only used for converters, not needed for full controllers +void scan_lockKeyboard( void ) +{ +} + +// NOTE: Only used for converters, not needed for full controllers +void scan_unlockKeyboard( void ) +{ +} + + +// Signal KeyIndex_Buffer that it has been properly read +// NOTE: Only really required for implementing "tricks" in converters for odd protocols +void scan_finishedWithBuffer( uint8_t sentKeys ) +{ + // Convenient place to clear the KeyIndex_Buffer + KeyIndex_BufferUsed = 0; + return; +} + + +// Signal KeyIndex_Buffer that it has been properly read and sent out by the USB module +// NOTE: Only really required for implementing "tricks" in converters for odd protocols +void scan_finishedWithUSBBuffer( uint8_t sentKeys ) +{ + return; +} + + +void +_delay_loop(uint8_t __count) +{ + __asm__ volatile ( + "1: dec %0" "\n\t" + "brne 1b" + : "=r" (__count) + : "0" (__count) + ); +} + + +void setup_ADC (void) { + // disable adc digital pins. + DIDR1 |= (1 << AIN0D) | (1< BUMP_THRESHOLD + delta) { + // ze horror. + return 1; + } else { + return 0; //all good. + }*/ + return 0; + +} + + +int sampleColumn_k(uint8_t column, int16_t * buffer) { + // ensure all probe lines are driven low, and chill for recovery delay. + //uint16_t sample; + + ADCSRA |= (1 << ADEN) | (1 << ADSC); // enable and start conversions + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + + // sync up with adc clock: + while (! (ADCSRA & (1 << ADIF))); // wait until ready. + ADC; // throw it away. // XXX Not sure if the compiler throws this away, but less compiler warnings -HaaTa + //sample = ADC; // throw it away. + + for(uint8_t mux=0; mux < 8; ++mux) { + + PORTC &= ~C_MASK; + PORTD &= ~D_MASK; + PORTE &= ~E_MASK; + + SET_FULL_MUX(mux); // our sample will use this + + for(uint8_t i=0; i < 2; ++i) { + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + //wait for last read to complete. + while (! (ADCSRA & (1 << ADIF))); + //sample = ADC; // throw away strobe'd value. + ADC; // throw away strobe'd value. + } + + recovery(0); + strobe_w(column); + + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + //wait for last read to complete. + while (! (ADCSRA & (1 << ADIF))); + //sample = ADC; // throw away strobe'd value. + ADC; // throw away strobe'd value. + + ADCSRA |= (1 << ADIF); // clear int flag by writing 1. + while (! (ADCSRA & (1 << ADIF))); + + // retrieve current read. + buffer[mux] = ADC - OFFSET_VOLTAGE; + recovery(1); + + } + + // turn off adc. + ADCSRA &= ~(1 << ADEN); + + // pull all columns' probe-lines low. + PORTC &= ~C_MASK; + PORTD &= ~D_MASK; + PORTE &= ~E_MASK; +// recovery(1); + + + return 0; +} + + +int sampleColumn(uint8_t column) { + int rval = 0; + + /* + sampleColumn_i(column, 0x0f, samples+SAMPLE_OFFSET); + sampleColumn_i(column, 0xf0, samples+SAMPLE_OFFSET + 4 ); +*/ + + rval = sampleColumn_k(column, samples+SAMPLE_OFFSET); + + for(uint8_t i=0; i<8; ++i) { + if(samples[SAMPLE_OFFSET + i] - adc_mux_averages[i] > BUMP_THRESHOLD) { + // was a hump + + _delay_us(BUMP_REST_US); + rval++; + error = 0x50; + error_data = samples[SAMPLE_OFFSET +i]; // | ((uint16_t)i << 8); + return rval; + } + } + + return rval; +} + + +uint8_t testColumn(uint8_t strobe) { + uint8_t column = 0; + uint8_t bit = 1; + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + uint16_t delta = keys_averages[(strobe << MUXES_COUNT_XSHIFT) + i]; + if ((int16_t)samples[SAMPLE_OFFSET + i] > threshold + delta) { + column |= bit; + } + bit <<= 1; + } + return column; +} + + +void dumpkeys(void) { + //print(" \n"); + if(error) { + for (uint8_t i=0; i < STROBE_LINES; ++i) { + printHex(usb_keymap[i]); + print(" "); + + //print(" "); + } + if (count >= WARMUP_LOOPS && error) { + dump(); + } + + print(" : "); + printHex(error); + error = 0; + print(" : "); + printHex(error_data); + error_data = 0; + print(" : " NL); + } + + // XXX Will be cleaned up eventually, but this will do for now :P -HaaTa + for (uint8_t i=0; i < STROBE_LINES; ++i) { + for(uint8_t j=0; j> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]); + printHex (keys_averages[i]); + } + + print("\n"); + + for(int i =0; i< KEY_COUNT; ++i) { + if(!(i & 0x0f)) { + print("\n"); + } else if (!(i & 0x07)) { + print(" "); + } + print(" "); + //printHex (keys_averages[(i >> MUXES_COUNT_XSHIFT) + (i & STROBE_LINES_MASK) ]); + //printHex (keys_averages_acc[i]); + printHex(full_samples[i]); + } + } + + + //} + +// uint8_t cur_strober = 0xe; + uint8_t cur_strober = ze_strober; + print("\n"); + + printHex(cur_strober); + //print(": "); + print(": "); +#if 1 + print("\n"); + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + print(" "); + printHex(full_samples[(cur_strober << MUXES_COUNT_XSHIFT) + i]); + } + + print("\n"); +// printHex(threshold); +// print(": "); + + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + print(" "); + printHex(keys_averages[(cur_strober << MUXES_COUNT_XSHIFT) + i]); + } + +#endif + /* + for (uint8_t i=0; i< SAMPLES; ++i) { + print(" "); + printHex(samples[i]); + //printHex(ADC); + }*/ + //print(" : "); + //dPrint((was_active)?" ":"*"); + + //printHex(keymap[TEST_KEY_STROBE] & TEST_KEY_MASK); + /*print(" "); */ + //printHex(keymap[TEST_KEY_STROBE]); + + + //print("\n"); + //print(":"); + //printHex(full_av); + //printHex(count); + //print(" : "); + print("\n"); + + for (uint8_t i=0; i < STROBE_LINES; ++i) { + printHex(cur_keymap[i]); + print(" "); + + //print(" "); + } + + + //print(": "); + //printHex(adc_strobe_averages[ze_strober]); + //print(" "); + + + + for (uint8_t i=0; i < MUXES_COUNT; ++i) { + print(" "); + //printHex(adc_mux_averages[i] + adc_strobe_averages[ze_strober] - full_av); + //printHex((adc_mux_averages[i] + adc_strobe_averages[ze_strober]) >> 1); + //printHex((adc_mux_averages[i] * 3 + adc_strobe_averages[ze_strober]) >> 2); + //printHex(adc_mux_averages[i] + threshold); + //printHex(gsamples[i + SAMPLE_OFFSET] - (adc_mux_averages[i] + threshold) + 0x100); + //printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i] + (uint8_t)threshold); + printHex(keys_averages[(ze_strober << MUXES_COUNT_XSHIFT) + i]); + } + + if(error) { + print(" "); + printHex(error); + print(" "); + printHex(error_data); + error = 0; + error_data = 0; + } + //print("\n"); + + ze_strober++; + ze_strober &= 0xf; + + + dump_count++; + dump_count &= 0x0f; + + + + //ze_strobe = (1 << (ze_strober ) ); + + + + //printHex(ADCSRA); + //print(" "); + //print("\n"); +} + diff --git a/Scan/avr-capsense/scan_loop.h b/Scan/avr-capsense/scan_loop.h new file mode 100644 index 0000000..465cf57 --- /dev/null +++ b/Scan/avr-capsense/scan_loop.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2013 by Jacob Alexander + * + * dfj, put whatever license here you want + * This file will probably be removed though. + */ + +#ifndef __SCAN_LOOP_H +#define __SCAN_LOOP_H + +// ----- Includes ----- + +// Compiler Includes +#include + +// Local Includes + + + +// ----- Defines ----- + +#define KEYBOARD_KEYS 0xFF // TODO Determine max number of keys +#define KEYBOARD_BUFFER 24 // Max number of key signals to buffer + // This limits the NKRO-ability, so at 24, the keyboard is 24KRO + // The buffer is really only needed for converter modules + // An alternative macro module could be written for matrix modules and still work well + + + +// ----- 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( uint8_t sentKeys ); +void scan_finishedWithUSBBuffer( uint8_t sentKeys ); +void scan_lockKeyboard( void ); +void scan_unlockKeyboard( void ); +void scan_resetKeyboard( void ); + + +#endif // __SCAN_LOOP_H + diff --git a/Scan/avr-capsense/setup.cmake b/Scan/avr-capsense/setup.cmake old mode 100755 new mode 100644 index bf516c2..ca7c719 --- a/Scan/avr-capsense/setup.cmake +++ b/Scan/avr-capsense/setup.cmake @@ -1,6 +1,6 @@ ###| CMake Kiibohd Controller Scan Module |### # -# Written by Jacob Alexander in 2011 for the Kiibohd Controller +# Written by Jacob Alexander in 2013 for the Kiibohd Controller # # Released into the Public Domain # @@ -11,26 +11,37 @@ # Module C files # -#| XXX Requires the ../ due to how the paths are constructed set( SCAN_SRCS - ../matrix/matrix_scan.c - ../matrix/scan_loop.c + 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 avrcapsense.h ) + + ### # Module Specific Options # add_definitions( -I${HEAD_DIR}/Keymap ) -add_definitions( - -I${HEAD_DIR}/Scan/matrix -) #| Keymap Settings add_definitions( - -DMODIFIER_MASK=budkeypad_ModifierMask - #-DKEYINDEX_MASK=budkeypad_TheProfosistMap - -DKEYINDEX_MASK=budkeypad_DefaultMap + -DMODIFIER_MASK=avrcapsense_ModifierMask + #-DKEYINDEX_MASK=avrcapsense_ColemakMap + -DKEYINDEX_MASK=avrcapsense_DefaultMap ) diff --git a/setup.cmake b/setup.cmake index 84e71a7..c754f92 100644 --- a/setup.cmake +++ b/setup.cmake @@ -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 "MBC-55X" ) +set( ScanModule "avr-capsense" ) ##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code set( MacroModule "buffer" )