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

📄 usbfunctions.c

📁 开发板MSP430F149
💻 C
📖 第 1 页 / 共 3 页
字号:
		EN_GINT();

	return num;				    //返回读到的字节数
}
/*******************************************
函数名称: Write_EP
功    能: 将数据写入端点
参    数: endp--端点索引号,取值 0 ~ 5 
	  	  len--要写入的数据长度
		  buf--发送数据指针					   
返回值  : num--实际写入的字节数
********************************************/
uchar Write_EP(uchar endp,uchar len,uchar * buf)
{
	uchar i;

	if(USB_FLAG.in_isr == 0)
		UEN_GINT();

	OutB(CMD,endp);			//发送选择端点命令
	Delayus(1);
	i=InB( );			    //可选地读取一个字节

	OutB(CMD,0xF0);			//发送写缓冲区命令	
	Delayus(1);
	OutB(DAT,0);			//写入一个保留字节
	Delayus(1);
	OutB(DAT,len);			//写入即将写入的字节数目
	Delayus(1);

	for(i=0; i<len; i++)
	{
		OutB(DAT,*(buf+i));	//写入指定的字节
	}
	Delayus(1);
	OutB(CMD,0xFA);			//使缓冲区有效

	if(USB_FLAG.in_isr == 0)
		EN_GINT();

	return len;				//返回写入的字节数
}
/*******************************************
函数名称: Ack_EP
功    能: 应答Setup
参    数: endp--端点索引号,取值 0 ~ 5 	   
返回值  : 无
********************************************/
void Ack_EP(uchar endp)
{
	OutB(CMD,endp);			//选择端点
	Delayus(1);
	OutB(CMD,0xF1);			//应答Setup指令
	Delayus(1);
	if(endp==0)	
	{	
		OutB(CMD,0xF2);		//清空该端点缓冲区
	}
}
/*******************************************
函数名称: Clear_buf
功    能: 清指定端点的缓冲区(包括双缓冲区)
参    数: endp--端点索引号,取值 0 ~ 5 	   
返回值  : 无
********************************************/
void Clear_buf(uchar endp)
{	
   	OutB(CMD,endp);			//选择端点
	Delayus(1);
	OutB(CMD,0xF2);			//清空第1个缓冲区	
	
	if (endp>=4)
	{
   		OutB(CMD,endp);		//选择端点
		Delayus(1);
		OutB(CMD,0xF2);		//清空第2个缓冲区	
	}
}
/*******************************************
函数名称: Stall_ep0
功    能: 使控制端点处于停止状态
参    数: 无   
返回值  : 无
********************************************/
void Stall_ep0(void)
{
	Set_EPsta(0,1);
	Set_EPsta(1,1);
}
/*******************************************
函数名称: S_trans
功    能: 通过端点索引 1 发送数据(DATA 类型)
参    数: buf--发送数据指针
		  len--发送数据长度   
返回值  : 无
********************************************/
void S_trans(uchar * buf, uchar len)
{
	if(len<=EP0_PACKET_SIZE) //长度小于EP0最大信息包大小才允许发送
	{			
		Write_EP(1,len,buf);
	}
}
/*******************************************
函数名称: Code_trans
功    能: 通过端点索引 1 发送数据(CODE类型)
参    数: buf--发送数据指针
		  len--发送数据长度   
返回值  : 无
********************************************/
void Code_trans(uchar *pRomData, uint len)
{
	ControlData.wCount = 0;								//传输字节数计数器清0
	if(ControlData.wLength > len)
		ControlData.wLength = len;						//传输数据总字节数不得超过len

	ControlData.pData = pRomData;						//传输数据指针指向pRomData
	if( ControlData.wLength >= EP0_PACKET_SIZE)         //传输数据总字节数大于端点0最大信息包大小
	{		
		Write_EP(1, EP0_PACKET_SIZE, ControlData.pData);//发送端点0最大信息包大小个字节
		ControlData.wCount += EP0_PACKET_SIZE;			//统计已发送字节数

		UEN_GINT();
		USB_FLAG.control_state = USB_TRANSMIT;	        //标志数据发送状态			
		EN_GINT();
	}
	else 
	{
		Write_EP(1, ControlData.wLength, pRomData);	    //写入传输数据总字节数
		ControlData.wCount += ControlData.wLength;	    //统计已发送字节数
		UEN_GINT();
		USB_FLAG.control_state = USB_IDLE;		        //标志空闲状态
		EN_GINT();
	}
}
/*******************************************
函数名称: USB_INT1
功    能: D12中断服务函数
参    数: 无   
返回值  : 无
********************************************/
#pragma vector=PORT1_VECTOR 
__interrupt void USB_INT1(void)
{
    uint int_sta;
    uchar tmp;
    
    if(P1IFG & BIT5)
    {
                	
        //UEN_GINT();			            //进入D12中断服务程序时关中断
        
        if((USBINT_IFG & BIT(D12_INT))==BIT(D12_INT))
        {
            USBINT_IFG&=~BIT(D12_INT);  //清除中断标志
    
            USB_FLAG.in_isr = 1;
            int_sta=Read_IntR();	    //读取PDIUSBD12中断寄存器值
          
            if(int_sta!=0) 
            {
                    if(int_sta&INT_BUSRESET)
                            USB_FLAG.bus_reset=1;	//USB总线复位标志	
                    if(int_sta&INT_ENDP0IN)
                            Ep0_txdone();		//控制端点发送数据处理
                    if(int_sta&INT_ENDP0OUT)
                            Ep0_rxdone();		//控制端点接收数据处理
                    if(int_sta&INT_ENDP1IN)
                            Ep1_txdone();		//端点 1发送数据处理
                    if(int_sta&INT_ENDP1OUT)
                            Ep1_rxdone();		//端点 1接收数据处理
                    if(int_sta&INT_ENDP2IN)
                            Ep2_txdone();		//端点 2发送数据处理
                    if(int_sta&INT_ENDP2OUT)
                            Ep2_rxdone();		//端点 2接收数据处理
            }
            USB_FLAG.in_isr = 0;
        }
        P1IFG &= ~BIT5;
       // EN_GINT();		                        //退出D12中断服务程序时开中断
    }
    else if(P1IFG & 0x0f)
    {
        tmp =~ (P1IN & 0x0f);
        switch(tmp)           //根据中断读入的数值赋予相应的键值
        {
        case 0xf1: KeyChar = 1;break;
        case 0xf2: KeyChar = 2;break;
        case 0xf4: KeyChar = 3;break;
        case 0xf8: KeyChar = 4;break;
        default:   KeyChar = 0;break;
        }
        P3OUT ^= BIT4;        //LED的状态取反
        SendFlag = 1;         //设置发送键值标志
        while((P1IN & 0x0f) != 0x0f);  //等待按键被放开
        P1IFG &= ~0x0f;       //清除中断标志
    }
}
/*******************************************
函数名称: 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

⌨️ 快捷键说明

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