Archived
1
0

Basic matrix module for the hall effect keypad now working.

- Includes new "table pinning" setup (much easier to understand)
- Matrix layouts will be split into their own dependent modules later
- Changed the HID Raw view id (too many teensy devices on this
  computer...)
- Moved the macro processing outside of the usb timer signal
  (this will be slower overall, but will result in more consistant
  behaviour)
This commit is contained in:
Jacob Alexander 2011-10-15 20:01:46 -07:00
parent 46916defa5
commit 6557022f20
11 changed files with 259 additions and 139 deletions

View File

@ -54,7 +54,7 @@ set( SRCS main.c ${SCAN_SRCS} ${MACRO_SRCS} ${USB_SRCS} ${DEBUG_SRCS} )
#| "atmega32u4" # Teensy 2.0
#| "at90usb646" # Teensy++ 1.0
#| "at90usb1286" # Teensy++ 2.0
set( MCU "at90usb1286" )
set( MCU "atmega32u4" )
#| Compiler flag to set the C Standard level.

View File

@ -42,24 +42,26 @@
// 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 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 )
inline void keyPressDetection( uint8_t *keys, uint8_t numberOfKeys, uint8_t *modifiers, uint8_t numberOfModifiers, uint8_t *map )
{
USBKeys_Sent = 0;
for ( uint8_t key = 1; key < numberOfKeys + 1; key++ )
//for ( uint8_t key = 0; key < numberOfKeys + 1; key++ )
// Parse the detection array starting from 1 (all keys are purposefully mapped from 1 -> total as per typical PCB labels)
for ( uint8_t key = 0; key < numberOfKeys + 1; key++ )
{
//if ( keys[key] & (1 << 7) )
if ( keys[key] )
if ( keys[key] & (1 << 7) )
{
uint8_t modFound = 0;
// Display the detected scancode
char tmpStr[4];
int8ToStr( key, tmpStr );
dPrintStrs( tmpStr, " " );
// Determine if the key is a modifier
uint8_t modFound = 0;
for ( uint8_t mod = 0; mod < numberOfModifiers; mod++ ) {
// Modifier found
if ( modifiers[mod] == key ) {
USBKeys_Modifiers |= map[key];
//USBKeys_Modifiers |= map[key];
modFound = 1;
break;
}
@ -80,17 +82,15 @@ void keyPressDetection( uint8_t *keys, uint8_t numberOfKeys, uint8_t *modifiers,
// Allow ignoring keys with 0's
if ( map[key] != 0 )
USBKeys_Array[USBKeys_Sent++] = map[key];
/*
char tmpStr[3];
hexToStr_op( USBKeys_Array[0], tmpStr, 2 );
warn_dPrint("Found key: 0x", tmpStr );
*/
}
}
// Add debug separator if keys sent via USB
if ( USBKeys_Sent > 0 )
print("\033[1;32m|\033[0m\n");
}
void process_macros(void)
inline void process_macros(void)
{
// Debounce Sampling Array to USB Data Array
keyPressDetection( KeyIndex_Array, KeyIndex_Size, MODIFIER_MASK, sizeof(MODIFIER_MASK), KEYINDEX_MASK );

View File

@ -28,76 +28,8 @@
#include <stdint.h>
// ----- Quick Map (don't change) -----
#define pinA0 0
#define pinA1 1
#define pinA2 2
#define pinA3 3
#define pinA4 4
#define pinA5 5
#define pinA6 6
#define pinA7 7
#define pinB0 10
#define pinB1 11
#define pinB2 12
#define pinB3 13
#define pinB4 14
#define pinB5 15
#define pinB6 16
#define pinB7 17
#define pinC0 20
#define pinC1 21
#define pinC2 22
#define pinC3 23
#define pinC4 24
#define pinC5 25
#define pinC6 26
#define pinC7 27
#define pinD0 30
#define pinD1 31
#define pinD2 32
#define pinD3 33
#define pinD4 34
#define pinD5 35
#define pinD6 36
#define pinD7 37
#define pinE0 40
#define pinE1 41
#define pinE2 42
#define pinE3 43
#define pinE4 44
#define pinE5 45
#define pinE6 46
#define pinE7 47
#define pinF0 50
#define pinF1 51
#define pinF2 52
#define pinF3 53
#define pinF4 54
#define pinF5 55
#define pinF6 56
#define pinF7 57
#define pinNULL 128
// ----- Scan Mode (usually dual-scan) -----
// Ordered by increasing memory/CPU usage
#define scanRow 0 // Needed for powered switches (Hall-Effect)
#define scanCol 1 // Opposite of scanRow
#define scanRow_powrCol 2 // NKRO supported (simple detection)
#define scanCol_powrRow 3 // Opposite of scanRow_powrCol
#define scanDual 4 // Typical ~2KRO matrix
// ----- Scan Mode Setting -----
// ----- Scan Mode Setting (See matrix_scan.h for more details) -----
#define scanMode scanCol
@ -105,6 +37,7 @@
// ----- Key Settings -----
#define KEYBOARD_SIZE 16 // # of keys
#define MAX_ROW_SIZE 16 // # of keys in the largest row
#define MAX_COL_SIZE 1 // # of keys in the largest column
@ -131,31 +64,18 @@ static const uint8_t matrix_pinout[][MAX_ROW_SIZE + 1] = {
// ... |
{ scanMode, pinF4, pinA6, pinA1, pinA3, pinF5, pinA5, pinA2, pinF0, pinF6, pinA7, pinA0, pinF1, pinF3, pinF7, pinA4, pinF2 },
{ scanMode, pinF0, pinF4, pinB7, pinD3, pinF5, pinF1, pinD1, pinD2, pinF6, pinF7, pinB2, pinD0, pinB0, pinB6, pinB1, pinB3 },
{ pinNULL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
// Example Rows
//{ pinE0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
//{ pinE1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, },
//{ pinE1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0 },
};
// ----- 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 -----
#endif // __MATRIX_H

View File

@ -24,14 +24,20 @@
// AVR Includes
#include <avr/io.h>
// Project Includes
#include <print.h>
// Local Includes
#include "matrix.h"
#include "matrix_scan.h"
// Matrix Configuration
#include <matrix.h>
// ----- Macros -----
#define REG_SET(reg) reg |= (1 << ( matrix[row][col] % 10 ) )
#define REG_SET(reg) reg |= (1 << ( matrix[row*(MAX_ROW_SIZE+1)+col] % 10 ) )
#define PIN_SET_COL(pin) \
switch ( scanMode ) { \
@ -64,21 +70,20 @@
case pin##pinLetter##7
#define PIN_TEST_COL(pin) \
if ( !( pin & ( 1 << ( matrix[0][col] % 10 ) ) \
detectArray[matrix[row][col]]++; \
if ( !( pin & ( 1 << ( matrix[0*(MAX_ROW_SIZE+1)+col] % 10 ) ) ) ) \
detectArray[matrix[row*(MAX_ROW_SIZE+1)+col]]++; \
break
// ----- Variables -----
uint8_t KeyIndex_Array[KEYBOARD_SIZE + 1];
// ----- Functions -----
void matrix_pinSetup( uint8_t *matrix )
// Goes through the defined matrix and matrix mode, and sets the initial state of all of the available pins
inline void matrix_pinSetup( uint8_t *matrix )
{
// Setup the variables
uint8_t portA = 0x00;
@ -96,12 +101,14 @@ void matrix_pinSetup( uint8_t *matrix )
uint8_t ddrF = 0x00;
// Loop through all the pin assignments, for the initial pin settings
//int row, col;
uint16_t row, col;
// Rows
/*
for ( row = 1; row < sizeof(matrix); row++ ) {
switch ( matrix[row][col] ) {
for ( col = 0, row = 1; row < MAX_COL_SIZE + 1; row++ )
{
// We can't pass 2D arrays, so just point to the first element and calculate directly
switch ( matrix[row*(MAX_ROW_SIZE+1)+col] )
{
PIN_CASE(A):
PIN_SET_ROW(A);
PIN_CASE(B):
@ -121,8 +128,11 @@ void matrix_pinSetup( uint8_t *matrix )
}
// Columns
for ( col = 1; col < sizeof(matrix[0]); row++ ) {
switch ( matrix[row][col] ) {
for ( col = 1, row = 0; col < (MAX_ROW_SIZE+1) + 1; col++ )
{
// We can't pass 2D arrays, so just point to the first element and calculate directly
switch ( matrix[row*(MAX_ROW_SIZE+1)+col] )
{
PIN_CASE(A):
PIN_SET_COL(A);
PIN_CASE(B):
@ -140,17 +150,42 @@ void matrix_pinSetup( uint8_t *matrix )
continue;
}
}
*/
// Pin Status
char tmpStr[6];
info_print("Initial Matrix Pin Setup");
info_print(" ddrA ddrB ddrC ddrD ddrE ddrF");
print(" ");
hexToStr_op( ddrA, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( ddrB, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( ddrC, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( ddrD, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( ddrE, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( ddrF, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
print("\n");
info_print("portA portB portC portD portE portF");
print(" ");
hexToStr_op( portA, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( portB, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( portC, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( portD, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( portE, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
hexToStr_op( portF, tmpStr, 2 ); dPrintStrs( " 0x", tmpStr );
print("\n");
// Setting the pins
#if defined(__AVR_AT90USB1286__)
DDRA = ddrA;
#endif
DDRB = ddrB;
DDRC = ddrC;
DDRD = ddrD;
DDRE = ddrE;
DDRF = ddrF;
#if defined(__AVR_AT90USB1286__)
PORTA = portA;
#endif
PORTB = portB;
PORTC = portC;
PORTD = portD;
@ -159,17 +194,20 @@ void matrix_pinSetup( uint8_t *matrix )
}
// TODO Proper matrix scanning
void matrix_scan( uint8_t *matrix, uint8_t *detectArray )
inline void matrix_scan( uint8_t *matrix, uint8_t *detectArray )
{
// Column Scan
#if scanMode == scanCol
/*
uint8_t col = 1;
uint8_t row = 1;
for ( ; col < sizeof(matrix[1]); col++ ) {
switch ( matrix[0][col] / 10 ) {
uint16_t col = 1;
uint16_t row = 1;
for ( ; col < (MAX_ROW_SIZE+1) + 1; col++ )
{
switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 )
{
#if defined(__AVR_AT90USB1286__)
case 0: // PINA
PIN_TEST_COL(PINA);
#endif
case 1: // PINB
PIN_TEST_COL(PINB);
case 2: // PINC
@ -182,7 +220,6 @@ void matrix_scan( uint8_t *matrix, uint8_t *detectArray )
PIN_TEST_COL(PINF);
}
}
*/
#endif
// Row Scan

115
Scan/matrix/matrix_scan.h Normal file
View File

@ -0,0 +1,115 @@
/* 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 __MATRIX_SCAN_H
#define __MATRIX_SCAN_H
// ----- Includes -----
// Compiler Includes
#include <stdint.h>
// Local Includes
// ----- Defines -----
// ----- Quick Map (don't change) -----
#define pinA0 0
#define pinA1 1
#define pinA2 2
#define pinA3 3
#define pinA4 4
#define pinA5 5
#define pinA6 6
#define pinA7 7
#define pinB0 10
#define pinB1 11
#define pinB2 12
#define pinB3 13
#define pinB4 14
#define pinB5 15
#define pinB6 16
#define pinB7 17
#define pinC0 20
#define pinC1 21
#define pinC2 22
#define pinC3 23
#define pinC4 24
#define pinC5 25
#define pinC6 26
#define pinC7 27
#define pinD0 30
#define pinD1 31
#define pinD2 32
#define pinD3 33
#define pinD4 34
#define pinD5 35
#define pinD6 36
#define pinD7 37
#define pinE0 40
#define pinE1 41
#define pinE2 42
#define pinE3 43
#define pinE4 44
#define pinE5 45
#define pinE6 46
#define pinE7 47
#define pinF0 50
#define pinF1 51
#define pinF2 52
#define pinF3 53
#define pinF4 54
#define pinF5 55
#define pinF6 56
#define pinF7 57
#define pinNULL 128
// ----- Scan Mode (usually dual-scan) -----
// Ordered by increasing memory/CPU usage
#define scanRow 0 // Needed for powered switches (Hall-Effect)
#define scanCol 1 // Opposite of scanRow
#define scanRow_powrCol 2 // NKRO supported matrix (simple detection)
#define scanCol_powrRow 3 // Opposite of scanRow_powrCol
#define scanDual 4 // Typical ~2KRO matrix
// ----- Variables -----
// ----- Functions -----
void matrix_pinSetup( uint8_t *matrix );
void matrix_scan( uint8_t *matrix, uint8_t *detectArray );
#endif // __MATRIX_SCAN_H

View File

@ -21,8 +21,16 @@
// ----- Includes -----
// AVR Includes
#include <avr/interrupt.h>
// Project Includes
#include <led.h>
#include <print.h>
// Local Includes
#include "scan_loop.h"
#include "matrix_scan.h"
@ -40,9 +48,8 @@
// If the number of samples is higher than the sample threshold, flag the high bit, clear otherwise
// This should be resetting VERY quickly, cutting off a potentially valid keypress is not an issue
#define DEBOUNCE_ASSESS(table,size) \
for ( uint8_t key = 1; key < size + 1; key++ ) {\
table[key] = ( table[key] & ~(1 << 7) ) > SAMPLE_THRESHOLD ? (1 << 7) : 0x00; \
} \
for ( uint8_t key = 1; key < size + 1; key++ ) \
table[key] = ( table[key] & ~(1 << 7) ) > SAMPLE_THRESHOLD ? (1 << 7) : 0x00
@ -51,29 +58,39 @@
// Keeps track of the number of scans, so we only do a debounce assess when it would be valid (as it throws away data)
uint8_t scan_count = 0;
// This is where the matrix scan data is held, as well as debouncing is evaluated to, which (depending on the read value) is handled
// by the macro module
uint8_t KeyIndex_Array[KEYBOARD_SIZE + 1];
// ----- Functions -----
// Setup
void scan_setup()
inline void scan_setup()
{
//matrix_pinSetup( matrix_pinout );
matrix_pinSetup( (uint8_t*)matrix_pinout );
}
// Main Detection Loop
void scan_loop()
inline uint8_t scan_loop()
{
//matrix_scan( matrix_pinout, keyboardDetectArray );
// Check count to see if the sample threshold may have been reached, otherwise collect more data
if ( scan_count++ < MAX_SAMPLES )
return;
{
matrix_scan( (uint8_t*)matrix_pinout, KeyIndex_Array );
// Signal Main Detection Loop to continue scanning
return 0;
}
// Reset Sample Counter
scan_count = 0;
// Assess debouncing sample table
//DEBOUNCE_ASSESS(keyDetectArray,KEYBOARD_SIZE)
DEBOUNCE_ASSESS( KeyIndex_Array, KeyIndex_Size );
// Ready to allow for USB send
return 1;
}

View File

@ -24,15 +24,34 @@
// ----- Includes -----
// Compiler Includes
#include <stdint.h>
// Local Includes
#include "matrix.h"
#include "matrix_scan.h"
// Matrix Configuration
#include <matrix.h>
// ----- Defines -----
// ----- 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 );
void scan_loop( void );
uint8_t scan_loop( void );
#endif // __SCAN_LOOP_H

View File

@ -12,7 +12,7 @@
#
set( SCAN_SRCS
matrix.c
matrix_scan.c
scan_loop.c
)
@ -22,3 +22,9 @@ set( SCAN_SRCS
#
add_definitions( -I${HEAD_DIR}/Keymap )
#| Keymap Settings
add_definitions(
-DMODIFIER_MASK=tandy1000_modifierMask
-DKEYINDEX_MASK=tandy1000_colemak
)

View File

@ -135,7 +135,8 @@ static const uint8_t PROGMEM keyboard_hid_report_desc[] = {
};
static const uint8_t PROGMEM debug_hid_report_desc[] = {
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

11
main.c
View File

@ -62,8 +62,11 @@ volatile uint8_t sendKeypresses = 0;
// Initial Pin Setup, make sure they are sane
inline void pinSetup(void)
{
// For each pin, 0=input, 1=output
#if defined(__AVR_AT90USB1286__)
DDRA = 0x00;
#endif
DDRB = 0x00;
DDRC = 0x00;
DDRD = 0x00;
@ -72,7 +75,9 @@ inline void pinSetup(void)
// Setting pins to either high or pull-up resistor
#if defined(__AVR_AT90USB1286__)
PORTA = 0x00;
#endif
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
@ -113,13 +118,13 @@ int main(void)
while ( scan_loop() );
sei();
// Run Macros over Key Indices and convert to USB Keys
process_macros();
// Send keypresses over USB if the ISR has signalled that it's time
if ( !sendKeypresses )
continue;
// Run Macros over Key Indices and convert to USB Keys
process_macros();
// Send USB Data
usb_send();

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 "Tandy1000" )
set( ScanModule "matrix" )
##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code
set( MacroModule "basic" )