📄 usbcore.c
字号:
case 1: //厂商字符串的索引值为1,所以这里为厂商字符串
#ifdef DEBUG0
Prints("(厂商描述)。\r\n");
#endif
pSendData=(uint8 *)ManufacturerStringDescriptor;
SendLength=ManufacturerStringDescriptor[0];
break;
case 2: //产品字符串的索引值为2,所以这里为产品字符串
#ifdef DEBUG0
Prints("(产品描述)。\r\n");
#endif
pSendData=(uint8 *)ProductStringDescriptor;
SendLength=ProductStringDescriptor[0];
break;
case 3: //产品序列号的索引值为3,所以这里为序列号
#ifdef DEBUG0
Prints("(产品序列号)。\r\n");
#endif
pSendData=(uint8 *)SerialNumberStringDescriptor;
SendLength=SerialNumberStringDescriptor[0];
break;
default :
#ifdef DEBUG0
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=(uint8 *)ReportDescriptor; //需要发送的数据为报告描述符
SendLength=sizeof(ReportDescriptor); //需要返回的数据长度
//判断请求的字节数是否比实际需要发送的字节数多
//如果请求的比实际的长,那么只返回实际长度的数据
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
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");
#endif
Prints("未知请求。\r\n");
//只需要返回一个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
{
UsbChipReadEndpointBuffer(0,16,Buffer);
UsbChipClearBuffer(0);
}
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点0输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp0In(void)
{
#ifdef DEBUG0
Prints("USB端点0输入中断。\r\n");
#endif
//清除端点0的输入完成中断标志位
AT91C_UDP_CSR[0]&=~(1<<0); //TXCOMP置0
while(AT91C_UDP_CSR[0]&(1<<0)); //等待被清除
//发送剩余的字节数
UsbEp0SendData();
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点1输入中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp1In(void)
{
#ifdef DEBUG0
Prints("USB端点1输入中断。\r\n");
#endif
//清除端点1的输入完成中断标志位
AT91C_UDP_CSR[1]&=~(1<<0); //TXCOMP置0
while(AT91C_UDP_CSR[1]&(1<<0)); //等待被清除
//端点1输入处于空闲状态
Ep1InIsBusy=0;
}
////////////////////////End of function//////////////////////////////
/********************************************************************
函数功能:端点1输出中断处理函数。
入口参数:无。
返 回:无。
备 注:无。
********************************************************************/
void UsbEp2Out(void)
{
uint8 Buf[2]; //用来保存2字节的输出报告,控制LED。
#ifdef DEBUG0
Prints("USB端点2输出中断。\r\n");
#endif
//清除端点2输出的中断标志位
//无操作
//从端点2输出缓冲读回1字节数据
UsbChipReadEndpointBuffer(2,2,Buf);
//清除端点缓冲区
UsbChipClearBuffer(2);
}
////////////////////////End of function//////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -