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

📄 usb_processor.c

📁 学习资料S12源程序UF32 USB MCU方测试程序 CW环境
💻 C
字号:
#include "usb_processor.h"
//-------------------------------------------------------------------------*
// 子函数名:USB_ModuleInit(void)                                          *
// 功能描述:USB模块的初始化.                                              *
// 入口参数:无                                                            *
// 返    回:无                                                            *
//-------------------------------------------------------------------------*
void USB_ModuleInit(void) 
{
	UMCR	= 0x4000;       //使能模块时钟
	                   		// bit 11-Normal PHY operation
//	UMCR	= 0x00;		
					             	// bit 4:SET_DESCRIPTOR不支持
					             	// bit 3:高速
					           	  // bit 2:支持过程唤醒
					            	// bit 1:自供电
					             	// bit 0:SYNC_FRAME命令不支持 
	            

	UIMR 	= 0x2801;	
		        	         	// bit0:使能SETUPIE
					             	// bit1:使能SETOVRIE
					             	// bit2:使能SOFIE
					             	// bit11:使能URSCIE
					             	// bit12:使能USSCIE
					             	// bit13:使能SETECRIE
	UIMR 	&= 0xbfff;      // 确认resume中断标志关

};
void IQUE_Module_Init(void)
{
	// 使能IQUE模块, 复位, 3,4通道使用block base
	IQUECR 		= IQUECR_IQUEEN_MASK | IQUECR_QC34DBE_MASK | IQUECR_IQUERST_MASK;
	// 使能 force handshake
	QC34DSHR	= QC34DSHR_DTHE_34_MASK | QC34DSHR_DRHE_34_MASK; 
}
//-------------------------------------------------------------------------*
// 子函数名:USB_InitBulkOnlyTransport(void)                               *
// 功能描述:USB批量传输初始化 -配置1x64字节BULK in 和1x64字节BULK out.    *
// 入口参数:无                                                            *
// 返    回:无                                                            *
//-------------------------------------------------------------------------*
void USB_InitBulkOnlyTransport(void) 
{	
  	// 选择只有一个配置和一个接口
  	UEPCSELR	= 0x0810;
  	UUCFGR		= 0x00000011;		       	
  	// 不支持交互
  	UEPCSELR	= 0x0910;
  	UUCFGR		= 0x00000000;	
  	// 配置物理端点1 - 为控制端点 
  	UEPCSELR	= 0x0110;		  		
  	UUCFGR		= 0x02000000;
	                  		//包的大小为:64字节	
								      	//交互为0
						            //接口为0
						            //配置为0
						            //类型为:control
						            //方向为:IO
						            //端点数为0
    // 清端点1发送和接受DVALID(数据无效)位, 
    // 清传输完成标志(TFRC),允许传送完成中断(TCIE)
  	UEPCSR0		= 0x3000;			  
  	UEPCSR1		= 0x3000;
    
    if(gUSBFullSpeed)
    {	
    	// 配置端点5
    	UEPCSELR 	= 0x0510;
    	UUCFGR		= 0x820000D1;
     								    // 包的大小:64字节
		      							// 交互为0
                     		// 接口为0
						            // 配置为1
						            // 类型为:BULK
						            // 方向:IN
						            // 端点号为1
    	// 使能通道3,小包,16位访问, 复位
    	QC3CR		= QC3CR_Q3EN_MASK | QC3CR_Q3PRST_MASK; 
    	// 64字节大小,地址 0x20F0 - 0x2130	
    	QC3SZB		= 0x3F;
     	// 配置端点4
     	UEPCSELR 	= 0x0410;
      							    // 包的大小:64字节
       									// 交互为0
                     		// 接口为0
  					            // 配置为1
  					            // 类型为:BULK
  					            // 方向:OUT
  					            // 端点号为1    	
      UUCFGR		= 0x820000C1;
    	// 使能通道1,小包,8位访问, 复位
    	QC1CR		= QC1CR_Q1EN_MASK | QC1CR_Q1PRST_MASK; 		   
    	// 64字节大小,地址 0x2000 - 0x2040	
    	QC1SZB		= 0x30;					      	    						
    }
    else
    {
    	// 配置端点5
    	UEPCSELR 	= 0x0510;
    	UUCFGR		= 0x900000D1;
								    // 包的大小:512字节
									  // 交互为0
                    // 接口为0
				            // 配置为1
				            // 类型为:BULK
				            // 方向:IN
				            // 端点号为1
  		// 512字节大小,地址 0x2200 - 0x2400
  		QC3SZB		= 0x12;						            
  		// 使能通道3,大包,16位访问, 复位
  		QC3CR		= QC3CR_Q3EN_MASK | QC3CR_Q316EN_MASK;
      // 配置端点4
      UEPCSELR 	= 0x0410;

  								    // 包的大小:512字节
  									  // 交互为0
                      // 接口为0
					            // 配置为1
					            // 类型为:BULK
					            // 方向:OUT
					            // 端点号为1    	
      UUCFGR		= 0x900000C1;
      	
  		// 512字节大小,地址 0x2000 - 0x2200
  		QC1SZB		= 0x10;	     	
  		// 使能通道1,小包,8位访问, 复位
  		QC1CR		= QC1CR_Q1EN_MASK| QC1CR_Q116EN_MASK;
    }
 
	  //清完成标志位,使能中断				               	
   	//UEPCSR5A	= 0x7800;
    do
      UEPCSR5A = 0x7800 ;
    while(!(UEPCSR5A & 0x4000));
   	UEPCSR5B	= 0x0000;
   	
   	// 请标志位,开中断
   	UEPCSR4A	= 0x3800;
   	UEPCSR4B	= 0x0000;
   	
   	// 通道3为USB Rx
    QC3REQ		= 0x01;
    // 通道1为USB Tx
    QC1REQ 		= 0x00;						        
};


