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

📄 usb_setup.#1

📁 源码 : KIEL C 单片机 : C8051F320 功能 : U盘 (64M) 关键字 : C8051F320,U盘,NANDFLASH,FAT,SCH 描述 : 源码完全可运行
💻 #1
字号:
#include "c8051F320.h"
#include "stdio.h"
#include "intrins.h"
/////////////////////////////
#include "Usb_Descreptor.h"
#include "Usb_FunDec.h"
#include "Usb_Parameter.h"
#include "Usb_Register.h"
#include "Usb_Request.h"

//全局变量
static unsigned int   DataSize;                  		// 需要端点0发送的数据大小
static unsigned int   DataSent;                  		// 端点0已经发送的数据大小
static unsigned char  *DataPtr;                  		// 端点0发送数据的指针
static unsigned char  ONES_PACKET[2] = {0x01, 0x00};    // 在Get_Status等命令中应用的数组
static unsigned char  ZERO_PACKET[2] = {0x00, 0x00};    // 在Get_Status等命令中应用的数组

unsigned char  Ep_Status[3]	={EP_IDLE,EP_STALL,EP_STALL};   // 定义端点的状态
unsigned char  USB_State	=DEV_ATTACHED;	                // 定义设备的状态
struct Usb_Setup						// Setup阶段收到的8字节的命令,此处定义为结构
{
	unsigned char bmRequestType;
	unsigned char bRequest;
	unsigned char wValue[2];
	unsigned char wIndex[2];
	unsigned char wLength[2];
}Setup;

///////////////////////////////////////////////////////////////////////////////////////////////
void Handle_Setup()						//端点0中断处理函数
{
    unsigned char ControlReg=0;         // 存放端点0控制/状态寄存器值的变量
    UWrite_Byte(INDEX, 0);           	// 指向端点0
    URead_Byte(E0CSR, ControlReg);  	// 读端点0控制寄存器
    if (ControlReg & rbSUEND)           // 如果上次数据阶段提前结束
    {  
		UWrite_Byte(E0CSR, rbDATAEND);  // 当前数据传完                                
        UWrite_Byte(E0CSR, rbSSUEND);   // 清除SUEND标志
        Ep_Status[0] = EP_IDLE;         // 端点返回到空闲状态
    }
    if (ControlReg & rbSTSTL)           // 如果上次传输因错误而发送了STALL使传输提前结束
    {                                  
        UWrite_Byte(E0CSR, 0);          // 清除STALL
        Ep_Status[0] = EP_IDLE;			// 端点0返回到空闲状态
    }

	if (ControlReg & rbOPRDY)           // 如果接收到输出数据包
	{
	    if (Ep_Status[0] == EP_IDLE)    // 如果端点0空闲
		{
			Fifo_Read(FIFO_EP0,8,(unsigned char *)&Setup);		// 读取设置数据包,8个字节
			switch(Setup.bRequest)  				    // 判断请求类型   
			{                              
				case GET_STATUS:		Get_Status();		break;				     	
				case CLEAR_FEATURE:		Clear_Feature();	break;
				case SET_FEATURE:    	Set_Feature(); 		break;   
				case SET_ADDRESS:		Set_Address();	 	break;	
				case GET_DESCRIPTOR:	Get_Descriptor();	break;	
				case GET_CONFIGURATION:	Get_Configuration();break;
				case SET_CONFIGURATION:	Set_Configuration();break;
				case GET_INTERFACE:		Get_Interface();	break;
				case SET_INTERFACE:		Set_Interface();	break;		
				case GET_MAXLUN:		Get_Maxlun();		break;
				default:				Force_Stall();		break;			
	     	}	
			                 
		/////////////////////////////////////////////////////////////////////////////////////////////
		}
		else if(Ep_Status[0]==EP_RX)	// 如果在OUT状态,此程序中不会从端点0接收其它信息,所以没相关的操作
		{}
	}
	if (Ep_Status[0] == EP_TX)			// 如果在IN状态
	{
		    unsigned char ControlReg=0,TempReg=0;	// 存放寄存器值的变量                                      
			URead_Byte(E0CSR, ControlReg);			// 读端点0控制寄存器                              
			TempReg = rbINPRDY;                     // 输出数据准备好           
			if (DataSize >= EP0_PACKET_SIZE)		// 如果待发送数据的长度大于端点0长度
			{
				Fifo_Write(FIFO_EP0, EP0_PACKET_SIZE,DataPtr);	// 发送数据包
		        DataPtr  += EP0_PACKET_SIZE;                    // 更新数据指针
		        DataSize -= EP0_PACKET_SIZE;                    // 更新待发送的数据量
		        DataSent += EP0_PACKET_SIZE;                    // 更新已发送的数据量
		    }
			else                        			// 如果待发送数据的长度小于端点0长度
			{
				Fifo_Write(FIFO_EP0, DataSize,DataPtr);	// 发送剩余的数据       
		        TempReg |= rbDATAEND;                  	// 指示数据发送完备,进入状态阶段		               
		        Ep_Status[0] = EP_IDLE;                 // 端点返回到空闲状态               
			}
			if (DataSent == (Setup.wLength[0]+256*Setup.wLength[1]))	//如果发送的数据量正好是端点0的整数倍
			                            
		    {
		        TempReg |= rbDATAEND;    // 指示数据发送完备,进入状态阶段
		        Ep_Status[0] = EP_IDLE;  // 端点返回到空闲状态
		    }
		        UWrite_Byte(E0CSR, TempReg);  // 写端点0控制寄存器
    }
}

void Force_Stall()
{
	UWrite_Byte(INDEX, 0);
    UWrite_Byte(E0CSR, rbSDSTL);       // 发送STALL
    Ep_Status[0] = EP_STALL;           // 端点0到STALL状态,直到下次复位
}

//处理标准请求的函数
void Get_Status()
{	
   	switch(Setup.bmRequestType)                  
   	{
      	case IN_DEVICE:                          	// 如果是设备的状态
           	DataPtr = ZERO_PACKET;               	// 发送 0x00, 总线供电,不支持远程唤醒
           	DataSize = 2;                        	
           	break;      
      	case IN_INTERFACE:                       	// 接口状态
           	DataPtr = ZERO_PACKET;               	// 接口状态永远返回0
           	DataSize = 2;         
           	break;  
      	case IN_ENDPOINT:                        	// 端点状态
           	if (Setup.wIndex[0] == IN_EP1)          // 如果是端点1
			{
				if (Ep_Status[1] == EP_HALT)
				{                               // 如果端点1在EN_HALT状态
					DataPtr = ONES_PACKET;		// 发送ONES_PACKET,指示端点1在HALT状态
	                DataSize = 2;
	            }
	            else
	            {
	                DataPtr = ZERO_PACKET;		// 否则发送ZERO_PACKET,指示端点1在空闲状态
	                DataSize = 2;
	            }
			}
	        if (Setup.wIndex[0] == OUT_EP2)
	        {                                 
				if (Ep_Status[2] == EP_HALT) 
				{
					DataPtr = ONES_PACKET;
	                DataSize = 2;
				}
	            else
				{
					DataPtr = ZERO_PACKET;
					DataSize = 2;
				}
			}
            break;
      default:	Force_Stall();	break;           
	}
   if (Ep_Status[0] != EP_STALL)
   {
   		UWrite_Byte(E0CSR, rbSOPRDY);                       
      	Ep_Status[0] = EP_TX;                     // 端点0在EP_TX状态
      	DataSent = 0;								// 已发送数据量清零
   }
}

