⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbfunctions.c

📁 LT-1B msp430 程序原理图集合
💻 C
📖 第 1 页 / 共 2 页
字号:
                        Ep2_rxdone();		//端点 2接收数据处理
        }
        USB_FLAG.in_isr = 0;
    }
}
/*******************************************
函数名称: Ep0_rxdone
功    能: 通过端点索引 0 接收数据
参    数: 无   
返回值  : 无
********************************************/
void Ep0_rxdone(void)
{
	uchar ep_last,i;
	ep_last=Read_LttransSta(0);     //清除中断寄存器状态,取得最后处理状态
	if (ep_last&SETUPPACKET) 
	{				                //如果收到了建立包(Setup包)
		ControlData.wLength=0;	    //传输字节总数清0
		ControlData.wCount=0;	    //传输字节计数器清0
		if(Read_EP(0,sizeof(ControlData.DeviceRequest),(uchar * )(&(ControlData.DeviceRequest)))!= sizeof(DEVICE_REQUEST))//从端点0读8个字节失败 
		{												 		 
			Set_EPsta(0,1);			//停止控制端点0
			Set_EPsta(1,1);			//停止控制端点1
			USB_FLAG.control_state = USB_IDLE;	 //设置为等待状态
			return;
		}		
		/********  接收建立包成功 **********/
		Ack_EP(0);						 //对控制端点0进行建立包应答
		Ack_EP(1);						 //对控制端点1进行建立包应答
		ControlData.wLength=ControlData.DeviceRequest.wLength; 	 //取出要传输数据的总字节数
		ControlData.wCount = 0;
        
		//如果控制传输是控制读取
		if(ControlData.DeviceRequest.bmRequestType&(uchar)USB_ENDPOINT_DIRECTION_MASK) 
		{

			 USB_FLAG.setup_packet=1;		        //通知control_handler()处理Setup包
			 USB_FLAG.control_state=USB_TRANSMIT;	//设置为发送状态
		}
		else    //如果控制传输是控制写入
		{						
			  if(ControlData.DeviceRequest.wLength==0) 
			  {
				  USB_FLAG.setup_packet=1;		    //通知control_handler()处理Setup包				  
				  USB_FLAG.control_state=USB_IDLE;	//设置为等待状态
			  }
			  else 
			  {     //如果数据长度出错
				    if(ControlData.DeviceRequest.wLength>MAX_CTLDAT_SIZE) 
				    {				         
					     USB_FLAG.control_state=USB_IDLE;	//设置为等待状态	
					     Set_EPsta(0,1);			        //停止控制端点0
				 	     Set_EPsta(1,1);			        //停止控制端点1
				    }
				    else
				    {
					    USB_FLAG.control_state=USB_RECEIVE;  //设置为接收状态
				    }
			  }// set command with data
		 }// else set command
	}// if setup packet

/************* 下面为控制写入的数据阶段  ***************/
	else if(USB_FLAG.control_state==USB_RECEIVE)     //如果为接收状态
	{	  	    
			 i=Read_EP(0,EP0_PACKET_SIZE,ControlData.dataBuffer+ControlData.wCount);	//从端点0接收数据
			 ControlData.wCount+=i;					 //统计已接收的字节数
			 if(i!=EP0_PACKET_SIZE||ControlData.wCount>=ControlData.wLength) //数据接收完毕
			 {  		                                  
				 USB_FLAG.setup_packet=1;		    //通知control_handler()处理Setup包				  
				 USB_FLAG.control_state=USB_IDLE;	//设置为等待状态
			 }
	}
	else 
	{
		 	 USB_FLAG.control_state = USB_IDLE;		//设置等待状态
	}
}
/*******************************************
函数名称: Ep0_txdone
功    能: 通过端点索引 0 发送数据
参    数: 无   
返回值  : 无
********************************************/
void Ep0_txdone(void)
{
	uint i=ControlData.wLength-ControlData.wCount;	  //计算未发送的字节数

	Read_LttransSta(1); 					          //清除中断寄存器标志位

	if (USB_FLAG.control_state!=USB_TRANSMIT)         //非发送状态	
	{	
		return;						//返回
	}	
	if(i>=EP0_PACKET_SIZE)  //未发送字节数大于16,发送16个字节
	{							
		Write_EP(1,EP0_PACKET_SIZE,ControlData.pData+ControlData.wCount);
		ControlData.wCount+= EP0_PACKET_SIZE;
		USB_FLAG.control_state=USB_TRANSMIT;	
	}
	else if(i!=0)           //发送所有未发送的字节
	{							
		Write_EP(1,i,ControlData.pData+ControlData.wCount);
		ControlData.wCount+=i;
		USB_FLAG.control_state=USB_IDLE;		//置状态为等待状态
	}
	else if (i == 0)
	{
		Write_EP(1, 0, 0); 				        //发送完毕,发0个字节
		USB_FLAG.control_state = USB_IDLE;
	}
}
/*******************************************
函数名称: Ep1_txdone
功    能: 端点1发送处理函数
参    数: 无   
返回值  : 无
********************************************/
void Ep1_txdone(void)
{
	Read_LttransSta(3);		//清中断标志位
}
/*******************************************
函数名称: Ep1_rxdone
功    能: 端点1接收处理函数
参    数: 无   
返回值  : 无
********************************************/
void Ep1_rxdone(void)
{
	uchar len;

	Read_LttransSta(2);		                //清中断标志位
	len=Read_EP(2,sizeof(Ep1Buf),Ep1Buf);	//读取数据
	if(len!=0)
		USB_FLAG.ep1_rxdone = 1;		    //标志接收到数据
}
/*******************************************
函数名称: Ep2_txdone
功    能: 端点2发送处理函数
参    数: 无   
返回值  : 无
********************************************/
void Ep2_txdone(void)
{
	Read_LttransSta(5);		//清中断标志位
}
/*******************************************
函数名称: Ep2_rxdone
功    能: 端点2接收处理函数
参    数: 无   
返回值  : 无
********************************************/
void Ep2_rxdone(void)
{
	uchar len;
	
	Read_LttransSta(4); 			        //清中断标志位
	len=Read_EP(4,EP2_PACKET_SIZE,Ep2Buf);	//读取缓冲区中的数据
	if (len!=0)
		USB_FLAG.ep2_rxdone = 1;
}
/*******************************************
函数名称: Control_handler
功    能: 控制传输
参    数: 无   
返回值  : 无
********************************************/
void Control_handler(void)
{
	uchar type,req; 
	
	type=ControlData.DeviceRequest.bmRequestType&USB_REQUEST_TYPE_MASK;
											//读取请求代码													
	req=ControlData.DeviceRequest.bRequest&USB_REQUEST_MASK;
	if(type==USB_STANDARD_REQUEST)
		(*StandardDeviceRequest[req])();	//标准请求处理
	else
		Stall_ep0();				        //无效请求,返回STALL				
}
/*******************************************
函数名称: Reserved
功    能: 保留子程序
参    数: 无   
返回值  : 无
********************************************/
void Reserved(void)
{
	Stall_ep0();				//返回STALL
}
/*******************************************
函数名称: Init_unconfig
功    能: 进入地址状态,禁止0除外的所有端点
参    数: 无   
返回值  : 无
********************************************/
void Init_unconfig(void)
{
	Set_EPen(0);	//禁止0除外的所有端点
}
/*******************************************
函数名称: Init_config
功    能: 配置处理,允许端点收发
参    数: 无   
返回值  : 无
********************************************/
void Init_config(void)
{
	Set_EPen(1);	//使能普通/同步端点使能
}
/*******************************************
函数名称: Get_status
功    能: 主机要求获取状态,设备返回16位的状态描述给主机
参    数: 无   
返回值  : 无
********************************************/
void Get_status(void)
{
	uchar endp,txdat[2],c;
	uchar bRecipient=ControlData.DeviceRequest.bmRequestType&USB_RECIPIENT;	//取得设备请求类型	
						
	if (bRecipient==USB_RECIPIENT_DEVICE)//对设备请求 
	{					
		if(USB_FLAG.remote_wakeup==1)			
		{
			txdat[0]=3;		//支持远程唤醒、自供电
		}
		else
		{
			txdat[0]=1;		//不支持远程唤醒、自供电
		}
		txdat[1]=0;			//高8位为0
		S_trans(txdat,2);	//发送16位的状态到主机
		
	} 
	else if (bRecipient == USB_RECIPIENT_INTERFACE) //对接口请求
	{			
		txdat[0]=0;
		txdat[1]=0;
		S_trans(txdat, 2);	//发送16位的状态到主机
						
	} 
	else if (bRecipient == USB_RECIPIENT_ENDPOINT) //对端点请求
	{			
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
		{
			c = Sel_EP(endp*2+1);	//读取输入端点状态
		}
		else
		{
			c = Sel_EP(endp*2);		//读取输出端点状态
		}
		if(c & STALL)
		{
			txdat[0] = 1;			//端点禁止
		}
		else
		{
			txdat[0] = 0;			//端点有效
		}
		txdat[1] = 0;
		S_trans(txdat, 2);			//发送16位的状态到主机

	} 
	else
	{
		Stall_ep0();				//非标准请求,发STALL
	}
}
/*******************************************
函数名称: Clr_feature
功    能: 清除特性
参    数: 无   
返回值  : 无
********************************************/
void Clr_feature(void)
{
	uchar endp;					//读取请求类型中的接收方
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT; //读取请求类型
										
	if (bRecipient == USB_RECIPIENT_DEVICE  //对设备请求
	&&ControlData.DeviceRequest.wValue==USB_FEATURE_REMOTE_WAKEUP) //清除远程唤醒特性	
	{
		UEN_GINT();								
		USB_FLAG.remote_wakeup = 0;			//清0远程唤醒标志
		EN_GINT();
		S_trans(0,0);						//返回一个空的数据表示执行完毕
	}
	
	else if (bRecipient == USB_RECIPIENT_ENDPOINT   //对端点请求
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //清除端点禁止特性,恢复其使用
	{
		
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
		{
			Set_EPsta(endp*2 + 1, 0);			    //清除控制输入端点STALL特性
		}
		else
		{
			Set_EPsta(endp*2, 0);				    //清除控制输出端点STALL特性
		}
		S_trans(0, 0);						        //返回一个空的数据表示执行完毕
	} 
	else
	{
		Stall_ep0();					            //没有该请求,返回STALL	
	}						
}
/*******************************************
函数名称: Set_feature
功    能: 设置特性
参    数: 无   
返回值  : 无
********************************************/
void Set_feature(void)
{
	uchar endp;		//读取请求类型中的接收方							
	uchar bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;//读取请求类型
											
	if (bRecipient == USB_RECIPIENT_DEVICE  //对设备请求
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) //设置远程唤醒特性
	{														
		UEN_GINT();
		USB_FLAG.remote_wakeup = 1;				//置1远程唤醒标志
		EN_GINT();
		S_trans(0, 0);						    //返回一个空的数据表示执行完毕
	}		
	else if (bRecipient == USB_RECIPIENT_ENDPOINT //对端点请求
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //禁止端点
	{		
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
		{
			Set_EPsta(endp*2 + 1, 1);		//设置输入端点禁止
		}
		else
		{
			Set_EPsta(endp*2, 1);			//设置输出端点禁止
		}
		S_trans(0, 0);					    //返回一个空的数据表示执行完毕
	} 
	else
	{
		Stall_ep0();					    //没有该请求,返回STALL
	}
}
/*******************************************
函数名称: Set_addr
功    能: 设置地址
参    数: 无   
返回值  : 无
********************************************/
void Set_addr(void)
{
	Set_addren((uchar)(ControlData.DeviceRequest.wValue&DEVICE_ADDRESS_MASK), 1);
	S_trans(0, 0);				//发送一个空的数据响应
}
/*******************************************
函数名称: Get_descriptor
功    能: 获取描述符
参    数: 无   
返回值  : 无
********************************************/
void Get_descriptor(void)
{
	uchar bDescriptor = MSB(ControlData.DeviceRequest.wValue); //读取请求的描述符类型

	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) //获取设备描述符
	{						
		Code_trans((uchar *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
	
	}
	else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) //获取其它描述符
	{		
		  		if (ControlData.DeviceRequest.wLength > CONFIG_DESCRIPTOR_LENGTH)
				{ 
					 ControlData.DeviceRequest.wLength = CONFIG_DESCRIPTOR_LENGTH;
				}   //发送描述符内容
			    Code_trans((uchar *)&(usb_descr.ConfigDescr), ControlData.DeviceRequest.wLength);
			    				
	}
	else
	{
			Stall_ep0();			//没有该请求,返回STALL
	}
	 
}
/*******************************************
函数名称: Get_config
功    能: 获取配置
参    数: 无   
返回值  : 无
********************************************/
void Get_config(void)
{
	uchar c = USB_FLAG.configuration;	//取出配置值
		
	S_trans(&c, 1);				        //发送配置值
}
/*******************************************
函数名称: Set_config
功    能: 设置配置
参    数: 无   
返回值  : 无
********************************************/
void Set_config(void)
{
	if (ControlData.DeviceRequest.wValue == 0) //配置值不对,设备进入未配置状态
	{			
		S_trans(0, 0);			    //发向一个空包响应
		UEN_GINT();
		USB_FLAG.configuration = 0;	//标记未配置
		EN_GINT();
		Init_unconfig();			//进入地址状态,禁止0除外的所有端点
		
	} 
	else if (ControlData.DeviceRequest.wValue == 1) //配置设备
	{		
		S_trans(0, 0);			    //发向一个空包响应
		Init_unconfig();			//进入地址状态,禁止0除外的所有端点
		Init_config();				//配置处理,允许端点收发
		UEN_GINT();
		USB_FLAG.configuration = 1;	//标志已配置
		EN_GINT();
	} 
	else
	{
		Stall_ep0();			    //没有该请求,返回STALL
	}
}
/*******************************************
函数名称: Get_interface
功    能: 获取接口信息
参    数: 无   
返回值  : 无
********************************************/
void Get_interface(void)
{
	uchar txdat = 0;		        //本设备只有一个接口
	S_trans(&txdat, 1);		        //发送一个字节
}
/*******************************************
函数名称: Set_interface
功    能: 设置接口信息
参    数: 无   
返回值  : 无
********************************************/
void Set_interface(void)
{
	if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
	{
		S_trans(0, 0);		        //发送一个空的数据表示执行完毕
	}
	else		
	{
		Stall_ep0();		        //没有该请求,返回STALL	
	}				
}
/*******************************************
函数名称: USB_connect
功    能: 连接USB总线
参    数: 无   
返回值  : 无
********************************************/
void USB_connect(void)
{
    //SoftConnect 连接上,并设置为无LazyClock,模式为非同步模式
	Set_DMA(0x00);
	Set_mode(NOLAZYCLOCK|SOFTCONNECT, SETTOONE | CLOCK_12M);
}	

/*******************************************
函数名称: Set_interface
功    能: 设置接口信息
参    数: 无   
返回值  : 无
********************************************/
void USB_disconnect(void)
{
	//SoftConnect 断开
	Set_mode(NOLAZYCLOCK, SETTOONE | CLOCK_12M);
}	
/*******************************************
函数名称: USB_reconnect
功    能: 重新连接USB总线
参    数: 无   
返回值  : 无
********************************************/
void USB_reconnect(void)
{
	USB_disconnect();	//断开芯片与USB总线连接
	Delayms(200);
	Set_addren(0,1);
	Set_EPen(1);
    USB_connect();		//连接到USB总线
}
/*******************************************
函数名称: Read_chipID
功    能: 读取芯片的ID
参    数: 无   
返回值  : 无
********************************************/
uint Read_chipID(void)
{
	uint i,j;
    
	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD, 0xFD);
	i=InB( );
	j=InB( );
	i += (j<<8);
    
	if(USB_FLAG.in_isr == 0)
		EN_GINT();
	return i;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -