📄 usbcore.c
字号:
}
break;
case GET_INTERFACE: //获取接口
#ifdef DEBUG0
Prints("获取接口。\r\n");
#endif
break;
case GET_STATUS: //获取状态
#ifdef DEBUG0
Prints("获取状态。\r\n");
#endif
break;
case SYNCH_FRAME: //同步帧
#ifdef DEBUG0
Prints("同步帧。\r\n");
#endif
break;
default: //未定义的标准请求
#ifdef DEBUG0
Prints("错误:未定义的标准输入请求。\r\n");
#endif
break;
}
break;
case 1: //类请求
#ifdef DEBUG0
Prints("USB类输入请求:");
#endif
switch(bRequest)
{
case GET_MAX_LUN: //请求为GET_MAX_LUN(0xFE)
#ifdef DEBUG0
Prints("获取最大逻辑单元。\r\n");
#endif
pSendData=MaxLun; //要返回的数据位置
SendLength=1; //长度为1字节
//如果请求的长度比实际长度短,则仅返回请求长度
if(wLength<SendLength)
{
SendLength=wLength;
}
//将数据通过EP0返回
UsbEp0SendData();
break;
default:
#ifdef DEBUG0
Prints("未知请求。\r\n");
#endif
break;
}
break;
case 2: //厂商请求
#ifdef DEBUG0
Prints("USB厂商输入请求:\r\n");
#endif
break;
default: //未定义的请求。这里只显示一个报错信息。
#ifdef DEBUG0
Prints("错误:未定义的输入请求。\r\n");
#endif
break;
}
}
//否则说明是输出请求
else //if(bmRequestType&0x80==0x80)之else
{
//根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
//0为标准请求,1为类请求,2为厂商请求。
switch((bmRequestType>>5)&0x03)
{
case 0: //标准请求
#ifdef DEBUG0
Prints("USB标准输出请求:");
#endif
//USB协议定义了几个标准输出请求,我们实现这些标准请求即可
//请求的代码在bRequest中,对不同的请求代码进行散转
switch(bRequest)
{
case CLEAR_FEATURE: //清除特性
#ifdef DEBUG0
Prints("清除特性。\r\n");
#endif
break;
case SET_ADDRESS: //设置地址
#ifdef DEBUG0
Prints("设置地址。地址为:");
PrintHex(wValue&0xFF); //显示所设置的地址
Prints("\r\n");
#endif
D12SetAddress(wValue&0xFF); //wValue中的低字节是设置的地址值
//设置地址没有数据过程,直接进入到状态过程,返回一个0长度的数据包
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
case SET_CONFIGURATION: //设置配置
#ifdef DEBUG0
Prints("设置配置。\r\n");
#endif
//使能非0端点。非0端点只有在设置为非0的配置后才能使能。
//wValue的低字节为配置的值,如果该值为非0,才能使能非0端点。
//保存当前配置值
ConfigValue=wValue&0xFF;
D12SetEndpointEnable(ConfigValue);
//返回一个0长度的状态数据包
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
case SET_DESCRIPTOR: //设置描述符
#ifdef DEBUG0
Prints("设置描述符。\r\n");
#endif
break;
case SET_FEATURE: //设置特性
#ifdef DEBUG0
Prints("设置特性。\r\n");
#endif
break;
case SET_INTERFACE: //设置接口
#ifdef DEBUG0
Prints("设置接口。\r\n");
#endif
//返回一个0长度的状态数据包
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
default: //未定义的标准请求
#ifdef DEBUG0
Prints("错误:未定义的标准输出请求。\r\n");
#endif
break;
}
break;
case 1: //类请求
#ifdef DEBUG0
Prints("USB类输出请求:");
#endif
switch(bRequest)
{
case MASS_STORAGE_RESET:
#ifdef DEBUG0
Prints("大容量存储设备复位。\r\n");
#endif
//接下来的数据为命令阶段(CBW)
TransportStage=COMMAND_STAGE;
//返回一个0长度的数据包
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
default:
#ifdef DEBUG0
Prints("未知请求。\r\n");
#endif
break;
}
break;
case 2: //厂商请求
#ifdef DEBUG0
Prints("USB厂商输出请求:\r\n");
#endif
break;
default: //未定义的请求。这里只显示一个报错信息。
#ifdef DEBUG0
Prints("错误:未定义的输出请求。\r\n");
#endif
break;
}
}
}
//普通数据输出
else //if(D12ReadEndpointLastStatus(0)&0x20)之else
{
D12ReadEndpointBuffer(0,16,Buffer);
D12ClearBuffer();
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点0输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp0In(void)
{
#ifdef DEBUG0
Prints("USB端点0输入中断。\r\n");
#endif
//读最后发送状态,这将清除端点0的中断标志位
D12ReadEndpointLastStatus(1);
//发送剩余的字节数
UsbEp0SendData();
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点1输出中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp1Out(void)
{
#ifdef DEBUG0
Prints("USB端点1输出中断。\r\n");
#endif
//读端点最后状态,这将清除端点1输出的中断标志位
D12ReadEndpointLastStatus(2);
//清除端点缓冲区
D12ClearBuffer();
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点1输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp1In(void)
{
#ifdef DEBUG0
Prints("USB端点1输入中断。\r\n");
#endif
//读最后发送状态,这将清除端点1输入的中断标志位
D12ReadEndpointLastStatus(3);
//端点1输入处于空闲状态
Ep1InIsBusy=0;
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点2输出中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp2Out(void)
{
uint8 Len;
#ifdef DEBUG0
Prints("USB端点2输出中断。\r\n");
#endif
//当双缓冲没有全满时,可以清除中断标志
if((D12ReadEndpointStatus(4)&0x60)!=0x60)
{
//读最后发送状态,这将清除端点2输入的中断标志位
D12ReadEndpointLastStatus(4);
}
if(TransportStage==COMMAND_STAGE)
{
//将数据读回到CBW缓冲区中
Len=D12ReadEndpointBuffer(4,sizeof(CBW),CBW);
//清除端点缓冲区
D12ClearBuffer();
if(Len==31) //如果接收到的数据长度是31字节,则说明是CBW
{
//检查CBW的签名是否正确,签名为“USBC”
if((CBW[0]=='U')&&(CBW[1]=='S')&&(CBW[2]=='B')&&(CBW[3]=='C'))
{
//CBW签名正确,处理SCSI命令
ProcScsiCommand();
}
}
}
else if(TransportStage==DATA_STAGE)
{
ProcScsiOutData(); //处理SCSI输出数据
}
else
{
D12ReadEndpointBuffer(4,0,0);
D12ClearBuffer();
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点2输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp2In(void)
{
#ifdef DEBUG0
Prints("USB端点2输入中断。\r\n");
#endif
//读最后发送状态,这将清除端点2输入的中断标志位
D12ReadEndpointLastStatus(5);
Ep2SendData(); //发送数据
//如果双缓冲区没有都满,还可以再写
if((D12ReadEndpointStatus(5)&0x06)!=0x06)
{
Ep2SendData(); //再发一次数据,利用双缓冲
}
}
////////////////////////End of function//////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -