Exemplo n.º 1
0
void UsbEp0Out(void)
{
#ifdef DEBUG
	Prints("USB ep0 out interrupt.\r\n");
#endif 
	if(D12ReadEndPointLastStatus(0)&0x20)
	{
		D12ReadEndPointBuffer(0,16,Buffer);
		D12AckSetup();
		D12ClearBuffer();

		bmRequestType=Buffer[0];
		bRequest=Buffer[1];
		wValue=Buffer[2]+(((u16)Buffer[3])<<8);
		wIndex=Buffer[4]+(((u16)Buffer[5])<<8);
		wLength=Buffer[6]+(((u16)Buffer[7])<<8);

		if((bmRequestType&0x80)==0x80)
		{
			switch((bmRequestType>>5)&0x03)
			{
				case 0:
				#ifdef DEBUG
				Prints("USB Standard in request.\r\n");
				#endif
			   	switch(bRequest)
				{
					case GET_CONFIGURATION:
					#ifdef DEBUG
					Prints("Get configuration.\r\n");
					#endif
					break;
	
					case GET_DESCRIPTOR:
					#ifdef DEBUG
					Prints("Get descriptor.\r\n");
					#endif
					switch((wValue>>8)&0xff)
					{
						case DEVICE_DESCRIPTOR:
						#ifdef DEBUG
						Prints("-Get device descriptor.\r\n");
						#endif
						pSendData=DeviceDescriptor;
						if(wLength>DeviceDescriptor[0])
						{
						#ifdef DEBUG
							Prints("Host want length of device descriptor is:");
							PrintShortIntHex(DeviceDescriptor[0]);
							Prints("\r\n");
						#endif
							SendLength=DeviceDescriptor[0];
							if(SendLength%DeviceDescriptor[7]==0)
							{
								NeedZeroPacket=1;
							}
						}
						else
						{
							SendLength=wLength;
						}
						UsbEp0SendData();
						break;

						case CONFIGURATION_DESCRIPTOR:
						#ifdef DEBUG
						Prints("-Get configuration descriptor.\r\n");
						#endif
						pSendData=ConfigurationDescriptor;
						SendLength=ConfigurationDescriptor[3];
						SendLength=SendLength*256+ConfigurationDescriptor[2];
						if(wLength>SendLength)
						{
							if(SendLength%DeviceDescriptor[7]==0)
							{
								NeedZeroPacket=1;
							}
						}
						else
						{
							SendLength=wLength;
						}
						UsbEp0SendData();
						break;

						case STRING_DESCRIPTOR:
						#ifdef DEBUG
						Prints("-Get string descriptor.\r\n");
						#endif
						switch(wValue&0xff)
						{
							case 0:
							#ifdef DEBUG 
							Prints("--Get Language ID.\r\n");
							#endif
							pSendData=LanguageId;
							SendLength=LanguageId[0];
							break;

							case 1:
							#ifdef DEBUG
							Prints("--Get Manufacturer string.\r\n");
							#endif
							pSendData=ManufacturerStringDescriptor;
							SendLength=ManufacturerStringDescriptor[0];
							break;

							case 2:
							#ifdef DEBUG
							Prints("--Get product string.\r\n");
							#endif
							pSendData=ProductStringDescriptor;
							SendLength=ProductStringDescriptor[0];
							break;

							case 3:
							#ifdef DEBUG
							Prints("--Get serial string.\r\n");
							#endif
							pSendData=SerialNumberStringDescriptor;
							SendLength=SerialNumberStringDescriptor[0];
							break;

							default:
							#ifdef DEBUG
							Prints("Undefined index.\r\n");
							#endif
							SendLength=0;
							NeedZeroPacket=1;
							break;
						}
						if(wLength>SendLength)
						{
							if(SendLength%DeviceDescriptor[7]==0)
								NeedZeroPacket=1;
						}
						else 
						{
							SendLength=wLength;
						}
						UsbEp0SendData();
						break;

						case REPORT_DESCRIPTOR:
						#ifdef DEBUG
						Prints("Get report descriptor.\r\n");
						#endif
						if(wLength>SendLength)
						{
							pSendData=ReportDescriptor;
							SendLength=sizeof(ReportDescriptor);
							if(wLength%DeviceDescriptor[7]==0)
							{
								NeedZeroPacket=1;
							}
							else
							{
								SendLength=wLength;
							}
							UsbEp0SendData();
						}
						break;

						default:
						#ifdef DEBUG
						Prints("-Get other descriptor(unrecognized).\r\n");
						#endif
						break;
					}
					break;
	
					case GET_INTERFACE:
					#ifdef DEBUG
					Prints("Get Interface.\r\n");
					#endif
					break;
	
					case GET_STATUS:
					#ifdef DEBUG
					Prints("Get status.\r\n");
					#endif
					break;
	
					case SYNCH_FRAME:
					#ifdef DEBUG
					Prints("Synch frame.\r\n");
					#endif
					break;
	
					default:
					#ifdef DEBUG
					Prints("Error,undefined standard device request.\r\n");
					#endif
					break;
				}
				break;
	
				case 1:   //Class request.
				#ifdef DEBUG
				Prints("Class request.\r\n");
				#endif
				break;
	
				case 2: //³§ÉÌÇëÇó
				#ifdef DEBUG
				Prints("Vendor request.\r\n");
				#endif
				break;
	
				default:
				#ifdef DEBUG
				Prints("Error,undefined request.\r\n");
				#endif
				break;
			}
		}
		else
		{
			switch((bmRequestType>>5)&0x03)
Exemplo n.º 2
0
/********************************************************************
函数功能:端点0输出中断处理函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbEp0Out(void)
{
#ifdef DEBUG0
    Prints("USB端点0输出中断。\r\n");
#endif
//读取端点0输出最后传输状态,该操作清除中断标志
//并判断第5位是否为1,如果是,则说明是建立包
    if(D12ReadEndpointLastStatus(0)&0x20)
    {
        D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据
        D12AcknowledgeSetup(); //应答建立包
        D12ClearBuffer(); //清缓冲区
        //将缓冲数据填到设备请求的各字段中
        bmRequestType=Buffer[0];
        bRequest=Buffer[1];
        wValue=Buffer[2]+(((uint16)Buffer[3])<<8);
        wIndex=Buffer[4]+(((uint16)Buffer[5])<<8);
        wLength=Buffer[6]+(((uint16)Buffer[7])<<8);
        //下面的代码判断具体的请求,并根据不同的请求进行相关操作
        //如果D7位为1,则说明是输入请求
        if((bmRequestType&0x80)==0x80)
        {
            //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
            //0为标准请求,1为类请求,2为厂商请求。
            switch((bmRequestType>>5)&0x03)
            {
            case 0:  //标准请求
#ifdef DEBUG0
                Prints("USB标准输入请求:");
#endif
                //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
                //请求的代码在bRequest中,对不同的请求代码进行散转
                //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
                //是不一样的。接收者在bmRequestType的D4~D0位中定义。
                //我们这里为了简化操作,有些就省略了对接收者的判断。
                //例如获取描述符的请求,只根据描述符的类型来区别。
                switch(bRequest)
                {
                case GET_CONFIGURATION: //获取配置
#ifdef DEBUG0
                    Prints("获取配置。\r\n");
#endif
                    break;

                case GET_DESCRIPTOR:  //获取描述符
#ifdef DEBUG0
                    Prints("获取描述符——");
#endif
                    //对描述符类型进行散转,对于全速设备,
                    //标准请求只支持发送到设备的设备、配置、字符串三种描述符
                    switch((wValue>>8)&0xFF)
                    {
                    case DEVICE_DESCRIPTOR: //设备描述符
#ifdef DEBUG0
                        Prints("设备描述符。\r\n");
#endif
                        pSendData=DeviceDescriptor;  //需要发送的数据
                        //判断请求的字节数是否比实际需要发送的字节数多
                        //这里请求的是设备描述符,因此数据长度就是
                        //DeviceDescriptor[0]。如果请求的比实际的长,
                        //那么只返回实际长度的数据
                        if(wLength>DeviceDescriptor[0])
                        {
                            SendLength=DeviceDescriptor[0];
                            if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
                            {
                                NeedZeroPacket=1; //需要返回0长度的数据包
                            }
                        }
                        else
                        {
                            SendLength=wLength;
                        }
                        //将数据通过EP0返回
                        UsbEp0SendData();
                        break;

                    case CONFIGURATION_DESCRIPTOR:  //配置描述符
#ifdef DEBUG0
                        Prints("配置描述符。\r\n");
#endif
                        pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符
                        //判断请求的字节数是否比实际需要发送的字节数多
                        //这里请求的是配置描述符集合,因此数据长度就是
                        //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。
                        //如果请求的比实际的长,那么只返回实际长度的数据
                        SendLength=ConfigurationDescriptor[3];
                        SendLength=SendLength*256+ConfigurationDescriptor[2];
                        if(wLength>SendLength)
                        {
                            if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
                            {
                                NeedZeroPacket=1; //需要返回0长度的数据包
                            }
                        }
                        else
                        {
                            SendLength=wLength;
                        }
                        //将数据通过EP0返回
                        UsbEp0SendData();
                        break;

                    case STRING_DESCRIPTOR:  //字符串描述符
#ifdef DEBUG0
                        Prints("字符串描述符");
#endif
                        switch(wValue&0xFF)  //根据wValue的低字节(索引值)散转
                        {
                        case 0:  //获取语言ID
#ifdef DEBUG0
                            Prints("(语言ID)。\r\n");
#endif
                            pSendData=LanguageId;
                            SendLength=LanguageId[0];
                            break;

                        case 1:  //厂商字符串的索引值为1,所以这里为厂商字符串
#ifdef DEBUG0
                            Prints("(厂商描述)。\r\n");
#endif
                            pSendData=ManufacturerStringDescriptor;
                            SendLength=ManufacturerStringDescriptor[0];
                            break;

                        case 2:  //产品字符串的索引值为2,所以这里为产品字符串
#ifdef DEBUG0
                            Prints("(产品描述)。\r\n");
#endif
                            pSendData=ProductStringDescriptor;
                            SendLength=ProductStringDescriptor[0];
                            break;

                        case 3:  //产品序列号的索引值为3,所以这里为序列号
#ifdef DEBUG0
                            Prints("(产品序列号)。\r\n");
#endif
                            pSendData=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=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)