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

📄 lpc177x_8x_usbhost.c

📁 NXPl788上lwip的无操作系统移植,基于Embest开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
					/*
					 * When DRWE is off, Connect Status Change
					 * is NOT a remote wakeup event
					*/
					if (LPC_USB->RhPortStatus1 & OR_RH_PORT_CCS) {
							HOST_TDControlStatus = 0;
							HOST_WdhIntr = 0;
							HOST_RhscIntr |= 0x01;
							gUSBConnected = 1;
					} else {
							//LPC_USB->InterruptEnable = 0; // why do we get multiple disc. rupts???
							HOST_RhscIntr &= ~0x01;
							gUSBConnected = 0;
					}
                }
            	LPC_USB->RhPortStatus1 = OR_RH_PORT_CSC;
            }
			if (LPC_USB->RhPortStatus2 & OR_RH_PORT_CSC) {
				if (LPC_USB->RhStatus & OR_RH_STATUS_DRWE) {
					/*
				 	* When DRWE is on, Connect Status Change
				 	* means a remote wakeup event.
					*/
					HOST_RhscIntr |= 0x02;// JUST SOMETHING FOR A BREAKPOINT
				}
				else {
					/*
				 	* When DRWE is off, Connect Status Change
				 	* is NOT a remote wakeup event
					*/
					if (LPC_USB->RhPortStatus2 & OR_RH_PORT_CCS) {
							HOST_TDControlStatus = 0;
							HOST_WdhIntr = 0;
							HOST_RhscIntr |= 0x02;
							gUSBConnected = 1;
					} else {
							//LPC_USB->InterruptEnable = 0; // why do we get multiple disc. rupts???
							HOST_RhscIntr &= ~0x02;
							gUSBConnected = 0;
					}
				}
				LPC_USB->RhPortStatus2 = OR_RH_PORT_CSC;
			}
			if (LPC_USB->RhPortStatus1 & OR_RH_PORT_PRSC) {
				LPC_USB->RhPortStatus1 = OR_RH_PORT_PRSC;
			}
			if (LPC_USB->RhPortStatus2 & OR_RH_PORT_PRSC) {
				LPC_USB->RhPortStatus2 = OR_RH_PORT_PRSC;
			}
		}
        if (int_status & OR_INTR_STATUS_WDH) {                  /* Writeback Done Head interrupt        */
            HOST_WdhIntr = 1;
			HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf;
        }
		if (int_status & OR_INTR_STATUS_UE) {                   /* Unrecoverable Error interrupt        */
			UnrecoverableIntCount++;
        }    

        LPC_USB->InterruptStatus = int_status;                         /* Clear interrupt status register      */
    }           
    return;
}

/*********************************************************************//**
 * @brief 			enumerate the device connected.
 * @param[in]		None.
 * @return 		None.
 **********************************************************************/
