CapsLock Support

Don't define DEBOUNCE.
This commit is contained in:
Jeffrey Sung 2012-09-17 18:51:42 +09:00
parent 78bfaed0f5
commit 3830de7839
3 changed files with 158 additions and 125 deletions

View file

@ -1,43 +1,45 @@
Alternative Controller for Apple IIgs/Standard(M0116) Alternative Controller for Apple IIgs/Standard(M0116)
JeffreySung(nattyman@gmail.com) JeffreySung(nattyman@gmail.com)
=============================== ===============================
Feature Feature
------- -------
- Replaceable keyboard controller for Apple IIgs(A9M0330)/Standard(M0116) - Replaceable keyboard controller for Apple IIgs(A9M0330)/Standard(M0116)
- Teensy++ 2.0 required - Teensy++ 2.0 required
- Some signal bypass required - Some signal bypass required
- ADB keyboard doesn't use matrix for modifier keys. With virtual row for modifier keys, these keys are merged into key matrix. - ADB keyboard doesn't use matrix for modifier keys. With virtual row for modifier keys, these keys are merged into key matrix.
- Power key couldn't be used because power key is not connected to controller. - Power key couldn't be used because power key is not connected to controller.
History History
======= =======
- 2012.09.17 First Release - 2012.09.17 First Release
- 2012.09.17 CapsLock support
Build
===== Build
0. Just Type "Make" and return. =====
0. Just Type "Make" and return.
Hardware
======== Hardware
PJRC Teensy ========
----------- PJRC Teensy
0. The following ports should not be connected to board. -----------
From top view of Teensy++, from GND and counter clock wise. 0. The following ports should not be connected to board.
-7,26(in keyboard PCB, these pins are VDD,GND) From top view of Teensy++, from GND and counter clock wise.
-30,31(in Teensy++, these pins are Ref,GND respectively) -7,26(in keyboard PCB, these pins are VDD,GND)
-5,6(D2,D3 for bluetooth in future) -30,31(in Teensy++, these pins are Ref,GND respectively)
1. Bypass 31 pin(from board) to E4(Teensy) -5,6(D2,D3 for bluetooth in future)
2. Bypass 30 pin(from board) to F2(Teensy) 1. Bypass 31 pin(from board) to E4(Teensy)
3. Refer doc directory 2. Bypass 30 pin(from board) to F2(Teensy)
3. Bypass 6 pin(from board) to A0(Teensy)
To Do 4. Refer doc directory
=====
0. Caps Lock connect To Do
1. Layer Change by toggling Clear Key =====
2. Eject Key add. (following files should be modified.) 0. When DEBOUNCE defined, there is a errors.
common/usb_keycodes.h 1. Layer Change by toggling Clear Key
common/keyboard.c 2. Eject Key add. (following files should be modified.)
3. Use bluetooth common/usb_keycodes.h
EOF common/keyboard.c
3. Use bluetooth
EOF

View file