//------------------------------------------------------------------------*
// 子函数名:USB_InitBulkOnlyTransport(void)                              *
// 功能描述:USB批量传输初始化 -配置1x64字节BULK in 和1x64字节BULK out.   *
// 入口参数:无                                                           *
// 返    回:无                                                           *
//------------------------------------------------------------------------*
/*备用
void USB_InitBulkOnlyTransport(void) 
{	
	//选择只有一个配置和一个接口
	UEPCSELR_h	= 0x08;			  
	UNCIR_h		= 0x0000;        
	UNCIR_l		= 0x0011; 	
	// 不支持交互
	UEPCSELR_h	= 0x09;	
	UNASR_h		= 0x0000;
	UNASR_l		= 0x0000;
	// 配置物理端点1 - 为控制端点
	UEPCSELR_h	= 0x01;
	UEPCSELR_l	= 0x10;			  		
	UPECFGR_h	= 0x0200;		//包的大小为:64字节
	
	UPECFGR_l	= 0x0000;		//交互为0
						            //接口为0
						            //配置为0
						            //类型为:control
						            //方向为:IO
						            //端点数为0
  // 清端点1发送DVALID(数据无效)位, 清传输完成标志(TFRC),允许传送完成中断(TCIE)
	UEPCSR0		= 0x3000;
	
	// 清端点1接受DVALID(数据无效)位, 清传输完成标志(TFRC),允许传送完成中断(TCIE)  
	UEPCSR1		= 0x3000;


            
            
    // 配置物理端点2 - 为接受端点 
  UEPCSELR_h 	= 0x02;		
                 
	UPECFGR_h  	= 0x0200;			// 包的大小:64字节
		
	UPECFGR_l  	= 0x00D1;			// 交互为0
                             		// 接口为0
						            // 配置为1
						            // 类型为:BULK
						            // 方向:IN
						            // 端点号为1
						            
  //端点2采用缓冲区UEPLB0, 端点3采用缓冲区UEPLB1
  UEPCSELR_l	= 0x32;
							            
	//清端点2接受DVALID(数据无效)位, 清传输完成标志(TFRC),允许传送完成中断(TCIE)					            
	UEPCSR2		= 0x3000;	
	
	//配置物理端点3 - 为发送端点,除了为OUT类型,其余同2端点 
	UEPCSELR_h 	= 0x03;				// 物理端点3(OUT)
	
  UPECFGR_h 	= 0x0200;			// 包的大小:64字节
	
	UPECFGR_l  	= 0x00C1;      		// 交互为0
						            // 接口为0
						            // 配置为1
						            // 类型为BULK
						            // 方向:OUT
						            // 端点数为1
	
	//端点2采用缓冲区UEPLB0, 端点3采用缓冲区UEPLB1				            
	UEPCSELR_l 	= 0x32;        							            
						            
	UEPCSR3		= 0x3000;						        
};
*/
//-------------------------------------------------------------------------*
// 子函数名:USB_DecodeSETUP(volatile UINT8 *p_Packet)                     *
// 功能描述:解析setup包,根据请求类型,返回相应的描述符                   *
// 入口参数:USTB(USB2.0 SETUP数据缓冲区首地址)                            *
// 返回:    无                                                            *
// 调用方法:USB_DecodeSETUP(&USTB)                                        *
//-------------------------------------------------------------------------*
void USB_DecodeSETUP(volatile UINT8 *p_Packet) {
	UINT8 Type; 
	UINT8 Index; 
	UINT16 Length, ThisLen;
	// 获取包长
	Length = (UINT16)(*(p_Packet+wLength_h) <<8) + *(p_Packet+wLength_l);
	switch (p_Packet[bRequest])	
	  // 判断请求命令代码(0:GET_STATUS,1:CLEAR_FEATURE,3:SET_FEATURE,
		// 5:SET_ADDRESS,6:GET_DESCRIPTOR,7:SET_DESCRIPTOR,
		// 8:GET_CONFIGURATION,9:SET_CONFIGURATION,10:GET_INTERFACE,
		// 11:SET_INTERFACE,12:SYNCH_FRAME,0xFE:Mass Storage)
	{ 
	case GET_DESCRIPTOR:
		Type = p_Packet[wValue_h];
		Index = p_Packet[wValue_l];
		switch (Type)
		{
		case DEVICE:
			ThisLen = USB_GetMin(Device_Descriptor[0],Length);
			USB_Move2LocalBuffer((UINT8*) Device_Descriptor,(UINT8*)USB_SetBufferPtr(PHY1IN),ThisLen);

			break;
		case CONFIGURATION:
			ThisLen = USB_GetMin(((UINT16) Configuration_DescriptorHS[3] << 8) | Configuration_DescriptorHS[2],Length);
			USB_Move2LocalBuffer((UINT8*)Configuration_Table[gUSBFullSpeed][Index],(UINT8*)USB_SetBufferPtr(PHY1IN),ThisLen);
			
			break;
		case STRING:
			ThisLen = USB_GetMin(String_Table[Index][0],Length);
			USB_Move2LocalBuffer((UINT8*)String_Table[Index],(UINT8*)USB_SetBufferPtr(PHY1IN),ThisLen);						

			break;
		case INTERFACE:
			ThisLen = USB_GetMin(Interface_Table[Index-1][0],Length);
			USB_Move2LocalBuffer((UINT8*)Interface_Table[Index-1],(UINT8*)USB_SetBufferPtr(PHY1IN),ThisLen);						
			
			break;
		case ENDPOINT:
			ThisLen = USB_GetMin(Endpoint_Table[gUSBFullSpeed][Index-1][0],Length);
			USB_Move2LocalBuffer((UINT8*)Endpoint_Table[gUSBFullSpeed][Index-1],(UINT8*)USB_SetBufferPtr(PHY1IN),ThisLen);
			SCISendNByte((UINT8*) Endpoint_Table[gUSBFullSpeed][Index-1], ThisLen);
			break;				
		};
		do
		{
			UEPCSR0 = 0x5000 | ThisLen;
		}
		while (!(UEPCSR0 & 0x4000));

		break;
	case SET_DESCRIPTOR:

		break;
	case SYNCH_FRAME:
		break;
	case SET_ADDRESS:
		break; 
	case	GET_STATUS:
		break;
	case	GET_CONFIGURATION:	
		break;
	case	SET_CONFIGURATION:	
		break;
	case	GET_INTERFACE:	
		break;
	case	SET_INTERFACE:	
		break;
	default:
		break;
	}		
}

