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

📄 usbhost.c

📁 USB Host在嵌入式系统中的实现.包括所有源代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
	Uint8	SetAddress[8] = {0, 5,  1, 0,  0, 0,  0, 0};
	
    HOSTPRINTF("USBH: Enumeration\n");
    
    status =NU_Reset_Queue(&USBH_CTRL_Queue);
	if(status!=NU_SUCCESS){
		HOSTPRINTF("Enumeration: Control Queue Status Error %d\n",status);
		return FALSE;
	}
    status =NU_Reset_Queue(&USBH_BIN_Queue);
	if(status!=NU_SUCCESS){
		HOSTPRINTF("Enumeration: Bulk In Queue Status Error %d\n",status);
		return FALSE;
	}
    status =NU_Reset_Queue(&USBH_BOUT_Queue);
	if(status!=NU_SUCCESS){
		HOSTPRINTF("Enumeration: Bulk OUT Queue Status Error %d\n",status);
		return FALSE;
	}
    status =NU_Reset_Queue(&USBH_INTIN_Queue);
	if(status!=NU_SUCCESS){
		HOSTPRINTF("Enumeration: INT IN Queue Status Error %d\n",status);
		return FALSE;
	}
	//if TD On Queue Head Removeit
	
	usb_host.DeviceReady = NOT_READY;
	
    *regEP0CTL = ENDPT_DISABLE;	/* Disable ep0 */
    reset_the_device();    		/* Reset the device */
    HOSTPRINTF("Enumeration: Reset the device 1\n");

    *regINT_ENB = INTR_ATTACH;	/* Enable attach interrupt */

    /* Enable host mode but don't start generating SOFs */
    *regCTL = CTRL_HOST_NO_SOF;
    
    HOSTPRINTF("Enumeration: Wait Attach Message\n");
	status = NU_Receive_From_Queue(&USBH_CTRL_Queue, &CtrlMsg, 4, &actual_size, NU_SUSPEND);
	if(status!=NU_SUCCESS){
		HOSTPRINTF("Enumeration: Queue Status Error %d\n",status);
		return FALSE;
	}
    if (CtrlMsg.process != USBH_ATTACH) {
        HOSTPRINTF("Enumeration: FAILED - NOT ATTACHED\n");
        return FALSE;
    }
    /* Reset the device a second time */
    reset_the_device();
    HOSTPRINTF("Enumeration: Reset the device 2\n");
    
    /* Device is now plugged in, enable all errors */
    *regERR_ENB = 0xff;

    /* Delay for the debounce interval */
    TaskSleep(&debounce_delay);
    
    /* Check if low-speed device */
    if ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) == 0) {
        HOSTPRINTF("Enumeration: Unsupport Low Speed Device\n");
        return FALSE;
    }
    /* Check if the device has detached */
    if ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) != CTRL_JSTATE) {
        HOSTPRINTF("process_attached NO DEVICE - ctrl_status %02x\n", *regCTL);
        return FALSE;
    }
    HOSTPRINTF("Enumeration: ATTACHED\n");
    /**************************************************************************/

    /*
     * Set SOF threshold so we are guaranteed to have enough time for
     * any transaction to complete (including ACK or NAK) without reaching
     * the time to send the next Start-of-frame packet.
     */
    *regSOF_THLD = SOF_THRESHOLD;

    /* Enable ep0 configured as CNTRL endpoint */
    *regEP0CTL = ENDPT_CNTL_0;

    /* Enable host mode and start generating SOFs */
    *regCTL = CTRL_HOST_SOF;

    /* Enable the token-done, error, STALL and RESET interrupts (Reset Command)*/
    *regINT_ENB = INTR_TOK_DNE | INTR_ERROR | INTR_STALL | INTR_USB_RST | INTR_SOF_TOK;

    /* Get up to first 18 bytes of the device descriptor */
    length = USB_GetDescriptor(DEVICE_TYPE, 0, &DeviceDesc, sizeof(DEVICE_DESC));
    if (length < 8){
        HOSTPRINTF("Enumeration: Get Device Length Error\n");
        return FALSE;
    }

   /**************************************************************************/

    /* Reset the device */
    reset_the_device();
	HOSTPRINTF("Enumeration: Reset the device 3\n");
    /**************************************************************************/
    /* Validate size and descriptor type of device descriptor */
    Ctrl_ep->pksize = dev_request_buffer[7];
    HOSTPRINTF("Enumeration: Set CNTRL pksize %d\n", Ctrl_ep->pksize);
    if (Ctrl_ep->pksize <  8                     ||
        Ctrl_ep->pksize > 64                     ||
        (Ctrl_ep->pksize & (Ctrl_ep->pksize - 1)) ||  /* must be power of 2 */
        dev_request_buffer[0] != 0x12           ||
        dev_request_buffer[1] != 1              )
    {
        HOSTPRINTF("Enumeration: GetDevDesc BAD\n");
        return FALSE;
    }
    
    /* Enable attach interrupt */
    *regINT_ENB = INTR_ATTACH;
	HOSTPRINTF("Enumeration: Wait Attach Message 2\n");
	status = NU_Receive_From_Queue(&USBH_CTRL_Queue, &CtrlMsg, 4, &actual_size, NU_SUSPEND);
	if(status!=NU_SUCCESS){
		HOSTPRINTF("Enumeration: Queue State Error %d\n",status);
		return FALSE;
	}
	if (CtrlMsg.process != USBH_ATTACH) {
	    HOSTPRINTF("Enumeration: FAILED - NOT ATTACHED\n");
	    return FALSE;
	}
    /* As above (restore after device reset) */
    *regSOF_THLD= SOF_THRESHOLD;
    *regEP0CTL	= ENDPT_CNTL_0;
    *regCTL		= CTRL_HOST_SOF;

    /* Enable the token done, error, stall , RESET and SOF interrupts */
    *regINT_ENB = INTR_TOK_DNE | INTR_ERROR | INTR_STALL | INTR_USB_RST | INTR_SOF_TOK;

    /**************************************************************************/
    /* Set address to USB address 1 */
    HOSTPRINTF("Enumeration: SET ADDRESS, threshold %d\n", *regSOF_THLD);
    if (USB_device_request(SetAddress)){
    	HOSTPRINTF("Enumeration: Set Address Fail\n");
        return FALSE;	
	}
    *regADDR = 1;
    usb_host.USB_addr=1;
    HOSTPRINTF("Enumeration: SET ADDRESS COMPLETE\n");
    return TRUE;
}

