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

📄 d12.c

📁 一个是混合鼠标键盘功能的HID设备使用d12
💻 C
📖 第 1 页 / 共 3 页
字号:
	D12_DAT = bLenth;
	
	for(i=0; i<bLenth; i++)
	{
		D12_DAT = *(buff+i);
	}
	D12_CMD = 0xfa;//使缓冲区有效
	return bLenth;
}
//*********
//普通命令
//*********
//发送恢复
void D12_resend_enable(void)
{
	D12_CMD = 0xf6;
}
//读取当前帧数目
uint16 D12_read_current_frame_cnt(uint8 *frame_cnt)
{
	uint16 i,j;
	D12_CMD = 0xf5;
    i = D12_DAT;
    j = D12_DAT;
    i += (j<<8);
    return i;
}
//****************************
//由以上命令扩展出来的扩展命令
//****************************
uint8 Endpoint2_full_flag;
//从端点读数据
uint16 D12_read_Endpoint(uint8 bEndpoint,uint8 bLenth,uint8 *buf)
{
	uint8 temp;
	temp = D12_Endpoint_select(bEndpoint);                                               //选择端点
	if((temp&0x01)==0)
		return 0;
		
    temp = D12_read_Endpoint_status(bEndpoint);
    temp &=0x60;
    if(bEndpoint == 4)
    {
    	if(temp == 0x60)                                                          //端点2的缓冲区满
    	   Endpoint2_full_flag = 1;
    	else
    	   Endpoint2_full_flag = 0;
    }
    return (D12_read_buff(buf,bLenth));                            //从缓冲区读出长度为bLenth的数据 
} 
//向端点写数据
uint16 D12_write_Endpoint(uint8 bEndpoint,uint8 bLenth,const uint8 *buf)
{

	D12_Endpoint_select(bEndpoint);                                                      //选择端点
		
	return (D12_write_buff(buf,bLenth));                             //向缓冲区写长度为bLenth的数据
}
//端点应答处理
void D12_ack_Endpoint(uint8 bEndpoint)
{
	D12_CMD = bEndpoint;
	D12_CMD = 0xf1;                                                                     //SETUP应答
	if(bEndpoint==0)                                                                  //假如为端点0
		D12_CMD = 0xf2;                                                                //清空缓冲区
}
//*************************************************************************************************
//断开连接
void USB_disconnect(void)
{
//	D12_set_mode(0x0e,0x47);                                                             //断开连接
	D12_set_mode(0x00,0x00);                                                             //断开连接
}
//联上连接
void USB_connect(void)
{
//	D12_set_mode(0x1e,0x47);
	D12_set_mode(0x10,0x00);
}
//重新连接
void USB_reconnect(void)
{
	D12_set_mode(0x00,0x00);
	DelayNS(10);
	D12_set_mode(0x10,0x00);
}
//USB初始化
void USB_init(void)
{
	D12_set_addr_en(0,0x01);
	D12_set_endpoint_en(0x01);                                                          //使能端点0
}
//*************************************************************************************************
//标准设备请求调用到的子程序
//*************************************************************************************************
//停止端点0
void stall_ep0(void)
{
	D12_set_Endpoint_status(0, 1);
	D12_set_Endpoint_status(1, 1);
}
//保留子程序
void reserved(void)
{
	stall_ep0();
}
//进入地址状态,禁止0除外的所有端点
void init_unconfig(void)
{
	D12_set_endpoint_en(0);
}
//配置处理,允许端点收发
void init_config(void)
{
	D12_set_endpoint_en(1);
}
//通过端点索引1发送数据(DATA类型)
void single_transmit(uint8 *buf,uint8 len)
{
	if(len <= EP0_PACKET_SIZE)
		D12_write_Endpoint(1,len,buf);
}
//通过端点索引1发送数据(CODE类型)
void code_transmit(uint8  *pRomData,uint16 len)
{
	control_data.wCount = 0;
	if(control_data.wLength>len)
		control_data.wLength = len;
	control_data.pData = pRomData;
	if(control_data.wLength>=EP0_PACKET_SIZE)
	{
		D12_write_Endpoint(1,EP0_PACKET_SIZE,control_data.pData);
		control_data.wCount += EP0_PACKET_SIZE;
		DISABLE();
		event_flag.bits.control_state = USB_TRANSMIT;
		ENABLE();
	}
	else
	{
		D12_write_Endpoint(1,control_data.wLength,pRomData);
		control_data.wCount +=control_data.wLength;
		DISABLE();
		event_flag.bits.control_state = USB_IDLE;
		ENABLE();
	}
}
//*****************************************************************************
//11个标准请求子程序
//*****************************************************************************
//获取状态请求
void get_status(void)
{
	
	uint8 endp,txdat[2], c;
	uint8 bRecipient = control_data.DeviceRequest.bmRequestType & USB_RECIPIENT;
	
	UART0_SendStr((uint8*)"get_status\n",14);	
																                 //取得设备请求类型	
	if (bRecipient == USB_RECIPIENT_DEVICE) 					                       //对设备请求
	{
		if(event_flag.bits.remote_wakeup == 1)			
			txdat[0] = 3;										             //支持远程唤醒、自供电
		else
			txdat[0] = 1;										           //不支持远程唤醒、自供电
		txdat[1]=0;												                         //高8位为0
		single_transmit(txdat, 2);								             //发送16位的状态到主机
	} 
	else 
	if (bRecipient == USB_RECIPIENT_INTERFACE)                                         //对接口请求
	{			
		txdat[0]=0;
		txdat[1]=0;
		single_transmit(txdat, 2);							                 //发送16位的状态到主机							
	} 
	else 
	if (bRecipient == USB_RECIPIENT_ENDPOINT)                                          //对端点请求
	{			
		endp = (uint8)(control_data.DeviceRequest.wIndex & MAX_ENDPOINTS);    //真正的原因不在这...
		if (control_data.DeviceRequest.wIndex & (int8)USB_ENDPOINT_DIRECTION_MASK)
			c = D12_Endpoint_select(endp*2 + 1);					             //读取输入端点状态
		else
			c = D12_Endpoint_select(endp*2);						             //读取输出端点状态
		if(c & D12_STALL)
			txdat[0] = 1;										                         //端点禁止
		else
			txdat[0] = 0;										                         //端点有效
		txdat[1] = 0;
		single_transmit(txdat, 2);								             //发送16位的状态到主机

	} else
		stall_ep0();					                                       //非标准请求,发STALL
}
//清除特性请求
void clear_feature(void)
{
	uint8 endp;												               //读取请求类型中的接收方
	uint8 bRecipient = control_data.DeviceRequest.bmRequestType & USB_RECIPIENT;
	
	UART0_SendStr((uint8*)"clear_feature\n",15);
															                         //读取请求类型
	if ((bRecipient == USB_RECIPIENT_DEVICE)					                       //对设备请求
		&& (control_data.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)) 
	{
		DISABLE();								                                 //清除远程唤醒特性	
		event_flag.bits.remote_wakeup = 0;					                      //清0远程唤醒标志
		ENABLE();
		single_transmit(0, 0);								         //返回一个空的数据表示执行完毕
	}
	
	else 
	if ((bRecipient == USB_RECIPIENT_ENDPOINT)			                               //对端点请求
		&& (control_data.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)) 
	{
		                                                              //清除端点禁止特性,恢复其使用
		endp = (uint8)(control_data.DeviceRequest.wIndex & MAX_ENDPOINTS);
		
		if (control_data.DeviceRequest.wIndex & (uint8)USB_ENDPOINT_DIRECTION_MASK)
			D12_set_Endpoint_status(endp*2 + 1, 0);			            //清除控制输入端点STALL特性
		else
			D12_set_Endpoint_status(endp*2, 0);				            //清除控制输出端点STALL特性
		single_transmit(0, 0);								         //返回一个空的数据表示执行完毕
	} 
	else
		stall_ep0();					                                     //没有该请求,返回STALL	
}
//设置特性请求
void set_feature(void)
{
	uint8 endp;											                   //读取请求类型中的接收方
	uint8 bRecipient = control_data.DeviceRequest.bmRequestType & USB_RECIPIENT;
	
	UART0_SendStr((uint8*)"set_feature\n",14);
														                             //读取请求类型
	if ((bRecipient == USB_RECIPIENT_DEVICE)		                                   //对设备请求
		&& (control_data.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)) 
	{
														                         //设置远程唤醒特性
		DISABLE();
		event_flag.bits.remote_wakeup = 1;				                          //置1远程唤醒标志
		ENABLE();
		single_transmit(0, 0);							             //返回一个空的数据表示执行完毕
	}	
	else 
	if (bRecipient == USB_RECIPIENT_ENDPOINT		                                   //对端点请求
		&& control_data.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) 
	{
		                                                                                 //禁止端点
		endp = (uint8)(control_data.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (control_data.DeviceRequest.wIndex & (uint8)USB_ENDPOINT_DIRECTION_MASK)
			D12_set_Endpoint_status(endp*2 + 1, 1);		                         //设置输入端点禁止
		else
			D12_set_Endpoint_status(endp*2, 1);			                         //设置输出端点禁止
		single_transmit(0, 0);							             //返回一个空的数据表示执行完毕
	} else
		stall_ep0();					                                      //没有该请求,返回STAL
}
//设置地址请求
void set_address(void)
{
	UART0_SendStr((uint8*)"set_address\n",13);
	D12_set_addr_en((uint8)(control_data.DeviceRequest.wValue &
						 DEVICE_ADDRESS_MASK), 1);
	single_transmit(0, 0);				                                       //发送一个空的数据响
	
}
//获取描述符请求
void get_descriptor(void)
{
	uint8 temp;
	uint8 bDescriptor = MSB(control_data.DeviceRequest.wValue);			     //读取请求的描述符类型
	
	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)						           //获取设备描述符 
	{						
		code_transmit((uint8 *)&Device_Descriptor, sizeof(Device_Descriptor));
		UART0_SendStr((uint8*)"device_type\n",14);
	}
	else 
	if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) 				 //获取配置+接口+端点描述符
	{	         
		if (control_data.DeviceRequest.wLength > CONFIG_DESCRIPTOR_LENGTH)
		{ 
			 control_data.DeviceRequest.wLength = CONFIG_DESCRIPTOR_LENGTH;
		}
		code_transmit((uint8 *)&(Configuration_Descriptor), control_data.DeviceRequest.wLength);
			    														           //发送描述符内容
		UART0_SendStr((uint8*)"config_type\n",14);
	}
	else
	if (bDescriptor == USB_STRING_DESCRIPTOR_TYPE)                           //获取字符串描述符内容
	{
		UART0_SendStr((uint8*)"string_type\n",14);

		temp = LSB(control_data.DeviceRequest.wValue);

		switch(temp)
		{
			
			case 0x00:code_transmit((uint8 *)&(LANGUAGE_ID), LANGUAGE_ID[0]);
					  UART0_SendStr((uint8*)"languag_ID\n",12);
				break;
			case 0x01:code_transmit((uint8 *)&(ManufacturerString), ManufacturerString[0]);
			          UART0_SendStr((uint8*)"ManufactureStr\n",16);
				break;
			case 0x02:code_transmit((uint8 *)&(ProducterString), ProducterString[0]);
			          UART0_SendStr((uint8*)"ProducterStr",14);
				break;
			case 0x03:code_transmit((uint8 *)&(device_serial_number), device_serial_number[0]);
			          UART0_SendStr((uint8*)"device_seri_num",16);
				break;
			default:
				break;
		}		
	} 
	else
	if (bDescriptor == REPORT_DESCRIPTOR)                                      //获取报告描述符内容
	{
		code_transmit((uint8 *)&(KeyBoardReportDescriptor),119);				 //发送鼠标的报告描述符
		UART0_SendStr((uint8*)"report_type\n",14);
	}                       
	else
		stall_ep0();					                                      //没有该请求,返回STAL

}
//获取配置请求
void get_configuration(void)
{
	uint8 c = event_flag.bits.configuration;	                                       //取出配置值
		
	single_transmit(&c, 1);				                                                 //发送配置
	
	//UART0_SendStr((uint8*)"get_configuration",17);
}
//设置配置请求
void set_configuration(void)
{
	
	if (LSB(control_data.DeviceRequest.wValue) == 0) 
	{														        //配置值不对,设备进入未配置状态
		single_transmit(0, 0);								                     //发向一个空包响应
		DISABLE();
		event_flag.bits.configuration = 0;					                           //标记未配置
		ENABLE();
		init_unconfig();									     //进入地址状态,禁止0除外的所有端点

	} 
	else 
	if (LSB(control_data.DeviceRequest.wValue) == 1) 			  
	{														                             //配置设备
		single_transmit(0, 0);								                     //发向一个空包响应
		init_unconfig();									     //进入地址状态,禁止0除外的所有端点
		init_config();										                //配置处理,允许端点收发
		DISABLE();
		event_flag.bits.configuration = 1;					                           //标志已配置
		ENABLE();
		UART0_SendStr((uint8*)"set_configuration\n",19);

	} else
		stall_ep0();						                                  //没有该请求,返回STAL 
}
//获取接口信息请求
void get_interface(void)
{
	uint8 txdat = 0x01;
	single_transmit(&txdat,1);
	UART0_SendStr((uint8*)"get_interface\n",15);
}
//设置接口请求
void set_interface(void)
{
	UART0_SendStr((uint8*)"set_interface\n",15);
	if((control_data.DeviceRequest.wValue == 0 )&&( control_data.DeviceRequest.wIndex == 0))
		single_transmit(0,0);
	else
		stall_ep0();
}
//*************************************************************************************************
//USB标准设备请求子程序入口地址表
//*************************************************************************************************
//USB标准设备请求入口地址指针表
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,
};
//*************************************************************************************************
//类请求子程序
//*************************************************************************************************
uint8 idle;
uint8 protocol;
void get_idle(void)
{
    single_transmit(&idle,1);
}

⌨️ 快捷键说明

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