📄 usbmouse.c
字号:
*UIFR3 = *UIFR3 & 0xfe; /*VBUSi僼儔僌僋儕傾*/
/*VBUSs僼儔僌傪傒傞*/
if( ( *UIFR3 & 0x02 ) != 0 ){ /*愙懕忬懺*/
usb_connect(); /*愙懕帪偺張棟傊*/
}else{ /*愗抐忬懺*/
usb_disconnect(); /*愗抐帪偺張棟傊*/
}
return;
}
/*僶僗儕僙僢僩妱傝崬傒敪惗*/
if( ( *UIFR0 & 0x80 ) != 0 ){
*UIFR0 = *UIFR0 & 0x7f; /*BRST僼儔僌僋儕傾*/
#ifdef DEBUG
sci_print("bus reset\n");
#endif
/*僼傽乕儉僂僃傾偺弶婜壔*/
/*僙僢僩傾僢僾妱傝崬傒懸偪*/
return;
}
/*僙僢僩傾僢僾僐儅儞僪庴怣姰椆*/
if( ( *UIFR0 & 0x01 ) != 0 ){ /*SetupTS*/
*UIFR0 = *UIFR0 & 0xfe; /*SetupTS僼儔僌僋儕傾*/
#ifdef DEBUG
sci_print("setup\n");
#endif
*UFCLR0 = *UFCLR0 | 0x06; /*EP0i FIFO僋儕傾*/
/*EP0o FIFO僋儕傾*/
for( i = 0; i < 8; i++ ){ /*僨僶僀僗儕僋僄僗僩傪庴怣*/
ep0_rxdat[i] = *UEDR0s; /*UEDR0s偐傜8僶僀僩偺僨乕僞傪僶僢僼傽偵儕乕僪*/
#ifdef DEBUG
sci_reg_print(ep0_rxdat[i]);
#endif
}
#ifdef DEBUG
sci_print("\n");
#endif
*UTRG0 = *UTRG0 | 0x01; /*EP0s撉傒弌偟姰椆價僢僩偵侾儔僀僩*/
device_request((struct DEVICE_REQUEST*)ep0_rxdat); /*僨僶僀僗儕僋僄僗僩敾暿*/
return;
}
/*EP0i憲怣姰椆 嵟弶偺僷働僢僩偑儂僗僩偵憲怣偝傟偨偁偲偵妱傝崬傒偑偐偐傞*/
if( ( *UIFR0 & 0x02 ) != 0 ){ /*UIFR0/EP0iTS=1*/
*UIFR0 = *UIFR0 & 0xfd; /*EP0i憲怣姰椆僼儔僌僋儕傾(UIFR0/EP0iTS=0)*/
#ifdef DEBUG
sci_print("UIFR0/EP0iTS=1\n");
#endif
ep0_tx(); /*巆傝偺僨乕僞傪憲怣*/
return;
}
/*EP0i揮憲儕僋僄僗僩*/
if( ( *UIFR0 & 0x04 ) != 0 ){ /*UIFR0/EP0iTR=1*/
*UIFR0 = *UIFR0 & 0xfb; /*EP0i揮憲儕僋僄僗僩僼儔僌僋儕傾*/
#ifdef DEBUG
sci_print("UIFR0/EP0iTR=1\n");
#endif
return;
}
/*EP0o庴怣姰椆*/
if( ( *UIFR0 & 0x08 ) != 0 ){ /*UIFR0/EP0oTS=1*/
*UIFR0 = *UIFR0 & 0xf7; /*EP0o庴怣姰椆僼儔僌僋儕傾(UIFR0/EP0oTS=0)*/
#ifdef DEBUG
sci_print("UIFR0/EP0oTS=1\n");
#endif
*UTRG0 = *UTRG0 | 0x04; /*EP0o撉傒弌偟姰椆價僢僩偵1儔僀僩(UTRG0/EP0oRDFN=1))*/
return;
}
}
/****************************************************************/
/* 妱傝崬傒張棟 EP1iTR EP1iTS */
/****************************************************************/
void exirq1( void )
{
/* EP1i揮憲儕僋僄僗僩(UIFR0/EP1iTR=1) */
if( ( *UIFR0 & 0x20 ) != 0 ){
*UIFR0 = *UIFR0 & 0xdf; /* EP1i揮憲儕僋僄僗僩僼儔僌僋儕傾 UIFR0/EP1iTR=0 */
mouse.button = 0x00; /*僨乕僞僋儕傾*/
mouse.x = 0; /*僨乕僞僋儕傾*/
mouse.y = 0; /*僨乕僞僋儕傾*/
if( (*PORTF & 0x01) == 0 ){
mouse.x -= 5;
}
if( (*PORTF & 0x02) == 0 ){
mouse.x += 5;
}
if( (*PORT3 & 0x04) == 0 ){
mouse.y -= 5;
}
if( (* PORT7 & 0x10) == 0 ){
mouse.y += 5;
}
/* USB僄儞僪億僀儞僩僨乕僞儗僕僗僞1i(UEDR1i)偵僨乕僞傪儔僀僩 */
*UEDR1i = mouse.button;
*UEDR1i = mouse.x;
*UEDR1i = mouse.y;
*UTRG0 = *UTRG0 | 0x08; /* EP1i僷働僢僩僀僱乕僽儖價僢僩偵1儔僀僩(UTRG0/EP1iPKTE=1) */
return;
}
/* EP0i憲怣姰椆(UIFR0/EP1iTS=1) */
if( ( *UIFR0 & 0x10 ) != 0 ){
*UIFR0 = *UIFR0 & 0xef; /* EP0i憲怣姰椆僼儔僌僋儕傾(UIFR0/EP1iTS=0) */
return;
}
}
/****************************************************************/
/* 僄儞僪億僀儞僩0憲怣張棟 */
/****************************************************************/
void ep0_tx( void )
{
int i;
if( ep0_txsize > 8 ){ /*憲怣僨乕僞偑8僶僀僩埲忋偁傞側傜*/
for( i=0; i<8; i++ ){
*UEDR0i = *ep0_txptr; /*USB僄儞僪億僀儞僩僨乕僞儗僕僗僞0i(UEDR0i)偵僨乕僞傪儔僀僩*/
#ifdef DEBUG
sci_reg_print(*ep0_txptr);
sci_print("\n");
#endif
ep0_txptr++; /*僨乕僞偺億僀儞僞僀儞僋儕儊儞僩*/
}
ep0_txsize = ep0_txsize - 8; /*憲怣偟偨暘僒僀僘傪堷偔*/
}else{ /*憲怣僨乕僞偑8僶僀僩埲壓側傜*/
for( i=0; i<ep0_txsize; i++ ){
*UEDR0i = *ep0_txptr; /*USB僄儞僪億僀儞僩僨乕僞儗僕僗僞0i(UEDR0i)偵僨乕僞傪儔僀僩*/
#ifdef DEBUG
sci_reg_print(*ep0_txptr);
sci_print("\n");
#endif
ep0_txptr++; /*僨乕僞偺億僀儞僞僀儞僋儕儊儞僩*/
}
ep0_txsize = 0; /*偡傋偰憲怣偟廔傢偭偨偺偱0傪彂偒崬傓*/
}
*UTRG0 = *UTRG0 | 0x02; /*EP0i僷働僢僩僀僱乕僽儖價僢僩偵1儔僀僩(UTRG0/EP0iPKTE = 0)*/
}
/****************************************************************/
/* USB愙懕帪偺張棟 */
/****************************************************************/
int usb_connect( void )
{
#ifdef DEBUG
sci_print("connect\n");
#endif
/*慡FIFO傪僋儕傾*/
*UFCLR0 = 0xff;
*UFCLR1 = 0xff;
/*僔僗僥儉弨旛俷俲丠*/
*P3DR = *P3DR | 0x40; /*D+僾儖傾僢僾ON*/
/*UDC僐傾儕僙僢僩夝彍*/
*UCTLR = *UCTLR & 0xfe;
}
/****************************************************************/
/* USB愗抐帪偺張棟 */
/****************************************************************/
int usb_disconnect( void )
{
#ifdef DEBUG
sci_print("disconnect\n");
#endif
if( ( *UCTLR & 0x40 ) == 1 ){ /*SOF儅乕僇婡擻僀僱乕僽儖偐丠*/
*UCTLR = *UCTLR & 0xbf; /*YES:SOF儅乕僇乕偺掆巭*/
}
*P3DR = *P3DR & 0xbf; /*D+僾儖傾僢僾OFF*/
*UCTLR = *UCTLR | 0x01; /*UDC僐傾儕僙僢僩*/
/*愙懕懸偪*/
}
/****************************************************************/
/* 僨僶僀僗儕僋僄僗僩偺敾暿 */
/****************************************************************/
void device_request( struct DEVICE_REQUEST *devreq )
{
#ifdef DEBUG
sci_print("device request\n");
#endif
/*僨僶僀僗儕僋僄僗僩偺張棟*/
switch( ( devreq->bmRequestType ) & 0x60 ){
case 0x00: /*倀俽俛昗弨*/
switch( devreq->bRequest ){
case 0x05: /*SET_ADDRESS*/
#ifdef DEBUG
sci_print("set address\n");
#endif
break;
case 0x06: /*GET_DESCRIPTOR*/
#ifdef DEBUG
sci_print("get descriptor\n");
#endif
get_descriptor(devreq);
break;
}
break;
case 0x20: /*僋儔僗掕媊*/
#ifdef DEBUG
sci_print("class\n");
#endif
break;
case 0x40: /*儀儞僟掕媊*/
#ifdef DEBUG
sci_print("vendor\n");
#endif
break;
case 0x60: /*梊栺嵪*/
#ifdef DEBUG
sci_print("reserved\n");
#endif
break;
default:
break;
}
}
/****************************************************************/
/* 僨傿僗僋儕僾僞偺敾暿 */
/****************************************************************/
void get_descriptor( struct DEVICE_REQUEST *devreq )
{
unsigned char *p;
unsigned short length;
unsigned char value;
p = (unsigned char *)(&(devreq->wValue)); /*庴怣偟偨僨僶僀僗儕僋僄僗僩偐傜梫媮偝傟偨僨傿僗僋儕僾僞僞僀僾傪庢摼*/
value = (*(p+1));
p = (unsigned char *)(&(devreq->wLength)); /*庴怣偟偨僨僶僀僗儕僋僄僗僩偐傜梫媮偝傟偨僨傿僗僋儕僾僞偺僒僀僘傪庢摼*/
length = *p + (*(p+1)<<8);
switch( value ){
case 0x01: /* Device Descriptor */
#ifdef DEBUG
sci_print("device descriptor\n");
#endif
if (length > dev_desc[0]){ /*儂僗僩偐傜偺梫媮僒僀僘偑僨僶僀僗僨傿僗僋儕僾僞偺僒僀僘傛傝戝偒偄応崌*/
length = dev_desc[0]; /*憲怣偡傞僨乕僞偺僒僀僘傪僨僶僀僗僨傿僗僋儕僾僞偺僒僀僘偵偡傞*/
}
ep0_txptr = &dev_desc[0]; /*憲怣偡傞僨乕僞偺愭摢傾僪儗僗傪擖傟傞*/
ep0_txsize = length; /*憲怣偡傞僨乕僞偺僒僀僘傪擖傟傞*/
ep0_tx(); /*憲怣*/
break;
case 0x02: /* Configuration Descriptor */
#ifdef DEBUG
sci_print("configuration descriptor\n");
#endif
if (length > config_inf[0]){ /*儂僗僩偐傜偺梫媮僒僀僘偑僐儞僼傿僌忣曬偺僒僀僘傛傝戝偒偄応崌*/
length = config_inf[0]; /*憲怣偡傞僨乕僞偺僒僀僘傪僐儞僼傿僌忣曬偺僒僀僘偵偡傞*/
}
ep0_txptr = &config_inf[1]; /*憲怣偡傞僨乕僞偺愭摢傾僪儗僗傪擖傟傞乮僨乕僞挿偼憲傜側偄乯*/
ep0_txsize = length; /*憲怣偡傞僨乕僞偺僒僀僘傪擖傟傞*/
ep0_tx(); /*憲怣*/
break;
case 0x09: /* Set Configuration */
#ifdef DEBUG
sci_print("set configuration\n");
#endif
break;
case 0x22: /* Report Descriptor */
#ifdef DEBUG
sci_print("report descriptor\n");
#endif
if (length > report_desc[0]){ /*儂僗僩偐傜偺梫媮僒僀僘偑儕億乕僩僨傿僗僋儕僾僞偺僒僀僘傛傝戝偒偄応崌*/
length = report_desc[0];/*憲怣偡傞僨乕僞偺僒僀僘傪儕億乕僩僨傿僗僋儕僾僞偺僒僀僘偵偡傞*/
}
ep0_txptr = &report_desc[1]; /*憲怣偡傞僨乕僞偺愭摢傾僪儗僗傪擖傟傞乮僨乕僞挿偼憲傜側偄乯*/
ep0_txsize = length; /*憲怣偡傞僨乕僞偺僒僀僘傪擖傟傞*/
ep0_tx(); /*憲怣*/
break;
default:
break;
}
}
/****************************************************************/
/* 僔儕傾儖暥帤楍昞帵 */
/****************************************************************/
void sci_print( char *data )
{
while( *data != '\0' ){ /*暥帤楍偺廔傢傝傑偱儖乕僾*/
if( *data == '\n' ){ /*夵峴*/
sci_write(0x0a);
sci_write(0x0d);
}else{
sci_write( *data ); /*侾暥帤弌椡*/
}
data++;
}
}
/****************************************************************/
/* 儘儞僌儚乕僪俫俤倃弌椡 */
/****************************************************************/
void sci_reg_print( unsigned long data )
{
const unsigned char disp_table[] = "0123456789ABCDEF";
sci_write( disp_table[ ( data & 0xf0000000 ) >> 28 ] );
sci_write( disp_table[ ( data & 0xf000000 ) >> 24 ] );
sci_write( disp_table[ ( data & 0xf00000 ) >> 20 ] );
sci_write( disp_table[ ( data & 0xf0000 ) >> 16 ] );
sci_write( disp_table[ ( data & 0xf000 ) >> 12 ] );
sci_write( disp_table[ ( data & 0xf00 ) >> 8 ] );
sci_write( disp_table[ ( data & 0xf0 ) >> 4 ] );
sci_write( disp_table[ ( data & 0xf ) ] );
}
/****************************************************************/
/* 僔儕傾儖弶婜壔 */
/****************************************************************/
void sci_init( void )
{
*MSTPCRB = *MSTPCRB & 0xdf; /*儌僕儏乕儖僗僩僢僾夝彍*/
*SMR_2 = 0x00;
*BRR_2 = 0x33; /*16MHz,9600bps*/
*SCR_2 = 0x30;
*SSR_2 = 0x80;
}
/****************************************************************/
/* 侾僶僀僩僨乕僞僔儕傾儖擖椡 */
/****************************************************************/
int sci_read( void )
{
char code;
if( ( *SSR_2 & 0x78 ) == 0 ){ /* RDRF套皋偑侽偺帪偼-1 */
return( -1 );
}
code = *RDR_2; /* 庴怣僨乕僞撉傒崬傒 */
*SSR_1 = *SSR_2 & ~0x78; /* RDRF套皋傪侽偵僋儕傾 */
return( code );
}
/****************************************************************/
/* 侾僶僀僩僨乕僞僔儕傾儖弌椡 */
/****************************************************************/
void sci_write( unsigned char data )
{
while( ( *SSR_2 & 0x80 ) == 0 ){
} /* TDRE套皋偑侾偵側傞傑偱wait */
*TDR_2 = data; /* 憲怣棉袄彂偒崬傒 */
*SSR_2 = *SSR_2 & ~0x80;
while( ( *SSR_2 & 0x04 ) == 0 ){
} /* TEND套皋偑侾偵側傞傑偱wait */
}
/****************************************************************/
/* 嬻儖乕僾 */
/****************************************************************/
void wait( int msec )
{
long i;
for( i=0; i<1000 * ( long )msec; i++ ){
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -