📄 keyboard.c
字号:
BYTE bit ;
BYTE col = 0 ;
/* Poll Row0 */
P3DR = 0x7F ;
cols[ col] = get_key() ;
col += 1 ;
P3DR = 0xFF ;
/* Poll Row1 */
P1DR = 0x40 ;
cols[ col] = get_key() ;
col += 1 ;
P1DR = 0xFF ;
/* Poll Row2-7 */
spp( P6C_PG) ;
for( bit = 0x20 ; bit ; bit >>= 1)
{
P6DR = ~bit ;
cols[ col] = get_key() ;
col += 1 ;
}
P6DR = 0xFF ;
/* Poll Row8-14 */
for( bit = 1 ; bit < 0x80 ; bit <<= 1)
{
P5DR = ~bit ;
cols[ col] = get_key() ;
col += 1 ;
}
P5DR = 0xFF ;
// if( !configuration_status[ 3]) /* Joystick is not active */
// {
// P5DR = 0x7F ;
// cols[ col] = get_key() ;
// P5DR = 0xFF ;
// }
/* Row 15: Joystick buttons */
P5DR = 0x7F ;
cols[ col] = get_key() ;
P5DR = 0xFF ;
}
BYTE ghost_f ;
static BYTE check_ghost( void)
{
BYTE i, j, t ;
for( i = 0 ; i < 15 ; i++)
{
for( j = i + 1 ; j < 16 ; j++)
{
if( cols[ i] & cols[ j]) /* At least one bit in common */
{
t = cols[ i] | cols[ j] ; /* Ghost key effect */
if( t & ~( t & -t)) /* Check at least 2 bits */
return 1 ;
}
}
}
return 0 ;
#if 0
j = cols[ i] ;
if( j & ~( j & -j)) /* if at least 2 bits are set */
{
BYTE sum ;
sum = 0 ;
for( j = i + 1 ; j < 16 ; j++)
{
// if( i != j)
// sum |= cols[ j] ;
// }
if( cols[ i] & cols[ j])
{
return 1 ;
}
}
}
}
return 0 ;
#endif
}
void kbd_poll( void)
{
BYTE col ;
cols_poll() ;
ghost_f = check_ghost() ;
if( ghost_f)
{
kbd_rollover() ;
}
else
{
kbd_idx = 2 ; /* Index for insertion in Buffer */
kbd_Buffer[ 0] = kbd_Buffer[ 1] = 0 ;
for( col = 0 ; col < 15 ; col++)
{
if( cols[ col] != 0)
do_col( col, cols[ col]) ;
}
if( configuration_status[ 3]) /* Joystick is active */
{
extern BYTE j_buttons ;
j_buttons = cols[ 15] ;
}
else
{
extern BYTE x, y ;
if( cols[ 15])
do_col( 15, cols[ 15]) ;
get_xy() ;
if( y < 64)
kbd_insert( 0x52) ;
if( y > 192)
kbd_insert( 0x51) ;
if( x >192) /* Right */
kbd_insert( 0x4F) ;
if( x < 64) /* Left */
kbd_insert( 0x50) ;
}
while( kbd_idx < 8)
{
kbd_Buffer[ kbd_idx++] = 0x00 ;
}
}
}
void KEYBOARD_proc( void)
{
if( configuration_status[ 1])
{
spp( 4) ;
if( (ENDPR3_A & 0x30) == 0x20 /* STAT_NAK */)
{
BYTE i, change ;
kbd_poll() ;
// if( !ghost_f)
// {
change = 0 ;
for( i = 0 ; i < 8 ; i++)
{
if( kbd_tmp[ i] != kbd_Buffer[ i])
{
change = 1 ;
}
kbd_tmp[ i] = kbd_Buffer[ i] ;
}
if( kbd_tmp[ 0] == 0x01 && kbd_tmp[ 2] == KL1 && kbd_tmp[ 4] == 0)
{
switch( kbd_tmp[ 3])
{
case KF19: /* USB European */
scanmap = &scancode[ 0] ;
change = 0 ;
break ;
case KF20: /* UK -> US */
scanmap = &scancode[ 1] ;
change = 0 ;
break ;
case KF21: /* GE -> US */
scanmap = &scancode[ 2] ;
change = 0 ;
break ;
case KF22: /* FR -> US */
scanmap = &scancode[ 3] ;
change = 0 ;
break ;
case KF23: /* IT -> US */
scanmap = &scancode[ 4] ;
change = 0 ;
break ;
case KF24: /* SP -> US */
scanmap = &scancode[ 5] ;
change = 0 ;
break ;
}
}
if( change)
KEYBOARD_Send() ;
// }
}
}
}
void KEYBOARD_Send( void)
{
EP3TxAddr = kbd_Buffer ;
EP3TxCount = sizeof kbd_Buffer ;
spp( 4) ;
ENDPR3_A |= 0x30 ; /* Tx Valid */
}
void KEYBOARD_reset( void)
{
/* Always called in Endpoint 0 (HUB) context */
spp( 4) ;
ENDPR2_A |= 0x02 ; /* Control endpoint */
EP2RxAddr = RxBuffer[ 1] ;
EP2RxCount = MAX_PACKET_SIZE ;
EP2TxAddr = 0 ; /* Insure there is a valid Tx address in case of a STATUS IN */
ENDPR2_A &= ~0x30 ; /* EP2 TX STAT_DISABLED */
ENDPR2_B |= 0x30 ; /* EP2 RX STAT_VALID */
/* INT IN */
ENDPR3_A &= ~0x30 ; /* EP3 TX STAT_DISABLED */
ENDPR3_B &= ~0x30 ; /* EP3 RX STAT_DISABLED */
ENDPR3_B |= 0x1 ; /* EP3 is Device 1 Endpoint 1 */
spp( USB_PG) ;
DADDR1 = 0 | 0x80 ; /* EP0 default address */
}
void KEYBOARD_set_configuration( BYTE configuration_status)
{
/* Called in the CTL endpoint context */
if( configuration_status == 0)
{
/* device is not configured */
ENDPR3_A &= ~0x30 ; /* Disable Tx */
}
else
{
/* device is configured */
scanmap = &scancode[ 0] ;
ENDPR3_A &= ~0x70 ;
ENDPR3_A |= 0x20 ; /* Tx STAT_NAK */
}
}
#pragma INTERRUPT ep2_int
void ep2_int( void)
{
spp( 4) ;
if( ENDPR2_A == 0xEE) /* Correct SETUP received */
{
ENDPR2_B |= 0x80 ; /* By default we expect STATUS_OUT */
CurDevice = 1 ;
CurRxBuffer = (BYTE *) EP2RxAddr ;
fsm_state[ 1] = do_setup() ;
switch( fsm_state[ 1])
{
case TX_STALL:
ENDPR2_A &= ~0x30 ; /* Clear STAT bits */
ENDPR2_A |= 0x10 ; /* Tx STAT_STALL */
break ;
case TX_N:
EP2TxAddr = data_ptr ;
if( data_size[ 1] >= MAX_PACKET_SIZE)
{
EP2TxCount = MAX_PACKET_SIZE ;
}
else
{
EP2TxCount = data_size[ 1] ;
fsm_state[ 1] = TX_LAST ;
}
ENDPR2_A |= 0x30 ; /* TX STAT_VALID */
break ;
case TX_ACK_ADDR:
case TX_0:
EP2TxCount = 0 ; /* Enable the transmission */
ENDPR2_A |= 0x30 ;
break ;
default:
nop() ;
}
}
else if( (ENDPR2_A & 0xBF) == 0xAA) /* IN (don't care toggle) */
{
switch( fsm_state[ 1])
{
case TX_N: /* after IN( n) => send next */
EP2TxAddr += EP2TxCount ;
data_size[ 1] -= EP2TxCount ;
if( data_size[ 1] < MAX_PACKET_SIZE)
{
EP2TxCount = data_size[ 1] ;
fsm_state[ 1] = TX_LAST ;
}
ENDPR2_A |= 0x30 ; /* Tx STAT_VALID */
break ;
case TX_LAST: /* after a IN( 0) => expect STATUS_OUT */
break ;
case TX_ACK_ADDR:
spp( USB_PG) ;
DADDR1 = 0x80 | address[ 1] ;
spp( 4) ;
/* Fall Through */
case TX_0: /* STATUS_IN */
fsm_state[ 1] = UNDEFINED ;
break ;
}
}
else if( (ENDPR2_A & 0x8F) == 0x82) /* OUT (don't care Tx STAT */
{
switch( fsm_state[ 1])
{
case TX_N: /* HOST stops transmission */
ENDPR2_A &= ~0x30 ; /* Tx STAT_DISABLE */
/* Fall Through */
case TX_LAST: /* Status_out following transmission */
fsm_state[ 1] = UNDEFINED ;
}
}
EP2RxCount = MAX_PACKET_SIZE ;
ENDPR2_B |= 0x30 ; /* Rx STAT_VALID */
ENDPR2_A &= ~0x80 ; /* Reset CTR */
}
#pragma INTERRUPT ep3_int
void ep3_int( void)
{
spp( 4) ;
ENDPR3_A &= ~0x80 ; /* Reset CTR bit */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -