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

📄 chap_9.c

📁 PDIUSBD12的固件程序可能对开发USB1.1的兄弟有用
💻 C
字号:
//协议层

#include <reg52.h>
#include "D12Config.h"
#include "D12CI.h"
#include "Chap_9.h"
#include "Descriptor.h"

CONTROL_XFER ControlData;
EPPFLAGS bEPPflags;

//USB标准设备请求入口地址指针表
code void (*StandardDeviceRequest[])(void) =
{
	get_status,
	clear_feature,
	reserved,
	set_feature,
	reserved,
	set_address,
	get_descriptor,
	reserved,
	get_configuration,
	set_configuration,
	get_interface,
	set_interface,
	reserved,
	reserved,
	reserved,
	reserved
};

// USB 协议层函数

void stall_ep0(void)
{
	D12_SetEndpointStatus(0, 1);
	D12_SetEndpointStatus(1, 1);
}
   
void reserved(void)
{
	stall_ep0();																//返回STALL
}


void init_unconfig(void)
{
	D12_SetEndpointEnable(0);													//禁止0除外的所有端点
}


void init_config(void)
{
	D12_SetEndpointEnable(1);
}


void single_transmit(INT8U * buf, INT8U len)
{
	if( len <= EP0_PACKET_SIZE)
		D12_WriteEndpoint(1, len, buf);
}


void code_transmit(INT8U *pRomData, INT16U len)
{
	ControlData.wCount = 0;
	if(ControlData.wLength > len)
		ControlData.wLength = len;

	ControlData.pData = pRomData;
	if( ControlData.wLength >= EP0_PACKET_SIZE)
    {
		D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData);
		ControlData.wCount += EP0_PACKET_SIZE;

		DISABLE();
		bEPPflags.bits.control_state = USB_TRANSMIT;		
		ENABLE();
	}
	else 
	{
		D12_WriteEndpoint(1, ControlData.wLength, pRomData);
		ControlData.wCount += ControlData.wLength;
		DISABLE();
		bEPPflags.bits.control_state = USB_IDLE;
		ENABLE();
	}
}


// USB 标准设备请求服务程序

void get_status(void)
{
	INT8U endp, txdat[2], c;
	INT8U bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;	

	if (bRecipient == USB_RECIPIENT_DEVICE) 
	{
		if(bEPPflags.bits.remote_wakeup == 1)			
			txdat[0] = 3;														//支持远程唤醒、自供电
		else
			txdat[0] = 1;
		txdat[1]=0;	
		single_transmit(txdat, 2);												//发送16位的状态到主机
		
	} 
	else if (bRecipient == USB_RECIPIENT_INTERFACE) 
	{	
		txdat[0]=0;
		txdat[1]=0;
		single_transmit(txdat, 2);
	
	}
	else if (bRecipient == USB_RECIPIENT_ENDPOINT) 
	{
		endp = (INT8U)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (INT8U)USB_ENDPOINT_DIRECTION_MASK)
			c = D12_SelectEndpoint(endp*2 + 1);									//读取输入端点状态
		else
			c = D12_SelectEndpoint(endp*2);										//读取输出端点状态
		if(c & D12_STALL)
			txdat[0] = 1;														//端点禁止
		else
			txdat[0] = 0;														//端点有效
		txdat[1] = 0;
		single_transmit(txdat, 2);

	} 
	else
		stall_ep0();															//非标准请求,发STALL
}


void clear_feature(void)
{
	INT8U endp;
	INT8U bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;

	if (bRecipient == USB_RECIPIENT_DEVICE&&ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) 
	{
		DISABLE();																//清除远程唤醒特性	
		bEPPflags.bits.remote_wakeup = 0;										//清0远程唤醒标志
		ENABLE();
		single_transmit(0, 0);													//返回一个空的数据表示执行完毕
	}
	
	else if (bRecipient == USB_RECIPIENT_ENDPOINT&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)
   	{		//清除端点禁止特性,恢复其使用
		endp = (INT8U)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (INT8U)USB_ENDPOINT_DIRECTION_MASK)
			D12_SetEndpointStatus(endp*2 + 1, 0);								//清除控制输入端点STALL特性
		else
			D12_SetEndpointStatus(endp*2, 0);									//清除控制输出端点STALL特性
		single_transmit(0, 0);
	} 
	else
		stall_ep0();															//没有该请求,返回STALL							
}


void set_feature(void)
{
	INT8U endp;
	INT8U bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;//读取请求类型中的接收方

	if (bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) 
	{//设置远程唤醒特性
		DISABLE();
		bEPPflags.bits.remote_wakeup = 1;										//置1远程唤醒标志
		ENABLE();
		single_transmit(0, 0);
	}	
	
	else if (bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) 
	{//禁止端点
		endp = (INT8U)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (INT8U)USB_ENDPOINT_DIRECTION_MASK)
			D12_SetEndpointStatus(endp*2 + 1, 1);								//设置输入端点禁止
		else
			D12_SetEndpointStatus(endp*2, 1);									//设置输出端点禁止
		single_transmit(0, 0);
	}
	else
		stall_ep0();
}


void set_address(void)
{
	D12_SetAddressEnable((INT8U)(ControlData.DeviceRequest.wValue &
						 DEVICE_ADDRESS_MASK), 1);
	single_transmit(0, 0);
}


void get_descriptor(void)
{
	INT8U bDescriptor = MSB(ControlData.DeviceRequest.wValue);					//读取请求的描述符类型

	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)
	{//获取设备描述符
		code_transmit((INT8U *)&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_transmit((INT8U *)&(usb_descr.ConfigDescr), ControlData.DeviceRequest.wLength);
			    																//发送描述符内容
	}
	else
		stall_ep0();
}


void get_configuration(void)
{
	INT8U c = bEPPflags.bits.configuration;										//取出配置值
	single_transmit(&c, 1);														//发送配置值
}


void set_configuration(void)
{
	if (ControlData.DeviceRequest.wValue == 0) 
	{//配置值不对,设备进入未配置状态
		single_transmit(0, 0);
		DISABLE();
		bEPPflags.bits.configuration = 0;
		ENABLE();
		init_unconfig();														//进入地址状态,禁止0除外的所有端点
	} 
	else if (ControlData.DeviceRequest.wValue == 1) 
	{
		single_transmit(0, 0);
		init_unconfig();
		init_config();
		DISABLE();
		bEPPflags.bits.configuration = 1;
		ENABLE();
	} 
	else
		stall_ep0();
}


void get_interface(void)
{
	INT8U txdat = 0;															//本设备只有一个接口
	single_transmit(&txdat, 1);													//发送一个字节
}


void set_interface(void)
{
	if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
		single_transmit(0, 0);
	else		
		stall_ep0();				
}


void control_handler(void) 															//协议控制子程序
{
	INT8U 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();			
}


void ep0_rxdone(void)  																//端点0接收数据
{
	INT8U ep_last, i;
	INT8U req[sizeof(DEVICE_REQUEST)];

	ep_last = D12_ReadLastTransactionStatus(0);			 							//清除中断寄存器状态,取得最后处理状态
	if (ep_last & D12_SETUPPACKET) 
	{					 															//如果收到了建立包(Setup包)
		ControlData.wLength = 0;				 		 							//传输字节总数清0
		ControlData.wCount = 0;					 		 							//传输字节计数器清0
		if(D12_ReadEndpoint(0, sizeof(ControlData.DeviceRequest),req) 
							!= sizeof(DEVICE_REQUEST) ) 
		{
												 		 							//从端点0读8个字节失败
			D12_SetEndpointStatus(0, 1);				 							//停止控制端点0
			D12_SetEndpointStatus(1, 1);			 	 							//停止控制端点1
			bEPPflags.bits.control_state = USB_IDLE;	 							//设置为等待状态
			return;
		}
		/******* 以下语句通信中的解决大小端问题,使该函数与编译器无关 ****/
		ControlData.DeviceRequest.bmRequestType = req[0];
		ControlData.DeviceRequest.bRequest	    = req[1];
		ControlData.DeviceRequest.wValue 	 	= req[3] * 256 + req[2]; 
		ControlData.DeviceRequest.wIndex        = req[5] * 256 + req[4];
		ControlData.DeviceRequest.wLength       = req[7] * 256 + req[6]; 
		
		/********  接收建立包成功 **********/
		D12_AcknowledgeEndpoint(0);													//对控制端点0进行建立包应答
		D12_AcknowledgeEndpoint(1);													//对控制端点1进行建立包应答
		ControlData.wLength = ControlData.DeviceRequest.wLength;					//取出要传输数据的总字节数
		
		if (ControlData.DeviceRequest.bmRequestType & (INT8U)USB_ENDPOINT_DIRECTION_MASK) 
		{
 																					//如果控制传输是控制读取
			 bEPPflags.bits.setup_packet = 1;										//通知control_handler()处理Setup包
			 bEPPflags.bits.control_state = USB_TRANSMIT;	         	   			//设置为发送状态
		}
		else
		{								 											//控制传输是控制写入
			if (ControlData.DeviceRequest.wLength == 0) 
			{
				bEPPflags.bits.setup_packet = 1;			       					//通知control_handler()处理Setup包				  
				bEPPflags.bits.control_state = USB_IDLE;	       					//设置为等待状态
			}
			else 
			{
				if (ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE) 
				{													 				//数据长度出错
					 bEPPflags.bits.control_state = USB_IDLE;	 				//设置为等待状态	
					 D12_SetEndpointStatus(0, 1);								//停止控制端点0
				 	 D12_SetEndpointStatus(1, 1);								//停止控制端点1
				}
				else
					bEPPflags.bits.control_state = USB_RECEIVE;  				//设置为接收状态
			}
		}
	}
	else if (bEPPflags.bits.control_state == USB_RECEIVE) 
	{							//控制写入的数据阶段
		i = D12_ReadEndpoint(0, EP0_PACKET_SIZE,
		ControlData.dataBuffer + ControlData.wCount);
		ControlData.wCount += i;
		if( i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength)
		{  		                                                          	//数据接收完毕
			bEPPflags.bits.setup_packet = 1;									//通知control_handler()处理Setup包				  
			bEPPflags.bits.control_state = USB_IDLE;
		}
	}
	else 
		bEPPflags.bits.control_state = USB_IDLE;
}



void ep0_txdone(void)
{
	INT16 i = ControlData.wLength - ControlData.wCount;								//计算未发送的字节数

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

	if (bEPPflags.bits.control_state != USB_TRANSMIT)
	{																				//非发送状态												
		single_transmit(0, 0);						
		return;
	}
	
	if( i >= EP0_PACKET_SIZE) 
	{																				//未发送字节数大于16,发送16个字节
		D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount);
		ControlData.wCount += EP0_PACKET_SIZE;
		bEPPflags.bits.control_state = USB_TRANSMIT;	
	}
	else if( i != 0) 
	{																//发送所有未发送的字节
		D12_WriteEndpoint(1, i, ControlData.pData + ControlData.wCount);
		ControlData.wCount += i;
		bEPPflags.bits.control_state = USB_IDLE;
	}
	else if (i == 0)
	{
		D12_WriteEndpoint(1, 0, 0);
		bEPPflags.bits.control_state = USB_IDLE;
	}
}

⌨️ 快捷键说明

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