📄 usb.c
字号:
/*******************************/
/* 处理 GET_CONFIGURATION 请求 */
/*******************************/
/*以下是Get Configuration的叙述:
This request returns the current device configuration value.
|--------------------------------------------------------------------
|bmRequestType| bRequest |wValue|wIndex|wLength| Data |
|=============+=================+======+======+=======+=============|
| 10000000B |GET_CONFIGURATION| Zero | Zero | One |Configuration|
| | | | | | Value |
---------------------------------------------------------------------
If the returned value is Zero,the device is not configured.
If wValue,wIndex,or wLength are not as specified above the the
device behavior is not specified.
*/
void getconfiguration(void)//OK
{
write_usb(TXD0,usb_cfg);/*load the config val */
}
/*******************************/
/* 处理 SET_CONFIGURATION 请求 */
/*******************************/
/*以下是Set Configuration的叙述:
This request sets the device configuration.
|------------------------------------------------------------------
|bmRequestType| bRequest | wValue |wIndex|wLength|Data|
|=============+=================+=============+======+=======+====|
| 00000000B |SET_CONFIGURATION|Configuration| Zero | Zero |None|
| | | Value | | | |
-------------------------------------------------------------------
The low byte of the wValue field specifies the desired configuration.
This configuration value must be zero or match a configuration value
from a configuration descriptor.If the configuration value is zero,the
deviced is placed in its Address state.The upper byte of the wValue field
is reserved.
If wIndex,wLength,or the upper byte of wValue is non-zero,the the
behavior of this request is not specified.
*/
void setconfiguration(void)//OK
{
usb_cfg = SetupData.wValue.ByteValue.Low; /*set the configuration # */
if (SetupData.wValue.ByteValue.Low!=0) /*set the configuration */
{
dtapid = 0; /*FIRST PID is DATA0 */
stalld = 0; /*nothing stalled */
/*此处各EP的number必须同CFG_DESC表中的描述一致*/
FLUSHTX1; /*flush TX1 and disable */
write_usb(EPC1,EP_EN+01); /*enable EP1 at adr 1 */
FLUSHRX1; /*flush RX1 and disable */
write_usb(EPC2,EP_EN+01); /*enable EP2 at adr 1 */
write_usb(RXC1,RX_EN); /*enable RX1 */
FLUSHTX2; /*flush TX2 and disable */
write_usb(EPC3,EP_EN+02); /*enable EP3 at adr 2 */
FLUSHRX2; /*flush RX2 and disable */
write_usb(EPC4,EP_EN+02); /*enable EP4 at adr 2 */
write_usb(RXC2,RX_EN); /*enable RX2 */
FLUSHTX3; /*flush TX1 and disable */
write_usb(EPC5,EP_EN+03); /*enable EP5 at adr 3 */
FLUSHRX3; /*flush RX3 and disable */
write_usb(EPC6,EP_EN+03); /*enable EP6 at adr 3 */
write_usb(RXC3,RX_EN); /*enable RX3 */
}
else /*unconfigure the device */
{
write_usb(EPC1,0); /*disable EP1 */
write_usb(EPC2,0); /*disable EP2 */
write_usb(EPC3,0); /*disable EP3 */
write_usb(EPC4,0); /*disable EP4 */
write_usb(EPC5,0); /*disable EP5 */
write_usb(EPC6,0); /*disable EP6 */
}
}
/************************************/
/* USB EndPoint0(FIFO0)接收处理程序 */
/************************************/
void rx_0(void)
{
rxstat=read_usb(RXS0); /*get Receive Status register for the bidirectional Control Endpoint 0*/
if(rxstat & SETUP_R) /*若为SETUP Token Packet*/
{
/*将数据读入缓冲区,然后清除并禁止RX*/
/*从FIFO读取数据至usb_buf*/
SetupData.bmRequestType =read_usb(RXD0);/*Offset 0*/
SetupData.bRequest =read_usb(RXD0);/*1*/
SetupData.wValue.ByteValue.Low =read_usb(RXD0);/*2*/
SetupData.wValue.ByteValue.High =read_usb(RXD0);/*3*/
SetupData.wIndex.ByteValue.Low =read_usb(RXD0);/*4*/
SetupData.wIndex.ByteValue.High =read_usb(RXD0);/*5*/
SetupData.wLength.ByteValue.Low =read_usb(RXD0);/*6*/
SetupData.wLength.ByteValue.High=read_usb(RXD0);/*7*/
FLUSHRX0; /*make sure the RX is off */
FLUSHTX0; /*make sure the TX is off */
bitclr(EPC0,STALL); /*turn off stall */
switch (SetupData.bmRequestType&0x60) /*屏蔽D7,D4~D0位,解读bmRequestType*/
{
case 0x00: /*bmRequestType=standard request*/
switch (SetupData.bRequest) /*解读bRequest类型*/
{
case GET_STATUS: /*bRequest=0*/
getstatus();
break;
case CLEAR_FEATURE: /*bRequest=1*/
clrfeature();
break;
case 0x02: /*bRequest=2->Reserved for future use*/
break;
case SET_FEATURE: /*bRequest=3*/
setfeature();
break;
case 0x04: /*bRequest=4->Reserved for future use*/
break;
case SET_ADDRESS: /*bRequest=5*/
setaddress();
break;
case GET_DESCRIPTOR: /*bRequest=6*/
getdescriptor();
break;
case SET_DESCRIPTOR: /*bRequest=7*/
setdescriptor();
break;
case GET_CONFIGURATION: /*bRequest=8*/
getconfiguration();
break;
case SET_CONFIGURATION: /*bRequest=9*/
setconfiguration();
break;
case GET_INTERFACE: /*bRequest=10*/
getinterface();
break;
case SET_INTERFACE: /*bRequest=11*/
setinterface();
break;
case SYNCH_FRAME: /*bRequest=12->unsupported standard req*/
synchframe();
break;
default: /*unsupported request type*/
bitset(EPC0,STALL); /*stall the endpoint */
break;
}
/*the following is done for all setup packets. Note that if*/
/*no data was stuffed into the FIFO, the result of the */
/*following will be a zero-length response. */
write_usb(TXC0,TX_TOGL+TX_EN); /*enable the TX (DATA1) */
CLRBIT(dtapid,TGL0PID); /*store NEXT PID state */
break;
case 0x20: /*bmRequestType=clasee request*/
switch (SetupData.bRequest)
{
case GET_MAXLUN:
status = 0; /*clear previous status */
write_usb(TXD0,0x0);
break;
case BO_RESET:
break;
}
write_usb(TXC0,TX_TOGL+TX_EN); /*enable the TX (DATA1) */
CLRBIT(dtapid,TGL0PID); /*store NEXT PID state */
break;
case 0x40: /*bmRequestType=vendor request*/
switch (SetupData.bRequest)
{
default: /*unsupported standard req*/
bitset(EPC0,STALL); /*stall the endpoint */
break;
}
break;
default: /*bmRequestType=Vendor,Reserved*/
/* or other unsupported request type*/
bitset(EPC0,STALL); /*stall the endpoint */
break;
}
/*the following is done for all setup packets. Note that if*/
/*no data was stuffed into the FIFO, the result of the */
/*following will be a zero-length response. */
// write_usb(TXC0,TX_TOGL+TX_EN); /*enable the TX (DATA1) */
// CLRBIT(dtapid,TGL0PID); /*store NEXT PID state */
}
/*若不是SETUP Token Packet,那么就必定是一个OUT packet*/
/*注意:由于在RXS0中没有RX_ERR 位,因此没有必要象对待其它的RX event*/
/*一样对待EndPoint0(FIFO0)接收事件*/
else
{
/*multi-pkt and getdesc or readsta status stage? */
if(TSTBIT(status,GETDESC)||TSTBIT(status,READSTA))
{
/*test for errors (zero length, correct PID) */
if ((rxstat& 0x5F)!=0x10) /*length error?? */
{}
if(TSTBIT(status,GETDESC)) /*exit multi-packet mode */
CLR_GETDESC;
if(TSTBIT(status,READSTA))
CLR_READSTA;
FLUSHTX0; /*flush TX0 and disable */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
else
{
}
}
/*we do this stuff for all rx_0 events **************************/
}
/**********************************************************************/
/* This subroutine handles RX events for FIFO1 (endpoint 2) */
/**********************************************************************/
extern INT8 BOTFSMstate;
extern INT32 BOTXfer_wResidue;
extern INT8 * BOTXfer_pData;
#define FSM4BOT_DATAIN 0x7
#define BOTFSM_IDLE 0x5
#define BOTFSM_DataOut 0x2
extern unsigned LBA_W32;
unsigned short wbuf[256*128];
unsigned int wlen;
extern unsigned LBA_Count;
extern TPBLK_STRUC TPBulk_Block;
#define TPBulk_CBW TPBulk_Block.TPBulk_CommandBlock
#define SCSI2_LUN TPBulk_CBW.bCBW_LUN
void rx_1(void)
{
int i=0;
rxstat=read_usb(RXS1); /*get receiver status */
if(rxstat & SETUP_R)
{}
else if (rxstat & RX_ERR)
{}
else
{
/*
* this DATAOUT is ONLY for write operation in fact!!
* because other DATAOUT operations are all less than 64 bytes
* and cannot enter thsi rx_1 isr
* so we need not additional FSMstate
*/
if(BOTFSMstate == BOTFSM_DataOut)
{
USB_ReadEndpoint(1, 64, ((INT8 *)wbuf)+wlen);
wlen += 64;
BOTXfer_wResidue -= 64;
/* get all data from host (less than 128*512B) */
if(BOTXfer_wResidue == 0)
{
wlen = 0;
BOTFSMstate = BOTFSM_IDLE;
/* device = SCSI2_LUN */
devio_write(2+SCSI2_LUN, 0L+(LBA_W32), (unsigned char *)wbuf, LBA_Count, 1);
//Uart_Printf("write now\n");
/* send CSW packet */
TPBulk_CSWHandler();
}
}
else
TPBulk_CBWHandler(); /*handle CBW */
}
FLUSHRX1; /*flush RX1 and disable */
write_usb(RXC1,RX_EN); /*re-enable the receiver */
}
void rx_2(void)
{}
void rx_3(void)
{}
/***********************************/
/* USB EndPoint0(FIFO0)发送处理程序 */
/***********************************/
void tx_0(void)
{
txstat=read_usb(TXS0); /*get transmitter status */
if(txstat & TX_DONE) /*if transmit completed */
{
FLUSHTX0; /*flush TX0 and disable */
if(txstat & ACK_STAT) /*ACK received: xmit ok */
{
if(TSTBIT(status,GETDESC)||TSTBIT(status,READSTA))
{
/*move the data into the FIFO(ugly code : assume 8 packets */
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
TXEN0_PID; /*enable TX, toggle PID */
}
else /*not in multi-packet mode*/
{
if(setaddr) /*if SET_ADDRESS in progr.*/
{
write_usb(FAR,setaddr); /*load new address */
setaddr=0; /*clear state */
}
/* otherwise send a zero_length packet */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
}
else /*no ACK: xmit failed */
{ /*this probably means we issued a stall handshake */
CLR_MLTIPKT; /*exit multi-packet mode */
write_usb(RXC0,RX_EN); /*re-enable the receiver */
}
}
/*otherwise something must have gone wrong with the previous ****/
/*transmission, or we got here somehow we shouldn't have ********/
else /*xmit didn't complete?? */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -