2011-07-20 15:32:52 +00:00
/*
Copyright 2011 Jun Wako < wakojun @ gmail . com >
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
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2011-02-10 06:51:30 +00:00
# include "keyboard.h"
2011-02-08 15:03:58 +00:00
# include "host.h"
2011-02-10 06:51:30 +00:00
# include "layer.h"
2011-02-21 06:43:17 +00:00
# include "matrix.h"
2011-02-08 15:03:58 +00:00
# include "led.h"
2011-02-10 06:51:30 +00:00
# include "usb_keycodes.h"
# include "timer.h"
2011-02-08 15:03:58 +00:00
# include "print.h"
2011-02-10 06:51:30 +00:00
# include "debug.h"
# include "command.h"
# ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
# endif
2011-09-17 13:39:50 +00:00
# ifdef EXTRAKEY_ENABLE
2011-02-21 06:43:17 +00:00
# include <util/delay.h>
# endif
2011-02-08 15:03:58 +00:00
2011-02-12 15:15:51 +00:00
static uint8_t last_leds = 0 ;
2011-02-08 15:03:58 +00:00
2011-02-10 06:51:30 +00:00
void keyboard_init ( void )
2011-02-08 15:03:58 +00:00
{
2011-02-10 06:51:30 +00:00
timer_init ( ) ;
matrix_init ( ) ;
# ifdef PS2_MOUSE_ENABLE
ps2_mouse_init ( ) ;
# endif
2011-02-08 15:03:58 +00:00
}
2011-02-10 06:51:30 +00:00
void keyboard_proc ( void )
2011-02-08 15:03:58 +00:00
{
2011-02-10 06:51:30 +00:00
uint8_t fn_bits = 0 ;
2011-09-17 13:39:50 +00:00
# ifdef EXTRAKEY_ENABLE
2011-05-31 12:17:56 +00:00
uint16_t consumer_code = 0 ;
2012-06-28 11:15:56 +00:00
uint16_t system_code = 0 ;
2011-05-31 12:17:56 +00:00
# endif
2011-02-10 06:51:30 +00:00
matrix_scan ( ) ;
if ( matrix_is_modified ( ) ) {
if ( debug_matrix ) matrix_print ( ) ;
# ifdef DEBUG_LED
// LED flash for debug
DEBUG_LED_CONFIG ;
DEBUG_LED_ON ;
# endif
2011-02-08 15:03:58 +00:00
}
2011-02-10 06:51:30 +00:00
if ( matrix_has_ghost ( ) ) {
// should send error?
debug ( " matrix has ghost!! \n " ) ;
return ;
2011-02-08 15:03:58 +00:00
}
2011-02-10 06:51:30 +00:00
host_swap_keyboard_report ( ) ;
host_clear_keyboard_report ( ) ;
for ( int row = 0 ; row < matrix_rows ( ) ; row + + ) {
for ( int col = 0 ; col < matrix_cols ( ) ; col + + ) {
if ( ! matrix_is_on ( row , col ) ) continue ;
2011-02-08 15:03:58 +00:00
2011-02-10 06:51:30 +00:00
uint8_t code = layer_get_keycode ( row , col ) ;
if ( code = = KB_NO ) {
// do nothing
} else if ( IS_MOD ( code ) ) {
host_add_mod_bit ( MOD_BIT ( code ) ) ;
} else if ( IS_FN ( code ) ) {
fn_bits | = FN_BIT ( code ) ;
}
2011-09-17 13:39:50 +00:00
// TODO: use table or something
# ifdef EXTRAKEY_ENABLE
2011-05-31 12:17:56 +00:00
// System Control
else if ( code = = KB_SYSTEM_POWER ) {
2011-05-21 01:28:57 +00:00
# ifdef HOST_PJRC
2011-02-10 06:51:30 +00:00
if ( suspend & & remote_wakeup ) {
usb_remote_wakeup ( ) ;
}
2011-05-21 01:28:57 +00:00
# endif
2012-06-28 11:15:56 +00:00
system_code = SYSTEM_POWER_DOWN ;
2011-05-31 12:17:56 +00:00
} else if ( code = = KB_SYSTEM_SLEEP ) {
2012-06-28 11:15:56 +00:00
system_code = SYSTEM_SLEEP ;
2011-05-31 12:17:56 +00:00
} else if ( code = = KB_SYSTEM_WAKE ) {
2012-06-28 11:15:56 +00:00
system_code = SYSTEM_WAKE_UP ;
2011-05-31 12:17:56 +00:00
}
// Consumer Page
else if ( code = = KB_AUDIO_MUTE ) {
consumer_code = AUDIO_MUTE ;
} else if ( code = = KB_AUDIO_VOL_UP ) {
consumer_code = AUDIO_VOL_UP ;
} else if ( code = = KB_AUDIO_VOL_DOWN ) {
consumer_code = AUDIO_VOL_DOWN ;
}
else if ( code = = KB_MEDIA_NEXT_TRACK ) {
consumer_code = TRANSPORT_NEXT_TRACK ;
} else if ( code = = KB_MEDIA_PREV_TRACK ) {
consumer_code = TRANSPORT_PREV_TRACK ;
} else if ( code = = KB_MEDIA_STOP ) {
consumer_code = TRANSPORT_STOP ;
} else if ( code = = KB_MEDIA_PLAY_PAUSE ) {
consumer_code = TRANSPORT_PLAY_PAUSE ;
} else if ( code = = KB_MEDIA_SELECT ) {
consumer_code = AL_CC_CONFIG ;
}
else if ( code = = KB_MAIL ) {
consumer_code = AL_EMAIL ;
} else if ( code = = KB_CALCULATOR ) {
consumer_code = AL_CALCULATOR ;
} else if ( code = = KB_MY_COMPUTER ) {
consumer_code = AL_LOCAL_BROWSER ;
}
else if ( code = = KB_WWW_SEARCH ) {
consumer_code = AC_SEARCH ;
} else if ( code = = KB_WWW_HOME ) {
consumer_code = AC_HOME ;
} else if ( code = = KB_WWW_BACK ) {
consumer_code = AC_BACK ;
} else if ( code = = KB_WWW_FORWARD ) {
consumer_code = AC_FORWARD ;
} else if ( code = = KB_WWW_STOP ) {
consumer_code = AC_STOP ;
} else if ( code = = KB_WWW_REFRESH ) {
consumer_code = AC_REFRESH ;
} else if ( code = = KB_WWW_FAVORITES ) {
consumer_code = AC_BOOKMARKS ;
2011-02-10 06:51:30 +00:00
}
# endif
else if ( IS_KEY ( code ) ) {
host_add_key ( code ) ;
}
# ifdef MOUSEKEY_ENABLE
else if ( IS_MOUSEKEY ( code ) ) {
mousekey_decode ( code ) ;
}
# endif
else {
debug ( " ignore keycode: " ) ; debug_hex ( code ) ; debug ( " \n " ) ;
}
}
2011-02-08 15:03:58 +00:00
}
2011-02-10 06:51:30 +00:00
layer_switching ( fn_bits ) ;
2011-02-08 15:03:58 +00:00
2011-02-10 06:51:30 +00:00
if ( command_proc ( ) ) {
return ;
2011-02-08 15:03:58 +00:00
}
2011-02-15 12:14:55 +00:00
// TODO: should send only when changed from last report
2011-02-10 06:51:30 +00:00
if ( matrix_is_modified ( ) ) {
host_send_keyboard_report ( ) ;
2011-09-17 13:39:50 +00:00
# ifdef EXTRAKEY_ENABLE
2011-05-31 12:17:56 +00:00
host_consumer_send ( consumer_code ) ;
2012-06-28 11:15:56 +00:00
host_system_send ( system_code ) ;
2011-05-31 12:17:56 +00:00
# endif
2011-02-10 06:51:30 +00:00
# ifdef DEBUG_LED
// LED flash for debug
DEBUG_LED_CONFIG ;
DEBUG_LED_OFF ;
# endif
2011-02-08 15:03:58 +00:00
}
2011-02-10 06:51:30 +00:00
# ifdef MOUSEKEY_ENABLE
mousekey_send ( ) ;
# endif
2011-02-08 15:03:58 +00:00
2011-02-10 06:51:30 +00:00
# ifdef PS2_MOUSE_ENABLE
// TODO: should comform new API
if ( ps2_mouse_read ( ) = = 0 )
ps2_mouse_usb_send ( ) ;
# endif
2011-02-12 15:15:51 +00:00
if ( last_leds ! = host_keyboard_leds ( ) ) {
keyboard_set_leds ( host_keyboard_leds ( ) ) ;
last_leds = host_keyboard_leds ( ) ;
2011-02-10 06:51:30 +00:00
}
2011-02-08 15:03:58 +00:00
}
2011-02-12 15:15:51 +00:00
void keyboard_set_leds ( uint8_t leds )
{
led_set ( leds ) ;
}