//-------------------------------------------------------------------------*
// 子函数名:*USB_SetBufferPtr(UINT8 PhyEPNo)                              *
// 功能描述:使能6个端点的Buffer区指针,返回相应端点对应的当前缓冲区首址   *
// 入口参数:PhyEPNo(端点号)                                             *
// 返回:    当前缓冲区首址                                                *
// 调用方法:USB_SetBufferPtr(1)                                           *
//-------------------------------------------------------------------------*
volatile UINT8 *USB_SetBufferPtr(UINT8 PhyEPNo) {
	switch (PhyEPNo) {
			case PHY1IN:
				UEPCSELR_l = 0x10;		// Select acessing through UEPLB0
				return &UEPLB0;
				break;
			case PHY1OUT:
				UEPCSELR_l = 0x10;		// Select acessing through UEPLB1
				return &UEPLB1;
				break;
			case PHY2:
				UEPCSELR_l = 0x32;		// Select acessing through UEPLB0
				return &UEPLB0;
				break;
			case PHY3:
				UEPCSELR_l = 0x32;		// Select acessing through UEPLB1
				return &UEPLB1;
				break;
			case PHY4:
				return &QC1DR_H;			// Select QUE channel 1
				break;
			case PHY5:
				return &QC2DR_H;			// Select QUE channel 2
				break;
			case PHY6:
				UEPCSELR_l = 0x16;		// Select acessing through UEPLB0
				return &UEPLB0;
				break;
			default:
				UEPCSELR_l = 0x10;		// PHY1IN default to UEPLB0
				return &UEPLB0;			  // PHY1OUT default to UEPLB1
				break;				
	};
};