@ -1,68 +1,68 @@
/* /*
Copyright 2011 Jun Wako <wakojun@gmail.com> Copyright 2011 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CONFIG_H #ifndef CONFIG_H
#define CONFIG_H #define CONFIG_H
/* controller configuration */ /* controller configuration */
#include "controller_teensy.h" #include "controller_teensy.h"
/* USB Device descriptor parameter */ /* USB Device descriptor parameter */
/* for Apple /* for Apple
#define VENDOR_ID 0x05AC #define VENDOR_ID 0x05AC
#define PRODUCT_ID 0xBEE0 #define PRODUCT_ID 0xBEE0
*/ */
#define VENDOR_ID 0xFEED #define VENDOR_ID 0xFEED
#define PRODUCT_ID 0xBEE0 #define PRODUCT_ID 0xBEE0
#define DEVICE_VER 0x0202 #define DEVICE_VER 0x0202
#define MANUFACTURER t.m.k. #define MANUFACTURER t.m.k.
#define PRODUCT Apple Desktop Bus Keyboard #define PRODUCT Apple Desktop Bus Keyboard
/* message strings */ /* message strings */
#define DESCRIPTION Apple M0116/A9M0660 keyboard firmware #define DESCRIPTION Apple M0116/A9M0660 keyboard firmware
/* matrix size */ /* matrix size */
#define MATRIX_ROWS 11 // last row is virtual for modifier #define MATRIX_ROWS 11 // last row is virtual for modifier
#define MATRIX_COLS 8 #define MATRIX_COLS 8
/* define if matrix has ghost */ /* define if matrix has ghost */
#define MATRIX_HAS_GHOST #define MATRIX_HAS_GHOST
/* Set 0 if need no debouncing */ /* Set 0 if need no debouncing */
#define DEBOUNCE 5 #define DEBOUNCE 0
/* key combination for command */ /* key combination for command */
#define IS_COMMAND() ( \ #define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_LCTRL) | MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) || \ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_LCTRL) | MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) || \
keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) \ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) \
) )
/* layer switching */ /* layer switching */
#define LAYER_SWITCH_DELAY 100 #define LAYER_SWITCH_DELAY 100
#define LAYER_SEND_FN_TERM 300 #define LAYER_SEND_FN_TERM 300
/* mouse keys */ /* mouse keys */
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
# define MOUSEKEY_DELAY_TIME 192 # define MOUSEKEY_DELAY_TIME 192
#endif #endif
#endif #endif

