📄 usbcore.c
字号:
NeedZeroPacket=1; //需要返回0长度的数据包
}
}
else
{
SendLength=wLength;
}
//将数据通过EP0返回
UsbEp0SendData();
break;
default: //其它描述符
#ifdef DEBUG0
Prints("其他描述符,描述符代码:");
PrintHex((wValue>>8)&0xFF);
Prints("\r\n");
#endif
break;
}
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类输入请求:\r\n");
#endif
switch(bRequest)
{
default:
#ifdef DEBUG0
Prints("未知类请求。\r\n");
#endif
SendLength=0;
NeedZeroPacket=1;
break;
}
//判断请求的字节数是否比实际需要发送的字节数多
//如果请求的比实际的长,那么只返回实际长度的数据
if(wLength>SendLength)
{
if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
{
NeedZeroPacket=1; //需要返回0长度的数据包
}
}
else
{
SendLength=wLength;
}
//将数据通过EP0返回
UsbEp0SendData();
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
//设置地址没有数据过程,直接进入到状态过程,返回一个0长度的数据包
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
UsbChipWriteAddress(wValue&0xFF); //wValue中的低字节是设置的地址值
break;
case SET_CONFIGURATION: //设置配置
#ifdef DEBUG0
Prints("设置配置。\r\n");
#endif
//wValue的低字节为配置的值,如果该值为非0,才能使能非0端点。
//保存当前配置值
ConfigValue=wValue&0xFF;
//设置芯片的config值
UsbChipSetConfig(ConfigValue);
//使能非0端点。非0端点只有在设置为非0的配置后才能使能。
UsbChipSetEndpointEnable(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
break;
default: //未定义的标准请求
#ifdef DEBUG0
Prints("错误:未定义的标准输出请求。\r\n");
Prints("未知请求。\r\n");
#endif
//只需要返回一个0长度的数据包即可
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
}
break;
case 1: //类请求
#ifdef DEBUG0
Prints("USB类输出请求:");
#endif
switch(bRequest)
{
case SET_IDLE:
#ifdef DEBUG0
Prints("设置空闲。\r\n");
#endif
//只需要返回一个0长度的数据包即可
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
default:
#ifdef DEBUG0
Prints("未知请求。\r\n");
#endif
//只需要返回一个0长度的数据包即可
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
}
break;
case 2: //厂商请求
#ifdef DEBUG0
Prints("USB厂商输出请求:\r\n");
#endif
break;
default: //未定义的请求。这里只显示一个报错信息。
#ifdef DEBUG0
Prints("错误:未定义的输出请求。\r\n");
#endif
break;
}
}
}
//普通数据输出
else //判断setup包之else
{
ClrCsr(0,1<<7); //设置DIR为0
UsbEp0DataOut(); //处理标准请求的数据部分
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点0输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp0In(void)
{
#ifdef DEBUG0
Prints("USB端点0输入中断。\r\n");
#endif
//清除端点0的输入完成中断标志位
ClrCsr(0,1<<0);
//发送剩余的字节数
UsbEp0SendData();
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点1输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp1In(void)
{
#ifdef DEBUG0
Prints("USB端点1输入中断。\r\n");
#endif
//清除端点1的输入完成中断标志位
ClrCsr(1,1<<0);
//端点1输入处于空闲状态
Ep1InIsBusy=0;
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点2输出中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp2Out(void)
{
uint8 Buf[64],Len;
#ifdef DEBUG0
Prints("USB端点2输出中断。\r\n");
#endif
//清除端点2输出的中断标志位
//无操作
//读取端点2的数据。返回值为实际读到的数据字节数
Len=UsbChipReadEndpointBuffer(2,64,Buf);
//清除端点缓冲区
UsbChipClearBuffer(2);
if(Len!=8) return; //如果长度不是8,说明不是我们应用程序发送的数据,直接返回
//输出报告第1字节为LED状态,某位为1时,表示LED亮。
if(Buf[0]&0x02) //LED2
{
OnLed2();
}
else
{
OffLed2();
}
if(Buf[0]&0x04) //LED3
{
OnLed3();
}
else
{
OffLed3();
}
if(Buf[0]&0x08) //LED4
{
OnLed4();
}
else
{
OffLed4();
}
LcdSetPoint(0,24); //设置位置
LcdPrints("1 2 3 4 5 6 7 8"); //显示位置
LcdSetPoint(0,32);
//在LCD上也显示按键状态
for(Len=0;Len<8;Len++)
{
if(Buf[0]&(1<<Len))
{
LcdPrints("* ");
}
else
{
LcdPrints(" ");
}
}
LcdRefresh(); //刷新LCD
//输出报告的第二字节非0时,清除发送计数器Count。
if(Buf[1]!=0)
{
Count=0;
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点3输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp3In(void)
{
#ifdef DEBUG0
Prints("USB端点3输入中断。\r\n");
#endif
//清除端点3的输入完成中断标志位
ClrCsr(3,1<<0);
//端点3输入处于空闲状态
Ep3InIsBusy=0;
}
////////////////////////End of function//////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -