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

📄 usbfndrv.cpp

📁 OMAP730 USB 驱动源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
BOOL CUsbFn::DeviceNotify(DWORD dwMsg, DWORD dwParam)
{
    DEBUGMSG (ZONE_WRITE|ZONE_EVENTS,(TEXT("DeviceNotify (0x%x,0x%x)\r\n"),dwMsg, dwParam));
    switch(dwMsg) {
        case UFN_MSG_BUS_EVENTS: {
            // Ensure device is in running state
            DEBUGCHK(m_hDefaultPipe);

           switch(dwParam) {                
                case UFN_DETACH:
                    CableDetached();
                    break;
                case UFN_ATTACH:
                    break;
                case UFN_RESET: {
                    CableDetached();
                    break;
                }
             } 

           break;
        }
        
        case UFN_MSG_BUS_SPEED:
             m_CurrentSpeed = (UFN_BUS_SPEED) dwParam;
        break;

        case UFN_MSG_SETUP_PACKET:
        case UFN_MSG_PREPROCESSED_SETUP_PACKET: {
            HandleRequest(dwMsg,*(PUSB_DEVICE_REQUEST)dwParam);
            break;
        }

        case UFN_MSG_CONFIGURED: {
            if (dwParam == 0) {
                CableDetached();
            }
            else {
                CableAttached();
            }
            break;
        }
        
    }
    return TRUE;
}
void CUsbFn::HandleRequest(
    DWORD dwMsg,
    USB_DEVICE_REQUEST udr
    )
{
    CONTROL_RESPONSE response;

    if (dwMsg == UFN_MSG_PREPROCESSED_SETUP_PACKET) {
        response = CR_SUCCESS; // Don't respond since it was already handled.
        
        if ( udr.bmRequestType ==
            (USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_STANDARD | USB_REQUEST_FOR_ENDPOINT) ) {
            switch (udr.bRequest) {
                case USB_REQUEST_CLEAR_FEATURE:
                    // This may be needed in the future to terminate a transfer 
                    // in progress
                    HandleClearFeature(udr);
                    break;
            }
        }
    }
    else {
        DEBUGCHK(dwMsg == UFN_MSG_SETUP_PACKET);
        response = CR_STALL_DEFAULT_PIPE;

        if (udr.bmRequestType & USB_REQUEST_CLASS) {
            response = HandleClassRequest(udr);
        }
    }

    if (response == CR_STALL_DEFAULT_PIPE) {
        m_pUfnFuncs->lpStallPipe(m_hDevice, m_hDefaultPipe);
        m_pUfnFuncs->lpSendControlStatusHandshake(m_hDevice);
    }
    else if (response == CR_SUCCESS_SEND_CONTROL_HANDSHAKE) {
        m_pUfnFuncs->lpSendControlStatusHandshake(m_hDevice);
    }
}
CONTROL_RESPONSE CUsbFn::HandleClassRequest(
    USB_DEVICE_REQUEST udr
    )
{

    CONTROL_RESPONSE response = CR_STALL_DEFAULT_PIPE;
           
    if (udr.bmRequestType == 
            (USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE | USB_REQUEST_HOST_TO_DEVICE) ) { 
        if (udr.bRequest == SET_CONTROL_LINE_STATE) {
            /* Host is notifying us of control line state.
             * wValue contains bitmask
             * 0 - DTR
             * 1 - RTS
             */
            DEBUGMSG( ZONE_FUNCTION, (TEXT("SET_CONTROL_LINE_STATE %X\r\n"),
                 udr.wValue));
            DWORD dwModemStatus = 0;
            if (udr.wValue & USB_COMM_DTR)
              dwModemStatus |= (MS_DSR_ON|MS_RLSD_ON); // DTR active, set DSR/RLSD
            if (udr.wValue & USB_COMM_RTS) 
              dwModemStatus |= MS_CTS_ON;   // RTS active, set CTS
            ModemSignal(dwModemStatus);
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE;
        }
    }
    else {
        RETAILMSG(1, (_T("Unrecognized Serial class bRequest -> 0x%x\r\n"), udr.bmRequestType));
        ASSERT(FALSE);
    }
    ASSERT(response == CR_SUCCESS_SEND_CONTROL_HANDSHAKE);
    return response;
}


void USBSerialFn::CableDetached()
{
    // This is last time to call this structure.
    CloseBulkIn();
    CloseBulkOut();
    CloseInterruptIn();
    ModemSignal(0);
}
void USBSerialFn::CableAttached() 
{
    m_HardwareLock.Lock();
    DWORD dwBulkSize = (m_CurrentSpeed == BS_HIGH_SPEED?
        m_HighSpeedEndpoints[BULK_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize:
        m_FullSpeedEndpoints[BULK_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize);
    BYTE uEdptAddr  = (m_CurrentSpeed == BS_HIGH_SPEED?
        m_HighSpeedEndpoints[BULK_IN_DESCRIPTOR_INDEX].Descriptor.bEndpointAddress:
        m_FullSpeedEndpoints[BULK_IN_DESCRIPTOR_INDEX].Descriptor.bEndpointAddress);
    OpenBulkIn(m_hDevice, m_pUfnFuncs,uEdptAddr,FALSE, dwBulkSize, 0x1000, 2);
    
    dwBulkSize = (m_CurrentSpeed == BS_HIGH_SPEED?
        m_HighSpeedEndpoints[BULK_OUT_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize:
        m_FullSpeedEndpoints[BULK_OUT_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize);
    uEdptAddr  = (m_CurrentSpeed == BS_HIGH_SPEED?
        m_HighSpeedEndpoints[BULK_OUT_DESCRIPTOR_INDEX].Descriptor.bEndpointAddress:
        m_FullSpeedEndpoints[BULK_OUT_DESCRIPTOR_INDEX].Descriptor.bEndpointAddress);
    OpenBulkOut(m_hDevice, m_pUfnFuncs,uEdptAddr,TRUE,dwBulkSize,dwBulkSize, 4); // WCEUSBSH Bug. Only can usb MaxPacketSize
    
    if (m_fInterrupt) {
        DWORD dwInterruptSize = (m_CurrentSpeed == BS_HIGH_SPEED?
            m_HighSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize:
            m_FullSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize);
        uEdptAddr  = (m_CurrentSpeed == BS_HIGH_SPEED?
            m_HighSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.bEndpointAddress:
            m_FullSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.bEndpointAddress);
        OpenInterruptIn(m_hDevice, m_pUfnFuncs,uEdptAddr,FALSE,dwInterruptSize,dwInterruptSize, 1);
    }
    m_HardwareLock.Unlock();
}
USBSerSerialFn::USBSerSerialFn(LPTSTR lpActivePath, PVOID pMdd, PHWOBJ pHwObj )
:   USBSerialFn(lpActivePath,pMdd,pHwObj )
{
    // Setup Discriptor default value for USBSer driver.
    m_FullSpeedDeviceDesc.bDeviceClass =    m_HighSpeedDeviceDesc.bDeviceClass = 0x20;
    m_FullSpeedDeviceDesc.bDeviceSubClass = m_HighSpeedDeviceDesc.bDeviceSubClass = 0;
    m_FullSpeedDeviceDesc.bDeviceProtocol = m_HighSpeedDeviceDesc.bDeviceProtocol = 0;
    
    m_FullSpeedDeviceDesc.idProduct = m_HighSpeedDeviceDesc.idProduct =   0x0079 ;
    m_FullSpeedDeviceDesc.idVendor = m_HighSpeedDeviceDesc.idVendor =    0x045e ;
    m_FullSpeedDeviceDesc.bcdDevice = m_HighSpeedDeviceDesc.bcdDevice =   0x90;

    m_FullSpeedInterface1.Descriptor.bInterfaceClass  = m_HighSpeedInterface1.Descriptor.bInterfaceClass = 0x02;
    m_FullSpeedInterface1.Descriptor.bInterfaceSubClass  = m_HighSpeedInterface1.Descriptor.bInterfaceSubClass = 0xff;
    m_FullSpeedInterface1.Descriptor.bInterfaceProtocol  = m_HighSpeedInterface1.Descriptor.bInterfaceProtocol = 0xff;

    const USB_COMM_LINE_CODING CommLineCoding = {
        9600, USB_COMM_STOPBITS_10, USB_COMM_PARITY_NONE,8             
    };
    m_CommLineCoding = CommLineCoding;
    m_hTransferHandle = NULL;
    m_wModemSetState = USB_COMM_DCD  ;
    const USB_COMM_SERIAL_STATUS CommSerialStatus= {
        0, USB_COMM_SERIAL_STATE, 0, 0, 0, USB_COMM_DCD
    };
    m_CommSerialStatus = CommSerialStatus;

    // USBSER requires interrupt endpoint maxpacket size bigger than 8. So we try 64 to find anything available.
    m_HighSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize = 0x40;
    m_FullSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize = 0x40;

    
}
USBSerSerialFn::~USBSerSerialFn()
{
    if (m_pUfnFuncs && m_hDevice && m_hDefaultPipe && m_hTransferHandle) {
        DWORD dwRet = m_pUfnFuncs->lpAbortTransfer(m_hDevice,m_hTransferHandle);
        DEBUGMSG (ZONE_EVENTS,(TEXT("USBSerSerialFn::~USBSerSerialFn(Handle=0x%x)\r\n"), m_pUfnFuncs));
    }
}
DWORD   USBSerSerialFn::StartUSBFunction()
{
    DWORD dwRet = ERROR_GEN_FAILURE;
    
    dwRet = m_pUfnFuncs->lpRegisterDevice(m_hDevice, &m_HighSpeedDeviceDesc, &m_HighSpeedConfig1, 
        &m_FullSpeedDeviceDesc, &m_FullSpeedConfig1, &m_rgStringSets, 1 );
    if (m_HighSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize <=8 ||
            m_FullSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize <=8) {
        DEBUGMSG (ZONE_ERROR,(TEXT("USBSerSerialFn::StartUSBFunction: Interrupt Endpoint point MaxPacket (%d, %d) is too small \r\n"),
            m_HighSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize,
            m_FullSpeedEndpoints[INTERRUPT_IN_DESCRIPTOR_INDEX].Descriptor.wMaxPacketSize));            
        return ERROR_GEN_FAILURE;
    }
    if (dwRet == ERROR_SUCCESS ) { // Do I need Initial Pipe Here?
        m_fInterrupt = TRUE;
        dwRet = m_pUfnFuncs->lpStart(m_hDevice, DeviceNotifyStub, (CUsbFn *)this,  &m_hDefaultPipe);

    }
    return dwRet;
}
BOOL  USBSerSerialFn::IssueTransfer(PBYTE pBuffer, DWORD dwLength, BOOL fIn)
{
    DWORD dwFlags = (fIn? USB_IN_TRANSFER: USB_OUT_TRANSFER);
    BOOL bReturn = FALSE;
    m_HardwareLock.Lock();
    if (pBuffer && m_hTransferHandle == NULL) {
        DWORD dwRet = m_pUfnFuncs->lpIssueTransfer(m_hDevice,m_hDefaultPipe,CompleteNotificationStub,this,dwFlags,
            dwLength,pBuffer,NULL,NULL,&m_hTransferHandle);
        if (dwRet != ERROR_SUCCESS)
            m_hTransferHandle = NULL;
        bReturn = (dwRet == ERROR_SUCCESS);     
    }
    m_HardwareLock.Unlock();
    ASSERT(bReturn == TRUE);
    return bReturn;
}
DWORD WINAPI  USBSerSerialFn::CompleteNotification()
{
    DWORD dwRet = ERROR_GEN_FAILURE ;
    m_HardwareLock.Lock();
    if (m_hTransferHandle) {
        m_pUfnFuncs->lpCloseTransfer(m_hDevice,m_hTransferHandle);
        m_pUfnFuncs->lpSendControlStatusHandshake(m_hDevice);  
        m_hTransferHandle = NULL;
        dwRet = ERROR_SUCCESS;
    }
    m_HardwareLock.Unlock();
    ASSERT(dwRet == ERROR_SUCCESS) ;
    return (dwRet);
}

CONTROL_RESPONSE USBSerSerialFn::HandleClassRequest(USB_DEVICE_REQUEST udr)
{
    CONTROL_RESPONSE response = CR_STALL_DEFAULT_PIPE;
    if (udr.bmRequestType ==  (USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE | USB_REQUEST_DEVICE_TO_HOST) ) { 
        switch (udr.bRequest) {
          case USB_COMM_GET_LINE_CODING:
            if (IssueTransfer((PBYTE)&m_CommLineCoding,min( sizeof(m_CommLineCoding), udr.wLength), TRUE )) {
                response = CR_SUCCESS ;
            }
            break;
        }
    }
    else if (udr.bmRequestType ==  (USB_REQUEST_CLASS | USB_REQUEST_FOR_INTERFACE | USB_REQUEST_HOST_TO_DEVICE) ) { 
        switch (udr.bRequest) {
          case USB_COMM_SET_LINE_CODING:
            if (IssueTransfer((PBYTE)&m_CommLineCoding, sizeof(m_CommLineCoding), FALSE )) {
                response = CR_SUCCESS ;
            }
            break;
          case USB_COMM_SET_CONTROL_LINE_STATE: {
            DEBUGMSG( ZONE_FUNCTION, (TEXT("SET_CONTROL_LINE_STATE %X\r\n"), udr.wValue));
            DWORD dwModemStatus = 0;
            if (udr.wValue & USB_COMM_DTR)
                dwModemStatus |= (MS_DSR_ON|MS_RLSD_ON); // DTR active, set DSR/RLSD
            //if (udr.wValue & USB_COMM_RTS) 
            //  dwModemStatus |= MS_CTS_ON;   // RTS active, set CTS
            // Desktop Driver has problem to set RTS. We always set it on.
            dwModemStatus |= MS_CTS_ON ;
            ModemSignal(dwModemStatus);
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE ;
            break;
          }
          case USB_COMM_SEND_BREAK: {
            EventCallback(EV_BREAK);
            // Do I need Sleep Here? Sleep(udr.wValue)
            response = CR_SUCCESS_SEND_CONTROL_HANDSHAKE ;
            break;
          }
          default:
            ASSERT(FALSE);
            break;
        }
    }
    return response;
    
}
void USBSerSerialFn::SetModemSignal(BOOL bSet, BYTE bBitSet)
{
    m_HardwareLock.Lock();
    if (bSet)
        m_wModemSetState |= bBitSet;
    else
        m_wModemSetState &= ~bBitSet;
    
    if (m_pInterruptIn && m_CommSerialStatus.SerialState != m_wModemSetState && m_pInterruptIn->IsAnySpaceAvailable()) {
        DWORD dwLength = sizeof(m_CommSerialStatus);
        m_CommSerialStatus.SerialState = m_wModemSetState;
        m_pInterruptIn->WriteData((PBYTE)&m_CommSerialStatus,&dwLength);
    }
    m_HardwareLock.Unlock();
}

CSerialPDD * CreateSerialObject(LPTSTR lpActivePath, PVOID pMdd,PHWOBJ pHwObj, DWORD dwDeviceArrayIndex )
{
    CSerialPDD * pSerialPDD = NULL;
    switch (dwDeviceArrayIndex) {
      case 0:
        pSerialPDD = new USBSerialFn(lpActivePath,pMdd, pHwObj);
        break;
      case 1:
        pSerialPDD = new USBSerSerialFn(lpActivePath,pMdd, pHwObj);
        break;
      default:
        ASSERT(FALSE);
    }
        
    if (pSerialPDD && !pSerialPDD->Init()) {
        delete pSerialPDD;
        pSerialPDD = NULL;
    }
    return pSerialPDD;
}
void DeleteSerialObject(CSerialPDD * pSerialPDD)
{
    if (pSerialPDD)
        delete pSerialPDD;
}

⌨️ 快捷键说明

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