View file

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h" #include "debug.h"
#include "util.h" #include "util.h"
#include "matrix.h" #include "matrix.h"
#include "led.h"
#if (MATRIX_COLS > 16) #if (MATRIX_COLS > 16)
@ -86,10 +87,13 @@ void matrix_init(void)
DDRE &= ~0b00000010; DDRE &= ~0b00000010;
PORTE |= 0b00000010; PORTE |= 0b00000010;
// modifier B3/4,F4/5,E4 always input // modifier B3/4,F4/5,E4 always input
DDRB |= 0b00011000; // A0
PORTB &= 0b00011000; //DDRA |= 0b00000001;
DDRF |= ~0b00110000; //PORTA &= 0b00000001;
PORTF &= 0b00110000; //DDRB |= 0b00011000;
//PORTB &= 0b00011000;
//DDRF |= ~0b00110000;
//PORTF &= 0b00110000;
//DDRB &= ~0b00011000; //DDRB &= ~0b00011000;
//PORTB |= 0b00011000; //PORTB |= 0b00011000;
//DDRF &= ~0b00110000; //DDRF &= ~0b00110000;
@ -116,14 +120,26 @@ uint8_t matrix_scan(void)
unselect_rows(); unselect_rows();
select_row(i); select_row(i);
_delay_us(30); // without this wait read unstable value. _delay_us(30); // without this wait read unstable value.
if (matrix[i] != (uint8_t)~read_col(i)) { if ( i == ( MATRIX_ROWS - 1 ) ) { // CHECK CAPS LOCK
matrix[i] = (uint8_t)~read_col(i); if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { // CAPS LOCK is ON on HOST
if (debouncing) { if ( ~read_col(i) & (1<< 4) ) { // CAPS LOCK is still DOWN ( 0bXXX1_XXXX)
debug("bounce!: "); debug_hex(debouncing); print("\n"); matrix[i] = ~read_col(i) & 0b11101111; // change CAPS LOCK as released
} } else { // CAPS LOCK in UP
debouncing = DEBOUNCE; matrix[i] = ~read_col(i) | 0b00010000; // send fake caps lock down
} }
} } else { // CAPS LOCK is OFF on HOST
matrix[i] = ~read_col(i);
}
} else {
if (matrix[i] != (uint8_t)~read_col(i)) {
matrix[i] = (uint8_t)~read_col(i);
}
}
if (debouncing) {
debug("bounce!: "); debug_hex(debouncing); print("\n");
}
debouncing = DEBOUNCE;
}
unselect_rows(); unselect_rows();
if (debouncing) { if (debouncing) {
@ -159,7 +175,17 @@ bool matrix_has_ghost(void)
inline inline
bool matrix_is_on(uint8_t row, uint8_t col) bool matrix_is_on(uint8_t row, uint8_t col)
{ {
return (matrix[row] & (1<<col)); // if ( row == ( MATRIX_ROWS - 1 ) && col == 4) { // CHECK CAPS LOCK
// if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { // CAPS LOCK is ON on HOST
// if ((matrix_prev[row] & 0b00010000) && (~matrix[row] & 0b00010000)) {
// debug("CapsLock Reverse:");debug_hex(matrix[row]);
// matrix[row] |= 0b00010000;
// matrix_prev[row] &= ~0b00010000;
// debug("->");debug_hex(matrix[row]);debug("\n");
// }
// }
// }
return (matrix[row] & (1<<col));
} }
inline inline
@ -229,11 +255,12 @@ static uint8_t read_col(uint8_t row)
// Modifier would be copied to report->mods except E4(CAPSLOCK) // Modifier would be copied to report->mods except E4(CAPSLOCK)
uint8_t tmp; uint8_t tmp;
if ( row == 10 ) { if ( row == 10 ) {
tmp = 0xF0; tmp = 0xE0;
tmp |= (PINB >> 3 ) & 0b00000011; // LEFT CTRL is 0bit in modifier (HID Spec) tmp |= (PINB >> 3 ) & 0b00000011; // LEFT CTRL is 0bit in modifier (HID Spec)
// LEFT SHIFT is 1bit in modifier (HID Spec) // LEFT SHIFT is 1bit in modifier (HID Spec)
tmp |= (PINF >> 3 ) & 0b00000100; // LEFT ALT is 2bit in modifier (HID Spec) tmp |= (PINF >> 3 ) & 0b00000100; // LEFT ALT is 2bit in modifier (HID Spec)
tmp |= (PINF >> 1 ) & 0b00001000; // LEFT GUI is 3bit in modifier (HID Spec) tmp |= (PINF >> 1 ) & 0b00001000; // LEFT GUI is 3bit in modifier (HID Spec)
tmp |= (PINA << 4 ) & 0b00010000; //
//tmp |= (PINE << 1 ) & 0b00010000; // Caps Lock(Should not be in modifier //tmp |= (PINE << 1 ) & 0b00010000; // Caps Lock(Should not be in modifier
} else { } else {
tmp = 0x00; tmp = 0x00;
@ -257,6 +284,8 @@ static void unselect_rows(void)
DDRF &= ~0b11000111; // PF: 7,6,2,1,0 DDRF &= ~0b11000111; // PF: 7,6,2,1,0
PORTF &= ~0b11000111; PORTF &= ~0b11000111;
// to unselect virtual row(modifier), set port to output with low // to unselect virtual row(modifier), set port to output with low
DDRA |= 0b00000001; // PA: 0
PORTA &= ~0b00000001;
DDRB |= 0b00011000; // PB: 3,4 for modifier(row10) DDRB |= 0b00011000; // PB: 3,4 for modifier(row10)
PORTB &= ~0b00011000; PORTB &= ~0b00011000;
DDRF |= 0b00110000; // PF: 4,5 for modifier DDRF |= 0b00110000; // PF: 4,5 for modifier
@ -314,6 +343,8 @@ static void select_row(uint8_t row)
case 10: case 10:
// modifier has no row enable // modifier has no row enable
// to select virtual row, set port as input // to select virtual row, set port as input
DDRA &= ~0b00000001;
PORTA |= 0b00000001;
DDRB &= ~0b00011000; DDRB &= ~0b00011000;
PORTB |= 0b00011000; PORTB |= 0b00011000;
DDRF &= ~0b00110000; DDRF &= ~0b00110000;