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

📄 ch375_host_int_para.c

📁 MCS51和ch375b做USB主机同普通键盘的通信
💻 C
📖 第 1 页 / 共 2 页
字号:
	issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
	if(status==USB_INT_SUCCESS)/* SETUP阶段操作成功 */
	{	toggle_send();
		Request.Req_buf[0]=0x01;
		wr_usb_data(1,Request.Req_buf);
		issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
		if(status==USB_INT_SUCCESS) /* DATA阶段操作成功 */
		{	endp6_mode=0xc0;
			toggle_recv();
			issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
			if(status==USB_INT_SUCCESS)/* 状态阶段操作成功 */
			{	if(rd_usb_data(data_buf)!=0)
				return(0);
			}
			else return(0);
		}
		else return(0);
	}	
	else return(0);
	
	
	return(1);
}
unsigned char get_descr_ex()
{	unsigned char descr_len;
	unsigned char *p=data_buf;
	endp7_mode=0x80;
	toggle_send();
	wr_usb_data(8,Request.Req_buf);
	issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
	if(status==USB_INT_SUCCESS)/* SETUP阶段操作成功 */
	{	endp6_mode=0xc0;
		toggle_recv();
	}
	else return(0);
	issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
	if(status==USB_INT_SUCCESS)/* DATA阶段操作成功 */
	{	if(flag_config_2)descr_len=data_buf[2]-rd_usb_data(data_buf);
		else descr_len=data_buf[0]-rd_usb_data(data_buf);	
		while(descr_len>0)
		{	toggle_recv();
			p+=0x08;
			issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
			if(status==USB_INT_SUCCESS)	/* DATA阶段操作成功 */
				descr_len-=rd_usb_data(p);	
			else return(0);
			
		}
	}
	else return(0);
	endp7_mode=0xc0;
	toggle_send();
	wr_usb_data(0,Request.Req_buf);
	issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
	if(status==USB_INT_SUCCESS)/* 状态阶段操作成功 */
		return(1);	
	else return(0);
}
unsigned char get_report_descr_ex()		
{	unsigned char descr_len;
	unsigned char *p=data_buf;
	unsigned char report_cou_temp=0;
	report_cou=0;
	endp7_mode=0x80;					
	toggle_send();						
	wr_usb_data(8,Request.Req_buf);		
	issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();	
	if(status==USB_INT_SUCCESS)/* SETUP阶段操作成功 */
	{	endp6_mode=0xc0;	
		toggle_recv();
	}
	else return(0);
	issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
	if(status==USB_INT_SUCCESS)/* DATA阶段操作成功 */
	{	rd_usb_data(data_buf);
		report_cou+=8;	
		descr_len=Request.Req_buf[6]-0x08;/*剩余描述符长度计算*/
		while(descr_len>0)
		{	toggle_recv();
			p+=0x08;
			issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
			if(status==USB_INT_SUCCESS)	/* DATA阶段操作成功 */
			{	report_cou_temp=rd_usb_data(p);
				if(report_cou_temp!=0x08){report_cou+=report_cou_temp;break;}
				else {descr_len-=0x08;report_cou+=8;}
			}
			else return(0);
			
		}
	}
	else return(0);
	endp7_mode=0xc0;
	toggle_send();
	wr_usb_data(0,Request.Req_buf);
	issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
	if(status==USB_INT_SUCCESS)/* 状态阶段操作成功 */
		return(1);	
	else return(0);
}
void get_int_in()
{	endp6_mode=0x80;
	toggle_recv();
	issue_token(( endp_int << 4 ) | DEF_USB_PID_IN);//status=wait_interrupt();
}
void reset_device()
{	
/* USB规范中未要求在USB设备插入后必须复位该设备,但是计算机的WINDOWS总是这样做,所以有些USB设备也要求在插入后必须先复位才能工作 */
	set_usb_mode( 7 );  /* 复位USB设备,CH375向USB信号线的D+和D-输出低电平 */
	delayms(10);
	set_usb_mode( 6 );  /* 结束复位 */
	while ( wait_interrupt()!=USB_INT_CONNECT );  /* 等待复位之后的设备端再次连接上来 */

}
unsigned char get_descr( unsigned char type ) {  /* 从设备端获取描述符 */
	status=0xff;
	CH375_WR_CMD_PORT( CMD_GET_DESCR );
	CH375_WR_DAT_PORT( type );  /* 描述符类型, 只支持1(设备)或者2(配置) */
	status=wait_interrupt();  /* 等待CH375操作完成 */
	if ( status==USB_INT_SUCCESS ) {  /* 操作成功 */
		unsigned char i, len;
		len=rd_usb_data( data_buf );
		printf( "%s描述符是:", type==1?"设备":"配置" );
		for ( i=0; i!=len; i++ ) printf( "%02x ", (unsigned int)data_buf[i] );
		printf( "\n" );
	}
	return( status );
}
unsigned char set_addr( unsigned char addr ) {  /* 设置设备端的USB地址 */
	unsigned char status;
	CH375_WR_CMD_PORT( CMD_SET_ADDRESS );  /* 设置USB设备端的USB地址 */
	CH375_WR_DAT_PORT( addr );  /* 地址, 从1到127之间的任意值, 常用2到20 */
	status=wait_interrupt();  /* 等待CH375操作完成 */
	if ( status==USB_INT_SUCCESS ) {  /* 操作成功 */
		CH375_WR_CMD_PORT( CMD_SET_USB_ADDR );  /* 设置USB主机端的USB地址 */
		CH375_WR_DAT_PORT( addr );  /* 当目标USB设备的地址成功修改后,应该同步修改主机端的USB地址 */
	}
	return( status );
}
unsigned char set_config( unsigned char cfg ) {  /* 设置设备端的USB配置 */
	CH375_WR_CMD_PORT( CMD_SET_CONFIG );  /* 设置USB设备端的配置值 */
	CH375_WR_DAT_PORT( cfg );  /* 此值取自USB设备的配置描述符中 */
	return( wait_interrupt() );  /* 等待CH375操作完成 */
}
void parse_config_descr()
{	unsigned char i;
	num_interfaces=data_buf[4];		//保存接口数
	config_value=data_buf[5];		//保存配置值
	for(i=0;i!=data_buf[2];i++)
	{	if((data_buf[i]==0x09)&&(data_buf[i+1]==0x04))//接口描述符
		{	}
		if((data_buf[i]==0x09)&&(data_buf[i+1]==0x21))//HID描述符
		{	report_descr_len=data_buf[i+7];}			//REPORT描述符长度
		if((data_buf[i]==0x07)&&(data_buf[i+1]==0x05))//端点描述符
		{	endp_int=data_buf[i+2]&0x0f;}				//中断端点号
	}	
}
void main() {
	unsigned char i;
	mInitSTDIO( );
	delayms(250);
	set_usb_mode( 6 );  /* 设置USB主机模式, 如果设备端是CH37X, 那么5和6均可 */
#ifdef	TEST_LOW_SPEED
	set_freq( );	       //使375B进入低速模式
#endif
	while(1)
	{	while ( wait_interrupt()!=USB_INT_CONNECT );  /* 等待设备端连接上来 */
		delayms(5);
		reset_device();
		delayms(5);
        set_freq( );       //使375B进入低速模式

//	get_descr(0x01);//获取设备描述符
//	printf("device\n");
	Request.Req.bmRequestType=0x80;
	Request.Req.bRequest=0x06;
	Request.Req.wValue=0x0001;
	Request.Req.wIndex=0x0000;
	Request.Req.wLength=0x1200;
	if(get_descr_ex()==1)
	{	for(i=0;i!=data_buf[0];i++)
			printf("%02x ",(unsigned int)data_buf[i]);	
		printf("\n");
	}
	else printf("get device descr failed\n");
		
	set_addr(5);//设置地址

//	get_descr(0x02);//获取配置描述符
	printf("config\n");
	Request.Req.bmRequestType=0x80;
	Request.Req.bRequest=0x06;
	Request.Req.wValue=0x0002;
	Request.Req.wIndex=0x0000;
	Request.Req.wLength=0x0900;
	if(get_descr_ex()==1)
	{	for(i=0;i!=data_buf[0];i++)
			printf("%02x ",(unsigned int)data_buf[i]);	
		printf("\n");
        if(data_buf[4]!=0x01)flag_interface_2=1;//有多个接口
	}
	else printf("get config descr failed\n");
		
	printf("config 2\n");
	if(data_buf[2]>0x09)
	{	flag_config_2=1;
		Request.Req.bmRequestType=0x80;
		Request.Req.bRequest=0x06;
		Request.Req.wValue=0x0002;
		Request.Req.wIndex=0x0000;
		Request.Req.wLength=0x0000|((unsigned int)data_buf[2]<<8);
		if(get_descr_ex()==1)
		{	for(i=0;i!=data_buf[2];i++)
				printf("%02x ",(unsigned int)data_buf[i]);	
			printf("\n");
			flag_config_2=0;
		}	
		else printf("get device descr again failed\n");
	}

	parse_config_descr();//保存描述符中一些值

	set_config(config_value);//设置配置
//	printf("set config\n");
//	if(set_config_ex()!=1)printf("set config failed\n");
	
	printf("set idle\n");
	if(set_idle()!=1)printf("set idle failed\n");
	
	printf("report\n");
	Request.Req.bmRequestType=0x81;
	Request.Req.bRequest=0x06;
	Request.Req.wValue=0x0022;
	Request.Req.wIndex=0x0000;
	Request.Req.wLength=0x0000|((unsigned int)(report_descr_len+0x40)<<8);
	if(get_report_descr_ex()==1)
	{	for(i=0;i!=report_cou;i++)
			printf("%02x ",(unsigned int)data_buf[i]);	
		printf("\n");
	}
	else printf("get report descr failed\n");
	
	printf("set report\n");		//对于键盘这一步,是点亮指示灯
	if(set_report()!=1)printf("set report failed\n");
	
	delayms(250);
	EA=1;			//打开中断,从中断端点接收数据
	get_int_in();	//发送从中断端点读数据的令牌
	do{	
		if(flag_output==1)
		{	for(i=0;i!=8;i++)printf("%02x ",(unsigned int)data_in[i]);
			printf("\n");
			flag_output=0;
		}
	}while(1);
	while ( wait_interrupt()!=USB_INT_DISCONNECT );  /* 等待设备端连接上来 */
}
}

⌨️ 快捷键说明

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