📄 bul_usbfn.cpp
字号:
udccr.ulValue = ReadControlRegister();
udccr.bit.OEN = 1;
udccr.bit.UDE = 1;
udccr.bit.EMCE = 0 ;
WriteControlRegister(udccr.ulValue);
udccr.ulValue = ReadControlRegister();
ASSERT(udccr.bit.EMCE==0);
if (udccr.bit.EMCE==1)
dwReturn = ERROR_INVALID_PARAMETER ;
Unlock();
FUNCTION_LEAVE_MSG();
return dwReturn;
}
DWORD BulUsbDevice::Stop()
{
SETFNAME();
FUNCTION_ENTER_MSG();
Lock();
//ASSERT(m_pvMddContext!=NULL);
//m_pvMddContext = NULL;
// Enable Device Interrupt.
WriteIntrCtr0Register(0);
WriteIntrCtr1Register(0);
Unlock();
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
DWORD BulUsbDevice::SetAddress( BYTE bAddress )
{
// Do we need handle this? NO?
return ERROR_SUCCESS;
}
void BulUsbDevice::PowerMgr(BOOL bOff)
{
Lock();
if (bOff) {
// Disable Device to simulate remove from bus.
UDCCR udccr;
udccr.ulValue = 0;
udccr.bit.UDE = 0 ;
WriteControlRegister(udccr.ulValue);
}
else {
UDCCR udccr;
udccr.ulValue = 0;
udccr.bit.UDE = 1 ;
udccr.bit.OEN = 1;
WriteControlRegister(udccr.ulValue);
SetInterruptEvent(m_dwSysIntr);
}
Unlock();
}
void BulUsbDevice::PowerDown()
{
if (m_CurPowerState == PwrDeviceUnspecified) {
PowerMgr(TRUE) ;
}
}
void BulUsbDevice::PowerUp()
{
m_fResumeOccurred = TRUE;
if (m_CurPowerState == PwrDeviceUnspecified) {
PowerMgr(FALSE) ;
}
}
void BulUsbDevice::SetPowerState( CEDEVICE_POWER_STATE cpsNew )
{
SETFNAME();
// Adjust cpsNew.
if (cpsNew != m_CurPowerState ) {
if (cpsNew == D1 || cpsNew == D2) {
// D1 and D2 are not supported.
cpsNew = D0;
}
else if (m_CurPowerState== D4) {
// D4 can only go to D0.
cpsNew = D0;
}
}
if (cpsNew != m_CurPowerState ) {
BOOL bBusSucceed = FALSE;
DEBUGMSG(ZONE_FUNCTION, (_T("%s Going from D%u to D%u\r\n"), pszFname, m_CurPowerState , cpsNew));
if ( (cpsNew < m_CurPowerState) && m_hParent) {
bBusSucceed = SetDevicePowerState(m_hParent, cpsNew, NULL);
if (bBusSucceed) {
PowerMgr(FALSE);
}
}
switch (cpsNew) {
case D0:
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr,sizeof(m_dwSysIntr), NULL, 0, NULL);
break;
case D3:
KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr), NULL, 0, NULL);
break;
case D4:
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr), NULL, 0, NULL);
break;
}
if ( (cpsNew > m_CurPowerState ) && m_hParent ) {
bBusSucceed = SetDevicePowerState(m_hParent, cpsNew, NULL);
if (bBusSucceed && cpsNew == D4) {
PowerMgr(TRUE);
}
}
m_CurPowerState = cpsNew;
}
}
DWORD BulUsbDevice::IOControl( IOCTL_SOURCE source, DWORD dwCode, PBYTE pbIn, DWORD cbIn, PBYTE pbOut, DWORD cbOut,PDWORD pcbActualOut )
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwRet = ERROR_INVALID_PARAMETER;
switch (dwCode) {
case IOCTL_UFN_GET_PDD_INFO:
if ( source != BUS_IOCTL || pbOut == NULL || cbOut != sizeof(UFN_PDD_INFO) ) {
break;
}
// Not currently supported.
break;
case IOCTL_BUS_GET_POWER_STATE:
if (source == MDD_IOCTL) {
PREFAST_DEBUGCHK(pbIn);
DEBUGCHK(cbIn == sizeof(CE_BUS_POWER_STATE));
PCE_BUS_POWER_STATE pCePowerState = (PCE_BUS_POWER_STATE) pbIn;
PREFAST_DEBUGCHK(pCePowerState->lpceDevicePowerState);
DEBUGMSG(ZONE_FUNCTION, (_T("%s IOCTL_BUS_GET_POWER_STATE\r\n"), pszFname));
*pCePowerState->lpceDevicePowerState = m_CurPowerState;
dwRet = ERROR_SUCCESS;
}
break;
case IOCTL_BUS_SET_POWER_STATE:
if (source == MDD_IOCTL) {
PREFAST_DEBUGCHK(pbIn);
DEBUGCHK(cbIn == sizeof(CE_BUS_POWER_STATE));
PCE_BUS_POWER_STATE pCePowerState = (PCE_BUS_POWER_STATE) pbIn;
PREFAST_DEBUGCHK(pCePowerState->lpceDevicePowerState);
DEBUGCHK(VALID_DX(*pCePowerState->lpceDevicePowerState));
DEBUGMSG(ZONE_FUNCTION, (_T("%s IOCTL_BUS_GET_POWER_STATE(D%u)\r\n"), pszFname, *pCePowerState->lpceDevicePowerState));
SetPowerState( *pCePowerState->lpceDevicePowerState );
dwRet = ERROR_SUCCESS;
}
break;
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
void BulUsbDevice::ISTProcess()
{
SETFNAME();
FUNCTION_ENTER_MSG();
m_ISTLock.Lock();
DWORD dwIntr0Status = ReadIntrStatus0Register() ;
DWORD dwIntr1Status = ReadIntrStatus1Register() ;
WriteIntrStatus0Register(dwIntr0Status) ;
WriteIntrStatus1Register(dwIntr1Status) ;
DEBUGMSG(ZONE_FUNCTION, (_T("%s : BulUsbDevice dwIntr0Status 0x%x, dwIntr1Status 0x%x, dwIntr0Ctrl=0x%x, dwIntr11Ctrl=0x%x, OTGICR=0x%x \r\n "), pszFname, dwIntr0Status,dwIntr1Status,ReadIntrCtr0Register(), ReadIntrCtr1Register()));
if (m_fIsCableAttached != IsCableAttached() || m_fResumeOccurred ) {
m_fIsCableAttached = IsCableAttached();
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
udccr.bit.EMCE = 0 ;
if (m_fIsCableAttached || m_fResumeOccurred ) {
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Attach Detected\r\n"),pszFname));
m_fResumeOccurred = FALSE ;
ReInit();
}
else {
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Detach Detected\r\n"),pszFname));
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_DETACH);
}
}
// Processing Device Interrupt
if ( (dwIntr1Status & UDCISR1_IRCC)!=0 || m_fOTGSetupFeature) { // Setup Config or Setup Interface has been received.
USB_DEVICE_REQUEST udr;
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Setup Configuration and Interface received UDCCR=0x%x.\r\n"),pszFname,udccr.ulValue));
udccr.bit.SMAC = 1;
udccr.bit.EMCE = 0 ;
WriteControlRegister(udccr.ulValue);
m_fOTGSetupFeature = FALSE;
if (udccr.bit.ACN != m_dwCurConfigure) { // COnfiguration has changed.
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_CONFIGURATION;
udr.wValue = (USHORT) udccr.bit.ACN;
udr.wIndex = 0;
udr.wLength =0;
m_dwCurConfigure = udccr.bit.ACN ;
DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
if (udccr.bit.AIN*0x100 + udccr.bit.AAISN != m_dwCurInterface) {
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_INTERFACE;
udr.wValue = (USHORT) udccr.bit.AAISN;
udr.wIndex = (USHORT) udccr.bit.AIN;
udr.wLength = 0;
m_dwCurInterface = udccr.bit.AIN*0x100 + udccr.bit.AAISN ;
// We can not do this because MDD will stall the endpoint.
//DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
// For OTG.
if (udccr.bit.BHNP !=0 && udccr.bit.BHNP!= m_prevUDCR.bit.BHNP) { // Host Set HNP Feature.
DEBUGMSG(ZONE_FUNCTION, (_T("%s : BHNP Detected\r\n"),pszFname));
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_FEATURE ;
udr.wValue = USB_FEATURE_B_HNP_ENABLE;
udr.wIndex = 0 ;
udr.wLength =0;
m_prevUDCR.bit.BHNP = udccr.bit.BHNP ;
DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
if (udccr.bit.AHNP !=0 && udccr.bit.AHNP != m_prevUDCR.bit.AHNP) {// Host Set HNP Support.
DEBUGMSG(ZONE_FUNCTION, (_T("%s : AHNP Detected\r\n"),pszFname));
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_FEATURE ;
udr.wValue = USB_FEATURE_A_HNP_SUPPORT;
udr.wIndex = 0 ;
udr.wLength =0;
m_prevUDCR.bit.AHNP = udccr.bit.AHNP;
DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
if (udccr.bit.AALTHNP!=0 && udccr.bit.AALTHNP != m_prevUDCR.bit.AALTHNP) { // Host Set Alter HNP Support.
DEBUGMSG(ZONE_FUNCTION, (_T("%s : AALTHNP Detected\r\n"),pszFname));
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_FEATURE ;
udr.wValue = USB_FEATURE_A_ALT_HNP_SUPPORT;
udr.wIndex = 0 ;
udr.wLength =0;
m_prevUDCR.bit.AALTHNP = udccr.bit.AALTHNP;
DeviceNotification(UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
}
if ( dwIntr1Status & UDCISR1_IRRU) { // Resume Detected
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Resume Detected\r\n"),pszFname));
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_RESUME);
}
if (dwIntr1Status & UDCISR1_IRSU ) { // Suspend Detected.
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Suspend Detected\r\n"),pszFname));
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_SUSPEND);
}
if (dwIntr1Status & UDCISR1_IRRS) { // Reset Detected.
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Reset Detected\r\n"),pszFname));
// Set DETACH First
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_DETACH);
// Set ATTACH.
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_ATTACH);
// Set Reset
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_RESET);
// This device can only support FULL Speed.
DeviceNotification( UFN_MSG_BUS_SPEED, BS_FULL_SPEED);
// The HW Filters the Set Address ... Fake it here
DeviceNotification( UFN_MSG_SET_ADDRESS, 0xFF);
UDCCR udccr;
USB_DEVICE_REQUEST udr;
udccr.ulValue = ReadControlRegister();
if (udccr.bit.ACN == m_dwCurConfigure) { // COnfiguration has changed.
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_CONFIGURATION;
udr.wValue = (USHORT) udccr.bit.ACN;
udr.wIndex = 0;
udr.wLength =0;
DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
else { // THis device is not configured
m_dwCurConfigure = MAXDWORD ;
}
if (udccr.bit.AIN*0x100 + udccr.bit.AAISN == m_dwCurInterface) {
udr.bmRequestType = USB_REQUEST_FOR_DEVICE;
udr.bRequest = USB_REQUEST_SET_INTERFACE;
udr.wValue = (USHORT) udccr.bit.AAISN;
udr.wIndex = (USHORT) udccr.bit.AIN;
udr.wLength = 0;
// We can not do this because MDD will stall the endpoint.
//DeviceNotification( UFN_MSG_SETUP_PACKET,(DWORD) &udr);
}
else { // THis device is not configured
m_dwCurInterface = MAXDWORD ;
}
m_prevUDCR.ulValue = 0 ; // Reset Should clear all previous state;
}
BulEndpoint *pEndpoint;
DWORD dwIntrStatusCopy = dwIntr0Status;
for (DWORD dwIndex =0 ; dwIndex < UDCIR0_MAX ; dwIndex ++ ) {
if ((dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ))!=0 ) {
if ((pEndpoint = ObjectIndex(dwIndex)) != NULL ) {
pEndpoint->IST(dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ));
pEndpoint->DeRef();
}
}
dwIntrStatusCopy >>=2;
}
dwIntrStatusCopy = dwIntr1Status;
for (DWORD dwIndex =UDCIR0_MAX ; dwIndex < MAX_ENDPOINT_NUMBER ; dwIndex ++ ) {
if ((dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ))!=0 ) {
if ((pEndpoint = ObjectIndex(dwIndex)) != NULL ) {
pEndpoint->IST(dwIntrStatusCopy & ( EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR ));
pEndpoint->DeRef();
}
}
dwIntrStatusCopy >>=2;
}
m_ISTLock.Unlock();
FUNCTION_LEAVE_MSG();
}
#ifdef DEBUG
const DWORD cISTTimeOut = 2000;
#else
const DWORD cISTTimeOut = INFINITE ;
#endif
DWORD BulUsbDevice::ThreadRun()
{
SETFNAME();
FUNCTION_ENTER_MSG();
while (!m_bTerminated && m_hISTEvent!=NULL) {
if ( WaitForSingleObject(m_hISTEvent,cISTTimeOut) != WAIT_OBJECT_0) {
DEBUGMSG(ZONE_FUNCTION, (_T("%s : Interrupt Time out dwIntr0Status=0x%x dwIntr1Status = 0x%x. dwIntr0Ctrl=0x%x, dwIntr11Ctrl=0x%x\r\n"),pszFname,
ReadIntrStatus0Register(), ReadIntrStatus1Register(),ReadIntrCtr0Register(), ReadIntrCtr1Register()));
DEBUGMSG(ZONE_FUNCTION, (_T("%s : ControlRegister() =0x%x ControlStatusRegister(0)=0x%x\r\n"),pszFname,
ReadControlRegister(), ReadUDCRegister( ENDPOINT_CONTROL_STATUS_REGISTER_OFFSET + 0 ) ));
continue;
}
ISTProcess();
InterruptDone(m_dwSysIntr);
}
FUNCTION_LEAVE_MSG();
return 1;
}
BulOTGEventThread::BulOTGEventThread( BulUsbDevice& BulverUSBDevice, HANDLE& hOTGEvent,DWORD dwPrority)
: m_BulverUSBDevice(BulverUSBDevice)
, m_hOTGEvent (hOTGEvent)
, m_dwPriority(dwPrority)
, CMiniThread (0, TRUE)
{
}
BulOTGEventThread::~BulOTGEventThread()
{
m_bTerminated=TRUE;
ThreadStart();
SetEvent(m_hOTGEvent);
ThreadTerminated(1000);
}
DWORD BulOTGEventThread::ThreadRun()
{
while (!m_bTerminated && m_hOTGEvent!=NULL) {
if ( WaitForSingleObject(m_hOTGEvent,INFINITE)== WAIT_OBJECT_0) {
m_BulverUSBDevice.OTGSetupFeature();
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -