📄 usbcore.c
字号:
Prints("(未知的索引值)。\r\n");
#endif
//对于未知索引值的请求,返回一个0长度的包
SendLength=0;
NeedZeroPacket=1;
break;
}
//判断请求的字节数是否比实际需要发送的字节数多
//如果请求的比实际的长,那么只返回实际长度的数据
if(wLength>SendLength)
{
if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
{
NeedZeroPacket=1; //需要返回0长度的数据包
}
}
else
{
SendLength=wLength;
}
//将数据通过EP0返回
UsbEp0SendData();
break;
case REPORT_DESCRIPTOR: //报告描述符
#ifdef DEBUG0
Prints("报告描述符。\r\n");
#endif
pSendData=0;
SendLength=0; //需要返回的数据长度
//判断请求的字节数是否比实际需要发送的字节数多
//如果请求的比实际的长,那么只返回实际长度的数据
if(wLength>SendLength)
{
if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
{
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)
{
case GET_LINE_CODING: //GET_LINE_CODING请求
#ifdef DEBUG0
Prints("GET_LINE_CODING。\r\n");
#endif
SendLength=0x07; //7字节的LineCoding
pSendData=LineCoding;
break;
case SERIAL_STATE: //获取SERIAL_STATE请求
//本来该请求是获取串口状态的,但是圈圈在实际使用中,
//发现主机从来未发送过该请求,因而这里并不对它进行处理,
//只是简单地发送一个0长度的数据包。
#ifdef DEBUG0
Prints("SERIAL_STATE。\r\n");
#endif
SendLength=0;
NeedZeroPacket=1;
break;
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_CONTROL_LINE_STATE:
#ifdef DEBUG0
Prints("SET_CONTROL_LINE_STATE。\r\n");
#endif
//该请求没有数据输出阶段,其中wValue字段的D0位表示DTR,
//D1位表示RTS。但是我们的板上的串口并没有这两引脚,因而
//对该请求我们仅是简单地返回一个0长度的状态过程数据包即可
SendLength=0;
NeedZeroPacket=1;
//将数据通过EP0返回
UsbEp0SendData();
break;
case SET_LINE_CODING:
//该请求设置串口的属性,但是实际的数据并不在设置过程发出,
//而是在之后的数据过程发出。这里不用做任何处理,在数据过程
//完成后返回0长度的状态包。
#ifdef DEBUG0
Prints("SET_LINE_CODING。\r\n");
#endif
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)
{
#ifdef DEBUG0
Prints("USB端点2输出中断。\r\n");
#endif
//如果缓冲区中的数据还未通过串口发送完毕,则暂时不处理该中断,直接返回。
if(UsbEp2ByteCount!=0) return;
//清除端点2输出的中断标志位
//无操作
//读取端点2的数据。返回值为实际读到的数据字节数
UsbEp2ByteCount=UsbChipReadEndpointBuffer(2,BUF_LEN,UsbEp2Buffer);
//清除端点缓冲区
UsbChipClearBuffer(2);
//输出位置设为0
UsbEp2BufferOutputPoint=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 + -