static void USB_Host_Task(UNSIGNED argc, VOID *argv)
{
	CHAR task_name[8];
	DATA_ELEMENT task_status;
	UNSIGNED scheduled_count;
	OPTION priority;
	OPTION preempt;
	UNSIGNED time_slice;
	VOID *stack_base;
	UNSIGNED stack_size;
	UNSIGNED minimum_stack;
	
    int i, enumOK;
	static TimeVal delay_enum = {1, 0};
	TRANSACTION_STRUCT *CurrTD;
	UNSIGNED actual_size;
	STATUS status;
	MSG_Q RSTMsg;
	Uint32 message[4];
	
    
    while (1) {
	    enumOK = FALSE;
	    for (i = 0;i < 10; i++) {
	        enumOK = USB_enumerate();
	        if (enumOK)
	            break;
	        HOSTPRINTF("USB_Host_Task: Failed to enumerate; retry %d...\n", i+1);
	        TaskSleep(&delay_enum);
	    }
        if (enumOK) {
            if (USB_GetConfiguration()) {
                if (StillImage.Config) {
                    if (USB_DoConfiguration(&StillImage)) {
                    	usb_host.DeviceReady = PB_READY;
                    	
						HOSTPRINTF("USB_Host_Task: StillImage Configuration Success\n");
						message[0]=StillImage.ep_in_pksize;
                        message[1]=StillImage.ep_out_pksize;
                        message[2]=StillImage.ep_intr_pksize;
                        message[3]=StillImage.ep_intr_pollms;
						//Detect PTP Task
						//Create PTP Task
//						status = NU_Create_Task (&TaskPTPLayerID, 
//                             "PTP Task",
//                             PTP_Layer_Task, 
//                             0, 
//                             &message[0], 
//                             TaskPTPLayer_stack,
//                             USBHTASK_STACKSIZE*4, 
//                             9,/*Proirity*/
//                             10,
//                             NU_PREEMPT, 
//                             NU_START);
//
//						ASSERT(status >= 0); 
                    }
                }
                else if (MassStorage.Config) {
                	if (USB_DoConfiguration(&MassStorage)){
                		usb_host.DeviceReady = MS_READY;
                		HOSTPRINTF("USB_Host_Task: MassStroage Configuration Success\n");
                	}
                }
                else{
                	HOSTPRINTF("USB_Host_Task: Unsupport Device\n");
                	HOSTPRINTF("USB_Host_Task: Please Plug OUT USB Device\n");
                }

            }
            else{
            	HOSTPRINTF("USB_Host_Task: USB GetConfiguration Fail\n");
            	HOSTPRINTF("USB_Host_Task: Please Plug OUT USB Device\n");
            }
WaitResetMessage:
			HOSTPRINTF("USB_Host_Task: Wait Reset\n");
			status = NU_Receive_From_Queue(&USBH_CTRL_Queue, &RSTMsg, 4, &actual_size, NU_SUSPEND);
			if(status!=NU_SUCCESS){
				HOSTPRINTF("USB_Host_Task: Receive Queue Error %d\n",status);
				NU_Sleep(0xFFFFffff);
			}
			if(RSTMsg.process!=USBH_RESET)
				goto WaitResetMessage;
			//Notify Read/Write/Int Read FCT
			RSTMsg.TID	= BULK_TRANSACTION|PROCESS_IN;
			NU_Send_To_Queue(&USBH_BIN_Queue, &RSTMsg, 4, NU_NO_SUSPEND);
			RSTMsg.TID	= BULK_TRANSACTION|PROCESS_OUT;
			NU_Send_To_Queue(&USBH_BOUT_Queue, &RSTMsg, 4, NU_NO_SUSPEND);
			RSTMsg.TID	= INT_TRANSACTION|PROCESS_IN;
			NU_Send_To_Queue(&USBH_INTIN_Queue, &RSTMsg, 4, NU_NO_SUSPEND);
			//Monitor PTP Task
//monitor_task:			
//			status = NU_Task_Information(&TaskPTPLayerID, task_name, 
//											&task_status,
//											&scheduled_count, 
//											&priority, 
//											&preempt,
//											&time_slice, 
//											&stack_base,
//											&stack_size, 
//											&minimum_stack);
//			/*If Task Not Create*/
//			if(status==NU_INVALID_TASK){
//				HOSTPRINTF("USB_Host_Task: PTP Task Not Create\n");
//				continue;
//			}
//			/* If status is NU_SUCCESS, the other information is accurate. */
//			if(status!=NU_SUCCESS){
//				HOSTPRINTF("USB_Host_Task: NU_Task_Information Fail\n");
//				while(1);
//			}
//			
//			if(task_status!=NU_FINISHED)
//				goto monitor_task;
//
////			//Terminate Task
////			status=NU_Terminate_Task(&Task_EVENT_RequestObjectTransfer);
////			if(status!=NU_SUCCESS){
////				HOSTPRINTF("NU_Terminate_Task Fail\n");
////				while(1);
////			}
//			//delete Task
//			status=NU_Delete_Task(&TaskPTPLayerID);
//			if(status!=NU_SUCCESS){
//				HOSTPRINTF("USB_Host_Task: Delete PTP Task Fail\n");
//				while(1);
//			}
//			HOSTPRINTF("USB_Host_Task: Delete PTP Task Success\n");
//													
		}
		else
			HOSTPRINTF("USB_Host_Task: No USB Device Attach Continue Retry\n");
	}
}

void USBHostPrologue(void)
{
    Uint8 i;
	STATUS status;
	
	HOSTPRINTF("USB 1.1 HOST Initiation\n");
    /* Create USB Host synchronization semaphore. */
    status = NU_Create_Semaphore(&USBH_READ_Semaphore, "HOST_RD",1,NU_FIFO);
    ASSERT(status >= 0);
    status = NU_Create_Semaphore(&USBH_WRITE_Semaphore, "HOST_WR",1,NU_FIFO);
    ASSERT(status >= 0);
    status = NU_Create_Semaphore(&USBH_INT_Semaphore, "HOST_INT",1,NU_FIFO);
    ASSERT(status >= 0);
    
	/*Create Queue For USBH HISR to AP FCT*/
	Ctrl_Queue_buff=(Uint32*)malloc((128*4));
	status = NU_Create_Queue(&USBH_CTRL_Queue, "CtrlPipe", Ctrl_Queue_buff, 128,
								NU_FIXED_SIZE, 4, NU_FIFO);
    ASSERT(status >= 0);
	BulkIN_Queue_buff=(Uint32*)malloc((128*4));
	status = NU_Create_Queue(&USBH_BIN_Queue, "IN Pipe", BulkIN_Queue_buff, 128,
								NU_FIXED_SIZE, 4, NU_FIFO);
    ASSERT(status >= 0);
	BulkOUT_Queue_buff=(Uint32*)malloc((128*4));
	status = NU_Create_Queue(&USBH_BOUT_Queue, "OUT Pipe", BulkOUT_Queue_buff, 128,
								NU_FIXED_SIZE, 4, NU_FIFO);
    ASSERT(status >= 0);
	IntIN_Queue_buff=(Uint32*)malloc((128*4));
	status = NU_Create_Queue(&USBH_INTIN_Queue, "INT Pipe", IntIN_Queue_buff, 128,
								NU_FIXED_SIZE, 4, NU_FIFO);
    ASSERT(status >= 0);
    
    usb_host.curr_TD  = NULL;
    usb_host.DeviceReady = FALSE;
    USBHOST_READY_FLAG=&usb_host.DeviceReady;

	Setup=(Uint8 *)calloc(8,1);					/*Control Setup Buffer Create*/
	dev_request_buffer=(Uint8 *)calloc(256,1);	/*Standard Device Request Buffer*/
	
	*regINT_STAT=0;//Init Interrupt Enable
    usbh_hw_init();

    /* Create the USBH task for task-level (vs. ISR) code. */
    status = NU_Create_Task (&TaskUSBH_ID, 
                             "USB Host",
                             USB_Host_Task, 
                             0, 
                             NU_NULL, 
                             TaskUSBH_stack,
                             USBHTASK_STACKSIZE*2, 
                             15,
                             10,
                             NU_PREEMPT, 
                             NU_START);

    ASSERT(status >= 0);
    
	/*Power On Init*/
    /* Zero out BDT ODD ping/pong bits, USB address and frame number */
    *regINT_ENB = 0;
    *regINT_STAT = 0xFF;
    
    *regCTL 	 = CTRL_ODD_RST;
    *regADDR 	 = 0;
    *regFRM_NUML = 0;
    *regFRM_NUMH = 0;

    usb_host.USB_addr	  = 0;
    usb_host.even_odd_OUT = BDT_OUT_BIT;	//Init For Even BTD
    usb_host.even_odd_IN  = BDT_IN_BIT;		//Init for Even BTD
    usb_host.DeviceReady  = NOT_READY;
    /* Enable interrupt */
    *(volatile Uint32 *)EXMSK1A |= (1 << USB1_INTERRUPT_BIT);
}

void usbh_interrupt_enable(void)
{
	*regINT_ENB = INTR_ERROR | INTR_USB_RST| INTR_SOF_TOK;
}

void USBHOST_DEVICEREADY_SET(int status)
{
	usb_host.DeviceReady=status;
}

void USBHOST_EVEN_ODD_IN_SET(void)
{
	usb_host.even_odd_IN ^= BDT_ODD_EVEN_BIT;
}

Boolean USBHOST_EVEN_ODD_IN_GET(void)
{
	return usb_host.even_odd_IN;
}

void USBHOST_EVEN_ODD_OUT_SET(void)
{
	usb_host.even_odd_OUT ^= BDT_ODD_EVEN_BIT;
}

Boolean USBHOST_EVEN_ODD_OUT_GET(void)
{
	return usb_host.even_odd_OUT;
}
void USBHOST_CURR_QH_SET(HOST_QUEUE_HEAD *QH)
{
	usb_host.curr_QH=QH;
}

HOST_QUEUE_HEAD *USBHOST_CURR_QH_GET(void)
{
	return usb_host.curr_QH;
}

void USBHOST_CURR_QH_RESET(void)
{
	usb_host.curr_QH=NULL;
}

void USBHOST_CURR_TD_SET(TRANSACTION_STRUCT *TD)
{
	usb_host.curr_TD=TD;
}

TRANSACTION_STRUCT *USBHOST_CURR_TD_GET(void)
{
	return usb_host.curr_TD;
}

void USBHOST_CURR_TD_RESET(void)
{
	usb_host.curr_TD=NULL;
}

void USBHOST_PRVE_TD_SET(TRANSACTION_STRUCT *TD)
{
	usb_host.prve_TD=TD;
}

TRANSACTION_STRUCT *USBHOST_PRVE_TD_GET(void)
{
	return usb_host.prve_TD;
}

void USBHOST_PRVE_TD_RESET(void)
{
	usb_host.prve_TD=NULL;
}

⌨️ 快捷键说明

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