//-------------------------------------------------------------------------*
// 子函数名:USB_Move2LocalBuffer(*FR_ptr,*TO_ptr,Len)                     *
// 功能描述:从指针FR_ptr所指向的位置移动长度为len数据到TO_ptr指针所指     *
//           向的当前缓冲区中去,在端点0向PC方发数据时用该函数              *
// 入口参数:FR_ptr:数据原首址,TO_ptr:目的地首址,Len:移动的字数        *
// 返回:    无                                                            *
// 调用方法:USB_Move2LocalBuffer((UINT8*)Configuration_Table              *
//           [gUSBFullSpeed][Index],                                       *
//            (UINT8*)USB_SetBufferPtr(PHY1IN),ThisLen)                    *
//-------------------------------------------------------------------------*
void USB_Move2LocalBuffer(UINT8 *FR_ptr, UINT8 *TO_ptr, UINT16 Len) {

	UINT16 i=0;
	for (i=0; i<Len; i=i+2) 
	{
#ifdef	_kUF32isMPW_							
		*(TO_ptr+i+1) = *(FR_ptr+i);
		*(TO_ptr+i) = *(FR_ptr+i+1);			// 高位和低位字节交换
#else
		*(TO_ptr+i) = *(FR_ptr+i);
		*(TO_ptr+i+1) = *(FR_ptr+i+1);
#endif		
	}
}


//-------------------------------------------------------------------------*
// 子函数名:USB_GetMin(UINT16 Value1, UINT16 Value2)                      *
// 功能描述:取长度较小的值                                                *
// 入口参数:Value1和Value2为比较的长度值                                  *
// 返回:    长度较小的值                                                  *
// 调用方法:USB_GetMin(0x001f, 0x0022),返回值?x001f                       *
//-------------------------------------------------------------------------*
UINT16	USB_GetMin(UINT16 Value1, UINT16 Value2)
{
	if (Value1 > Value2)
		return(Value2);
	else
		return(Value1);
}

void USB_Move2QUE3(UINT8 *FR_ptr, UINT16 Len)
{

	UINT16 i=0;
	
	for (i=0; i<Len; i=i+2) {

		QC3DR = ( (UINT16) *(FR_ptr+i) << 8) | *(FR_ptr+i+1);
	}
}

void USBMS_SetPhyEP5Int(UINT16 Length)
{
  
  	do
  	{
  	//清发送完成标志位、出错仍然发送、下次发送长度 
  	UEPCSR5A = (1<<TFRC)|(1<<USBTCIE)|(1<<CTERR)|Length;
  	
  	//UEPCSR5A &= ~(1<<15);
  	}
  	//When this bit is set,NAKhandshake will be generated for all transactions assocated with this endpoint.
    //It is also recommended to set this bit and NAK all incoming USB traffic addressed to this endpoint
    //when the RXSIZ or the associated IQUE channel need to be manipulated by software. When STALL
    //is also set, STALL handshake will be sent instead
  	while (mCheckBit(SNAK,UEPCSR5A));
  	//This control bit acknowledges the data transmitted from queue channel is consumed. Buffer status
    //registers advance when this bit asserts. This bit will be deserted in next cycle automatically.
    //Transmitted data of last buffer will be flushed and overrided by next write cycle.
  	//数据已经准备好,可以发送
  	mSetBit(RXDA,QC34DTR);
}

⌨️ 快捷键说明

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