2020-06-09 08:21:05 +03:00
/* Copyright 2020 Frank Adams
Licensed under the Apache License , Version 2.0 ( the " License " ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an " AS IS " BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
*/
2020-08-01 08:22:07 +03:00
//
// ***************************************IMPORTANT*****************************************************************************
// ****************You must remove the LED on the Teensy ++2.0 in order to use this program***********************************
// ***************If you leave the LED installed, it will cause 1 15 to be displayed and then the program will hang**********
// *************************************The LED is controlled by PIN_D6 which is connected to FPC pin 15**********************
//
2020-06-09 08:21:05 +03:00
// It will determine how a laptop keyboard matrix is wired using a Teensy ++2.0 on an FPC daughterboard.
// Open an editor on a computer and load or create a file that lists every key
// on the laptop keyboard that will be tested. Connect the FPC cable of the test keyboard
// to the Teensy/FPC board. Connect a USB cable from the Teensy to the computer.
// Wait a few seconds for the computer to see the Teensy as a keyboard. If numbers are reported on the screen
// before any keys are pressed, these pin numbers are shorted together and must be fixed.
// Press each key one by one on the test keyboard as listed on the editor screen. When a key
// is pressed on the test keyboard, the program detects which two pins on the FPC connector
// were connected. Those two pin numbers are sent over USB (separated by a TAB) and displayed
// on the editor. After sending the numbers, a DOWN ARROW is sent over USB to prepare for
// the next key. Once all keys on the test keyboard have been pressed, the file in
// the editor can be saved to create a row-column matrix.
//
// If your keyboard has diodes, you must pay attention to the order of the two pins that are reported by the Teensy. The code performs
// a bottom up test first, followed by a top down test so that one of the two tests will forward bias the diode.
// The first pin reported over USB is the cathode side and the second pin is the anode side. The diode direction must be taken into
// account when programming the TMK or Teensyduino keyboard routine.
//
// Revision History
// Rev 1.00 - June 6, 2020 - Original Release
//
2020-08-01 08:22:07 +03:00
// Load an array with the Teensy ++2.0 I/O numbers that correspond to FPC pins 1 thru 36. LED HERE
2020-06-09 08:21:05 +03:00
int con_pin [ ] = { PIN_B7 , PIN_B6 , PIN_D0 , PIN_B5 , PIN_D1 , PIN_B4 , PIN_D2 , PIN_B3 , PIN_D3 , PIN_B2 , PIN_D4 , PIN_B1 , PIN_D5 , PIN_B0 , PIN_D6 , PIN_E7 , PIN_D7 , PIN_E6 ,
PIN_E0 , PIN_E1 , PIN_F0 , PIN_C0 , PIN_F1 , PIN_C1 , PIN_F2 , PIN_C2 , PIN_F3 , PIN_C3 , PIN_F4 , PIN_C4 , PIN_F5 , PIN_C5 , PIN_F6 , PIN_C6 , PIN_F7 , PIN_C7 } ;
//
// Define maximum and minimum pin numbers that will be tested.
// max_pin is usually set to the FPC connector size. min_pin is usually set to 1. The routine will start testing at pin 1 and go up to the max pin size.
// The max and min pin values can be adjusted to exclude testing the FPC traces at the edges if they are reported as shorted. An example would be if pin 1
// and pin 36 are both grounds. They will be reported as tied together but they are not needed by the key matrix. In this case, set the
// min_pin to 2 or the max_pin to 35.
//
2020-10-16 01:37:43 +03:00
int max_pin = 36 ; // the keyboard FPC connector pin count.
2020-06-09 08:21:05 +03:00
int min_pin = 1 ; // the first pin to be tested on the FPC connector (usually pin 1)
//
// load the key codes used in sending usb numbers, tab, and down arrow
int key_1 = KEY_1 ;
int key_2 = KEY_2 ;
int key_3 = KEY_3 ;
int key_4 = KEY_4 ;
int key_5 = KEY_5 ;
int key_6 = KEY_6 ;
int key_7 = KEY_7 ;
int key_8 = KEY_8 ;
int key_9 = KEY_9 ;
int key_0 = KEY_0 ;
int key_tab = KEY_TAB ;
int key_down = KEY_DOWN ;
//
// Function to set a pin as an input with a pullup so it's high unless grounded by a key press
void go_z ( int pin )
{
pinMode ( pin , INPUT_PULLUP ) ;
digitalWrite ( pin , HIGH ) ;
}
// Function to set a pin as an output and drive it to a logic low (0 volts)
void go_0 ( int pin )
{
pinMode ( pin , OUTPUT ) ;
digitalWrite ( pin , LOW ) ;
}
// Function to send numbers over USB for display on an editor
void usb_num ( int num ) // the numbers 0 thru 33 are sent over usb as 1 thru 34
{
switch ( num ) {
case 0 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
break ;
case 1 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
break ;
case 2 :
Keyboard . set_key1 ( key_3 ) ;
Keyboard . send_now ( ) ;
break ;
case 3 :
Keyboard . set_key1 ( key_4 ) ;
Keyboard . send_now ( ) ;
break ;
case 4 :
Keyboard . set_key1 ( key_5 ) ;
Keyboard . send_now ( ) ;
break ;
case 5 :
Keyboard . set_key1 ( key_6 ) ;
Keyboard . send_now ( ) ;
break ;
case 6 :
Keyboard . set_key1 ( key_7 ) ;
Keyboard . send_now ( ) ;
break ;
case 7 :
Keyboard . set_key1 ( key_8 ) ;
Keyboard . send_now ( ) ;
break ;
case 8 :
Keyboard . set_key1 ( key_9 ) ;
Keyboard . send_now ( ) ;
break ;
case 9 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_0 ) ;
Keyboard . send_now ( ) ;
break ;
case 10 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 50 ) ;
Keyboard . set_key1 ( 0 ) ;
Keyboard . send_now ( ) ;
delay ( 50 ) ;
Keyboard . set_key2 ( key_1 ) ;
Keyboard . send_now ( ) ;
break ;
case 11 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_2 ) ;
Keyboard . send_now ( ) ;
break ;
case 12 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_3 ) ;
Keyboard . send_now ( ) ;
break ;
case 13 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_4 ) ;
Keyboard . send_now ( ) ;
break ;
case 14 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_5 ) ;
Keyboard . send_now ( ) ;
break ;
case 15 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_6 ) ;
Keyboard . send_now ( ) ;
break ;
case 16 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_7 ) ;
Keyboard . send_now ( ) ;
break ;
case 17 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_8 ) ;
Keyboard . send_now ( ) ;
break ;
case 18 :
Keyboard . set_key1 ( key_1 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_9 ) ;
Keyboard . send_now ( ) ;
break ;
case 19 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_0 ) ;
Keyboard . send_now ( ) ;
break ;
case 20 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_1 ) ;
Keyboard . send_now ( ) ;
break ;
case 21 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 50 ) ;
Keyboard . set_key1 ( 0 ) ;
Keyboard . send_now ( ) ;
delay ( 50 ) ;
Keyboard . set_key2 ( key_2 ) ;
Keyboard . send_now ( ) ;
break ;
case 22 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_3 ) ;
Keyboard . send_now ( ) ;
break ;
case 23 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_4 ) ;
Keyboard . send_now ( ) ;
break ;
case 24 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_5 ) ;
Keyboard . send_now ( ) ;
break ;
case 25 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_6 ) ;
Keyboard . send_now ( ) ;
break ;
case 26 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_7 ) ;
Keyboard . send_now ( ) ;
break ;
case 27 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_8 ) ;
Keyboard . send_now ( ) ;
break ;
case 28 :
Keyboard . set_key1 ( key_2 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_9 ) ;
Keyboard . send_now ( ) ;
break ;
case 29 :
Keyboard . set_key1 ( key_3 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_0 ) ;
Keyboard . send_now ( ) ;
break ;
case 30 :
Keyboard . set_key1 ( key_3 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_1 ) ;
Keyboard . send_now ( ) ;
break ;
case 31 :
Keyboard . set_key1 ( key_3 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_2 ) ;
Keyboard . send_now ( ) ;
break ;
case 32 :
Keyboard . set_key1 ( key_3 ) ;
Keyboard . send_now ( ) ;
delay ( 50 ) ;
Keyboard . set_key1 ( 0 ) ;
Keyboard . send_now ( ) ;
delay ( 50 ) ;
Keyboard . set_key2 ( key_3 ) ;
Keyboard . send_now ( ) ;
break ;
case 33 :
Keyboard . set_key1 ( key_3 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key2 ( key_4 ) ;
Keyboard . send_now ( ) ;
break ;
}
delay ( 20 ) ;
Keyboard . set_key1 ( 0 ) ; // clear out the key slots
Keyboard . set_key2 ( 0 ) ;
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key1 ( key_tab ) ; // Tab over to position for next number
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key1 ( 0 ) ; // clear out the tab from the slot
Keyboard . send_now ( ) ;
delay ( 20 ) ;
}
// Function to send a down arrow over usb to position for the next key
void down_arrow ( void ) {
Keyboard . set_key1 ( key_down ) ; // send a down arrow
Keyboard . send_now ( ) ;
delay ( 20 ) ;
Keyboard . set_key1 ( 0 ) ; // release the down arrow
Keyboard . send_now ( ) ;
}
// --------------------------------------------------Setup-----------------------------------
void setup ( ) {
for ( int k = 0 ; k < max_pin ; k + + ) { // loop thru all connector pins
go_z ( con_pin [ k ] ) ; // set each pin as an input with a pullup
}
delay ( 15000 ) ; // Wait for the host to connect to the Teensy as a keyboard. If 2 pins are shorted,
// you want the host to be ready to receive the pin numbers.
}
//
// -------------------------------------------Main Loop--------------------------------------
//
void loop ( ) {
//
// ***********Bottom up Test************
//
for ( int i = min_pin - 1 ; i < max_pin - 1 ; i + + ) { // outer loop pin (min_pin-1 is typically = 0)
go_0 ( con_pin [ i ] ) ; // make the outer loop pin an output and send this pin low
for ( int j = i + 1 ; j < max_pin ; j + + ) { // inner loop pin
delayMicroseconds ( 10 ) ; // give time to let the signals settle out
if ( ! digitalRead ( con_pin [ j ] ) ) { // check for connection between inner and outer pins
usb_num ( i ) ; // send outer loop pin number over usb
usb_num ( j ) ; // send inner loop pin number over usb
down_arrow ( ) ; // send a down arrow over usb
while ( ! digitalRead ( con_pin [ j ] ) ) { // wait until key is released
; // if 2 pins are shorted, the code will hang here
}
}
}
go_z ( con_pin [ i ] ) ; // return the outer loop pin to float with pullup
}
//
// *********Top down Test***********
//
for ( int p = max_pin - 1 ; p > min_pin - 1 ; p - - ) { // outer loop pin
go_0 ( con_pin [ p ] ) ; // make the outer loop pin an output and send this pin low
for ( int r = p - 1 ; r > = min_pin - 1 ; r - - ) { // inner loop pin
delayMicroseconds ( 10 ) ; // give time to let the signals settle out
if ( ! digitalRead ( con_pin [ r ] ) ) { // check for connection between inner and outer pins
usb_num ( p ) ; // send outer loop pin number over usb
usb_num ( r ) ; // send inner loop pin number over usb
down_arrow ( ) ; // send a down arrow over usb
while ( ! digitalRead ( con_pin [ r ] ) ) { // wait until key is released
;
}
}
}
go_z ( con_pin [ p ] ) ; // return the outer loop pin to float with pullup
}
//
delay ( 25 ) ; // overall keyboard scan rate is about 30 milliseconds
//
}