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

📄 usbhost.c

📁 USB Host在嵌入式系统中的实现.包括所有源代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
	STATUS status,sem_status;
	
	/*HOSTPRINTF("read size %d\n",Size);*/
	
    /*Get StillImage device Info*/
    dev=device_info[DEVID_STILL_IMAGE];
    if(!dev.addr)
    	return PTP_USB_ERROR;
    /*Get Endpoint*/
    for(i=0;i<dev.ep_num;i++){
    	ep=(EP_DATA *)dev.ep_list[i];
    	if(ep->pipe_type==PIPE_IN)
    		break;
	}
    //Check ep Valid or Not(if ep list no bulk in ep)
    if(ep->pipe_type!=PIPE_IN)
    	return PTP_USB_ERROR;
	//Set Semaphone for usb_read Function
    sem_status = NU_Obtain_Semaphore(&USBH_READ_Semaphore, NU_SUSPEND);
	ASSERT(sem_status >= 0);

	USBH_BulkIN_FCT(&device_info[DEVID_STILL_IMAGE], ep ,Buf, Size);
//	HOSTPRINTF("USBH read %d start\n",Size);
WaitInDone:
	status = NU_Receive_From_Queue(&USBH_BIN_Queue, &RDMsg, 4, &actual_size, NU_SUSPEND);
//	HOSTPRINTF("usb r QueueData\n");
	ASSERT(status==NU_SUCCESS);

	
	if(RDMsg.process==USBH_RESET){
		HOSTPRINTF("USBH RESET\n");
		ret= PTP_USB_GONE;
	}
	else if(RDMsg.TID!=(BULK_TRANSACTION|PROCESS_IN))
		goto WaitInDone;
		
	if(RDMsg.process==USBH_DONE){
//		HOSTPRINTF("read Done\n");
		*retCount=ep->curr_count;
		ret= PTP_USB_OK;
	}
	else if(RDMsg.process==USBH_STALL){
		HOSTPRINTF("USBH STALL\n");
		ret= PTP_USB_D_CANCEL;
	}
	else{
		HOSTPRINTF("Bulk IN Transaction NAK Timeout\n");
		HOSTPRINTF("USBH Read Fail, istate 0x%x, err 0x%x, regstate 0x%x\n",RDMsg.istate,RDMsg.error,RDMsg.regstate);
		while(1);
		ret= PTP_USB_ERROR;
	}
	
	sem_status = NU_Release_Semaphore(&USBH_READ_Semaphore);
	ASSERT(sem_status >= 0);
	/*HOSTPRINTF("read actual size %d\n",*retCount);*/
	return ret;
}


PTPIO_RETN PTP_USB_Write(Uint32 UniqueDeviceID,Uint8 *Buf,Uint32 Size)
{
	Uint8 i;
	Sint32 ret;
    EP_DATA *ep;
	DEV_INFO dev;
	MSG_Q WRMsg;
	STATUS status,sem_status;
	Uint32 actual_size;

	/*HOSTPRINTF("write size %d\n",Size);*/
		
	/*Semaphone for Protect PTP_USB_Write*/
    sem_status = NU_Obtain_Semaphore(&USBH_WRITE_Semaphore, NU_SUSPEND);
	ASSERT(sem_status >= 0);

    /*Get StillImage device Info*/
    dev=device_info[DEVID_STILL_IMAGE];
    if(!dev.addr)
    	return PTP_USB_ERROR;
    /*Get Endpoint*/
    for(i=0;i<dev.ep_num;i++){
    	ep=(EP_DATA *)dev.ep_list[i];
    	if(ep->pipe_type==PIPE_OUT)
    		break;
	}

	USBH_BulkOUT_FCT(&device_info[DEVID_STILL_IMAGE], ep ,Buf, Size);
//	HOSTPRINTF("USBH Write %d start\n",Size);
	
WaitOutDone:
	status = NU_Receive_From_Queue(&USBH_BOUT_Queue, &WRMsg, 4, &actual_size, NU_SUSPEND);
//	HOSTPRINTF("usb w QueueData\n");
	ASSERT(status==NU_SUCCESS);

	if(WRMsg.process==USBH_RESET){
		ret= PTP_USB_GONE;
	}
	else if(WRMsg.TID!=(BULK_TRANSACTION|PROCESS_OUT))
		goto WaitOutDone;
	else if(WRMsg.process==USBH_DONE){
//		HOSTPRINTF("write done\n");
		ret= PTP_USB_OK;
	}
	else if(WRMsg.process==USBH_STALL){
		ret= PTP_USB_D_CANCEL;
	}
	else{
		HOSTPRINTF("process Code %d\n",WRMsg.process);
		HOSTPRINTF("Transecation ID 0x%x\n",WRMsg.TID);
		HOSTPRINTF("USBH Write Fail, istate 0x%x, err 0x%x, regstate 0x%x\n",WRMsg.istate,WRMsg.error,WRMsg.regstate);
		ASSERT(0);
		while(1);
		ret= PTP_USB_ERROR;
	}
	sem_status = NU_Release_Semaphore(&USBH_WRITE_Semaphore);
	ASSERT(sem_status >= 0);
	
	return ret;
}


PTPIO_RETN PTP_USB_ReadInterrupt(Uint32 UniqueDeviceID, Uint8 *Buf, Uint32 Size, Uint32 *retCount)
{
	Uint8 i;
	Sint32 ret;
    EP_DATA *ep;
	DEV_INFO dev;
	MSG_Q IIMsg;
	Uint32 actual_size;
	STATUS status,sem_status;
	
	//Set Semaphone for usb_read Function
    sem_status = NU_Obtain_Semaphore(&USBH_INT_Semaphore, NU_SUSPEND);
    ASSERT(sem_status >= 0);
    
    //Get StillImage device Info
    dev=device_info[DEVID_STILL_IMAGE];
    if(!dev.addr)
    	return PTP_USB_ERROR;
    //Get Endpoint
    for(i=0;i<dev.ep_num;i++){
    	ep=(EP_DATA *)dev.ep_list[i];
    	if(ep->pipe_type==PIPE_INT)
    		break;
	}
	USBH_INTIN_FCT(&device_info[DEVID_STILL_IMAGE], ep ,Buf, Size);
//	HOSTPRINTF("USBH INT start\n");
	
WaitINTDone:
	status = NU_Receive_From_Queue(&USBH_INTIN_Queue, &IIMsg, 4, &actual_size, NU_SUSPEND);
	ASSERT(status==NU_SUCCESS);
	
		
	if(IIMsg.process==USBH_RESET){
		ret= PTP_USB_GONE;
	}
	else if(IIMsg.TID!=(INT_TRANSACTION|PROCESS_IN))
		goto WaitINTDone;
		
	else if(IIMsg.process==USBH_DONE){
		ret= PTP_USB_OK;
		*retCount=ep->curr_count;
//		HOSTPRINTF("INT Done\n");
	}
	else if(IIMsg.process==USBH_STALL){
		ret= PTP_USB_D_CANCEL;
	}
	else if(IIMsg.process==USBH_INTNAK){
		ret= PTP_USB_NAK;
	}
	else{
		HOSTPRINTF("process Code %d\n",IIMsg.process);
		HOSTPRINTF("Transecation ID 0x%x\n",IIMsg.TID);
		HOSTPRINTF("USBH Int In Fail, istate 0x%x, err 0x%x, regstate 0x%x\n",IIMsg.istate,IIMsg.error,IIMsg.regstate);
		ret= PTP_USB_ERROR;
	}
	sem_status = NU_Release_Semaphore(&USBH_INT_Semaphore);
	ASSERT(sem_status >= 0);
	
	return ret;
}

Sint16 Control_Setup_TD(Uint8 *setup)
{
	STATUS		status;
	Uint32		actual_size;
	TRANSACTION_STRUCT *CurrTD;
	MSG_Q		CtrlMsg;
	
	/*Default Pipe Data Init*/
	Ctrl_ep->DATAx 		= 0;
	Ctrl_ep->NAKcount	= 0;
	Ctrl_ep->curr_count	= 0;
	Ctrl_ep->type 		= ENDPT_CNTL_0;
	Ctrl_ep->pid_ep 	= VUSB_TOKEN_SETUP;
	
	CurrTD=(TRANSACTION_STRUCT*)calloc(sizeof(TRANSACTION_STRUCT),1);
	
	/*Init IO Buffer,Length*/
	CurrTD->state=CTRL_TRANSACTION|CNTRL_SETUP;
	CurrTD->QH=(Uint32*)&CONTROL_QH;
	CurrTD->curr_EP=Ctrl_ep;
	CurrTD->io_bf=setup;
	CurrTD->length=8;
		
	/*BDT Setting*/
	CurrTD->bdt_PID		=	BDT_PID_OWN | Ctrl_ep->DATAx;
	CurrTD->bdt_BC		=	8;
	IObf_2_BDT(CurrTD,CurrTD->io_bf);//BDT IO Buffer Address Setting
	
	/*USB HOST Control Register Setting*/
	CurrTD->ADDR		=	usb_host.USB_addr;
	CurrTD->EP0CTL		=	Ctrl_ep->type;
	CurrTD->TOKEN		=	Ctrl_ep->pid_ep;
  
    TD_add2QH(&CONTROL_QH,CurrTD);
    
WaitControlSetupMessage:
	status = NU_Receive_From_Queue(&USBH_CTRL_Queue, &CtrlMsg, 4, &actual_size, NU_SUSPEND);
	
	if(CtrlMsg.process==USBH_DONE){
		if(CtrlMsg.TID!=(CTRL_TRANSACTION|CNTRL_SETUP))
			goto WaitControlSetupMessage;
		return USBH_DONE;
	}    
	return CtrlMsg.process;
}

Sint16 Control_IN_TD(Uint8 *in_bf, Uint32 in_len)
{
	STATUS		status;
	MSG_Q	CtrlMsg;
	Uint32		actual_size;
	TRANSACTION_STRUCT *CurrTD;
	
	Ctrl_ep->DATAx		= 0;	//Init for Control IN
	Ctrl_ep->curr_count	= 0;
	Ctrl_ep->NAKcount	= 0;
	Ctrl_ep->type		= ENDPT_CNTL_0;
	Ctrl_ep->pksize		= FS_CTRL_PKCT_SIZE;
	Ctrl_ep->pid_ep		= VUSB_TOKEN_IN;
	Ctrl_ep->io_bf		= in_bf;
	  
	CurrTD=(TRANSACTION_STRUCT*)calloc(sizeof(TRANSACTION_STRUCT),1);

	//Send SetupToken
	CurrTD->state	= CTRL_TRANSACTION|PROCESS_IN;
	CurrTD->QH		= (Uint32*)&CONTROL_QH;
	CurrTD->curr_EP = Ctrl_ep;
	CurrTD->io_bf	= Ctrl_ep->io_bf;
	CurrTD->length	= in_len;
		
	/*BDT Setting*/
	CurrTD->bdt_PID	= BDT_PID_OWN | Ctrl_ep->DATAx;
	CurrTD->bdt_BC	= Ctrl_ep->pksize;
	IObf_2_BDT(CurrTD,CurrTD->io_bf);	//Data Buffer Address Setting
	
	/*USB HOST Control Register Setting*/
	CurrTD->ADDR		=	usb_host.USB_addr;
	CurrTD->EP0CTL		=	Ctrl_ep->type;
	CurrTD->TOKEN		=	Ctrl_ep->pid_ep;

    TD_add2QH(&CONTROL_QH,CurrTD);
    
WaitProcessINMessage:
	status = NU_Receive_From_Queue(&USBH_CTRL_Queue, &CtrlMsg, 4, &actual_size, NU_SUSPEND);		
	if(CtrlMsg.process==USBH_DONE){
		if(CtrlMsg.TID!=(CTRL_TRANSACTION|PROCESS_IN))
			goto WaitProcessINMessage;
		return USBH_DONE;
	}
	return CtrlMsg.process;
}
Sint16 Control_Last_TD(void)
{
	STATUS		status;
	MSG_Q	CtrlMsg;
	Uint32		actual_size;
	TRANSACTION_STRUCT *CurrTD;

	Ctrl_ep->curr_count = 0;
	Ctrl_ep->NAKcount	= 0;
	Ctrl_ep->type 		= ENDPT_CNTL_0;
	Ctrl_ep->pksize		= FS_CTRL_PKCT_SIZE;
	Ctrl_ep->pid_ep 	= VUSB_TOKEN_OUT;
	  
	//Create Transfer
	CurrTD=(TRANSACTION_STRUCT*)calloc(sizeof(TRANSACTION_STRUCT),1);
  	
	//Send SetupToken
	CurrTD->state=CTRL_TRANSACTION|CNTRL_LAST;
	CurrTD->QH=(Uint32*)&CONTROL_QH;
	CurrTD->curr_EP=Ctrl_ep;
		
	//5.EP Transfer Setting
	CurrTD->bdt_PID		=	BDT_PID_OWN | BDT_PID_DATA01;
	CurrTD->bdt_BC		=	0;	
	CurrTD->BUFBASEH	=	0;
	CurrTD->BUFBASEL	=	0;
	CurrTD->bdt_ADDRH	=	0;	
	CurrTD->bdt_ADDRL	=	0;
	
	//USB HOST Control Register Setting
	CurrTD->ADDR		=	usb_host.USB_addr;
	CurrTD->EP0CTL		=	Ctrl_ep->type;
	CurrTD->TOKEN		=	Ctrl_ep->pid_ep;

    TD_add2QH(&CONTROL_QH,CurrTD);

WaitControlLastMessage:
	status = NU_Receive_From_Queue(&USBH_CTRL_Queue, &CtrlMsg, 4, &actual_size, NU_SUSPEND);
	if(CtrlMsg.process==USBH_DONE){
		if(CtrlMsg.TID!=(CTRL_TRANSACTION|CNTRL_LAST))
			goto WaitControlLastMessage;
		return USBH_DONE;
	}
	
	return CtrlMsg.process;
}

Sint16 USB_device_request(Uint8 *setup)
{
  	Sint16 ret;
  	Uint32 setup_length;
  	
  	ret=Control_Setup_TD(setup);
	if(ret!=USBH_DONE){
		HOSTPRINTF("Control Setup Fail %d\n",ret);
		return -1;
	}
	/* Lengths are under our control; must never exceed 0x3ff */
	setup_length = ((Uint32)setup[wLength_high] << 8) | setup[wLength_low];
	ret=Control_IN_TD(dev_request_buffer,setup_length);
	if(ret!=USBH_DONE){
		HOSTPRINTF("Control IN Fail %d\n",ret);
		return -1;
	}
	/*If Length=0 Don't Do BulkOut Transaction*/
	if(setup_length==0){
		return 0;
	}
	ret=Control_Last_TD();
	if(ret!=USBH_DONE){
		HOSTPRINTF("Control LAST Fail %d\n",ret);
		return -1;
	}

	return 0;
}

static int USB_GetString(Uint8 index, Uint16 lang_id)
{
    int i, length,rstatus;
    Uint8 setup[8];


    setup[bmRequestType] = DEVICE_TO_HOST;
    setup[bRequest]      = GET_DESCRIPTOR;
    setup[wValue_low]    = index;
    setup[wValue_high]   = STRING_TYPE;
    setup[wIndex_low]    = lang_id & 255;
    setup[wIndex_high]   = lang_id >> 8;
    setup[wLength_low]   = 255;
    setup[wLength_high]  = 0;

	for (i = 0; i < 10 ; i++) {
		/* If power is off (or printer powering down) return immediately */
		rstatus=USB_device_request(setup);
		if(!rstatus)
			break;
    	HOSTPRINTF("STRING INDEX %d FAILED %d\n", index, i);
	}
	if(rstatus)
		return 0;
	
	if (dev_request_buffer[BLENGTH] > 3    &&
	    dev_request_buffer[BDESCRIPTORTYPE] == STRING_TYPE){
	    length = dev_request_buffer[BLENGTH];
	    return length;
	}
    return 0;
}


static void USB_PrintString(Uint8 index, Uint16 lang_id)
{
    int length, i;

    length = USB_GetString(index, lang_id);
    HOSTPRINTF("'");
    for (i = 2; i < length; i += 2) {
        HOSTPRINTF("%c", dev_request_buffer[i]);
    }
    HOSTPRINTF("'\n");
}

static int USB_GetDescriptor(Uint8 type, Uint8 index, void *desc, Uint16 length)
{
	int i, rstatus;
	Uint8 len;
  	Uint32 setup_length;

	HOSTPRINTF("Get Descriptor\n");

	Setup[bmRequestType] = DEVICE_TO_HOST;
	Setup[bRequest]      = GET_DESCRIPTOR;
	Setup[wValue_low]    = index;
	Setup[wValue_high]   = type;
	Setup[wIndex_low]    = 0;
	Setup[wIndex_high]   = 0;
	Setup[wLength_low]   = length & 255;
	Setup[wLength_high]  = length / 256;
	
	for (i = 1; i <= 10 ; i++) {
		/* If power is off (or printer powering down) return immediately */
		rstatus=USB_device_request(Setup);
		if(!rstatus)
			break;
    	HOSTPRINTF("USB_GetDescriptor retry %d\n", i);
	}
	if(rstatus){
		HOSTPRINTF("DEVICE DESC Get FAILED\n");
    	return 0;
    }
	
    if(dev_request_buffer[BDESCRIPTORTYPE] == type){
			memcpy((Uint8 *)desc,dev_request_buffer, length);
            return length;

⌨️ 快捷键说明

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