瀏覽代碼

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)
simple
Jacob Alexander 12 年之前
父節點
當前提交
6557022f20
共有 11 個文件被更改,包括 260 次插入140 次删除
  1. 1
    1
      CMakeLists.txt
  2. 15
    15
      Macro/basic/macro.c
  3. 5
    85
      Scan/matrix/matrix.h
  4. 58
    21
      Scan/matrix/matrix_scan.c
  5. 115
    0
      Scan/matrix/matrix_scan.h
  6. 27
    10
      Scan/matrix/scan_loop.c
  7. 21
    2
      Scan/matrix/scan_loop.h
  8. 7
    1
      Scan/matrix/setup.cmake
  9. 2
    1
      USB/pjrc/usb_keyboard_debug.c
  10. 8
    3
      main.c
  11. 1
    1
      setup.cmake

+ 1
- 1
CMakeLists.txt 查看文件

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

+ 15
- 15
Macro/basic/macro.c 查看文件

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

+ 5
- 85
Scan/matrix/matrix.h 查看文件

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



Scan/matrix/matrix.c → Scan/matrix/matrix_scan.c 查看文件

@@ -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
- 0
Scan/matrix/matrix_scan.h 查看文件

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


+ 27
- 10
Scan/matrix/scan_loop.c 查看文件

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


+ 21
- 2
Scan/matrix/scan_loop.h 查看文件

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


+ 7
- 1
Scan/matrix/setup.cmake 查看文件

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


+ 2
- 1
USB/pjrc/usb_keyboard_debug.c 查看文件

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

+ 8
- 3
main.c 查看文件

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


+ 1
- 1
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 "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" )