int32_t  Host_EnumDev (void)
{
    int32_t  rc;

    while (!gUSBConnected);
    Host_DelayMS(100);                             /* USB 2.0 spec says atleast 50ms delay beore port reset */
	
	if ( HOST_RhscIntr & 0x01 )
	{
	  LPC_USB->RhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
	  while (LPC_USB->RhPortStatus1 & OR_RH_PORT_PRS)
		; // Wait for port reset to complete...
	  LPC_USB->RhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
	}
	if ( HOST_RhscIntr & 0x02 )
	{
	  LPC_USB->RhPortStatus2 = OR_RH_PORT_PRS; // Initiate port reset
	  while (LPC_USB->RhPortStatus2 & OR_RH_PORT_PRS)
		; // Wait for port reset to complete...
	  LPC_USB->RhPortStatus2 = OR_RH_PORT_PRSC; // ...and clear port reset signal
	}
    Host_DelayMS(200);                                                 /* Wait for 100 MS after port reset  */

    EDCtrl->Control = DEVICE_DESCRIPTOR_SIZE << 16;                    /* Put max pkt size = 8              */
                                                                       /* Read device desc */
    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, USB_DeviceDescriptor, DEVICE_DESCRIPTOR_SIZE);
    if (rc != USB_HOST_FUNC_OK) {
        return (rc);
    }
    EDCtrl->Control = USB_DeviceDescriptor[7] << 16;                               /* Get max pkt size of endpoint 0    */
    rc = HOST_SET_ADDRESS(1);                                          /* Set the device address to 1       */
    if (rc != USB_HOST_FUNC_OK) {
        return (rc);
    }
    Host_DelayMS(2);
    EDCtrl->Control = (EDCtrl->Control) | 1;                          /* Modify control pipe with address 1 */
                                                                      /* Get the configuration descriptor   */
    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, USB_ConfigDescriptor, DEVICE_CONFIGURATION_SIZE);
    if (rc != USB_HOST_FUNC_OK) {
        return (rc);
    }
                                                                       /* Get the first configuration data  */
    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, USB_ConfigDescriptor, 
    							ReadLE16U(&USB_ConfigDescriptor[2]));
    if (rc != USB_HOST_FUNC_OK) {
        return (rc);
    }
    rc = Host_ParseConfiguration();                                      /* Parse the configuration           */
    if (rc != USB_HOST_FUNC_OK) {
        return (rc);
    }
    rc = USBH_SET_CONFIGURATION(1);                                    /* Select device configuration 1     */
    if (rc != USB_HOST_FUNC_OK) {
    }
    Host_DelayMS(100);                                               /* Some devices may require this delay */
    return (rc);
}

/*********************************************************************//**
 * @brief 			parse the configuration.
 * @param[in]		None.
 * @return 		OK		              if Success.
 *                         ERR_BAD_CONFIGURATION    Failed in case of bad configuration.
 *				ERR_NO_MS_INTERFACE	  Failed in case of no MS interface.
 **********************************************************************/
int32_t  Host_ParseConfiguration (void)
{
    volatile  uint8_t  *desc_ptr;
              uint8_t   ms_int_found;


    desc_ptr     = USB_ConfigDescriptor;
    ms_int_found = 0;

    if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {    
        return (ERR_BAD_CONFIGURATION);
    }
    desc_ptr += desc_ptr[0];

    while (desc_ptr != USB_ConfigDescriptor + ReadLE16U(&USB_ConfigDescriptor[2])) {

        switch (desc_ptr[1]) {

            case USB_DESCRIPTOR_TYPE_INTERFACE:                       /* If it is an interface descriptor   */
                 if (desc_ptr[5] == MASS_STORAGE_CLASS &&             /* check if the class is mass storage */
                     desc_ptr[6] == MASS_STORAGE_SUBCLASS_SCSI &&     /* check if the subclass is SCSI      */
                     desc_ptr[7] == MASS_STORAGE_PROTOCOL_BO) {       /* check if the protocol is Bulk only */
                     ms_int_found = 1;
					 gUSBDeviceType = MASS_STORAGE_DEVICE;
                     desc_ptr    += desc_ptr[0];                      /* Move to next descriptor start      */
                 }
                 break;

            case USB_DESCRIPTOR_TYPE_ENDPOINT:                        /* If it is an endpoint descriptor    */
                 if ((desc_ptr[3] & 0x03) == 0x02) {                  /* If it is Bulk endpoint             */
                     if (desc_ptr[2] & 0x80) {                        /* If it is In endpoint               */
                         EDBulkIn->Control =  1                             |      /* USB address           */
                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
                                              (2 << 11)                     |      /* direction             */
                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
                         desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
                     } else {                                         /* If it is Out endpoint              */
                         EDBulkOut->Control = 1                             |      /* USB address           */
                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
                                              (1 << 11)                     |      /* direction             */
                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
                         desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
                     }
                 } else {                                             /* If it is not bulk end point        */
                     desc_ptr += desc_ptr[0];                         /* Move to next descriptor start      */
                 }
                 break;

            default:                                 /* If the descriptor is neither interface nor endpoint */
                 desc_ptr += desc_ptr[0];                             /* Move to next descriptor start      */
                 break;
        }
    }
    if (ms_int_found) {
        return (USB_HOST_FUNC_OK);
    } else {
        return (ERR_NO_MS_INTERFACE);
    }
}
/*********************************************************************//**
 * @brief 			Get the type of the USB which is being connected.
 * @param[in]		None.
 * @return 		USB_DEVICE_TYPE value
 **********************************************************************/