void Clear_Feature()
{
	if ((Setup.bmRequestType & 0x02)&&			// 如果是端点
        (Setup.wValue[0] == ENDPOINT_HALT)  && 	// 并且这些端点的状态是EP_HALT
       ((Setup.wIndex[0] == IN_EP1) ||         	// 并且选择的是端点1 IN
        (Setup.wIndex[0] == OUT_EP2)))         	// 或端点2 OUT 
	{
         if (Setup.wIndex[0] == IN_EP1) 
         {
            UWrite_Byte (INDEX, 1);             // 使toggle复位为零
            UWrite_Byte (EINCSRL, rbInCLRDT);       
            Ep_Status[1] = EP_IDLE;             // 端点1到空闲状态                    
         }
         else
         {
            UWrite_Byte (INDEX, 2);         
            UWrite_Byte (EOUTCSRL, rbOutCLRDT);         
            Ep_Status[2] = EP_IDLE;             
         }
	}
	else
    { 
         Force_Stall();                         
    }
   if (Ep_Status[0] != EP_STALL)
   {
   		UWrite_Byte(E0CSR, rbSOPRDY);
		UWrite_Byte(E0CSR, rbDATAEND);                       
   }
}
void Set_Feature()
{
	if ((Setup.bmRequestType  & 0x02) && 		// 意义同上
        (Setup.wValue[0] == ENDPOINT_HALT) &&  
       ((Setup.wIndex[0] == IN_EP1)      || 
        (Setup.wIndex[0] == OUT_EP2)))
	{
         if (Setup.wIndex[0] == IN_EP1) 
         {
            UWrite_Byte (INDEX, 1);         	  
            UWrite_Byte (EINCSRL, rbInSDSTL);   // rbInSDSTL=1,发送STALL作为对IN令牌的响应,
												// 在端点1中断处理函数中将rbInSDSTl和rbInSTSTL清零    
            Ep_Status[1] = EP_HALT;             // 端点1到HALT状态                     
         }
         else
         {
            UWrite_Byte(INDEX, 2);         		
            UWrite_Byte (EOUTCSRL, rbOutSDSTL); // 同上       
            Ep_Status[2] = EP_HALT;  		    
         }
	}
	else
    { 
		Force_Stall();                         	
    }  
   if (Ep_Status[0] != EP_STALL)
   {
   		UWrite_Byte(E0CSR, rbSOPRDY);
		UWrite_Byte(E0CSR, rbDATAEND);                       
   }
}
void Set_Address()
{
   	if (Setup.wValue[0] != 0) 
   	{
      	USB_State = DEV_ADDRESS;            // 收到不为0的地址,设备处于地址状态,此次传输的
      	UWrite_Byte(FADDR, Setup.wValue[0]);// 状态阶段结束后新地址将起作用
      	Ep_Status[0] = EP_IDLE;

   	}
   	else 
   	{
     	USB_State = DEV_DEFAULT;            // 收到的地址为0,设备仍旧处于默认状态
   	}
   	UWrite_Byte(E0CSR, rbSOPRDY);
	UWrite_Byte(E0CSR, rbDATAEND);                       
                                              
}
void Get_Descriptor()
{
	unsigned int In_DataSize=0;			// 要发送的数据总量
	In_DataSize=Setup.wLength[0]+Setup.wLength[1]*256;
	switch(Setup.wValue[1])             // 判断描述符的类型
    {                                            
		case DSC_DEVICE:         		// 设备描述符  
	       	DataPtr  = DeviceDesc;
			if(In_DataSize>18)
			{DataSize = 18;	}       
			else
			{DataSize = In_DataSize;}
        break;      
		case DSC_CONFIG:				// 配置描述符
        	DataPtr  = ConfigDesc;
			if(In_DataSize==0x09)
			{
			 	DataSize=0x09;
			}
			else if(In_DataSize==0x20)
			{
			 	DataSize=0x20;
			}
			else if(In_DataSize==0xff)
			{
			 	DataSize=0x20;
			}
        break;
		case DSC_STRING:				// 字符串描述符
			 DataPtr=&StringDes[Setup.wValue[0]];
			 DataSize=In_DataSize;
			 break;
		default:	         break;
   	}
	UWrite_Byte(E0CSR, rbSOPRDY);
    Ep_Status[0] = EP_TX;                      // 端点0在发送状态
    DataSent = 0;                              
}
void Get_Configuration()
{
   if (USB_State == DEV_CONFIGURED)   // If the device is configured, then return value 0x01
   {                                  // since this software only supports one configuration
         DataPtr  = ONES_PACKET;
         DataSize = 1;
   }
   if (USB_State == DEV_ADDRESS)      // If the device is in address state, it is not
   {                                  // configured, so return 0x00
         DataPtr  = ZERO_PACKET;
         DataSize = 1;
   }
   if (Ep_Status[0] != EP_STALL)
   {
   		UWrite_Byte(E0CSR, rbSOPRDY);
        Ep_Status[0] = EP_TX;                 
        DataSent = 0;                         
   }
}
void Set_Configuration()
{
   if (Setup.wValue[0] > 0)                  // Any positive configuration request
   {                                         // results in configuration being set to 1
         USB_State = DEV_CONFIGURED;
		 ///////////////////////////////////////////////////////////////////////////////////
         UWrite_Byte(INDEX, 1);     
         UWrite_Byte(EINCSRH,0xa0); // 双缓冲、ISO、FIFO分割和强制数据Toggle禁止,IN端点
		 Ep_Status[1]=EP_IDLE;
		  
         UWrite_Byte(INDEX, 2);            
         UWrite_Byte(EOUTCSRH, 0x80);      // 双缓冲和ISO禁止,OUT端点
		 Ep_Status[2]=EP_IDLE; 
		 ///////////////////////////////////////////////////////////////////////////////////
         UWrite_Byte(INDEX, 0);           
   }
   else
   {
         USB_State = DEV_ADDRESS;         // 设备仍旧在地址状态
		 Ep_Status[1]=EP_STALL;
		 Ep_Status[2]=EP_STALL;
   }
   if (Ep_Status[0] != EP_STALL)
   {
   		UWrite_Byte(E0CSR, rbSOPRDY);
		UWrite_Byte(E0CSR, rbDATAEND);                
   }
}
void Get_Interface()
{
	DataPtr = ZERO_PACKET;            
	DataSize = 1;
    if (Ep_Status[0] != EP_STALL)
    { 
   		UWrite_Byte(E0CSR, rbSOPRDY);                  
        Ep_Status[0] = EP_TX;          
        DataSent = 0;
    }
}
void Set_Interface()
{
   	UWrite_Byte(E0CSR, rbSOPRDY);
	UWrite_Byte(E0CSR, rbDATAEND);             
}

void Get_Maxlun()			// U盘支持一个逻辑单元,返回1即可
{
	DataPtr = ZERO_PACKET;            
	DataSize = 1;
    if (Ep_Status[0] != EP_STALL)
    {                       
        Ep_Status[0] = EP_TX;           
        DataSent = 0;
    }
   	UWrite_Byte(E0CSR, rbSOPRDY);
}////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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