Last active
April 13, 2023 03:31
-
-
Save wjes/ed98ffea3f15ff1631a7fb25019d3f14 to your computer and use it in GitHub Desktop.
Teensy-LC code for a dell inspiron 1420 latam spanish keyboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Copyright 2018 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 Dell Inspiron 1420 Laptop Keyboard Controller using a Teensy LC on | |
// a daughterboard with a 25 pin FPC connector. The keyboard part number is ONK769. | |
// This routine uses the Teensyduino "Press / Release" to send Normal, Modifier and Media | |
// keys over USB. The layout implemented is Latam Spanish. | |
// Description of Teensyduino keyboard functions is at www.pjrc.com/teensy/td_keyboard.html | |
// | |
// Revision History | |
// Initial Release June 11, 2019 | |
// | |
// | |
#define MODIFIERKEY_FN 0x8f // give Fn key a HID code | |
#define CAPS_LED 13 // Teensy LED shows Caps-Lock | |
// | |
const byte rows_max = 17; // sets the number of rows 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 | |
// A zero indicates no normal key at that location. | |
// | |
int normal[rows_max][cols_max] = { | |
{0,KEY_INSERT,0,KEY_F12,0,0,0,KEY_RIGHT}, | |
{0,KEY_DELETE,0,KEY_F11,0,0,0,KEY_DOWN}, | |
{KEY_UP,KEY_HOME,KEY_MENU,KEY_END,0,0,0,KEY_LEFT}, | |
{0,KEY_F8,KEY_F7,'9','o','l','.',0}, | |
{'{','\'',KEY_LEFT_BRACE,'0','p','ñ','}','-'}, | |
{KEY_F6,'¿','+','8','i','k',',',0}, | |
{'h','6','y','7','u','j','m','n'}, | |
{KEY_F5,KEY_F9,KEY_BACKSPACE,KEY_F10,0,0,KEY_ENTER,KEY_SPACE}, | |
{'g','5','t','4','r','f','v','b'}, | |
{KEY_F4,KEY_F2,KEY_F3,'3','e','d','c',0}, | |
{'<',KEY_F1,KEY_CAPS_LOCK,'2','w','s','x',0}, | |
{KEY_ESC,'|',KEY_TAB,'1','q','a','z',0}, | |
{0,0,0,KEY_PRINTSCREEN,KEY_NUM_LOCK,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_UP,KEY_PAGE_DOWN,0,0}, | |
{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,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}, | |
{MODIFIERKEY_LEFT_ALT,0,0,0,0,0,0,MODIFIERKEY_RIGHT_ALT}, | |
{0,0,MODIFIERKEY_LEFT_SHIFT,0,0,0,MODIFIERKEY_RIGHT_SHIFT,0}, | |
{0,MODIFIERKEY_LEFT_CTRL,0,0,0,0,MODIFIERKEY_RIGHT_CTRL,0}, | |
{0,0,0,MODIFIERKEY_GUI,0,0,0,0}, | |
{0,0,0,0,0,MODIFIERKEY_FN,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,KEY_PAUSE,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,'9','6','3','.',0}, | |
{0,0,0,'/','*','-',0,'+'}, | |
{0,0,0,'8','5','2',0,0}, | |
{0,0,0,'7','4','1','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_SYSTEM_SLEEP,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,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. | |
// HIGH = key not pressed, LOW = key is pressed | |
boolean old_normal_key[rows_max][cols_max]; | |
boolean old_media_key[rows_max][cols_max]; | |
boolean old_modifier_key[rows_max][cols_max]; | |
// | |
// Define the Teensy LC I/O numbers (translated from the FPC pin #) | |
// Row FPC pin # 01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17 | |
// Teensy I/O # 23,00,22,01,24,02,21,03,25,04,20,05,19,06,18,07,17 | |
int Row_IO[rows_max] = {23,0,22,1,24,2,21,3,25,4,20,5,19,6,18,7,17}; // Teensy LC I/O numbers for rows | |
// | |
// Column FPC pin # 18,19,20,21,22,23,24,25 | |
// Teensy I/O # 08,16,09,15,10,14,11,26 | |
int Col_IO[cols_max] = {8,16,9,15,10,14,11,26}; // Teensy LC I/O numbers for columns | |
// | |
// 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++) | |
go_pu(Col_IO[a]); // set each column pin as an input with a pullup | |
for (int b = 0; b < rows_max; b++) | |
go_z(Row_IO[b]); // set each row pin as a floating output | |
for (int r = 0; r < rows_max; r++) | |
for (int c = 0; c < cols_max; c++) | |
old_normal_key[r][c] = old_media_key[r][c] = old_modifier_key[r][c] = HIGH; | |
} | |
// | |
boolean fn = HIGH; // Initialize Fn key to HIGH = "not pressed" | |
//uint16_t mod = 0; // Initialize the modifier keys (bitwise OR between all the modifier keys) | |
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 r = 0; r < rows_max; r++) { | |
go_0(Row_IO[r]); // Activate Row (send it low) | |
delayMicroseconds(10); // give the row time to go low and settle out | |
for (int c = 0; c < cols_max; c++) { | |
// Modifier keys | |
if (modifier[r][c]) { | |
if (!digitalRead(Col_IO[c]) && old_modifier_key[r][c] == HIGH) { // Key first press | |
if (modifier[r][c] != MODIFIERKEY_FN) { | |
Keyboard.press(modifier[r][c]); | |
//mod |= modifier[r][c]; | |
//Keyboard.set_modifier(mod); | |
//Keyboard.send_now(); | |
} | |
else fn = LOW; | |
old_modifier_key[r][c] = LOW; | |
} | |
else if (digitalRead(Col_IO[c]) && old_modifier_key[r][c] == LOW) { // Key release | |
if (modifier[r][c] != MODIFIERKEY_FN) { | |
Keyboard.release(modifier[r][c]); | |
//mod &= ~modifier[r][c] | 0xE000; | |
//Keyboard.set_modifier(mod); | |
//Keyboard.send_now(); | |
} | |
else fn = HIGH; | |
old_modifier_key[r][c] = HIGH; | |
} | |
} | |
else { | |
// Normal keys | |
if (normal[r][c]) { | |
if (!digitalRead(Col_IO[c]) && old_normal_key[r][c] == HIGH) { // Key first press | |
if (fn == HIGH) Keyboard.press(normal[r][c]); | |
old_normal_key[r][c] = LOW; | |
} | |
else if (digitalRead(Col_IO[c]) && old_normal_key[r][c] == LOW) { // Key release | |
Keyboard.release(normal[r][c]); | |
old_normal_key[r][c] = HIGH; | |
} | |
} | |
// Media keys | |
if (media[r][c]) { | |
if (!digitalRead(Col_IO[c]) && old_media_key[r][c] == HIGH) { // Key first press | |
if (fn == LOW) Keyboard.press(media[r][c]); | |
old_media_key[r][c] = LOW; | |
} | |
else if (digitalRead(Col_IO[c]) && old_media_key[r][c] == LOW) { // Key release | |
Keyboard.release(media[r][c]); | |
old_media_key[r][c] = HIGH; | |
} | |
} | |
} | |
} | |
go_z(Row_IO[r]); // De-activate Row (send it to hi-z) | |
} | |
// Turn on the LED on the Teensy for Caps Lock | |
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 | |
delay(5); // The overall keyboard scanning rate is about 30ms | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment