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

📄 iusbhandledevreq.c

📁 Dragonball USB驱动
💻 C
字号:
/* * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright (C) 2002 Motorola Semiconductors HK Ltd * */// This routine handle device requests from host.#include "prototype.h"#include "define.h"#include "mx1.h"void _iUsbHandleGetDevDscptr(void);void _iUsbHandleGetConfDscptr(void);void _iUsbHandleGetStrDscptr(void);void _iUsbReturnStrDscptr0(void);void _iUsbReturnStrDscptr2(void);void _iUsbReturnStrDscptr3(void);U8  _gUsbDevReq[8];     /* device request from host *//*const U16 _gUsbDevDscptr[9] = {    0x1201, 0x0001, 0xFF00, 0x0008, 0xC407, 0x05A0, 0x0D01, 0x0102, 0x0301 };const U16 _gUsbConfDscptr[16] = {    0x0902, 0x2000, 0x0101, 0x0080, 0x3209, 0x0400, 0x0002, 0x0500,    0x0000, 0x0705, 0x8102, 0x2000, 0x0007, 0x0502, 0x0220, 0x0000};const U16 _gUsbStrDscptr0[2] = {0x0403, 0x0904};const U16 _gUsbStrDscptr2[12] = {    0x1803, 0x5300, 0x5A00, 0x2000, 0x5500, 0x5300, 0x4200, 0x2000,    0x6400, 0x6500, 0x6D00, 0x6F00};const U16 _gUsbStrDscptr3[11] = {    0x1603, 0x4300, 0x3900, 0x4600, 0x3900, 0x3100, 0x4300, 0x3100,    0x4100, 0x4600, 0x3900};*/const U32 _gUsbDevDscptr[5] = {//    0x12011001, 0x00000008, 0xC40700A2, 0x00130000, 0x00000001 };		// assume big endian    0x12011001, 0x00000008, 0xC4070000, 0x00130000, 0x00000001 };		// assume big endianconst U32 _gUsbConfDscptr[8] = {//    0x09022000, 0x01010080, 0xFA090400, 0x00020806,    0x09022000, 0x010100C0, 0x01090400, 0x00020806,//    0x50000705, 0x81022000, 0x00070502, 0x02200000};    0x50040705, 0x81022000, 0x00070502, 0x02200000};const U32 _gUsbStrDscptr0 = 0x04030904;const U32 _gUsbStrDscptr2[7] =  {//	 0x18035300, 0x5A002000, 0x55005300, 0x42002000,//  0x64006500, 0x6D006F00};	 0x18034D00, 0x58003100, 0x20005500, 0x53004200,	 0x20006400, 0x65006D00, 0x00006F00};const U32 _gUsbStrDscptr3[6] = {    0x16034300, 0x39004600, 0x39003100, 0x43003100,    0x41004600, 0x00003900};void _iUsbHandleDevReq(){    U32 fifoWord;    U8  i, j;    /* read device request data from FIFO */    j = 0;    for (i=0; i<2; i++)    {        fifoWord = _reg_USBD_EP0_FDAT;        _gUsbDevReq[j++] = (U8)(fifoWord >> 24);        _gUsbDevReq[j++] = (U8)(fifoWord >> 16);        _gUsbDevReq[j++] = (U8)(fifoWord >> 8);        _gUsbDevReq[j++] = (U8)fifoWord;    }/*DPRINTK("Device Request: ");for (i=0; i<8; i++)	DPRINTK("0x%02x ", _gUsbDevReq[i]);DPRINTK("\n");*/    /* decode device request */    if ((_gUsbDevReq[0] = 0x80) && (_gUsbDevReq[1] = 0x06))    {        switch (_gUsbDevReq[3])        {            case 0x01:  // device descriptor                _iUsbHandleGetDevDscptr();                break;            case 0x02:  // configuration descriptor                _iUsbHandleGetConfDscptr();                break;            case 0x03:  // string descriptor                _iUsbHandleGetStrDscptr();                break;        }    }	 // turn on SOF interrupt to signal CMD_OVER bit	 _reg_USBD_INTR_MASK &= ~(SOF_MASK);}void _iUsbHandleGetDevDscptr(){//DPRINTK("Device Descr\n");	 /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbDevDscptr[0];    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    _reg_USBD_EP0_FDAT = _gUsbDevDscptr[1];//    _reg_USB_CTRL |= USB_CTRL_CMOV_MASK;    /* if length is not exactly 0x12, just return one packet */    /* otherwise, return all 0x12 bytes */    if (_gUsbDevReq[6] == 0x12)    {        _reg_USBD_EP0_FDAT = _gUsbDevDscptr[2];        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        _reg_USBD_EP0_FDAT = _gUsbDevDscptr[3];		// due a bug in gcc, half-word access is compiled into word access		// so we'll use byte access instead      *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbDevDscptr[4]>>8);      _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet      *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)_gUsbDevDscptr[4];	}}void _iUsbHandleGetConfDscptr(){    /* if length is exactly 9, return 9 bytes only */    if (_gUsbDevReq[6] == 0x09)    {        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[0];        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[1];        /* here comes the last byte */        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbConfDscptr[2]>>24);    }    else    /* otherwise, return all 32 bytes */    {        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[0];        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[1];        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[2];        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[3];        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[4];        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[5];        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[6];        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        _reg_USBD_EP0_FDAT = _gUsbConfDscptr[7];        /* need to end with a zero length packet */        _reg_USBD_EP0_STAT |= ZLPS_MASK;    // next one is a zero length packet    }}void _iUsbHandleGetStrDscptr(){    switch (_gUsbDevReq[2])    {        case 0:            _iUsbReturnStrDscptr0();            break;        case 2:            _iUsbReturnStrDscptr2();            break;        case 3:            _iUsbReturnStrDscptr3();            break;    }}void _iUsbReturnStrDscptr0(){    /* if length is 2, return 2 bytes only */    if (_gUsbDevReq[6] == 0x02)    {        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr0>>24);        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr0>>16);    }    else    /* otherwise, return all 4 bytes */    {        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr0>>24);        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr0>>16);        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr0>>8);        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)_gUsbStrDscptr0;    }//    _reg_USBD_EP0_ISR |= USBD_EPINTR_EOT_MASK; // clear EOT intr//    _reg_USBD_EP0_MASK = ENABLE_DEVREQ & ENABLE_EOT;}void _iUsbReturnStrDscptr2(){    /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbStrDscptr2[0];    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    _reg_USBD_EP0_FDAT = _gUsbStrDscptr2[1];    /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbStrDscptr2[2];    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    _reg_USBD_EP0_FDAT = _gUsbStrDscptr2[3];    /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbStrDscptr2[4];    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    _reg_USBD_EP0_FDAT = _gUsbStrDscptr2[5];    *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr2[6]>>8);    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)_gUsbStrDscptr2[6];	 /* the next packet is an zero-length one *///    _reg_USBD_EP0_STAT |= ZLPS_MASK;//    _reg_USBD_EP0_ISR |= USBD_EPINTR_EOT_MASK; // clear EOT intr//    _reg_USBD_EP0_MASK = ENABLE_DEVREQ & ENABLE_EOT;}void _iUsbReturnStrDscptr3(){    /* if length is 2, return 2 bytes only */    if (_gUsbDevReq[6] == 0x02)    {        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr3[0]>>24);        _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet        *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr3[0]>>16);    }    else    /* otherwise return all 22 bytes */    {    /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbStrDscptr3[0];    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    _reg_USBD_EP0_FDAT = _gUsbStrDscptr3[1];    /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbStrDscptr3[2];    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    _reg_USBD_EP0_FDAT = _gUsbStrDscptr3[3];    /* 8 bytes per packet */    _reg_USBD_EP0_FDAT = _gUsbStrDscptr3[4];    *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)(_gUsbStrDscptr3[5]>>8);    _reg_USBD_EP0_FCTRL |= 0x20000000;  // next write is last one of packet    *((volatile U8 *)((U32)&_reg_USBD_EP0_FDAT+3)) = (U8)_gUsbStrDscptr3[5];    }//    _reg_USBD_EP0_ISR |= USBD_EPINTR_EOT_MASK; // clear EOT intr//    _reg_USBD_EP0_MASK = ENABLE_DEVREQ & ENABLE_EOT;    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -