⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 joystick.c

📁 用ST92163开发的鼠标
💻 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 + -