USB_DEVICE_TYPE Host_GetDeviceType(void)
{
	return gUSBDeviceType;
}

/*********************************************************************//**
 * @brief 			processes the transfer descriptor.
 * @param[in]		ed            Endpoint descriptor that contains this transfer descriptor.
 * @param[in]		 token         SETUP, IN, OUT
 * @param[in]		 buffer        Current Buffer Pointer of the transfer descriptor
 * @param[in]		 buffer_len    Length of the buffer
 * @return 		USB_HOST_FUNC_OK       if TD submission is successful.
 *                          ERROR    if TD submission fails
 **********************************************************************/
int32_t  Host_ProcessTD (volatile  HCED       *ed,
                            volatile  uint32_t  token,
                            volatile  uint8_t *buffer,
                                      uint32_t  buffer_len)
{
    volatile  uint32_t   td_toggle;


    if (ed == EDCtrl) {
        if (token == TD_SETUP) {
            td_toggle = TD_TOGGLE_0;
        } else {
            td_toggle = TD_TOGGLE_1;
        }
    } else {
        td_toggle = 0;
    }
    TDHead->Control = (TD_ROUNDING    |
                      token           |
                      TD_DELAY_INT(0) |                           
                      td_toggle       |
                      TD_CC);
    TDTail->Control = 0;
    TDHead->CurrBufPtr   = (uint32_t) buffer;
    TDTail->CurrBufPtr   = 0;
    TDHead->Next         = (uint32_t) TDTail;
    TDTail->Next         = 0;
    TDHead->BufEnd       = (uint32_t)(buffer + (buffer_len - 1));
    TDTail->BufEnd       = 0;

    ed->HeadTd  = (uint32_t)TDHead | ((ed->HeadTd) & 0x00000002);
    ed->TailTd  = (uint32_t)TDTail;
    ed->Next    = 0;

    if (ed == EDCtrl) {
        LPC_USB->ControlHeadED  = (uint32_t)ed;
        LPC_USB->CommandStatus |= OR_CMD_STATUS_CLF;
        LPC_USB->Control       |= OR_CONTROL_CLE;
    } else {
        LPC_USB->BulkHeadED     = (uint32_t)ed;
        LPC_USB->CommandStatus |= OR_CMD_STATUS_BLF;
        LPC_USB->Control       |= OR_CONTROL_BLE;
    }    

    Host_WDHWait();

//    if (!(TDHead->Control & 0xF0000000)) {
	if (!HOST_TDControlStatus) {
        return (USB_HOST_FUNC_OK);
    } else {      
        return (ERR_TD_FAIL);
    }
}
   
/*********************************************************************//**
 * @brief 			receive the control information.
 * @param[in]		bm_request_type.
 * @param[in]		 b_request
 * @param[in]		 w_value
 * @param[in]		w_index
 * @param[in]		w_length
 * @param[in]		buffer
 * @return 		USB_HOST_FUNC_OK       if Success
 *                          ERROR    if Failed
 **********************************************************************/
int32_t  Host_CtrlRecv (         uint8_t   bm_request_type,
                                    uint8_t   b_request,
                                    uint16_t   w_value,
                                    uint16_t   w_index,
                                    uint16_t   w_length,
                          volatile  uint8_t  *buffer)

⌨️ 快捷键说明

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