Compare commits
11 commits
b3cd5c28a8
...
a8f211e6e5
Author | SHA1 | Date | |
---|---|---|---|
|
a8f211e6e5 | ||
|
ccbd9eebe2 | ||
|
89a9ff0243 | ||
|
4294250041 | ||
|
27be4d5a4d | ||
|
d5f0d32860 | ||
|
7864c6a0e9 | ||
|
ec29edd1ba | ||
|
e9a6f3ff66 | ||
|
0c7d36a77e | ||
|
f8e44fb1af |
14 changed files with 13487 additions and 6 deletions
397
Example_Keyboards/GRID_1550_US/GRID_1550_US.ino
Normal file
397
Example_Keyboards/GRID_1550_US/GRID_1550_US.ino
Normal file
|
@ -0,0 +1,397 @@
|
||||||
|
/* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
// This software implements a GRID 1550 Laptop Keyboard Controller using a Teensy LC
|
||||||
|
// for use with a Windows PC.
|
||||||
|
//
|
||||||
|
// Revision History
|
||||||
|
// Initial Release Dec 12, 2019 - Created from Linux version, uses alt codes for \ and | which are not
|
||||||
|
// compatible with Linux
|
||||||
|
//
|
||||||
|
#define MODIFIERKEY_FN 0x8f // give Fn key a fake HID code
|
||||||
|
#define CAPS_LED 13 // Teensy LED on IO#13 shows Caps-Lock. Add another LED (anode) on IO#13 with its own dropping resistor to ground.
|
||||||
|
#define NUM_LED 26 // Teensy IO#26 shows Num-Lock (wire to anode of new LED)then to a dropping resistor to ground.
|
||||||
|
//
|
||||||
|
const byte rows_max = 11; // sets the number of rows in the matrix
|
||||||
|
const byte cols_max = 13; // sets the number of columns in the matrix
|
||||||
|
//
|
||||||
|
// Load the normal key matrix with the Teensyduino key names
|
||||||
|
// described at www.pjrc.com/teensy/td_keyboard.html
|
||||||
|
// A zero indicates no normal key at that location.
|
||||||
|
int normal[rows_max][cols_max] = {
|
||||||
|
{0,0,0,0,0,KEY_F1,KEY_F2,KEY_F3,KEY_F4,KEY_F5,0,KEY_F9,0},
|
||||||
|
{KEY_SPACE,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,KEY_ESC,KEY_1,0,KEY_F6,KEY_F7,KEY_F8,KEY_F10,0},
|
||||||
|
{0,0,0,0,0,KEY_TAB,KEY_Q,KEY_W,KEY_2,KEY_3,0,KEY_6,0},
|
||||||
|
{0,0,0,0,0,KEY_CAPS_LOCK,KEY_A,KEY_S,KEY_E,KEY_4,KEY_5,KEY_7,0},
|
||||||
|
{0,0,0,0,KEY_LEFT,0,KEY_SPACE,KEY_Z,KEY_F,KEY_D,KEY_8,KEY_9,0},
|
||||||
|
{0,0,0,0,KEY_NUM_LOCK,KEY_SCROLL_LOCK,KEY_V,KEY_B,KEY_H,KEY_Y,KEY_U,KEY_MINUS,0},
|
||||||
|
{0,0,0,0,KEY_DOWN,0,KEY_X,KEY_C,KEY_G,KEY_R,KEY_T,KEY_0,0},
|
||||||
|
{0,0,0,0,KEY_TILDE,KEY_UP,KEY_N,KEY_M,KEY_J,KEY_K,KEY_I,KEY_INSERT,0},
|
||||||
|
{0,0,0,0,KEY_BACKSLASH,KEY_RIGHT_BRACE,KEY_COMMA,KEY_BACKSPACE,KEY_L,KEY_DELETE,KEY_O,KEY_EQUAL,0},
|
||||||
|
{0,0,0,0,KEY_RIGHT,KEY_ENTER,KEY_SLASH,KEY_PERIOD,KEY_QUOTE,KEY_SEMICOLON,KEY_LEFT_BRACE,KEY_P,0}
|
||||||
|
};
|
||||||
|
// Load the numlock key matrix with key names at the correct row-column location.
|
||||||
|
// This matrix is the same as the normal matrix except for the number pad keys
|
||||||
|
// A zero indicates no numlock key at that location.
|
||||||
|
int numlock[rows_max][cols_max] = {
|
||||||
|
{0,0,0,0,0,KEY_F1,KEY_F2,KEY_F3,KEY_F4,KEY_F5,0,KEY_F9,0},
|
||||||
|
{KEY_SPACE,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,KEY_ESC,KEY_1,0,KEY_F6,KEY_F7,KEY_F8,KEY_F10,0},
|
||||||
|
{0,0,0,0,0,KEY_TAB,KEY_Q,KEY_W,KEY_2,KEY_3,0,KEY_6,0},
|
||||||
|
{0,0,0,0,0,KEY_CAPS_LOCK,KEY_A,KEY_S,KEY_E,KEY_4,KEY_5,KEYPAD_7,0},
|
||||||
|
{0,0,0,0,KEY_LEFT,0,KEY_SPACE,KEY_Z,KEY_F,KEY_D,KEYPAD_8,KEYPAD_9,0},
|
||||||
|
{0,0,0,0,KEY_NUM_LOCK,KEY_SCROLL_LOCK,KEY_V,KEY_B,KEY_H,KEY_Y,KEYPAD_4,KEY_MINUS,0},
|
||||||
|
{0,0,0,0,KEY_DOWN,0,KEY_X,KEY_C,KEY_G,KEY_R,KEY_T,KEYPAD_ASTERIX,0},
|
||||||
|
{0,0,0,0,KEY_TILDE,KEY_UP,KEY_N,KEY_M,KEYPAD_1,KEYPAD_2,KEYPAD_5,KEY_INSERT,0},
|
||||||
|
{0,0,0,0,KEY_BACKSLASH,KEY_RIGHT_BRACE,KEYPAD_0,KEY_BACKSPACE,KEYPAD_3,KEY_DELETE,KEYPAD_6,KEY_EQUAL,0},
|
||||||
|
{0,0,0,0,KEY_RIGHT,KEY_ENTER,KEYPAD_SLASH,KEYPAD_PERIOD,KEY_QUOTE,KEYPAD_PLUS,KEY_LEFT_BRACE,KEYPAD_MINUS,0}
|
||||||
|
};
|
||||||
|
// Load the modifier key matrix with key names at the correct row-column location.
|
||||||
|
// A zero indicates no modifier key at that location.
|
||||||
|
int modifier[rows_max][cols_max] = {
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,MODIFIERKEY_RIGHT_SHIFT,MODIFIERKEY_LEFT_SHIFT,MODIFIERKEY_FN,0,0,0,0,0,0,0,0,MODIFIERKEY_LEFT_ALT},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,MODIFIERKEY_LEFT_CTRL,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
// Load the media key matrix with Fn key names at the correct row-column location.
|
||||||
|
// A zero indicates no media key at that location.
|
||||||
|
int media[rows_max][cols_max] = {
|
||||||
|
{0,0,0,0,0,0,0,0,0,KEY_MEDIA_MUTE,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,KEY_MEDIA_VOLUME_DEC,KEY_MEDIA_VOLUME_INC,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,KEY_HOME,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,KEY_PAGE_DOWN,KEY_PRINTSCREEN,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,KEY_PAGE_UP,0,0,0,0,0,KEY_F11,0},
|
||||||
|
{0,0,0,0,0,0,0,0,0,KEY_F12,0,0,0},
|
||||||
|
{0,0,0,0,KEY_END,0,0,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
// Initialize the old_key matrix with one's.
|
||||||
|
// 1 = key not pressed, 0 = key is pressed
|
||||||
|
boolean old_key[rows_max][cols_max] = {
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1,1,1,1,1,1}
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// Define the Teensy LC I/O numbers (translated from the FPC pin #)
|
||||||
|
// Row FPC pin # 23,21,19,17,15,13,11,07,03,01,05 (These are the FPC pins if a connector board is used)
|
||||||
|
// Teensy I/O # 14,15,16,17,18,19,20,21,22,23,24
|
||||||
|
int Row_IO[rows_max] = {14,15,16,17,18,19,20,21,22,23,24}; // Teensy LC I/O numbers for rows
|
||||||
|
//
|
||||||
|
// Column FPC pin # 02,04,06,08,10,12,14,16,18,20,22,24,26 (These are the FPC pins if a connector board is used)
|
||||||
|
// Teensy I/O # 00,01,02,03,04,05,06,07,08,09,10,11,12
|
||||||
|
int Col_IO[cols_max] = {0,1,2,3,4,5,6,7,8,9,10,11,12}; // Teensy LC I/O numbers for columns
|
||||||
|
|
||||||
|
// Declare variables that will be used by functions
|
||||||
|
boolean slots_full = LOW; // Goes high when slots 1 thru 6 contain normal keys
|
||||||
|
// slot 1 thru slot 6 hold the normal key values to be sent over USB.
|
||||||
|
int slot1 = 0; //value of 0 means the slot is empty and can be used.
|
||||||
|
int slot2 = 0;
|
||||||
|
int slot3 = 0;
|
||||||
|
int slot4 = 0;
|
||||||
|
int slot5 = 0;
|
||||||
|
int slot6 = 0;
|
||||||
|
//
|
||||||
|
int mod_shift_l = 0; // These variables are sent over USB as modifier keys.
|
||||||
|
int mod_shift_r = 0; // Each is either set to 0 or MODIFIER_ ...
|
||||||
|
int mod_ctrl_l = 0;
|
||||||
|
int mod_ctrl_r = 0;
|
||||||
|
int mod_alt_l = 0;
|
||||||
|
int mod_alt_r = 0;
|
||||||
|
int mod_gui = 0;
|
||||||
|
//
|
||||||
|
// Function to load the key name into the first available slot
|
||||||
|
void load_slot(int key) {
|
||||||
|
if (!slot1) {
|
||||||
|
slot1 = key;
|
||||||
|
}
|
||||||
|
else if (!slot2) {
|
||||||
|
slot2 = key;
|
||||||
|
}
|
||||||
|
else if (!slot3) {
|
||||||
|
slot3 = key;
|
||||||
|
}
|
||||||
|
else if (!slot4) {
|
||||||
|
slot4 = key;
|
||||||
|
}
|
||||||
|
else if (!slot5) {
|
||||||
|
slot5 = key;
|
||||||
|
}
|
||||||
|
else if (!slot6) {
|
||||||
|
slot6 = key;
|
||||||
|
}
|
||||||
|
if (!slot1 || !slot2 || !slot3 || !slot4 || !slot5 || !slot6) {
|
||||||
|
slots_full = LOW; // slots are not full
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slots_full = HIGH; // slots are full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to clear the slot that contains the key name
|
||||||
|
void clear_slot(int key) {
|
||||||
|
if (slot1 == key) {
|
||||||
|
slot1 = 0;
|
||||||
|
}
|
||||||
|
else if (slot2 == key) {
|
||||||
|
slot2 = 0;
|
||||||
|
}
|
||||||
|
else if (slot3 == key) {
|
||||||
|
slot3 = 0;
|
||||||
|
}
|
||||||
|
else if (slot4 == key) {
|
||||||
|
slot4 = 0;
|
||||||
|
}
|
||||||
|
else if (slot5 == key) {
|
||||||
|
slot5 = 0;
|
||||||
|
}
|
||||||
|
else if (slot6 == key) {
|
||||||
|
slot6 = 0;
|
||||||
|
}
|
||||||
|
if (!slot1 || !slot2 || !slot3 || !slot4 || !slot5 || !slot6) {
|
||||||
|
slots_full = LOW; // slots are not full
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slots_full = HIGH; // slots are full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to load the modifier key name into the appropriate mod variable
|
||||||
|
void load_mod(int m_key) {
|
||||||
|
if (m_key == MODIFIERKEY_LEFT_SHIFT) {
|
||||||
|
mod_shift_l = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_SHIFT) {
|
||||||
|
mod_shift_r = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_CTRL) {
|
||||||
|
mod_ctrl_l = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_CTRL) {
|
||||||
|
mod_ctrl_r = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_ALT) {
|
||||||
|
mod_alt_l = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_ALT) {
|
||||||
|
mod_alt_r = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_GUI) {
|
||||||
|
mod_gui = m_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to load 0 into the appropriate mod variable
|
||||||
|
void clear_mod(int m_key) {
|
||||||
|
if (m_key == MODIFIERKEY_LEFT_SHIFT) {
|
||||||
|
mod_shift_l = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_SHIFT) {
|
||||||
|
mod_shift_r = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_CTRL) {
|
||||||
|
mod_ctrl_l = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_CTRL) {
|
||||||
|
mod_ctrl_r = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_ALT) {
|
||||||
|
mod_alt_l = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_ALT) {
|
||||||
|
mod_alt_r = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_GUI) {
|
||||||
|
mod_gui = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send the modifier keys over usb
|
||||||
|
void send_mod() {
|
||||||
|
Keyboard.set_modifier(mod_shift_l | mod_shift_r | mod_ctrl_l | mod_ctrl_r | mod_alt_l | mod_alt_r | mod_gui);
|
||||||
|
Keyboard.send_now();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send the normal keys in the 6 slots over usb
|
||||||
|
void send_normals() {
|
||||||
|
Keyboard.set_key1(slot1);
|
||||||
|
Keyboard.set_key2(slot2);
|
||||||
|
Keyboard.set_key3(slot3);
|
||||||
|
Keyboard.set_key4(slot4);
|
||||||
|
Keyboard.set_key5(slot5);
|
||||||
|
Keyboard.set_key6(slot6);
|
||||||
|
Keyboard.send_now();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to set a pin to high impedance (acts like open drain output)
|
||||||
|
void go_z(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to set a pin as an input with a pullup
|
||||||
|
void go_pu(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, INPUT_PULLUP);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send a pin to a logic low
|
||||||
|
void go_0(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send a pin to a logic high
|
||||||
|
void go_1(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//----------------------------------Setup-------------------------------------------
|
||||||
|
void setup() {
|
||||||
|
for (int a = 0; a < cols_max; a++) { // loop thru all column pins
|
||||||
|
go_pu(Col_IO[a]); // set each column pin as an input with a pullup
|
||||||
|
}
|
||||||
|
//
|
||||||
|
for (int b = 0; b < rows_max; b++) { // loop thru all row pins
|
||||||
|
go_z(Row_IO[b]); // set each row pin as a floating output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
boolean Fn_pressed = HIGH; // Initialize Fn key to HIGH = "not pressed"
|
||||||
|
extern volatile uint8_t keyboard_leds; // 8 bits sent from Pi to Teensy that give keyboard LED status. Caps lock is bit D1.
|
||||||
|
//
|
||||||
|
//---------------------------------Main Loop---------------------------------------------
|
||||||
|
//
|
||||||
|
void loop() {
|
||||||
|
// Scan keyboard matrix with an outer loop that drives each row low and an inner loop that reads every column (with pull ups).
|
||||||
|
// The routine looks at each key's present state (by reading the column input pin) and also the previous state from the last scan
|
||||||
|
// that was 30msec ago. The status of a key that was just pressed or just released is sent over USB and the state is saved in the old_key matrix.
|
||||||
|
// The keyboard keys will read as logic low if they are pressed (negative logic).
|
||||||
|
// The old_key matrix also uses negative logic (low=pressed).
|
||||||
|
//
|
||||||
|
for (int x = 0; x < rows_max; x++) { // loop thru the rows
|
||||||
|
go_0(Row_IO[x]); // Activate Row (send it low)
|
||||||
|
delayMicroseconds(10); // give the row time to go low and settle out
|
||||||
|
for (int y = 0; y < cols_max; y++) { // loop thru the columns
|
||||||
|
// **********Modifier keys including the Fn special case
|
||||||
|
if (modifier[x][y] != 0) { // check if modifier key exists at this location in the array (a non-zero value)
|
||||||
|
if (!digitalRead(Col_IO[y]) && (old_key[x][y])) { // Read column to see if key is low (pressed) and was previously not pressed
|
||||||
|
if (modifier[x][y] != MODIFIERKEY_FN) { // Exclude Fn modifier key
|
||||||
|
load_mod(modifier[x][y]); // function reads which modifier key is pressed and loads it into the appropriate mod_... variable
|
||||||
|
send_mod(); // function sends the state of all modifier keys over usb including the one that just got pressed
|
||||||
|
old_key[x][y] = LOW; // Save state of key as "pressed"
|
||||||
|
}
|
||||||
|
else { // Fn is pressed
|
||||||
|
Fn_pressed = LOW; // Fn status variable is active low
|
||||||
|
old_key[x][y] = LOW; // old_key state is "pressed" (active low)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (digitalRead(Col_IO[y]) && (!old_key[x][y])) { //check if key is not pressed and was previously pressed
|
||||||
|
if (modifier[x][y] != MODIFIERKEY_FN) { // Exclude Fn modifier key
|
||||||
|
clear_mod(modifier[x][y]); // function reads which modifier key was released and loads 0 into the appropriate mod_... variable
|
||||||
|
send_mod(); // function sends all mod's over usb including the one that just released
|
||||||
|
old_key[x][y] = HIGH; // Save state of key as "not pressed"
|
||||||
|
}
|
||||||
|
else { // Fn is released
|
||||||
|
Fn_pressed = HIGH; // Fn is no longer active
|
||||||
|
old_key[x][y] = HIGH; // old_key state is "not pressed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ***********end of modifier section
|
||||||
|
//
|
||||||
|
// ***********Normal keys and media keys in this section
|
||||||
|
else if ((normal[x][y] != 0) || (media[x][y] != 0)) { // check if normal or media key exists at this location in the array
|
||||||
|
if (!digitalRead(Col_IO[y]) && (old_key[x][y]) && (!slots_full)) { // check if key pressed and not previously pressed and slots not full
|
||||||
|
old_key[x][y] = LOW; // Save state of key as "pressed"
|
||||||
|
if (Fn_pressed) { // Fn_pressed is active low so it is not pressed and normal key needs to be sent
|
||||||
|
if (keyboard_leds & 1) { // test if Num Lock is turned on
|
||||||
|
load_slot(numlock[x][y]); //update first available slot with key name from numlock matrix
|
||||||
|
send_normals(); // send all slots over USB including the key that just got pressed
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
load_slot(normal[x][y]); //update first available slot with key name from normal matrix
|
||||||
|
send_normals(); // send all slots over USB including the key that just got pressed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (media[x][y] != 0) { // Fn is pressed so send media if a key exists in the matrix
|
||||||
|
Keyboard.press(media[x][y]); // media key is sent using keyboard press function per PJRC
|
||||||
|
delay(5); // delay 5 milliseconds before releasing to make sure it gets sent over USB
|
||||||
|
Keyboard.release(media[x][y]); // send media key release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (digitalRead(Col_IO[y]) && (!old_key[x][y])) { //check if key is not pressed, but was previously pressed
|
||||||
|
old_key[x][y] = HIGH; // Save state of key as "not pressed"
|
||||||
|
if (Fn_pressed) { // Fn is not pressed
|
||||||
|
if (keyboard_leds & 1) { // test if Num Lock is turned on
|
||||||
|
clear_slot(numlock[x][y]); //clear slot with key name from numlock matrix
|
||||||
|
send_normals(); // send all slots over USB including the key that just got released
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clear_slot(normal[x][y]); //clear slot with key name from normal matrix
|
||||||
|
send_normals(); // send all slots over USB including the key that just got released
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// **************end of normal and media key section
|
||||||
|
//
|
||||||
|
}
|
||||||
|
go_z(Row_IO[x]); // De-activate Row (send it to hi-z)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// **********keyboard scan complete
|
||||||
|
//
|
||||||
|
// Turn on the LED on the Teensy for Caps Lock based on bit 1 in the keyboard_leds variable controlled by the USB host computer
|
||||||
|
//
|
||||||
|
if (keyboard_leds & 1<<1) { // mask off all bits but D1 and test if set
|
||||||
|
go_1(CAPS_LED); // turn on the LED
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go_0(CAPS_LED); // turn off the LED
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Turn on the LED on the Teensy for Num Lock based on bit 0 in the keyboard_leds variable controlled by the USB host computer
|
||||||
|
//
|
||||||
|
if (keyboard_leds & 1) { // mask off all bits but D0 and test if set
|
||||||
|
go_1(NUM_LED); // turn on the Num Lock LED
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go_0(NUM_LED); // turn off the Num Lock LED
|
||||||
|
}
|
||||||
|
//
|
||||||
|
delay(25); // The overall keyboard scanning rate is about 30ms
|
||||||
|
}
|
BIN
Example_Keyboards/GRID_1550_US/Grid 1550 US Keyboard layout.pdf
Normal file
BIN
Example_Keyboards/GRID_1550_US/Grid 1550 US Keyboard layout.pdf
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,338 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
// this software will determine how a laptop keyboard matrix is wired using a Teensy 4.0 on an T41 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 I/O 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 Teensy I/O's
|
||||||
|
// were connected. Those two I/O's 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.
|
||||||
|
//
|
||||||
|
// Revision History
|
||||||
|
// Rev 1.00 - Aug 10, 2023 - Original Release
|
||||||
|
//
|
||||||
|
// FPC 02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,32
|
||||||
|
// I/O 33,32,08,10,31,30,07,11,29,28,06,12,27,26,05,24,25,04,20,03,21,02,22,01
|
||||||
|
// Load an array with the Teensy 4.0 I/O numbers that correspond to the FPC pins
|
||||||
|
int io_pin[] = {33,32,8,10,31,30,7,11,29,28,6,12,27,26,5,24,25,4,20,3,21,2,22,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 0 thru 33
|
||||||
|
{
|
||||||
|
switch (num) {
|
||||||
|
case 0:
|
||||||
|
Keyboard.set_key1(key_0);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Keyboard.set_key1(key_3);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
Keyboard.set_key1(key_4);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
Keyboard.set_key1(key_5);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
Keyboard.set_key1(key_6);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
Keyboard.set_key1(key_7);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
Keyboard.set_key1(key_8);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
Keyboard.set_key1(key_9);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_0);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
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 12:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_3);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_4);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_5);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_6);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_7);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_8);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
Keyboard.set_key1(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_9);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_0);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
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 23:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_3);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_4);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_5);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_6);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_7);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_8);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
Keyboard.set_key1(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_9);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
Keyboard.set_key1(key_3);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_0);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
Keyboard.set_key1(key_3);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_1);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
Keyboard.set_key1(key_3);
|
||||||
|
Keyboard.send_now();
|
||||||
|
delay(20);
|
||||||
|
Keyboard.set_key2(key_2);
|
||||||
|
Keyboard.send_now();
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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 < 24; k++) { // loop thru all connected Teensy IO's
|
||||||
|
go_z(io_pin[k]); // set each I/O pin as an input with a pullup
|
||||||
|
}
|
||||||
|
delay(15000); // Wait for the host to connect to the Teensy as a keyboard. If 2 I/O pins are shorted,
|
||||||
|
// you want the host to be ready to receive the numbers.
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// -------------------------------------------Main Loop--------------------------------------
|
||||||
|
//
|
||||||
|
void loop() {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
for (int i=0; i<23; i++) { // outer loop index
|
||||||
|
go_0(io_pin[i]); // make the outer loop I/O pin an output and send it low
|
||||||
|
for (int j=i+1; j<24; j++) { // inner loop index
|
||||||
|
delayMicroseconds(10); // give time to let the signals settle out
|
||||||
|
if (!digitalRead(io_pin[j])) { // check for connection between inner and outer I/O pins
|
||||||
|
usb_num(io_pin[i]); // send outer loop I/O number over usb
|
||||||
|
usb_num(io_pin[j]); // send inner loop I/O number over usb
|
||||||
|
down_arrow(); // send a down arrow over usb
|
||||||
|
while(!digitalRead(io_pin[j])) { // wait until key is released
|
||||||
|
; // if 2 I/O pins are shorted, the code will hang here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go_z(io_pin[i]); // return the outer loop I/O pin to float with pullup
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
delay(25); // overall keyboard scan rate is about 30 milliseconds
|
||||||
|
//
|
||||||
|
}
|
1818
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41.brd
Normal file
1818
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41.brd
Normal file
File diff suppressed because it is too large
Load diff
5940
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41.sch
Normal file
5940
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41.sch
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
745
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41_TPad.brd
Normal file
745
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41_TPad.brd
Normal file
|
@ -0,0 +1,745 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE eagle SYSTEM "eagle.dtd">
|
||||||
|
<eagle version="9.6.2">
|
||||||
|
<drawing>
|
||||||
|
<settings>
|
||||||
|
<setting alwaysvectorfont="yes"/>
|
||||||
|
<setting verticaltext="up"/>
|
||||||
|
</settings>
|
||||||
|
<grid distance="0.1" unitdist="mm" unit="mm" style="lines" multiple="1" display="no" altdistance="5" altunitdist="mil" altunit="mil"/>
|
||||||
|
<layers>
|
||||||
|
<layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="17" name="Pads" color="2" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="18" name="Vias" color="2" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="20" name="Dimension" color="24" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="25" name="tNames" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="26" name="bNames" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="27" name="tValues" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="28" name="bValues" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="29" name="tStop" color="7" fill="3" visible="no" active="yes"/>
|
||||||
|
<layer number="30" name="bStop" color="7" fill="6" visible="no" active="yes"/>
|
||||||
|
<layer number="31" name="tCream" color="7" fill="4" visible="no" active="yes"/>
|
||||||
|
<layer number="32" name="bCream" color="7" fill="5" visible="no" active="yes"/>
|
||||||
|
<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="yes"/>
|
||||||
|
<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="yes"/>
|
||||||
|
<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="yes"/>
|
||||||
|
<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="yes"/>
|
||||||
|
<layer number="37" name="tTest" color="7" fill="1" visible="no" active="yes"/>
|
||||||
|
<layer number="38" name="bTest" color="7" fill="1" visible="no" active="yes"/>
|
||||||
|
<layer number="39" name="tKeepout" color="4" fill="11" visible="yes" active="yes"/>
|
||||||
|
<layer number="40" name="bKeepout" color="1" fill="11" visible="yes" active="yes"/>
|
||||||
|
<layer number="41" name="tRestrict" color="4" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="42" name="bRestrict" color="1" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="43" name="vRestrict" color="2" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
|
||||||
|
<layer number="45" name="Holes" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
|
||||||
|
<layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
|
||||||
|
<layer number="48" name="Document" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="49" name="Reference" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="51" name="tDocu" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="52" name="bDocu" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
|
||||||
|
<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
|
||||||
|
<layer number="56" name="wert" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="57" name="tCAD" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="59" name="tCarbon" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="60" name="bCarbon" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="88" name="SimResults" color="9" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="89" name="SimProbes" color="9" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="90" name="Modules" color="5" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="91" name="Nets" color="2" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="92" name="Busses" color="1" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="93" name="Pins" color="2" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="94" name="Symbols" color="4" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="95" name="Names" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="96" name="Values" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="97" name="Info" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="98" name="Guide" color="6" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="99" name="SpiceOrder" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="100" name="Muster" color="7" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="101" name="Patch_Top" color="12" fill="4" visible="yes" active="yes"/>
|
||||||
|
<layer number="102" name="Vscore" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="103" name="tMap" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="104" name="Name" color="16" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="105" name="tPlate" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="106" name="bPlate" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="107" name="Crop" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="108" name="tplace-old" color="10" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="109" name="ref-old" color="11" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="110" name="fp0" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="111" name="LPC17xx" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="112" name="tSilk" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="113" name="IDFDebug" color="4" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="114" name="Badge_Outline" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="115" name="ReferenceISLANDS" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="116" name="Patch_BOT" color="9" fill="4" visible="yes" active="yes"/>
|
||||||
|
<layer number="118" name="Rect_Pads" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="121" name="_tsilk" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="122" name="_bsilk" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="123" name="tTestmark" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="124" name="bTestmark" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="125" name="_tNames" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="126" name="_bNames" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="127" name="_tValues" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="128" name="_bValues" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="129" name="Mask" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="131" name="tAdjust" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="132" name="bAdjust" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="144" name="Drill_legend" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="150" name="Notes" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="151" name="HeatSink" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="152" name="_bDocu" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="153" name="FabDoc1" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="154" name="FabDoc2" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="155" name="FabDoc3" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="199" name="Contour" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="200" name="200bmp" color="1" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="201" name="201bmp" color="2" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="202" name="202bmp" color="3" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="203" name="203bmp" color="4" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="204" name="204bmp" color="5" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="205" name="205bmp" color="6" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="206" name="206bmp" color="7" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="207" name="207bmp" color="8" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="208" name="208bmp" color="9" fill="10" visible="yes" active="yes"/>
|
||||||
|
<layer number="209" name="209bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="210" name="210bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="211" name="211bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="212" name="212bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="213" name="213bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="214" name="214bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="215" name="215bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="216" name="216bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="217" name="217bmp" color="18" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="218" name="218bmp" color="19" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="219" name="219bmp" color="20" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="220" name="220bmp" color="21" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="221" name="221bmp" color="22" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="222" name="222bmp" color="23" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="223" name="223bmp" color="24" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="224" name="224bmp" color="25" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="225" name="225bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="226" name="226bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="227" name="227bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="228" name="228bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="229" name="229bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="230" name="230bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="231" name="231bmp" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="232" name="Eagle3D_PG2" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="233" name="Eagle3D_PG3" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="248" name="Housing" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="249" name="Edge" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="250" name="Descript" color="3" fill="1" visible="no" active="no"/>
|
||||||
|
<layer number="251" name="SMDround" color="12" fill="11" visible="no" active="no"/>
|
||||||
|
<layer number="254" name="cooling" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
<layer number="255" name="routoute" color="7" fill="1" visible="yes" active="yes"/>
|
||||||
|
</layers>
|
||||||
|
<board>
|
||||||
|
<plain>
|
||||||
|
<wire x1="0" y1="0" x2="17.5" y2="0" width="0" layer="20"/>
|
||||||
|
<wire x1="17.5" y1="0" x2="17.5" y2="19" width="0" layer="20"/>
|
||||||
|
<wire x1="17.5" y1="19" x2="0" y2="19" width="0" layer="20"/>
|
||||||
|
<wire x1="0" y1="19" x2="0" y2="0" width="0" layer="20"/>
|
||||||
|
<hole x="2" y="2" drill="2.4"/>
|
||||||
|
<hole x="15.5" y="17" drill="2.4"/>
|
||||||
|
<text x="6.5" y="12" size="0.6096" layer="21">1</text>
|
||||||
|
<text x="6.4" y="5.7" size="0.6096" layer="21">2</text>
|
||||||
|
<text x="10.9" y="12" size="0.6096" layer="21">19</text>
|
||||||
|
<text x="11" y="5.7" size="0.6096" layer="21">20</text>
|
||||||
|
<text x="0.8" y="13.1" size="0.6096" layer="21">1</text>
|
||||||
|
<text x="0.8" y="15.8" size="0.6096" layer="21">3</text>
|
||||||
|
<text x="3.2" y="13.2" size="0.6096" layer="21">5</text>
|
||||||
|
<text x="3.2" y="15.8" size="0.6096" layer="21">7</text>
|
||||||
|
<text x="5.8" y="13.3" size="0.6096" layer="21">9</text>
|
||||||
|
<text x="5.5" y="15.8" size="0.6096" layer="21">11</text>
|
||||||
|
<text x="7.9" y="13.2" size="0.6096" layer="21">13</text>
|
||||||
|
<text x="8" y="15.9" size="0.6096" layer="21">15</text>
|
||||||
|
<text x="10.4" y="13.3" size="0.6096" layer="21">17</text>
|
||||||
|
<text x="10.5" y="15.8" size="0.6096" layer="21">19</text>
|
||||||
|
<text x="4.1" y="5" size="0.6096" layer="21">2</text>
|
||||||
|
<text x="4.1" y="2.7" size="0.6096" layer="21">4</text>
|
||||||
|
<text x="6.6" y="5" size="0.6096" layer="21">6</text>
|
||||||
|
<text x="6.6" y="2.6" size="0.6096" layer="21">8</text>
|
||||||
|
<text x="8.8" y="5.1" size="0.6096" layer="21">10</text>
|
||||||
|
<text x="8.8" y="2.6" size="0.6096" layer="21">12</text>
|
||||||
|
<text x="11.3" y="5" size="0.6096" layer="21">14</text>
|
||||||
|
<text x="11.3" y="2.7" size="0.6096" layer="21">16</text>
|
||||||
|
<text x="13.8" y="5" size="0.6096" layer="21">18</text>
|
||||||
|
<text x="13.9" y="2.8" size="0.6096" layer="21">20</text>
|
||||||
|
<text x="14.9" y="10.7" size="0.6096" layer="21">Tab</text>
|
||||||
|
<text x="1.3" y="7.6" size="0.6096" layer="21">Tab</text>
|
||||||
|
<text x="0.8" y="11.6" size="0.6096" layer="21">DF12-20DP</text>
|
||||||
|
<text x="11.7" y="8.1" size="0.6096" layer="22" rot="MR0">DF12-20DP
|
||||||
|
T41 Touchpad
|
||||||
|
Connector Breakout</text>
|
||||||
|
</plain>
|
||||||
|
<libraries>
|
||||||
|
<library name="DF12-20DP">
|
||||||
|
<packages>
|
||||||
|
<package name="DF12-20DP">
|
||||||
|
<smd name="2" x="0" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="1" x="0" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="4" x="0.5" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="3" x="0.5" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="6" x="1" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="5" x="1" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="8" x="1.5" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="7" x="1.5" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="10" x="2" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="9" x="2" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="12" x="2.5" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="11" x="2.5" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="14" x="3" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="13" x="3" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="16" x="3.5" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="15" x="3.5" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="18" x="4" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="17" x="4" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="20" x="4.5" y="-1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="19" x="4.5" y="1.8" dx="1.6" dy="0.3" layer="1" rot="R90"/>
|
||||||
|
<smd name="TAB1" x="-1.75" y="0" dx="0.8" dy="1.7" layer="1"/>
|
||||||
|
<smd name="TAB2" x="6.25" y="0" dx="0.8" dy="1.7" layer="1"/>
|
||||||
|
<text x="-6.6" y="4.6" size="1.27" layer="25">>Name</text>
|
||||||
|
<text x="-6.6" y="3.2" size="1.27" layer="27">>Value</text>
|
||||||
|
<hole x="-1.05" y="1.5" drill="0.6"/>
|
||||||
|
<hole x="5.55" y="1.5" drill="0.6"/>
|
||||||
|
</package>
|
||||||
|
</packages>
|
||||||
|
</library>
|
||||||
|
<library name="SparkFun-Connectors" urn="urn:adsk.eagle:library:513">
|
||||||
|
<description><h3>SparkFun Connectors</h3>
|
||||||
|
This library contains electrically-functional connectors.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
We've spent an enormous amount of time creating and checking these footprints and parts, but it is <b> the end user's responsibility</b> to ensure correctness and suitablity for a given componet or application.
|
||||||
|
<br>
|
||||||
|
<br>If you enjoy using this library, please buy one of our products at <a href=" www.sparkfun.com">SparkFun.com</a>.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.</description>
|
||||||
|
<packages>
|
||||||
|
<package name="2X5_NOSILK" urn="urn:adsk.eagle:footprint:37735/1" library_version="1">
|
||||||
|
<description><h3>Plated Through Hole - 2x5 No Silk Outline</h3>
|
||||||
|
<p>Specifications:
|
||||||
|
<ul><li>Pin count:10</li>
|
||||||
|
<li>Pin pitch:0.1"</li>
|
||||||
|
</ul></p>
|
||||||
|
<p>Example device(s):
|
||||||
|
<ul><li>CONN_05x2</li>
|
||||||
|
</ul></p></description>
|
||||||
|
<pad name="1" x="0" y="0" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="2" x="0" y="2.54" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="3" x="2.54" y="0" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="4" x="2.54" y="2.54" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="5" x="5.08" y="0" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="6" x="5.08" y="2.54" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="7" x="7.62" y="0" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="8" x="7.62" y="2.54" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="9" x="10.16" y="0" drill="1.016" diameter="1.8796"/>
|
||||||
|
<pad name="10" x="10.16" y="2.54" drill="1.016" diameter="1.8796"/>
|
||||||
|
<rectangle x1="-0.254" y1="-0.254" x2="0.254" y2="0.254" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="-0.254" y1="2.286" x2="0.254" y2="2.794" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="2.286" y1="2.286" x2="2.794" y2="2.794" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="2.286" y1="-0.254" x2="2.794" y2="0.254" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="4.826" y1="-0.254" x2="5.334" y2="0.254" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="9.906" y1="2.286" x2="10.414" y2="2.794" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="9.906" y1="-0.254" x2="10.414" y2="0.254" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="7.366" y1="-0.254" x2="7.874" y2="0.254" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="7.366" y1="2.286" x2="7.874" y2="2.794" layer="51" rot="R90"/>
|
||||||
|
<rectangle x1="4.826" y1="2.286" x2="5.334" y2="2.794" layer="51" rot="R90"/>
|
||||||
|
<wire x1="0.635" y1="-1.27" x2="-0.635" y2="-1.27" width="0.2032" layer="51"/>
|
||||||
|
<text x="-0.889" y="3.81" size="0.6096" layer="25" font="vector" ratio="20">>NAME</text>
|
||||||
|
<text x="-0.762" y="-2.159" size="0.6096" layer="27" font="vector" ratio="20">>VALUE</text>
|
||||||
|
</package>
|
||||||
|
<package name="1X01" urn="urn:adsk.eagle:footprint:37642/1" library_version="1">
|
||||||
|
<description><h3>Plated Through Hole</h3>
|
||||||
|
<p>Specifications:
|
||||||
|
<ul><li>Pin count:1</li>
|
||||||
|
<li>Pin pitch:0.1"</li>
|
||||||
|
</ul></p>
|
||||||
|
<p>Example device(s):
|
||||||
|
<ul><li>CONN_01</li>
|
||||||
|
</ul></p></description>
|
||||||
|
<wire x1="1.27" y1="0.635" x2="0.635" y2="1.27" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="0.635" y1="1.27" x2="-0.635" y2="1.27" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="-0.635" y1="1.27" x2="-1.27" y2="0.635" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="-1.27" y1="0.635" x2="-1.27" y2="-0.635" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="-1.27" y1="-0.635" x2="-0.635" y2="-1.27" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="-0.635" y1="-1.27" x2="0.635" y2="-1.27" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="0.635" y1="-1.27" x2="1.27" y2="-0.635" width="0.2032" layer="21"/>
|
||||||
|
<wire x1="1.27" y1="-0.635" x2="1.27" y2="0.635" width="0.2032" layer="21"/>
|
||||||
|
<pad name="1" x="0" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
|
||||||
|
<text x="-1.27" y="1.397" size="0.6096" layer="25" font="vector" ratio="20">>NAME</text>
|
||||||
|
<text x="-1.27" y="-1.524" size="0.6096" layer="27" font="vector" ratio="20" align="top-left">>VALUE</text>
|
||||||
|
<rectangle x1="-0.254" y1="-0.254" x2="0.254" y2="0.254" layer="51"/>
|
||||||
|
</package>
|
||||||
|
</packages>
|
||||||
|
<packages3d>
|
||||||
|
<package3d name="2X5_NOSILK" urn="urn:adsk.eagle:package:38114/1" type="box" library_version="1">
|
||||||
|
<description>Plated Through Hole - 2x5 No Silk Outline
|
||||||
|
Specifications:
|
||||||
|
Pin count:10
|
||||||
|
Pin pitch:0.1"
|
||||||
|
|
||||||
|
Example device(s):
|
||||||
|
CONN_05x2
|
||||||
|
</description>
|
||||||
|
<packageinstances>
|
||||||
|
<packageinstance name="2X5_NOSILK"/>
|
||||||
|
</packageinstances>
|
||||||
|
</package3d>
|
||||||
|
<package3d name="1X01" urn="urn:adsk.eagle:package:38028/1" type="box" library_version="1">
|
||||||
|
<description>Plated Through Hole
|
||||||
|
Specifications:
|
||||||
|
Pin count:1
|
||||||
|
Pin pitch:0.1"
|
||||||
|
|
||||||
|
Example device(s):
|
||||||
|
CONN_01
|
||||||
|
</description>
|
||||||
|
<packageinstances>
|
||||||
|
<packageinstance name="1X01"/>
|
||||||
|
</packageinstances>
|
||||||
|
</package3d>
|
||||||
|
</packages3d>
|
||||||
|
</library>
|
||||||
|
</libraries>
|
||||||
|
<attributes>
|
||||||
|
</attributes>
|
||||||
|
<variantdefs>
|
||||||
|
</variantdefs>
|
||||||
|
<classes>
|
||||||
|
<class number="0" name="default" width="0" drill="0">
|
||||||
|
</class>
|
||||||
|
</classes>
|
||||||
|
<designrules name="oshpark-2layer">
|
||||||
|
<description language="en"><b>OSH Park Design Rules</b>
|
||||||
|
<p>
|
||||||
|
Please make sure your boards conform to these design rules.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Note, that not all DRC settings must be set by the manufacturer. Several can be adjusted for the design, including those listed on our docs page here.
|
||||||
|
<a href="http://docs.oshpark.com/design-tools/eagle/design-rules-files/">Adjustable Settings</a>
|
||||||
|
</p></description>
|
||||||
|
<param name="layerSetup" value="(1*16)"/>
|
||||||
|
<param name="mtCopper" value="0.035559375mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.0356mm 0.035559375mm"/>
|
||||||
|
<param name="mtIsolate" value="1.6mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm 0.1499mm 0.2007mm"/>
|
||||||
|
<param name="mdWireWire" value="6mil"/>
|
||||||
|
<param name="mdWirePad" value="6mil"/>
|
||||||
|
<param name="mdWireVia" value="6mil"/>
|
||||||
|
<param name="mdPadPad" value="6mil"/>
|
||||||
|
<param name="mdPadVia" value="6mil"/>
|
||||||
|
<param name="mdViaVia" value="6mil"/>
|
||||||
|
<param name="mdSmdPad" value="6mil"/>
|
||||||
|
<param name="mdSmdVia" value="6mil"/>
|
||||||
|
<param name="mdSmdSmd" value="6mil"/>
|
||||||
|
<param name="mdViaViaSameLayer" value="8mil"/>
|
||||||
|
<param name="mnLayersViaInSmd" value="2"/>
|
||||||
|
<param name="mdCopperDimension" value="15mil"/>
|
||||||
|
<param name="mdDrill" value="6mil"/>
|
||||||
|
<param name="mdSmdStop" value="0mil"/>
|
||||||
|
<param name="msWidth" value="6mil"/>
|
||||||
|
<param name="msDrill" value="10mil"/>
|
||||||
|
<param name="msMicroVia" value="10mil"/>
|
||||||
|
<param name="msBlindViaRatio" value="0.5"/>
|
||||||
|
<param name="rvPadTop" value="0.25"/>
|
||||||
|
<param name="rvPadInner" value="0.25"/>
|
||||||
|
<param name="rvPadBottom" value="0.25"/>
|
||||||
|
<param name="rvViaOuter" value="0.25"/>
|
||||||
|
<param name="rvViaInner" value="0.25"/>
|
||||||
|
<param name="rvMicroViaOuter" value="0.25"/>
|
||||||
|
<param name="rvMicroViaInner" value="0.25"/>
|
||||||
|
<param name="rlMinPadTop" value="5mil"/>
|
||||||
|
<param name="rlMaxPadTop" value="20mil"/>
|
||||||
|
<param name="rlMinPadInner" value="5mil"/>
|
||||||
|
<param name="rlMaxPadInner" value="20mil"/>
|
||||||
|
<param name="rlMinPadBottom" value="5mil"/>
|
||||||
|
<param name="rlMaxPadBottom" value="20mil"/>
|
||||||
|
<param name="rlMinViaOuter" value="5mil"/>
|
||||||
|
<param name="rlMaxViaOuter" value="20mil"/>
|
||||||
|
<param name="rlMinViaInner" value="5mil"/>
|
||||||
|
<param name="rlMaxViaInner" value="20mil"/>
|
||||||
|
<param name="rlMinMicroViaOuter" value="5mil"/>
|
||||||
|
<param name="rlMaxMicroViaOuter" value="20mil"/>
|
||||||
|
<param name="rlMinMicroViaInner" value="5mil"/>
|
||||||
|
<param name="rlMaxMicroViaInner" value="20mil"/>
|
||||||
|
<param name="psTop" value="-1"/>
|
||||||
|
<param name="psBottom" value="-1"/>
|
||||||
|
<param name="psFirst" value="-1"/>
|
||||||
|
<param name="psElongationLong" value="100"/>
|
||||||
|
<param name="psElongationOffset" value="100"/>
|
||||||
|
<param name="mvStopFrame" value="1"/>
|
||||||
|
<param name="mvCreamFrame" value="0"/>
|
||||||
|
<param name="mlMinStopFrame" value="2.5mil"/>
|
||||||
|
<param name="mlMaxStopFrame" value="2.5mil"/>
|
||||||
|
<param name="mlMinCreamFrame" value="0mil"/>
|
||||||
|
<param name="mlMaxCreamFrame" value="0mil"/>
|
||||||
|
<param name="mlViaStopLimit" value="0mil"/>
|
||||||
|
<param name="srRoundness" value="0"/>
|
||||||
|
<param name="srMinRoundness" value="0mil"/>
|
||||||
|
<param name="srMaxRoundness" value="0mil"/>
|
||||||
|
<param name="slThermalIsolate" value="10mil"/>
|
||||||
|
<param name="slThermalsForVias" value="0"/>
|
||||||
|
<param name="dpMaxLengthDifference" value="10mm"/>
|
||||||
|
<param name="dpGapFactor" value="2.5"/>
|
||||||
|
<param name="checkAngle" value="0"/>
|
||||||
|
<param name="checkFont" value="1"/>
|
||||||
|
<param name="checkRestrict" value="1"/>
|
||||||
|
<param name="checkStop" value="0"/>
|
||||||
|
<param name="checkValues" value="0"/>
|
||||||
|
<param name="checkNames" value="1"/>
|
||||||
|
<param name="checkWireStubs" value="1"/>
|
||||||
|
<param name="checkPolygonWidth" value="0"/>
|
||||||
|
<param name="useDiameter" value="13"/>
|
||||||
|
<param name="maxErrors" value="50"/>
|
||||||
|
</designrules>
|
||||||
|
<autorouter>
|
||||||
|
<pass name="Default">
|
||||||
|
<param name="RoutingGrid" value="50mil"/>
|
||||||
|
<param name="AutoGrid" value="1"/>
|
||||||
|
<param name="Efforts" value="0"/>
|
||||||
|
<param name="TopRouterVariant" value="1"/>
|
||||||
|
<param name="tpViaShape" value="round"/>
|
||||||
|
<param name="PrefDir.1" value="a"/>
|
||||||
|
<param name="PrefDir.2" value="0"/>
|
||||||
|
<param name="PrefDir.3" value="0"/>
|
||||||
|
<param name="PrefDir.4" value="0"/>
|
||||||
|
<param name="PrefDir.5" value="0"/>
|
||||||
|
<param name="PrefDir.6" value="0"/>
|
||||||
|
<param name="PrefDir.7" value="0"/>
|
||||||
|
<param name="PrefDir.8" value="0"/>
|
||||||
|
<param name="PrefDir.9" value="0"/>
|
||||||
|
<param name="PrefDir.10" value="0"/>
|
||||||
|
<param name="PrefDir.11" value="0"/>
|
||||||
|
<param name="PrefDir.12" value="0"/>
|
||||||
|
<param name="PrefDir.13" value="0"/>
|
||||||
|
<param name="PrefDir.14" value="0"/>
|
||||||
|
<param name="PrefDir.15" value="0"/>
|
||||||
|
<param name="PrefDir.16" value="a"/>
|
||||||
|
<param name="cfVia" value="8"/>
|
||||||
|
<param name="cfNonPref" value="5"/>
|
||||||
|
<param name="cfChangeDir" value="2"/>
|
||||||
|
<param name="cfOrthStep" value="2"/>
|
||||||
|
<param name="cfDiagStep" value="3"/>
|
||||||
|
<param name="cfExtdStep" value="0"/>
|
||||||
|
<param name="cfBonusStep" value="1"/>
|
||||||
|
<param name="cfMalusStep" value="1"/>
|
||||||
|
<param name="cfPadImpact" value="4"/>
|
||||||
|
<param name="cfSmdImpact" value="4"/>
|
||||||
|
<param name="cfBusImpact" value="0"/>
|
||||||
|
<param name="cfHugging" value="3"/>
|
||||||
|
<param name="cfAvoid" value="4"/>
|
||||||
|
<param name="cfPolygon" value="10"/>
|
||||||
|
<param name="cfBase.1" value="0"/>
|
||||||
|
<param name="cfBase.2" value="1"/>
|
||||||
|
<param name="cfBase.3" value="1"/>
|
||||||
|
<param name="cfBase.4" value="1"/>
|
||||||
|
<param name="cfBase.5" value="1"/>
|
||||||
|
<param name="cfBase.6" value="1"/>
|
||||||
|
<param name="cfBase.7" value="1"/>
|
||||||
|
<param name="cfBase.8" value="1"/>
|
||||||
|
<param name="cfBase.9" value="1"/>
|
||||||
|
<param name="cfBase.10" value="1"/>
|
||||||
|
<param name="cfBase.11" value="1"/>
|
||||||
|
<param name="cfBase.12" value="1"/>
|
||||||
|
<param name="cfBase.13" value="1"/>
|
||||||
|
<param name="cfBase.14" value="1"/>
|
||||||
|
<param name="cfBase.15" value="1"/>
|
||||||
|
<param name="cfBase.16" value="0"/>
|
||||||
|
<param name="mnVias" value="20"/>
|
||||||
|
<param name="mnSegments" value="9999"/>
|
||||||
|
<param name="mnExtdSteps" value="9999"/>
|
||||||
|
<param name="mnRipupLevel" value="10"/>
|
||||||
|
<param name="mnRipupSteps" value="100"/>
|
||||||
|
<param name="mnRipupTotal" value="100"/>
|
||||||
|
</pass>
|
||||||
|
<pass name="Follow-me" refer="Default" active="yes">
|
||||||
|
</pass>
|
||||||
|
<pass name="Busses" refer="Default" active="yes">
|
||||||
|
<param name="cfNonPref" value="4"/>
|
||||||
|
<param name="cfBusImpact" value="4"/>
|
||||||
|
<param name="cfHugging" value="0"/>
|
||||||
|
<param name="mnVias" value="0"/>
|
||||||
|
</pass>
|
||||||
|
<pass name="Route" refer="Default" active="yes">
|
||||||
|
</pass>
|
||||||
|
<pass name="Optimize1" refer="Default" active="yes">
|
||||||
|
<param name="cfVia" value="99"/>
|
||||||
|
<param name="cfExtdStep" value="10"/>
|
||||||
|
<param name="cfHugging" value="1"/>
|
||||||
|
<param name="mnExtdSteps" value="1"/>
|
||||||
|
<param name="mnRipupLevel" value="0"/>
|
||||||
|
</pass>
|
||||||
|
<pass name="Optimize2" refer="Optimize1" active="yes">
|
||||||
|
<param name="cfNonPref" value="0"/>
|
||||||
|
<param name="cfChangeDir" value="6"/>
|
||||||
|
<param name="cfExtdStep" value="0"/>
|
||||||
|
<param name="cfBonusStep" value="2"/>
|
||||||
|
<param name="cfMalusStep" value="2"/>
|
||||||
|
<param name="cfPadImpact" value="2"/>
|
||||||
|
<param name="cfSmdImpact" value="2"/>
|
||||||
|
<param name="cfHugging" value="0"/>
|
||||||
|
</pass>
|
||||||
|
<pass name="Optimize3" refer="Optimize2" active="yes">
|
||||||
|
<param name="cfChangeDir" value="8"/>
|
||||||
|
<param name="cfPadImpact" value="0"/>
|
||||||
|
<param name="cfSmdImpact" value="0"/>
|
||||||
|
</pass>
|
||||||
|
<pass name="Optimize4" refer="Optimize3" active="yes">
|
||||||
|
<param name="cfChangeDir" value="25"/>
|
||||||
|
</pass>
|
||||||
|
</autorouter>
|
||||||
|
<elements>
|
||||||
|
<element name="J1" library="DF12-20DP" package="DF12-20DP" value="" x="6.62" y="9.12" smashed="yes">
|
||||||
|
<attribute name="NAME" x="0.02" y="13.72" size="1.27" layer="25" display="off"/>
|
||||||
|
<attribute name="VALUE" x="0.02" y="12.32" size="1.27" layer="27"/>
|
||||||
|
</element>
|
||||||
|
<element name="J2" library="SparkFun-Connectors" library_urn="urn:adsk.eagle:library:513" package="2X5_NOSILK" package3d_urn="urn:adsk.eagle:package:38114/1" value="" x="5.35" y="1.9" smashed="yes">
|
||||||
|
<attribute name="NAME" x="4.461" y="5.71" size="0.6096" layer="25" font="vector" ratio="20" display="off"/>
|
||||||
|
<attribute name="VALUE" x="4.588" y="-0.259" size="0.6096" layer="27" font="vector" ratio="20"/>
|
||||||
|
</element>
|
||||||
|
<element name="J3" library="SparkFun-Connectors" library_urn="urn:adsk.eagle:library:513" package="2X5_NOSILK" package3d_urn="urn:adsk.eagle:package:38114/1" value="" x="2" y="14.5" smashed="yes">
|
||||||
|
<attribute name="NAME" x="1.111" y="18.31" size="0.6096" layer="25" font="vector" ratio="20" display="off"/>
|
||||||
|
<attribute name="VALUE" x="1.238" y="12.341" size="0.6096" layer="27" font="vector" ratio="20"/>
|
||||||
|
</element>
|
||||||
|
<element name="J4" library="SparkFun-Connectors" library_urn="urn:adsk.eagle:library:513" package="1X01" package3d_urn="urn:adsk.eagle:package:38028/1" value="" x="1.9" y="6.1" smashed="yes">
|
||||||
|
<attribute name="NAME" x="0.63" y="7.497" size="0.6096" layer="25" font="vector" ratio="20" display="off"/>
|
||||||
|
<attribute name="VALUE" x="0.63" y="4.576" size="0.6096" layer="27" font="vector" ratio="20" align="top-left"/>
|
||||||
|
</element>
|
||||||
|
<element name="J5" library="SparkFun-Connectors" library_urn="urn:adsk.eagle:library:513" package="1X01" package3d_urn="urn:adsk.eagle:package:38028/1" value="" x="15.5" y="12.9" smashed="yes">
|
||||||
|
<attribute name="NAME" x="14.23" y="14.297" size="0.6096" layer="25" font="vector" ratio="20" display="off"/>
|
||||||
|
<attribute name="VALUE" x="14.23" y="11.376" size="0.6096" layer="27" font="vector" ratio="20" align="top-left"/>
|
||||||
|
</element>
|
||||||
|
</elements>
|
||||||
|
<signals>
|
||||||
|
<signal name="N$21">
|
||||||
|
<contactref element="J1" pad="TAB1"/>
|
||||||
|
<contactref element="J4" pad="1"/>
|
||||||
|
<wire x1="4.87" y1="9.12" x2="4.85" y2="9.1" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="4.85" y1="9.1" x2="2.5" y2="9.1" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="2.5" y1="9.1" x2="1.9" y2="8.5" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="1.9" y1="8.5" x2="1.9" y2="6.1" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$22">
|
||||||
|
<contactref element="J1" pad="TAB2"/>
|
||||||
|
<contactref element="J5" pad="1"/>
|
||||||
|
<wire x1="15.5" y1="12.9" x2="15.2934875" y2="12.97250625" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="15.2934875" y1="12.97250625" x2="12.87" y2="9.12" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$2">
|
||||||
|
<contactref element="J1" pad="3"/>
|
||||||
|
<contactref element="J3" pad="2"/>
|
||||||
|
<wire x1="7.12" y1="10.92" x2="7.12" y2="11.78" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.3" y1="12.6" x2="3.8" y2="12.6" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="3.8" y1="12.6" x2="3.3" y2="13.1" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="3.3" y1="15.74" x2="2" y2="17.04" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="7.12" y1="11.78" x2="6.3" y2="12.6" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="3.3" y1="13.1" x2="3.3" y2="15.74" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$3">
|
||||||
|
<contactref element="J1" pad="1"/>
|
||||||
|
<contactref element="J3" pad="1"/>
|
||||||
|
<wire x1="6.62" y1="10.92" x2="6.62" y2="11.28" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5.7" y1="12.2" x2="2.1" y2="12.2" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="2.1" y1="12.2" x2="2" y2="12.3" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="2" y1="12.3" x2="2" y2="14.5" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.62" y1="11.28" x2="5.7" y2="12.2" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$4">
|
||||||
|
<contactref element="J1" pad="5"/>
|
||||||
|
<contactref element="J3" pad="3"/>
|
||||||
|
<wire x1="7.62" y1="10.92" x2="7.62" y2="11.78" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="7.62" y1="11.78" x2="6.4" y2="13" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.4" y1="13" x2="5" y2="13" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5" y1="13" x2="4.54" y2="13.46" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="4.54" y1="13.46" x2="4.54" y2="14.5" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$5">
|
||||||
|
<contactref element="J1" pad="7"/>
|
||||||
|
<contactref element="J3" pad="4"/>
|
||||||
|
<wire x1="8.12" y1="10.92" x2="8.12" y2="11.78" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.5952" y1="13.3048" x2="6.1" y2="13.3048" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.1" y1="13.3048" x2="5.8" y2="13.6048" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5.8" y1="15.78" x2="4.54" y2="17.04" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="8.12" y1="11.78" x2="6.5952" y2="13.3048" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5.8" y1="13.6048" x2="5.8" y2="15.78" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$6">
|
||||||
|
<contactref element="J1" pad="9"/>
|
||||||
|
<contactref element="J3" pad="5"/>
|
||||||
|
<wire x1="8.62" y1="10.92" x2="8.62" y2="11.88" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="7.08" y1="13.42" x2="7.08" y2="14.5" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="8.62" y1="11.88" x2="7.08" y2="13.42" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$7">
|
||||||
|
<contactref element="J1" pad="11"/>
|
||||||
|
<contactref element="J3" pad="6"/>
|
||||||
|
<wire x1="9.12" y1="10.92" x2="9.12" y2="12.08" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="8.3" y1="15.82" x2="7.08" y2="17.04" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.12" y1="12.08" x2="8.3" y2="12.9" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="8.3" y1="12.9" x2="8.3" y2="15.82" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$8">
|
||||||
|
<contactref element="J1" pad="13"/>
|
||||||
|
<contactref element="J3" pad="7"/>
|
||||||
|
<wire x1="9.62" y1="10.92" x2="9.62" y2="14.5" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$9">
|
||||||
|
<contactref element="J1" pad="15"/>
|
||||||
|
<contactref element="J3" pad="8"/>
|
||||||
|
<wire x1="10.12" y1="10.92" x2="10.12" y2="13.02" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.12" y1="13.02" x2="10.9" y2="13.8" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.9" y1="13.8" x2="10.9" y2="15.4" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.62" y1="16.68" x2="9.62" y2="17.04" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.9" y1="15.4" x2="9.62" y2="16.68" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$10">
|
||||||
|
<contactref element="J1" pad="17"/>
|
||||||
|
<contactref element="J3" pad="9"/>
|
||||||
|
<wire x1="10.62" y1="10.92" x2="10.62" y2="12.52" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="12.16" y1="14.06" x2="12.16" y2="14.5" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.62" y1="12.52" x2="12.16" y2="14.06" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$1">
|
||||||
|
<contactref element="J1" pad="19"/>
|
||||||
|
<contactref element="J3" pad="10"/>
|
||||||
|
<wire x1="11.12" y1="10.92" x2="11.12" y2="12.02" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="12" y1="12.9" x2="13.2" y2="12.9" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="13.2" y1="12.9" x2="13.4" y2="13.1" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="13.4" y1="15.8" x2="12.16" y2="17.04" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.12" y1="12.02" x2="12" y2="12.9" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="13.4" y1="13.1" x2="13.4" y2="15.8" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$11">
|
||||||
|
<contactref element="J1" pad="2"/>
|
||||||
|
<contactref element="J2" pad="2"/>
|
||||||
|
<wire x1="6.62" y1="7.32" x2="6.62" y2="6.72" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.62" y1="6.72" x2="5.3" y2="5.4" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5.3" y1="5.4" x2="5.3" y2="4.59" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5.3" y1="4.59" x2="5.35" y2="4.44" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$12">
|
||||||
|
<contactref element="J1" pad="4"/>
|
||||||
|
<contactref element="J2" pad="1"/>
|
||||||
|
<wire x1="5.35" y1="1.9" x2="5.35" y2="2.65" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="7.12" y1="6.42" x2="7.12" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="5.35" y1="2.65" x2="6.7" y2="4" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.7" y1="4" x2="6.7" y2="6" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="6.7" y1="6" x2="7.12" y2="6.42" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$13">
|
||||||
|
<contactref element="J1" pad="6"/>
|
||||||
|
<contactref element="J2" pad="4"/>
|
||||||
|
<wire x1="7.89" y1="4.44" x2="7.89" y2="5.41" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="7.62" y1="5.68" x2="7.62" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="7.89" y1="5.41" x2="7.62" y2="5.68" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$14">
|
||||||
|
<contactref element="J1" pad="8"/>
|
||||||
|
<contactref element="J2" pad="3"/>
|
||||||
|
<wire x1="7.89" y1="1.9" x2="9.2" y2="3.31" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.2" y1="3.31" x2="9.2" y2="5" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="8.12" y1="6.08" x2="8.12" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.2" y1="5" x2="8.12" y2="6.08" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$15">
|
||||||
|
<contactref element="J1" pad="10"/>
|
||||||
|
<contactref element="J2" pad="6"/>
|
||||||
|
<wire x1="10.43" y1="4.44" x2="8.62" y2="6.35" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="8.62" y1="6.35" x2="8.62" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$16">
|
||||||
|
<contactref element="J1" pad="12"/>
|
||||||
|
<contactref element="J2" pad="5"/>
|
||||||
|
<wire x1="10.43" y1="1.9" x2="10.43" y2="2.63" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.43" y1="2.63" x2="11.8" y2="4" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.8" y1="4" x2="11.8" y2="4.82236875" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.8" y1="4.82236875" x2="11.01396875" y2="5.6084" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.12" y1="6.28105625" x2="9.12" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.01396875" y1="5.6084" x2="9.79265625" y2="5.6084" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.79265625" y1="5.6084" x2="9.12" y2="6.28105625" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$17">
|
||||||
|
<contactref element="J1" pad="14"/>
|
||||||
|
<contactref element="J2" pad="8"/>
|
||||||
|
<wire x1="9.62" y1="7.32" x2="9.62" y2="6.2932" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="9.62" y1="6.2932" x2="10" y2="5.9132" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10" y1="5.9132" x2="11.140225" y2="5.9132" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="12.513425" y1="4.54" x2="12.97" y2="4.44" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.140225" y1="5.9132" x2="12.513425" y2="4.54" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$18">
|
||||||
|
<contactref element="J1" pad="16"/>
|
||||||
|
<contactref element="J2" pad="7"/>
|
||||||
|
<wire x1="10.12" y1="7.32" x2="10.12" y2="6.38" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.282" y1="6.218" x2="13.782" y2="6.218" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="13.782" y1="6.218" x2="14.2" y2="5.8" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="14.2" y1="3.13" x2="12.97" y2="1.9" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.12" y1="6.38" x2="10.282" y2="6.218" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="14.2" y1="5.8" x2="14.2" y2="3.13" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$19">
|
||||||
|
<contactref element="J1" pad="18"/>
|
||||||
|
<contactref element="J2" pad="10"/>
|
||||||
|
<wire x1="10.62" y1="7.32" x2="10.62" y2="8.62" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="10.8" y1="8.8" x2="11.6" y2="8.8" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.6" y1="8.8" x2="11.9" y2="8.5" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.9" y1="8.5" x2="11.9" y2="8" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="11.9" y1="8" x2="12" y2="7.9" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="12" y1="7.9" x2="14.8" y2="7.9" width="0.1524" layer="1"/>
|
||||||
|
<via x="14.8" y="7.9" extent="1-16" drill="0.35"/>
|
||||||
|
<wire x1="14.8" y1="7.9" x2="15.51" y2="7.19" width="0.1524" layer="16"/>
|
||||||
|
<wire x1="15.51" y1="7.19" x2="15.51" y2="4.44" width="0.1524" layer="16"/>
|
||||||
|
<wire x1="10.62" y1="8.62" x2="10.8" y2="8.8" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
<signal name="N$20">
|
||||||
|
<contactref element="J1" pad="20"/>
|
||||||
|
<contactref element="J2" pad="9"/>
|
||||||
|
<wire x1="15.51" y1="1.9" x2="16.8" y2="3.276578125" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="16.8" y1="3.276578125" x2="16.8" y2="7" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="16.8" y1="7" x2="16.48" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
<wire x1="16.48" y1="7.32" x2="11.12" y2="7.32" width="0.1524" layer="1"/>
|
||||||
|
</signal>
|
||||||
|
</signals>
|
||||||
|
<mfgpreviewcolors>
|
||||||
|
<mfgpreviewcolor name="soldermaskcolor" color="0xC8008000"/>
|
||||||
|
<mfgpreviewcolor name="silkscreencolor" color="0xFFFEFEFE"/>
|
||||||
|
<mfgpreviewcolor name="backgroundcolor" color="0xFF282828"/>
|
||||||
|
<mfgpreviewcolor name="coppercolor" color="0xFFFFBF00"/>
|
||||||
|
<mfgpreviewcolor name="substratecolor" color="0xFF786E46"/>
|
||||||
|
</mfgpreviewcolors>
|
||||||
|
</board>
|
||||||
|
</drawing>
|
||||||
|
<compatibility>
|
||||||
|
<note version="6.3" minversion="6.2.2" severity="warning">
|
||||||
|
Since Version 6.2.2 text objects can contain more than one line,
|
||||||
|
which will not be processed correctly with this version.
|
||||||
|
</note>
|
||||||
|
<note version="8.2" severity="warning">
|
||||||
|
Since Version 8.2, EAGLE supports online libraries. The ids
|
||||||
|
of those online libraries will not be understood (or retained)
|
||||||
|
with this version.
|
||||||
|
</note>
|
||||||
|
<note version="8.3" severity="warning">
|
||||||
|
Since Version 8.3, EAGLE supports URNs for individual library
|
||||||
|
assets (packages, symbols, and devices). The URNs of those assets
|
||||||
|
will not be understood (or retained) with this version.
|
||||||
|
</note>
|
||||||
|
<note version="8.3" severity="warning">
|
||||||
|
Since Version 8.3, EAGLE supports the association of 3D packages
|
||||||
|
with devices in libraries, schematics, and board files. Those 3D
|
||||||
|
packages will not be understood (or retained) with this version.
|
||||||
|
</note>
|
||||||
|
</compatibility>
|
||||||
|
</eagle>
|
1941
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41_TPad.sch
Normal file
1941
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41_TPad.sch
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
BIN
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41_Teensy.pdf
Normal file
BIN
Example_Keyboards/IBM_T41_Keyboard_and_Touchpad/T41_Teensy.pdf
Normal file
Binary file not shown.
|
@ -0,0 +1,94 @@
|
||||||
|
cntrl-l 10 22
|
||||||
|
cntrl-r 26 22
|
||||||
|
shift-l 30 21
|
||||||
|
shift-r 26 21
|
||||||
|
alt-l 32 1
|
||||||
|
alt-r 24 1
|
||||||
|
gui
|
||||||
|
fn
|
||||||
|
a 28 20
|
||||||
|
b 29 24
|
||||||
|
c 27 26
|
||||||
|
d 28 27
|
||||||
|
e 11 27
|
||||||
|
f 29 28
|
||||||
|
g 32 29
|
||||||
|
h 33 32
|
||||||
|
i 8 11
|
||||||
|
j 33 28
|
||||||
|
k 8 28
|
||||||
|
l 7 28
|
||||||
|
m 33 26
|
||||||
|
n 33 24
|
||||||
|
o 7 11
|
||||||
|
p 11 6
|
||||||
|
q 11 20
|
||||||
|
r 11 29
|
||||||
|
s 28 25
|
||||||
|
t 30 29
|
||||||
|
u 33 11
|
||||||
|
v 29 26
|
||||||
|
w 11 25
|
||||||
|
x 26 25
|
||||||
|
y 33 30
|
||||||
|
z 26 20
|
||||||
|
` 10 20
|
||||||
|
1 12 20
|
||||||
|
2 12 25
|
||||||
|
3 12 27
|
||||||
|
4 29 12
|
||||||
|
5 10 29
|
||||||
|
6 33 10
|
||||||
|
7 33 12
|
||||||
|
8 8 12
|
||||||
|
9 7 12
|
||||||
|
0 6 12
|
||||||
|
- 10 6
|
||||||
|
= 8 10
|
||||||
|
bckspace 31 30
|
||||||
|
esc 32 20
|
||||||
|
f1 10 25
|
||||||
|
f2 10 27
|
||||||
|
f3 30 27
|
||||||
|
f4 32 27
|
||||||
|
f5 32 31
|
||||||
|
f6 32 8
|
||||||
|
f7 30 7
|
||||||
|
f8 10 7
|
||||||
|
f9 10 31
|
||||||
|
f10 31 12
|
||||||
|
f11 12 5
|
||||||
|
f12 12 4
|
||||||
|
insert 10 4
|
||||||
|
delete 10 5
|
||||||
|
home 10 2
|
||||||
|
pg-up 10 3
|
||||||
|
pg-dn 12 3
|
||||||
|
end 12 2
|
||||||
|
arrow-r 24 4
|
||||||
|
arrow-l 24 2
|
||||||
|
arrow-u 32 2
|
||||||
|
arrow-d 5 24
|
||||||
|
menu
|
||||||
|
/ 6 24
|
||||||
|
period 7 26
|
||||||
|
comma 8 26
|
||||||
|
; 28 6
|
||||||
|
' 32 6
|
||||||
|
enter 31 26
|
||||||
|
[ 30 6
|
||||||
|
] 8 30
|
||||||
|
\ 31 28
|
||||||
|
caps-lck 30 25
|
||||||
|
tab 30 20
|
||||||
|
space 31 24
|
||||||
|
prt-sc 12 1
|
||||||
|
screen-lk 11 1
|
||||||
|
pause 26 2
|
||||||
|
access IBM 32 5
|
||||||
|
vol down 30 5
|
||||||
|
vol up 11 5
|
||||||
|
mute 28 5
|
||||||
|
page left 26 3
|
||||||
|
page right 24 3
|
||||||
|
|
|
@ -21,10 +21,15 @@
|
||||||
// Initial Release Aug 2, 2022
|
// Initial Release Aug 2, 2022
|
||||||
//
|
//
|
||||||
#define MODIFIERKEY_FN 0x8f // give Fn key a HID code
|
#define MODIFIERKEY_FN 0x8f // give Fn key a HID code
|
||||||
#define CAPS_LED 13 // Teensy LED shows Caps-Lock
|
#define CAPS_LED 13 // Teensy LED shows Caps-Lock
|
||||||
|
#define NUM_LOCK_LED 14 // Teensy pin 14 for Num-Lock
|
||||||
|
#define SCROLL_LOCK_LED 15 // Teensy pin 15 for Scroll-Lock
|
||||||
|
#define USB_CAPS_LOCK 1
|
||||||
|
#define USB_NUM_LOCK 0
|
||||||
|
#define USB_SCROLL_LOCK 2
|
||||||
|
|
||||||
const byte rows_max = 16; // sets the number of rows in the matrix
|
const byte rows_max = 16; // sets the number of rows in the matrix
|
||||||
const byte cols_max = 8; // sets the number of columns in the matrix
|
const byte cols_max = 8; // sets the number of columns in the matrix
|
||||||
//
|
//
|
||||||
// Load the normal key matrix with the Teensyduino key names described at www.pjrc.com/teensy/td_keyboard.html
|
// Load the normal key matrix with the Teensyduino key names described at www.pjrc.com/teensy/td_keyboard.html
|
||||||
// A zero indicates no normal key at that location.
|
// A zero indicates no normal key at that location.
|
||||||
|
@ -38,12 +43,12 @@ int normal[rows_max][cols_max] = {
|
||||||
{KEY_T,KEY_B,KEY_V,KEY_F,KEY_4,KEY_R,KEY_5,KEY_G},
|
{KEY_T,KEY_B,KEY_V,KEY_F,KEY_4,KEY_R,KEY_5,KEY_G},
|
||||||
{KEY_LEFT_BRACE,KEY_SLASH,KEY_BACKSLASH,KEY_SEMICOLON,KEY_0,KEY_P,KEY_MINUS,KEY_QUOTE},
|
{KEY_LEFT_BRACE,KEY_SLASH,KEY_BACKSLASH,KEY_SEMICOLON,KEY_0,KEY_P,KEY_MINUS,KEY_QUOTE},
|
||||||
{0,0,0,0,0,0,0,0},
|
{0,0,0,0,0,0,0,0},
|
||||||
{KEYPAD_5,0,KEYPAD_9,KEYPAD_7,0,0,KEYPAD_4,0},
|
{KEYPAD_5,0,KEYPAD_9,KEYPAD_7,KEY_PRINTSCREEN,0,KEYPAD_4,0},
|
||||||
{KEYPAD_2,KEY_RIGHT,KEYPAD_6,KEYPAD_1,KEY_F12,KEYPAD_3,KEY_INSERT,KEYPAD_PLUS},
|
{KEYPAD_2,KEY_RIGHT,KEYPAD_6,KEYPAD_1,KEY_F12,KEYPAD_3,KEY_INSERT,KEYPAD_PLUS},
|
||||||
{0,KEY_DOWN,KEYPAD_ASTERIX,0,KEY_F11,0,KEY_DELETE,0},
|
{0,KEY_DOWN,KEYPAD_ASTERIX,0,KEY_F11,0,KEY_DELETE,0},
|
||||||
{KEYPAD_8,0,0,KEY_MENU,KEY_PAGE_DOWN,0,KEY_PAGE_UP,KEYPAD_SLASH},
|
{KEYPAD_8,0,0,KEY_MENU,KEY_PAGE_DOWN,0,KEY_PAGE_UP,KEYPAD_SLASH},
|
||||||
{KEY_BACKSPACE,KEY_SPACE,KEY_ENTER,0,KEY_F10,0,KEY_F9,KEY_F5},
|
{KEY_BACKSPACE,KEY_SPACE,KEY_ENTER,0,KEY_F10,0,KEY_F9,KEY_F5},
|
||||||
{KEYPAD_0,KEY_LEFT,0,0,0,KEYPAD_ENTER,0,KEY_UP},
|
{KEYPAD_0,KEY_LEFT,KEY_PAUSE,0,0,KEYPAD_ENTER,0,KEY_UP},
|
||||||
{KEY_RIGHT_BRACE,0,KEY_COMMA,KEY_K,KEY_8,KEY_I,KEY_EQUAL,KEY_F6},
|
{KEY_RIGHT_BRACE,0,KEY_COMMA,KEY_K,KEY_8,KEY_I,KEY_EQUAL,KEY_F6},
|
||||||
{KEY_F7,0,KEY_PERIOD,KEY_L,KEY_9,KEY_O,KEY_F8,0}
|
{KEY_F7,0,KEY_PERIOD,KEY_L,KEY_9,KEY_O,KEY_F8,0}
|
||||||
};
|
};
|
||||||
|
@ -80,7 +85,7 @@ int media[rows_max][cols_max] = {
|
||||||
{0,0,0,0,0,0,0,0},
|
{0,0,0,0,0,0,0,0},
|
||||||
{0,0,0,0,0,0,0,0},
|
{0,0,0,0,0,0,0,0},
|
||||||
{0,KEY_MEDIA_VOLUME_INC,0,0,KEY_MEDIA_FAST_FORWARD,0,0,0},
|
{0,KEY_MEDIA_VOLUME_INC,0,0,KEY_MEDIA_FAST_FORWARD,0,0,0},
|
||||||
{0,0,0,0,KEY_MEDIA_REWIND,0,0,0},
|
{0,0,0,0,KEY_MEDIA_REWIND,0,KEY_SCROLL_LOCK,0},
|
||||||
{0,0,0,0,KEY_END,0,KEY_HOME,0},
|
{0,0,0,0,KEY_END,0,KEY_HOME,0},
|
||||||
{0,0,0,0,KEY_MEDIA_STOP,0,KEY_MEDIA_PLAY_PAUSE,0},
|
{0,0,0,0,KEY_MEDIA_STOP,0,KEY_MEDIA_PLAY_PAUSE,0},
|
||||||
{0,KEY_MEDIA_VOLUME_DEC,0,0,0,0,0,0},
|
{0,KEY_MEDIA_VOLUME_DEC,0,0,0,0,0,0},
|
||||||
|
@ -372,12 +377,22 @@ void loop() {
|
||||||
//
|
//
|
||||||
// Turn on the LED on the Teensy for Caps Lock based on bit 1 in the keyboard_leds variable controlled by the USB host computer
|
// Turn on the LED on the Teensy for Caps Lock based on bit 1 in the keyboard_leds variable controlled by the USB host computer
|
||||||
//
|
//
|
||||||
if (keyboard_leds & 1<<1) { // mask off all bits but D1 and test if set
|
if (keyboard_leds & 1<<USB_CAPS_LOCK) { // mask off all bits but D1 and test if set
|
||||||
go_1(CAPS_LED); // turn on the LED
|
go_1(CAPS_LED); // turn on the LED
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
go_0(CAPS_LED); // turn off the LED
|
go_0(CAPS_LED); // turn off the LED
|
||||||
}
|
}
|
||||||
|
if(keyboard_leds & 1<<USB_NUM_LOCK) { // mask off all bits but D0 and test if set
|
||||||
|
go_1(NUM_LOCK_LED);
|
||||||
|
}else{
|
||||||
|
go_0(NUM_LOCK_LED);
|
||||||
|
}
|
||||||
|
if(keyboard_leds & 1<<USB_SCROLL_LOCK) { // mask off all bits but D2 and test if set
|
||||||
|
go_1(SCROLL_LOCK_LED);
|
||||||
|
}else {
|
||||||
|
go_0(SCROLL_LOCK_LED);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
delay(25); // The overall keyboard scanning rate is about 30ms
|
delay(25); // The overall keyboard scanning rate is about 30ms
|
||||||
}
|
}
|
||||||
|
|
960
Example_Touchpads/KB_TP_Stream_mode.ino
Normal file
960
Example_Touchpads/KB_TP_Stream_mode.ino
Normal file
|
@ -0,0 +1,960 @@
|
||||||
|
/* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
// This software creates a USB keyboard and touchpad.
|
||||||
|
// The touchpad is PS/2 and the code uses "stream mode" instead of "remote mode".
|
||||||
|
//
|
||||||
|
// define the pins on the Teensy used for the touchpad ps2 bus
|
||||||
|
#define TP_DATA 11 // Touchpad ps/2 data connected to Teensy I/O pin
|
||||||
|
#define TP_CLK 12 // Touchpad ps/2 clock connected to Teensy I/O pin
|
||||||
|
#define CAPS_LOCK_N 8 // driven low to turn on the CAPS LED
|
||||||
|
#define NUM_LOCK_N 13 // driven low to turn on the NUM LED (Note the LED on the Teensy 3.2 is also connected to this I/O and has opposite polarity)
|
||||||
|
//
|
||||||
|
#define MODIFIERKEY_FN 0x8f // give the Fn key a HID code so it can be handled like any other key
|
||||||
|
//
|
||||||
|
const byte rows_max = 15; // sets the number of rows in the keyboard matrix
|
||||||
|
const byte cols_max = 8; // sets the number of columns in the keyboard matrix
|
||||||
|
//
|
||||||
|
// Load the normal key matrix with the Teensyduino key names described at www.pjrc.com/teensy/td_keyboard.html
|
||||||
|
// A zero indicates no normal key at that location.
|
||||||
|
//
|
||||||
|
int normal[rows_max][cols_max] = {
|
||||||
|
{KEY_END,KEY_RIGHT,0,KEY_PRINTSCREEN,KEY_DELETE,KEY_HOME,KEY_PAGE_UP,KEY_PAGE_DOWN},
|
||||||
|
{KEY_QUOTE,KEY_ENTER,KEY_PAUSE,0,KEY_EQUAL,KEY_BACKSPACE,KEY_RIGHT_BRACE,KEY_BACKSLASH},
|
||||||
|
{KEY_SLASH,KEY_UP,KEY_MINUS,KEY_F12,KEY_0,KEY_P,KEY_LEFT_BRACE,KEY_SEMICOLON},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,KEY_F8,KEY_F9,0,0,KEY_MENU,KEY_LEFT},
|
||||||
|
{KEY_COMMA,KEY_INSERT,KEY_F7,KEY_F6,KEY_F5,KEY_8,KEY_I,KEY_K},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{KEY_PERIOD,KEY_DOWN,0,KEY_F11,KEY_F10,KEY_9,KEY_O,KEY_L},
|
||||||
|
{KEY_M,KEY_N,KEY_H,KEY_Y,KEY_6,KEY_7,KEY_U,KEY_J},
|
||||||
|
{KEY_V,KEY_B,KEY_G,KEY_T,KEY_5,KEY_4,KEY_R,KEY_F},
|
||||||
|
{KEY_X,KEY_Z,KEY_F2,KEY_F1,KEY_ESC,KEY_2,KEY_W,KEY_S},
|
||||||
|
{KEY_C,KEY_SPACE,KEY_F3,KEY_F4,KEY_CAPS_LOCK,KEY_3,KEY_E,KEY_D},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,KEY_TAB,KEY_TILDE,KEY_1,KEY_Q,KEY_A},
|
||||||
|
{0,0,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
// Load the numlock key matrix with key names at the correct row-column location.
|
||||||
|
// This matrix is the same as the normal matrix except for the number pad keys
|
||||||
|
// A zero indicates no numlock key at that location.
|
||||||
|
int numlock[rows_max][cols_max] = {
|
||||||
|
{KEY_END,KEY_RIGHT,0,KEY_PRINTSCREEN,KEY_DELETE,KEY_HOME,KEY_PAGE_UP,KEY_PAGE_DOWN},
|
||||||
|
{KEY_QUOTE,KEY_ENTER,KEY_PAUSE,0,KEY_EQUAL,KEY_BACKSPACE,KEY_RIGHT_BRACE,KEY_BACKSLASH},
|
||||||
|
{KEYPAD_SLASH,KEY_UP,KEY_MINUS,KEY_F12,KEYPAD_ASTERIX,KEYPAD_MINUS,KEY_LEFT_BRACE,KEYPAD_PLUS},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,KEY_F8,KEY_F9,0,0,KEY_MENU,KEY_LEFT},
|
||||||
|
{KEY_COMMA,KEY_INSERT,KEY_F7,KEY_F6,KEY_F5,KEYPAD_8,KEYPAD_5,KEYPAD_2},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{KEYPAD_PERIOD,KEY_DOWN,0,KEY_F11,KEY_F10,KEYPAD_9,KEYPAD_6,KEYPAD_3},
|
||||||
|
{KEYPAD_0,KEY_N,KEY_H,KEY_Y,KEY_6,KEYPAD_7,KEYPAD_4,KEYPAD_1},
|
||||||
|
{KEY_V,KEY_B,KEY_G,KEY_T,KEY_5,KEY_4,KEY_R,KEY_F},
|
||||||
|
{KEY_X,KEY_Z,KEY_F2,KEY_F1,KEY_ESC,KEY_2,KEY_W,KEY_S},
|
||||||
|
{KEY_C,KEY_SPACE,KEY_F3,KEY_F4,KEY_CAPS_LOCK,KEY_3,KEY_E,KEY_D},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,KEY_TAB,KEY_TILDE,KEY_1,KEY_Q,KEY_A},
|
||||||
|
{0,0,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
// Load the modifier key matrix with key names at the correct row-column location.
|
||||||
|
// A zero indicates no modifier key at that location.
|
||||||
|
int modifier[rows_max][cols_max] = {
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,MODIFIERKEY_LEFT_CTRL,0,0,MODIFIERKEY_RIGHT_CTRL,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{MODIFIERKEY_RIGHT_SHIFT,MODIFIERKEY_LEFT_SHIFT,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{MODIFIERKEY_RIGHT_ALT,MODIFIERKEY_LEFT_ALT,0,0,0,0,0,0},
|
||||||
|
{0,0,MODIFIERKEY_FN,0,0,0,0,0},
|
||||||
|
{0,MODIFIERKEY_GUI,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
// Load the media key matrix with Fn key names at the correct row-column location.
|
||||||
|
// A zero indicates no media key at that location.
|
||||||
|
int media[rows_max][cols_max] = {
|
||||||
|
{0,0,0,0,KEY_SCROLL_LOCK,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,KEY_NUM_LOCK,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,KEY_MEDIA_MUTE,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,KEY_MEDIA_VOLUME_DEC,KEY_MEDIA_VOLUME_INC,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0},
|
||||||
|
{0,0,0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
// Initialize the old_key matrix with one's (no keys pressed).
|
||||||
|
// 1 = key not pressed, 0 = key is pressed
|
||||||
|
boolean old_key[rows_max][cols_max] = {
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1},
|
||||||
|
{1,1,1,1,1,1,1,1}
|
||||||
|
};
|
||||||
|
//
|
||||||
|
// Define the Teensy 3.2 I/O numbers that are connected to the keyboard FPC connector pins
|
||||||
|
// Row FPC pin # 09,10,11,12,13,14,15,16,17,18,19,20,21,22,23
|
||||||
|
// Teensy I/O # 18,33,19,20,21,22,23,24,25,26,27,28,07,06,05
|
||||||
|
int Row_IO[rows_max] = {18,33,19,20,21,22,23,24,25,26,27,28,7,6,5}; // Teensy 3.2 I/O numbers for rows 0 thru 14
|
||||||
|
//
|
||||||
|
// Column FPC pin # 01,02,03,04,05,06,07,08
|
||||||
|
// Teensy I/O # 14,29,15,30,16,31,17,32
|
||||||
|
int Col_IO[cols_max] = {14,29,15,30,16,31,17,32}; // Teensy 3.2 I/O numbers for columns 0 thru 7
|
||||||
|
//
|
||||||
|
// Declare global variables that will be used by functions
|
||||||
|
//
|
||||||
|
boolean slots_full = LOW; // Goes high when USB slots 1 thru 6 contain normal keys
|
||||||
|
boolean touchpad_error = LOW; // set high if the touchpad fails to give the correct power-up response
|
||||||
|
char mstat; // touchpad status 8 bit register = Y overflow, X overflow, Y sign bit, X sign bit, Always 1, Middle Btn, Right Btn, Left Btn
|
||||||
|
char mx; // touchpad x movement = 8 data bits. The sign bit is in the status register to
|
||||||
|
// make a 9 bit 2's complement value. Left to right on the touchpad gives a positive value.
|
||||||
|
char my; // touchpad y movement also 8 bits plus sign bit in status reg. Touchpad movement away from the user gives a positive value.
|
||||||
|
//
|
||||||
|
// slot 1 thru slot 6 hold the normal key values to be sent over USB.
|
||||||
|
int slot1 = 0; //value of 0 means the slot is empty and can be used.
|
||||||
|
int slot2 = 0;
|
||||||
|
int slot3 = 0;
|
||||||
|
int slot4 = 0;
|
||||||
|
int slot5 = 0;
|
||||||
|
int slot6 = 0;
|
||||||
|
//
|
||||||
|
int mod_shift_l = 0; // These variables are sent over USB as modifier keys.
|
||||||
|
int mod_shift_r = 0; // Each is either set to 0 or MODIFIER_ ...
|
||||||
|
int mod_ctrl_l = 0;
|
||||||
|
int mod_ctrl_r = 0;
|
||||||
|
int mod_alt_l = 0;
|
||||||
|
int mod_alt_r = 0;
|
||||||
|
int mod_gui = 0;
|
||||||
|
//
|
||||||
|
// ********************Common Functions**********************************************
|
||||||
|
//
|
||||||
|
// Function to set a pin to high impedance (acts like open drain output)
|
||||||
|
void go_z(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to set a pin as an input with a pullup
|
||||||
|
void go_pu(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, INPUT_PULLUP);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send a pin to a logic low
|
||||||
|
void go_0(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send a pin to a logic high
|
||||||
|
void go_1(int pin)
|
||||||
|
{
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, HIGH);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// ********************Functions for keyboard scanning*******************************
|
||||||
|
//
|
||||||
|
// Function to load the key name into the first available slot
|
||||||
|
void load_slot(int key) {
|
||||||
|
if (!slot1) { // check if slot 1 is empty
|
||||||
|
slot1 = key; // and load it with the key name
|
||||||
|
}
|
||||||
|
else if (!slot2) { // otherwise go thru all the other slots looking for an empty to load
|
||||||
|
slot2 = key;
|
||||||
|
}
|
||||||
|
else if (!slot3) {
|
||||||
|
slot3 = key;
|
||||||
|
}
|
||||||
|
else if (!slot4) {
|
||||||
|
slot4 = key;
|
||||||
|
}
|
||||||
|
else if (!slot5) {
|
||||||
|
slot5 = key;
|
||||||
|
}
|
||||||
|
else if (!slot6) {
|
||||||
|
slot6 = key;
|
||||||
|
}
|
||||||
|
if (!slot1 || !slot2 || !slot3 || !slot4 || !slot5 || !slot6) { // are any slots empty?
|
||||||
|
slots_full = LOW; // slots are not full
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slots_full = HIGH; // slots are full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to clear the slot that contains the key name
|
||||||
|
void clear_slot(int key) {
|
||||||
|
if (slot1 == key) { // check if slot 1 contains the key that needs to be cleared
|
||||||
|
slot1 = 0; // and clear it
|
||||||
|
}
|
||||||
|
else if (slot2 == key) { // otherwise keep checking the other slots for a match
|
||||||
|
slot2 = 0;
|
||||||
|
}
|
||||||
|
else if (slot3 == key) {
|
||||||
|
slot3 = 0;
|
||||||
|
}
|
||||||
|
else if (slot4 == key) {
|
||||||
|
slot4 = 0;
|
||||||
|
}
|
||||||
|
else if (slot5 == key) {
|
||||||
|
slot5 = 0;
|
||||||
|
}
|
||||||
|
else if (slot6 == key) {
|
||||||
|
slot6 = 0;
|
||||||
|
}
|
||||||
|
if (!slot1 || !slot2 || !slot3 || !slot4 || !slot5 || !slot6) { // are any slots empty?
|
||||||
|
slots_full = LOW; // slots are not full
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slots_full = HIGH; // slots are full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to load the modifier key name into the appropriate mod variable
|
||||||
|
void load_mod(int m_key) {
|
||||||
|
if (m_key == MODIFIERKEY_LEFT_SHIFT) { // Figure out which modifier key was pushed
|
||||||
|
mod_shift_l = m_key; // and load it into 1 of 7 possible variables
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_SHIFT) {
|
||||||
|
mod_shift_r = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_CTRL) {
|
||||||
|
mod_ctrl_l = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_CTRL) {
|
||||||
|
mod_ctrl_r = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_ALT) {
|
||||||
|
mod_alt_l = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_ALT) {
|
||||||
|
mod_alt_r = m_key;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_GUI) {
|
||||||
|
mod_gui = m_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to load 0 into the appropriate mod variable
|
||||||
|
void clear_mod(int m_key) {
|
||||||
|
if (m_key == MODIFIERKEY_LEFT_SHIFT) { // Figure out which modifier key was released
|
||||||
|
mod_shift_l = 0; // and clear the matching variable
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_SHIFT) {
|
||||||
|
mod_shift_r = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_CTRL) {
|
||||||
|
mod_ctrl_l = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_CTRL) {
|
||||||
|
mod_ctrl_r = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_LEFT_ALT) {
|
||||||
|
mod_alt_l = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_RIGHT_ALT) {
|
||||||
|
mod_alt_r = 0;
|
||||||
|
}
|
||||||
|
else if (m_key == MODIFIERKEY_GUI) {
|
||||||
|
mod_gui = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send the modifier keys over usb
|
||||||
|
void send_mod() {
|
||||||
|
Keyboard.set_modifier(mod_shift_l | mod_shift_r | mod_ctrl_l | mod_ctrl_r | mod_alt_l | mod_alt_r | mod_gui);
|
||||||
|
Keyboard.send_now(); // sends all modifier values including the one that just changed (and all normal slots)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to send the normal keys in the 6 slots over usb
|
||||||
|
void send_normals() {
|
||||||
|
Keyboard.set_key1(slot1); // load each slot into the cooresponding key number
|
||||||
|
Keyboard.set_key2(slot2);
|
||||||
|
Keyboard.set_key3(slot3);
|
||||||
|
Keyboard.set_key4(slot4);
|
||||||
|
Keyboard.set_key5(slot5);
|
||||||
|
Keyboard.set_key6(slot6);
|
||||||
|
Keyboard.send_now(); // sends all slots including the one that just changed (and all modifier values)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// *****************Functions for Touchpad***************************
|
||||||
|
//
|
||||||
|
// Function to send the touchpad a byte of data (command)
|
||||||
|
//
|
||||||
|
void tp_write(char send_data)
|
||||||
|
{
|
||||||
|
unsigned int timeout = 200; // break out of loop if watchdog over this value in msec
|
||||||
|
elapsedMillis watchdog; // zero the watchdog timer clock
|
||||||
|
char odd_parity = 0; // clear parity bit count
|
||||||
|
// Enable the PS/2 bus by floating the clock and data
|
||||||
|
go_pu(TP_CLK); //
|
||||||
|
go_pu(TP_DATA); //
|
||||||
|
delayMicroseconds(250); // wait before requesting the bus
|
||||||
|
go_0(TP_CLK); // Send the Clock line low to request to transmit data
|
||||||
|
delayMicroseconds(100); // wait for 100 microseconds per bus spec
|
||||||
|
go_0(TP_DATA); // Send the Data line low (the start bit)
|
||||||
|
delayMicroseconds(1); //
|
||||||
|
go_pu(TP_CLK); // Release the Clock line so it is pulled high
|
||||||
|
delayMicroseconds(1); // give some time to let the clock line go high
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop because tp did not respond
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// send the 8 bits of send_data
|
||||||
|
for (int j=0; j<8; j++) {
|
||||||
|
if (send_data & 1) { //check if lsb is set
|
||||||
|
go_pu(TP_DATA); // send a 1 to TP
|
||||||
|
odd_parity = odd_parity + 1; // keep running total of 1's sent
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go_0(TP_DATA); // send a 0 to TP
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send_data = send_data >> 1; // shift data right by 1 to prepare for next loop
|
||||||
|
}
|
||||||
|
// send the parity bit
|
||||||
|
if (odd_parity & 1) { //check if lsb of parity is set
|
||||||
|
go_0(TP_DATA); // already odd so send a 0 to TP
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go_pu(TP_DATA); // send a 1 to TP to make parity odd
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go_pu(TP_DATA); // Release the Data line so it goes high as the stop bit
|
||||||
|
delayMicroseconds(80); // testing shows delay at least 40us
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // wait to let the data settle
|
||||||
|
if (digitalRead(TP_DATA)) { // Ack bit s/b low if good transfer
|
||||||
|
}
|
||||||
|
while ((digitalRead(TP_CLK) == LOW) || (digitalRead(TP_DATA) == LOW)) { // loop if clock or data are low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Inhibit the bus so the tp only talks when the Teensy is listening
|
||||||
|
go_0(TP_CLK);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to get a byte of data from the touchpad
|
||||||
|
//
|
||||||
|
char tp_read(void)
|
||||||
|
{
|
||||||
|
unsigned int timeout = 200; // break out of loop if over this value in msec
|
||||||
|
elapsedMillis watchdog; // zero the watchdog timer clock
|
||||||
|
char rcv_data = 0; // initialize to zero
|
||||||
|
char mask = 1; // shift a 1 across the 8 bits to select where to load the data
|
||||||
|
char rcv_parity = 0; // count the ones received
|
||||||
|
go_pu(TP_CLK); // release the clock
|
||||||
|
go_pu(TP_DATA); // release the data
|
||||||
|
delayMicroseconds(5); // delay to let clock go high
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // Start bit s/b low from tp
|
||||||
|
// start bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int k=0; k<8; k++) {
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if data is high
|
||||||
|
rcv_data = rcv_data | mask; // set the appropriate bit in the rcv data
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
mask = mask << 1;
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// receive parity
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if received parity is high
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
rcv_parity = rcv_parity & 1; // mask off all bits except the lsb
|
||||||
|
if (rcv_parity == 0) { // check for bad (even) parity
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// stop bit
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA) == LOW) { // check if stop bit is bad (low)
|
||||||
|
// send bad stop bit to future error handler
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
if (watchdog >= timeout) { //check for infinite loop
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
break; // break out of infinite loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Inhibit the bus so the tp only talks when the Teensy is listening
|
||||||
|
go_0(TP_CLK);
|
||||||
|
return rcv_data; // pass the received data back
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Function to decode 3 bytes of data from the touchpad = status, X Delta, Y Delta
|
||||||
|
//
|
||||||
|
char tp_packet(void)
|
||||||
|
{
|
||||||
|
// ******************************Receive Byte 0 = Status***********************
|
||||||
|
char rcv_data = 0; // initialize to zero
|
||||||
|
char mask = 1; // shift a 1 across the 8 bits to select where to load the data
|
||||||
|
char rcv_parity = 0; // count the ones received
|
||||||
|
//
|
||||||
|
unsigned int time_leftover = 24; // breakout of tp loop if timer is over this value in msec
|
||||||
|
elapsedMillis tp_timer; // zero the tp timer clock
|
||||||
|
//
|
||||||
|
go_pu(TP_CLK); // release the clock
|
||||||
|
go_pu(TP_DATA); // release the data
|
||||||
|
delayMicroseconds(5); // delay to let clock go high
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
if (tp_timer >= time_leftover) { //check if ready for next keyboard scan due to no tp activity
|
||||||
|
go_0(TP_CLK); // Inhibit the bus so the tp won't try to send data
|
||||||
|
return 1; // go back to main routine with a 1 signifying no tp data was received
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // Start bit s/b low from tp
|
||||||
|
// start bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
for (int k=0; k<8; k++) {
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if data is high
|
||||||
|
rcv_data = rcv_data | mask; // set the appropriate bit in the rcv data
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
mask = mask << 1;
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// receive parity
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if received parity is high
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
rcv_parity = rcv_parity & 1; // mask off all bits except the lsb
|
||||||
|
if (rcv_parity == 0) { // check for bad (even) parity
|
||||||
|
// parity bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
// stop bit
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA) == LOW) { // check if stop bit is bad (low)
|
||||||
|
// stop bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
mstat = rcv_data; // save data result in status byte
|
||||||
|
// ******************************Receive Byte 1 = Delta X**************************
|
||||||
|
rcv_data = 0; // initialize to zero
|
||||||
|
mask = 1; // shift a 1 across the 8 bits to select where to load the data
|
||||||
|
rcv_parity = 0; // count the ones received
|
||||||
|
delayMicroseconds(5); // delay to let the clock stop ringing
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // Start bit s/b low from tp
|
||||||
|
// start bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
for (int k=0; k<8; k++) {
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if data is high
|
||||||
|
rcv_data = rcv_data | mask; // set the appropriate bit in the rcv data
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
mask = mask << 1;
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// receive parity
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if received parity is high
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
rcv_parity = rcv_parity & 1; // mask off all bits except the lsb
|
||||||
|
if (rcv_parity == 0) { // check for bad (even) parity
|
||||||
|
// parity bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
// stop bit
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA) == LOW) { // check if stop bit is bad (low)
|
||||||
|
// stop bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
mx = rcv_data; // save data result in delta x byte
|
||||||
|
// Receive Byte 1 = Delta Y
|
||||||
|
// ******************************Receive Byte 2 = Delta Y**************************
|
||||||
|
rcv_data = 0; // initialize to zero
|
||||||
|
mask = 1; // shift a 1 across the 8 bits to select where to load the data
|
||||||
|
rcv_parity = 0; // count the ones received
|
||||||
|
delayMicroseconds(5); // delay to let the clock stop ringing
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // Start bit s/b low from tp
|
||||||
|
// start bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
for (int k=0; k<8; k++) {
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if data is high
|
||||||
|
rcv_data = rcv_data | mask; // set the appropriate bit in the rcv data
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
mask = mask << 1;
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// receive parity
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA)) { // check if received parity is high
|
||||||
|
rcv_parity++; // increment the parity bit counter
|
||||||
|
}
|
||||||
|
rcv_parity = rcv_parity & 1; // mask off all bits except the lsb
|
||||||
|
if (rcv_parity == 0) { // check for bad (even) parity
|
||||||
|
// parity bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
// stop bit
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == HIGH) { // loop until the clock goes low
|
||||||
|
}
|
||||||
|
if (digitalRead(TP_DATA) == LOW) { // check if stop bit is bad (low)
|
||||||
|
// stop bit not correct - put error handler here if desired
|
||||||
|
}
|
||||||
|
delayMicroseconds(1); // delay to let the clock settle out
|
||||||
|
while (digitalRead(TP_CLK) == LOW) { // loop until the clock goes high
|
||||||
|
}
|
||||||
|
my = rcv_data; // save data result in delta y byte
|
||||||
|
//
|
||||||
|
// Inhibit the bus so the tp only talks when we're listening
|
||||||
|
go_0(TP_CLK);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
void touchpad_init()
|
||||||
|
{
|
||||||
|
touchpad_error = LOW; // start with no error
|
||||||
|
go_pu(TP_CLK); // float the clock and data to touchpad
|
||||||
|
go_pu(TP_DATA);
|
||||||
|
// Sending reset command to touchpad
|
||||||
|
tp_write(0xff);
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
delay(1000); // wait 1 second so tp can run its self diagnostic
|
||||||
|
// verify proper response from tp
|
||||||
|
if (tp_read() != 0xaa) { // verify basic assurance test passed
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
if (tp_read() != 0x00) { // verify basic assurance test passed
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// Send touchpad disable code so that the mode byte can be loaded next
|
||||||
|
tp_write(0xf5); // tp disable
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// Load Mode Byte with 00 using the following special sequence from page 38 of Synaptics Interfaceing Guide.
|
||||||
|
// Send set resolution to 0 four times followed by a set sample rate to 0x14
|
||||||
|
// The resolution and sample rate are not actually changed but instead it loads the mode byte.
|
||||||
|
// #1 set resolution
|
||||||
|
tp_write(0xe8); // set resolution (actually part of setting mode byte)
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x00); // to zero
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// #2 set resolution (actually part of setting mode byte)
|
||||||
|
tp_write(0xe8); // set resolution
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x00); // to zero
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// #3 set resolution
|
||||||
|
tp_write(0xe8); // set resolution
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x00); // to zero
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// #4 set resolution (actually part of setting mode byte)
|
||||||
|
tp_write(0xe8); // set resolution
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x00); // to zero
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// Set sample rate (actually part of setting mode byte)
|
||||||
|
tp_write(0xf3); // set sample rate
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x14); // to 14 hex
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// This completes the mode byte load
|
||||||
|
// set the resolution for real
|
||||||
|
tp_write(0xe8); // Sending resolution command
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x03); // value of 0x03 = 8 counts/mm resolution (default is 4 counts/mm)
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// set the sample rate for real
|
||||||
|
tp_write(0xf3); // Sending sample rate command
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
tp_write(0x28); // 0x28 = 40 samples per second, the default value used for Synaptics TP
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// Load stream mode command so tp will send data whenever it's available
|
||||||
|
tp_write(0xea); // stream mode
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
// Send touchpad enable code
|
||||||
|
tp_write(0xf4); // tp enable
|
||||||
|
if (tp_read() != 0xfa) { // verify correct ack byte
|
||||||
|
touchpad_error = HIGH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//----------------------------------Setup before main loop-------------------------------------------
|
||||||
|
//
|
||||||
|
void setup() {
|
||||||
|
for (int a = 0; a < cols_max; a++) { // loop thru all keyboard column pins
|
||||||
|
go_pu(Col_IO[a]); // set each column pin as an input with a pullup
|
||||||
|
}
|
||||||
|
//
|
||||||
|
for (int b = 0; b < rows_max; b++) { // loop thru all keyboard row pins
|
||||||
|
go_z(Row_IO[b]); // set each row pin as a floating output
|
||||||
|
}
|
||||||
|
touchpad_init(); // reset tp and check that self diagnostic passed. Put tp in stream mode and enable it
|
||||||
|
//
|
||||||
|
}
|
||||||
|
//
|
||||||
|
boolean Fn_pressed = HIGH; // Active low, shows when the Fn key is pressed
|
||||||
|
extern volatile uint8_t keyboard_leds; // 8 bits sent from Host to Teensy that give keyboard LED status.
|
||||||
|
// declare and initialize touchpad variables
|
||||||
|
boolean over_flow; // Active high, set if x or y movement values are bad due to overflow
|
||||||
|
boolean left_button = 0; // Active high, on/off variable for left button is set if bit 0 of mstat is set
|
||||||
|
boolean right_button = 0; // Active high, on/off variable for right button is set if bit 1 of mstat is set
|
||||||
|
boolean old_left_button = 0; // Active high, on/off variable for left button status from the previous polling cycle
|
||||||
|
boolean old_right_button = 0; // Active high, on/off variable for right button status from the previous polling cycle
|
||||||
|
boolean button_change = 0; // Active high, shows when a touchpad left or right button has changed since the last polling cycle
|
||||||
|
//
|
||||||
|
//---------------------------------Main Loop---------------------------------------------
|
||||||
|
//
|
||||||
|
void loop() {
|
||||||
|
// Scan keyboard matrix with an outer loop that drives each row low and an inner loop that reads every column (with pull ups).
|
||||||
|
// The routine looks at each key's present state (by reading the column input pin) and also the previous state from the last scan
|
||||||
|
// that was 30msec ago. The status of a key that was just pressed or just released is sent over USB and the state is saved in the old_key matrix.
|
||||||
|
// The keyboard keys will read as logic low if they are pressed (negative logic).
|
||||||
|
// The old_key matrix also uses negative logic (low=pressed).
|
||||||
|
//
|
||||||
|
for (int x = 0; x < rows_max; x++) { // loop thru the rows
|
||||||
|
go_0(Row_IO[x]); // Activate Row (send it low)
|
||||||
|
delayMicroseconds(10); // give the row time to go low and settle out
|
||||||
|
for (int y = 0; y < cols_max; y++) { // loop thru the columns
|
||||||
|
//
|
||||||
|
// **********Modifier keys including the Fn special case
|
||||||
|
if (modifier[x][y] != 0) { // check if modifier key exists at this location in the array (a non-zero value)
|
||||||
|
if (!digitalRead(Col_IO[y]) && (old_key[x][y])) { // Read column to see if key is low (pressed) and was previously not pressed
|
||||||
|
if (modifier[x][y] != MODIFIERKEY_FN) { // Exclude Fn modifier key because Fn is not sent to USB host
|
||||||
|
load_mod(modifier[x][y]); // function reads which modifier key is pressed and loads it into the appropriate mod_... variable
|
||||||
|
send_mod(); // function sends the state of all modifier keys over usb including the one that just got pressed
|
||||||
|
old_key[x][y] = LOW; // Save state of key as "pressed"
|
||||||
|
}
|
||||||
|
else { // keep track of Fn key being pressed
|
||||||
|
Fn_pressed = LOW; // Fn status variable is active low
|
||||||
|
old_key[x][y] = LOW; // old_key state is "pressed" (active low)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (digitalRead(Col_IO[y]) && (!old_key[x][y])) { //check if key is not pressed and was previously pressed
|
||||||
|
if (modifier[x][y] != MODIFIERKEY_FN) { // Exclude Fn modifier key
|
||||||
|
clear_mod(modifier[x][y]); // function reads which modifier key was released and loads 0 into the appropriate mod_... variable
|
||||||
|
send_mod(); // function sends all mod's over usb including the one that was just released
|
||||||
|
old_key[x][y] = HIGH; // Save state of key as "not pressed"
|
||||||
|
}
|
||||||
|
else { // keep track of Fn key being released
|
||||||
|
Fn_pressed = HIGH; // Fn is no longer active
|
||||||
|
old_key[x][y] = HIGH; // old_key state is "not pressed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ***********end of modifier section
|
||||||
|
//
|
||||||
|
// ***********Normal keys, num lock, and media keys in this section
|
||||||
|
else if ((normal[x][y] != 0) || (media[x][y] != 0)) { // check if normal or media key exists at this location in the array
|
||||||
|
if (!digitalRead(Col_IO[y]) && (old_key[x][y]) && (!slots_full)) { // check if key pressed and not previously pressed and slots not full
|
||||||
|
old_key[x][y] = LOW; // Save state of key as "pressed"
|
||||||
|
if (Fn_pressed) { // Fn is not pressed and normal or num lock key needs to be sent
|
||||||
|
if (keyboard_leds & 1) { // test if Num Lock is turned on
|
||||||
|
load_slot(numlock[x][y]); //update first available slot with key name from numlock matrix
|
||||||
|
send_normals(); // send all slots over USB including the key that just got pressed
|
||||||
|
}
|
||||||
|
else { // Num Lock is not turned on so send normal key
|
||||||
|
load_slot(normal[x][y]); //update first available slot with normal key name
|
||||||
|
send_normals(); // send all slots over USB including the key that just got pressed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (media[x][y] != 0) { // Fn is pressed so send media if a key exists in the matrix
|
||||||
|
Keyboard.press(media[x][y]); // media key is sent using keyboard.press function per PJRC instructions
|
||||||
|
delay(5); // delay 5 milliseconds before releasing to make sure it gets sent over USB
|
||||||
|
Keyboard.release(media[x][y]); // send media key release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Key release
|
||||||
|
else if (digitalRead(Col_IO[y]) && (!old_key[x][y])) { //check if key is not pressed, but was previously pressed
|
||||||
|
old_key[x][y] = HIGH; // Save state of key as "not pressed"
|
||||||
|
if (Fn_pressed) { // only clear the slot if the Fn key is not pressed
|
||||||
|
if (keyboard_leds & 1) { // test if Num Lock is turned on
|
||||||
|
clear_slot(numlock[x][y]); //clear slot with key name from numlock matrix
|
||||||
|
send_normals(); // send all slots over USB including the key that just got released
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clear_slot(normal[x][y]); //clear the slot that contains the normal key name
|
||||||
|
send_normals(); // send all slots over USB including the key that was just released
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// **************end of normal, media, and backlight section
|
||||||
|
//
|
||||||
|
} // end of column loop
|
||||||
|
go_z(Row_IO[x]); // De-activate the current Row (send it to hi-z) so the next row can be activated
|
||||||
|
} // end of row loop
|
||||||
|
//
|
||||||
|
// **********Keyboard scan complete
|
||||||
|
//
|
||||||
|
// ***********Touchpad Section
|
||||||
|
//
|
||||||
|
if (touchpad_error == LOW) { // Only proceed if the touchpad was initialized correctly and passed its self test
|
||||||
|
//
|
||||||
|
if (tp_packet() == 0x00) { // tp_packet returned zero so data was received in mstat, mx, and my variables
|
||||||
|
if (((0x80 & mstat) == 0x80) || ((0x40 & mstat) == 0x40)) { // x or y overflow bits set?
|
||||||
|
over_flow = 1; // set the overflow flag
|
||||||
|
}
|
||||||
|
// change the x data from 9 bit to 8 bit 2's complement
|
||||||
|
mx = mx & 0x7f; // mask off 8th bit
|
||||||
|
if ((0x10 & mstat) == 0x10) { // move the sign into
|
||||||
|
mx = 0x80 | mx; // the 8th bit position
|
||||||
|
}
|
||||||
|
// change the y data from 9 bit to 8 bit 2's complement and then take the 2's complement
|
||||||
|
// because y movement on ps/2 format is opposite of touchpad.move function
|
||||||
|
my = my & 0x7f; // mask off 8th bit
|
||||||
|
if ((0x20 & mstat) == 0x20) { // move the sign into
|
||||||
|
my = 0x80 | my; // the 8th bit position
|
||||||
|
}
|
||||||
|
my = (~my + 0x01); // change the sign of y data by taking the 2's complement (invert and add 1)
|
||||||
|
// zero out mx and my if over_flow is set
|
||||||
|
if (over_flow) {
|
||||||
|
mx = 0x00; // data is bad due to the overflow so zero it out
|
||||||
|
my = 0x00;
|
||||||
|
}
|
||||||
|
// send the x and y data back via usb if either one is non-zero
|
||||||
|
if ((mx != 0x00) || (my != 0x00)) {
|
||||||
|
Mouse.move(mx,my);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// read the left and right button bits in the PS/2 status byte from the touchpad
|
||||||
|
if ((0x01 & mstat) == 0x01) { // if left button is set in the status byte
|
||||||
|
left_button = 1; // set the left button variable
|
||||||
|
}
|
||||||
|
else { // otherwise clear the left button variable
|
||||||
|
left_button = 0;
|
||||||
|
}
|
||||||
|
if ((0x02 & mstat) == 0x02) { // if right button is set in the status byte
|
||||||
|
right_button = 1; // set the right button variable
|
||||||
|
}
|
||||||
|
else { // otherwise clear right button variable
|
||||||
|
right_button = 0;
|
||||||
|
}
|
||||||
|
// Determine if the left or right touchpad buttons have changed since last polling cycle using xor
|
||||||
|
button_change = (left_button ^ old_left_button) | (right_button ^ old_right_button);
|
||||||
|
// Don't send button status if there's no change since last time.
|
||||||
|
if (button_change){
|
||||||
|
Mouse.set_buttons(left_button, 0, right_button); // send left, middle, and right button status
|
||||||
|
}
|
||||||
|
old_left_button = left_button; // remember button status for next polling cycle
|
||||||
|
old_right_button = right_button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// End of touchpad routine
|
||||||
|
//
|
||||||
|
// Turn on or off the LEDs for Num Lock and Caps Lock based on bits 0 and 1 from the
|
||||||
|
// keyboard_leds variable returned by the host computer over USB. Sending the I/O pin low turns on the
|
||||||
|
// LED.
|
||||||
|
//
|
||||||
|
if (keyboard_leds & 1) { // mask off all bits but D0 and test if set
|
||||||
|
go_0(NUM_LOCK_N); // turn on the Num Lock LED
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go_1(NUM_LOCK_N); // turn off the Num Lock LED
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
if (keyboard_leds & 1<<1) { // mask off all bits but D1 and test if set
|
||||||
|
go_0(CAPS_LOCK_N); // turn on the Caps Lock LED
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
go_1(CAPS_LOCK_N); // turn off the Caps Lock LED
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// repeat loop at 30msec scan rate
|
||||||
|
}
|
Loading…
Reference in a new issue