2011-12-14 03:13:32 +00:00
/*
2012-05-21 15:14:02 +00:00
Copyright 2011 , 2012 Jun Wako < wakojun @ gmail . com >
2011-12-14 03:13:32 +00:00
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/>.
*/
/*
* scan matrix
*/
# include <stdint.h>
# include <stdbool.h>
# include <avr/io.h>
# include <util/delay.h>
# include "print.h"
# include "util.h"
# include "debug.h"
# include "host.h"
# include "led.h"
# include "m0110.h"
# include "matrix.h"
# define CAPS 0x39
2012-05-14 18:41:07 +00:00
# define CAPS_BREAK (CAPS | 0x80)
2011-12-14 03:13:32 +00:00
# define ROW(key) ((key)>>3&0x0F)
# define COL(key) ((key)&0x07)
static bool is_modified = false ;
// matrix state buffer(1:on, 0:off)
static uint8_t * matrix ;
static uint8_t _matrix0 [ MATRIX_ROWS ] ;
static void register_key ( uint8_t key ) ;
inline
uint8_t matrix_rows ( void )
{
return MATRIX_ROWS ;
}
inline
uint8_t matrix_cols ( void )
{
return MATRIX_COLS ;
}
void matrix_init ( void )
{
print_enable = true ;
debug_enable = true ;
debug_matrix = false ;
debug_keyboard = false ;
debug_mouse = false ;
print ( " debug enabled. \n " ) ;
m0110_init ( ) ;
// initialize matrix state: all keys off
for ( uint8_t i = 0 ; i < MATRIX_ROWS ; i + + ) _matrix0 [ i ] = 0x00 ;
matrix = _matrix0 ;
return ;
}
uint8_t matrix_scan ( void )
{
uint8_t key ;
is_modified = false ;
key = m0110_recv_key ( ) ;
# ifdef MATRIX_HAS_LOCKING_CAPS
// Send Caps key up event
if ( matrix_is_on ( ROW ( CAPS ) , COL ( CAPS ) ) ) {
is_modified = true ;
2012-05-14 18:41:07 +00:00
register_key ( CAPS_BREAK ) ;
2011-12-14 03:13:32 +00:00
}
# endif
if ( key = = M0110_NULL ) {
return 0 ;
2012-04-27 16:57:36 +00:00
} else if ( key = = M0110_ERROR ) {
return 0 ;
2011-12-14 03:13:32 +00:00
} else {
# ifdef MATRIX_HAS_LOCKING_CAPS
if ( host_keyboard_leds ( ) & ( 1 < < USB_LED_CAPS_LOCK ) ) {
// CAPS LOCK on:
// Ignore LockingCaps key down event
if ( key = = CAPS ) return 0 ;
// Convert LockingCaps key up event into down event
2012-05-14 18:41:07 +00:00
if ( key = = CAPS_BREAK ) key = CAPS ;
2011-12-14 03:13:32 +00:00
} else {
// CAPS LOCK off:
// Ignore LockingCaps key up event
2012-05-14 18:41:07 +00:00
if ( key = = CAPS_BREAK ) return 0 ;
2011-12-14 03:13:32 +00:00
}
# endif
is_modified = true ;
register_key ( key ) ;
}
if ( debug_enable ) {
2012-05-21 15:14:02 +00:00
print ( " [ " ) ; phex ( key ) ; print ( " ] \n " ) ;
2011-12-14 03:13:32 +00:00
}
return 1 ;
}
bool matrix_is_modified ( void )
{
return is_modified ;
}
inline
bool matrix_has_ghost ( void )
{
return false ;
}
inline
bool matrix_is_on ( uint8_t row , uint8_t col )
{
return ( matrix [ row ] & ( 1 < < col ) ) ;
}
inline
uint8_t matrix_get_row ( uint8_t row )
{
return matrix [ row ] ;
}
void matrix_print ( void )
{
print ( " \n r/c 01234567 \n " ) ;
for ( uint8_t row = 0 ; row < matrix_rows ( ) ; row + + ) {
phex ( row ) ; print ( " : " ) ;
pbin_reverse ( matrix_get_row ( row ) ) ;
print ( " \n " ) ;
}
}
uint8_t matrix_key_count ( void )
{
uint8_t count = 0 ;
for ( uint8_t i = 0 ; i < MATRIX_ROWS ; i + + ) {
count + = bitpop ( matrix [ i ] ) ;
}
return count ;
}
inline
static void register_key ( uint8_t key )
{
if ( key & 0x80 ) {
matrix [ ROW ( key ) ] & = ~ ( 1 < < COL ( key ) ) ;
} else {
matrix [ ROW ( key ) ] | = ( 1 < < COL ( key ) ) ;
}
}