소스 검색

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