📄 joystick.c
字号:
#include <cpu.h>
#include <usb.h>
#pragma register_file EP6TxAddr 48
extern volatile void *EP6TxAddr ;
#pragma register_file EP6TxCount 50
extern volatile WORD EP6TxCount ;
#pragma register_file EP6RxAddr 52
extern volatile void *EP6RxAddr ;
#pragma register_file EP6RxCount 54
extern volatile WORD EP6RxCount ;
#pragma register_file EP7TxAddr 56
extern volatile void *EP7TxAddr ;
#pragma register_file EP7TxCount 58
extern volatile WORD EP7TxCount ;
//#pragma register_file EP7RxAddr 60
//extern volatile void *EP7RxAddr ;
//#pragma register_file EP7RxCount 62
//extern volatile WORD EP7RxCount ;
void JOYSTICK_Send( BYTE buts, BYTE x, BYTE y) ;
BYTE x, y ; /* Joystick values */
static BYTE xmin = 255 ;
static BYTE xmax = 0 ;
static WORD xrange ;
static BYTE ymin = 255 ;
static BYTE ymax = 0 ;
static WORD yrange ;
WORD stretch( WORD val)
{
// WORD val ;
// val = coord ;
// coord >>= 2 ;
// val += coord ;
// coord >>=1 ;
// val += coord ;
// coord >>= 1 ;
// val += coord ; /* val = 1.4375 coord (> square 2) */
val += val >> 1 ; /* 1.5 */
if( val < 63)
val = 0 ;
else
val -= 63 ;
if( val > 255)
val = 255 ;
return val ;
}
void get_xy( void)
{
spp( FAD_PG) ;
/* do conversion */
FAD_CLR = 0xA5 ; /* Start channel 5 on P6.7 */
while( FAD_CLR & 1)
;
x = FAD_DTR ;
FAD_CLR = 0x95 ; /* Start channel 4 on P6.6 */
while( FAD_CLR & 1)
;
y = FAD_DTR ;
x = 255 - x ; /* Invert X sensing */
// x &= 0xFC ; /* Drop last bits */
// y &= 0xFC ; /* Drop last bits */
if( x < xmin)
xmin = x ;
if( xmax < x)
xmax = x ;
if( (xmin < 43) && (xmax > 212))
{
xrange = xmax - xmin + 1;
x = ((x - xmin) * 256) / xrange ;
}
x = stretch( x) ;
if( y < ymin)
ymin = y ;
if( ymax < y)
ymax = y ;
if( (ymin < 43) && (ymax > 212))
{
yrange = ymax - ymin + 1;
y = ((y - ymin) * 256) / yrange ;
}
y = stretch( y) ;
}
BYTE j_buttons ; /* Set by keyboard polling routine when no ghost key */
void joy_poll( void)
{
BYTE buts, tmp, cnt ;
get_xy() ;
if( configuration_status[ 1]) /* Keyboard polling is active */
{
buts = j_buttons ;
}
else
{
extern BYTE get_key() ;
// buts = 0 ;
// tmp = 0 ;
// cnt = 0 ;
P5DR = 0x7F ;
// do
// {
// buts = ~P3DR & 0x0F ;
// buts |= (~P4DR << 4) & 0xF0 ;
// if( tmp == buts)
// {
// cnt += 1 ;
// }
// else
// {
// cnt = 0 ;
// tmp = buts ;
// }
// }
// while( cnt < 8) ;
buts = get_key() ;
P5DR = 0xFF ;
}
/* Process the raw values */
tmp = 0 ;
if( buts & 1)
tmp |= 0x08 ;
if( buts & 2)
tmp |= 0x20 ;
if( buts & 4)
tmp |= 0x04 ;
if( buts & 8)
tmp |= 0x10 ;
if( buts & 16)
tmp |= 0x01 ;
if( buts & 32)
tmp |= 0x02 ;
buts = tmp ;
JOYSTICK_Send( buts, x, y) ;
}
BYTE Joy_Buffer[ 3] ;
void JOYSTICK_Send( BYTE buts, BYTE x, BYTE y)
{
if( Joy_Buffer[ 0] != buts ||
Joy_Buffer[ 1] != x ||
Joy_Buffer[ 2] != y)
{
Joy_Buffer[ 0] = buts ;
Joy_Buffer[ 1] = x ;
Joy_Buffer[ 2] = y ;
EP7TxAddr = Joy_Buffer ;
EP7TxCount = sizeof Joy_Buffer ;
spp( 4) ;
ENDPR7_A |= 0x30 ; /* Tx Valid */
}
}
void JOYSTICK_proc( void)
{
if( configuration_status[ 3])
{
spp( 4) ;
if( (ENDPR7_A & 0x30) == 0x20 /* STAT_NAK */)
{
joy_poll() ;
}
}
}
void JOYSTICK_reset( void)
{
/* Always called in Endpoint 0 (HUB) context */
spp( 4) ;
ENDPR6_A |= 0x02 ; /* Control endpoint */
EP6RxAddr = RxBuffer[ 3] ;
EP6RxCount = MAX_PACKET_SIZE ;
EP6TxAddr = 0 ; /* Insure there is a valid Tx address in case of a STATUS IN */
ENDPR6_A &= ~0x30 ; /* EP2 TX STAT_DISABLED */
ENDPR6_B |= 0x30 ; /* EP2 RX STAT_VALID */
/* INT IN */
ENDPR7_A &= ~0x30 ; /* EP3 TX STAT_DISABLED */
ENDPR7_B &= ~0x30 ; /* EP3 RX STAT_DISABLED */
ENDPR7_B |= 0x1 ; /* EP3 is Device 1 Endpoint 1 */
spp( USB_PG) ;
DADDR3 = 0 | 0x80 ; /* EP0 default address */
}
void JOYSTICK_set_configuration( BYTE configuration_status)
{
/* Called in the CTL endpoint context */
if( configuration_status == 0)
{
/* device is not configured */
ENDPR7_A &= ~0x30 ; /* Disable Tx */
}
else
{
/* device is configured */
ENDPR7_A &= ~0x70 ;
ENDPR7_A |= 0x20 ; /* Tx STAT_NAK */
}
}
#pragma INTERRUPT ep6_int
void ep6_int( void)
{
spp( 4) ;
if( ENDPR6_A == 0xEE) /* Correct SETUP received */
{
ENDPR6_B |= 0x80 ; /* By default we expect STATUS_OUT */
CurDevice = 3 ;
CurRxBuffer = (BYTE *) EP6RxAddr ;
fsm_state[ 3] = do_setup() ;
switch( fsm_state[ 3])
{
case TX_STALL:
ENDPR6_A &= ~0x30 ; /* Clear STAT bits */
ENDPR6_A |= 0x10 ; /* Tx STAT_STALL */
break ;
case TX_N:
EP6TxAddr = data_ptr ;
if( data_size[ 3] >= MAX_PACKET_SIZE)
{
EP6TxCount = MAX_PACKET_SIZE ;
}
else
{
EP6TxCount = data_size[ 3] ;
fsm_state[ 3] = TX_LAST ;
}
ENDPR6_A |= 0x30 ; /* TX STAT_VALID */
break ;
case TX_ACK_ADDR:
case TX_0:
EP6TxCount = 0 ; /* Enable the transmission */
ENDPR6_A |= 0x30 ;
break ;
default:
nop() ;
}
}
else if( (ENDPR6_A & 0xBF) == 0xAA) /* IN (don't care toggle) */
{
switch( fsm_state[ 3])
{
case TX_N: /* after IN( n) => send next */
EP6TxAddr += EP6TxCount ;
data_size[ 3] -= EP6TxCount ;
if( data_size[ 3] < MAX_PACKET_SIZE)
{
EP6TxCount = data_size[ 3] ;
fsm_state[ 3] = TX_LAST ;
}
ENDPR6_A |= 0x30 ; /* Tx STAT_VALID */
break ;
case TX_LAST: /* after a IN( 0) => expect STATUS_OUT */
break ;
case TX_ACK_ADDR:
spp( USB_PG) ;
DADDR3 = 0x80 | address[ 3] ;
spp( 4) ;
/* Fall Through */
case TX_0: /* STATUS_IN */
fsm_state[ 3] = UNDEFINED ;
break ;
}
}
else if( (ENDPR6_A & 0x8F) == 0x82) /* OUT (don't care Tx STAT */
{
switch( fsm_state[ 3])
{
case TX_N: /* HOST stops transmission */
ENDPR6_A &= ~0x30 ; /* Tx STAT_DISABLE */
/* Fall Through */
case TX_LAST: /* Status_out following transmission */
fsm_state[ 3] = UNDEFINED ;
}
}
EP6RxCount = MAX_PACKET_SIZE ;
ENDPR6_B |= 0x30 ; /* Rx STAT_VALID */
ENDPR6_A &= ~0x80 ; /* Reset CTR */
}
#pragma INTERRUPT ep7_int
void ep7_int( void)
{
spp( 4) ;
ENDPR7_A &= ~0x80 ; /* Reset CTR bit */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -