📄 bul_usbfn.cpp
字号:
m_bNeedAck = FALSE;
if (m_fBackedudr) {
m_bNeedAck = TRUE;
m_bSetupDirIn = ((m_backup_udr.bmRequestType & USB_REQUEST_DEVICE_TO_HOST)!=0?TRUE:FALSE);
m_fZeroPacket = FALSE;
m_fBackedudr = FALSE;
m_cur_udr = m_backup_udr ;
m_pUsbDevice->DeviceNotification(UFN_MSG_SETUP_PACKET, (DWORD) &m_backup_udr);
if (!m_fInIST) {
IST(EPINT_PACKET_COMPLETE);
}
}
else if (m_bSetupDirIn && !m_fInIST )
IST(EPINT_PACKET_COMPLETE);
DEBUGMSG(ZONE_TRANSFER, (_T("%s Complete\r\n"),pszFname));
}
else
DEBUGMSG(ZONE_TRANSFER, (_T("%s Skipped\r\n"),pszFname));
Unlock();
return ERROR_SUCCESS;
}
DWORD BulEndpointZero::IST(DWORD dwIRBit)
{
Lock();
BOOL bContinue = TRUE;
m_fInIST = TRUE;
SETFNAME();
FUNCTION_ENTER_MSG();
if ((dwIRBit & EPINT_FIFO_ERROR)!=0) { // FIFO Error. End
DWORD dwUdccsr;
dwUdccsr = ReadControlStatusRegister();
DEBUGMSG(ZONE_TRANSFER, (_T("FIFO Error on Endpoint Zero UDCCSR=0x%x"),dwUdccsr));
};
while (bContinue && (dwIRBit & EPINT_PACKET_COMPLETE)!=0) {
bContinue = FALSE;
m_fStalled = FALSE; // Endpoint Zero is auto clear stall condition.
UDCCSR udccsr;
udccsr.ulValue = ReadControlStatusRegister();
DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero ReadControlStatusRegister()=0x%x\n"),udccsr.ulValue));
udccsr.ep0bit.FST = 0;
if (udccsr.ep0bit.SA !=0 && udccsr.ep0bit.OPC==0) {
m_pUsbDevice->IncBadSetupCounter();
RETAILMSG(1, (_T("Endpoint Zero FAILED SETUP udccsr=0x%x. Sent STALL \n"),udccsr.ulValue));
udccsr.ep0bit.FST = 1;
}
if (udccsr.ep0bit.OPC) {
if ( udccsr.ep0bit.SA ) { // This is setup Packet.
if (m_pCurTransfer) { // Outstanding transfer.
//DebugBreak();
DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero Current Transfer Canceled\n")));
WriteControlStatusRegister( udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer( UFN_CANCELED_ERROR );
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
}
ASSERT(ReadByteCountRegister() == sizeof (USB_DEVICE_REQUEST));
union {
USB_DEVICE_REQUEST udr;
DWORD dw8Byte[2];
};
dw8Byte[0] = ReadDataRegister();
dw8Byte[1] = ReadDataRegister();
DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero Setup bmRequestType = 0xx%x, bRequest=0x%x, wValue=0x%x,wIndex=0x%x,wLength=0x%x\n"),
udr.bmRequestType,udr.bRequest,udr.wValue,udr.wIndex,udr.wLength));
if (m_bNeedAck) { // Previous setup haven't ack yet. Disable Interrupt and wait for the Ack.
m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,FALSE);
DEBUGMSG(ZONE_TRANSFER, (_T("Endpoint Zero Disable Interrupt")));
m_fBackedudr = TRUE;
m_backup_udr = udr;
WriteControlStatusRegister( udccsr.ulValue);
continue;
}
else {
m_bNeedAck = TRUE;
m_bSetupDirIn = ((udr.bmRequestType & USB_REQUEST_DEVICE_TO_HOST)!=0?TRUE:FALSE);
bContinue = TRUE ;
m_fZeroPacket = FALSE;
m_cur_udr = udr ;
WriteControlStatusRegister( udccsr.ulValue);
m_pUsbDevice->DeviceNotification(UFN_MSG_SETUP_PACKET, (DWORD) &udr);
}
continue;
}
else if ( ReadByteCountRegister() == 0 ) { // ACK from Host.
bContinue = TRUE;
}
else if (m_pCurTransfer ) {
if((m_pCurTransfer->dwFlags & USB_IN_TRANSFER)==0) { // Out Data.
BOOL bComplete = (ReadByteCountRegister()<m_epDesc.wMaxPacketSize);
DWORD dwSize = (m_pCurTransfer->cbTransferred< m_pCurTransfer->cbBuffer? m_pCurTransfer->cbBuffer-m_pCurTransfer->cbTransferred: 0);
if (dwSize!=0) {
dwSize= ReceiveData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred , dwSize);
m_pCurTransfer->cbTransferred += dwSize;
}
bComplete = (bComplete || (m_pCurTransfer->cbTransferred>= m_pCurTransfer->cbBuffer));
// Check for the completeion.
if ( bComplete ) {
WriteControlStatusRegister( udccsr.ulValue);
PSTransfer pTransfer =CompleteTransfer(UFN_NO_ERROR);
bContinue = TRUE;
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
}
else { // Error
udccsr.ep0bit.FST = 1;
}
}
else { // Transfer Not queue yet.
//m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,FALSE);
// Do not clean OPC
udccsr.ep0bit.OPC = 0;
}
}
if (udccsr.ep0bit.IPR==0 ) {
// Because the Ep0 is half duplex. We assume the direction is correct.
if (m_pCurTransfer && (m_pCurTransfer->dwFlags & USB_IN_TRANSFER)!=0 &&
m_pCurTransfer->cbTransferred <= m_pCurTransfer->cbBuffer) {
DWORD dwTotalData = m_pCurTransfer->cbBuffer - m_pCurTransfer->cbTransferred ;
dwTotalData = min (dwTotalData,m_epDesc.wMaxPacketSize) ;
// Spec 12.5.5
DWORD dwReturn = XmitData(((PBYTE)m_pCurTransfer->pvBuffer)+ m_pCurTransfer->cbTransferred, dwTotalData );
ASSERT(dwReturn == dwTotalData);
m_pCurTransfer->cbTransferred += dwReturn;
if (dwTotalData< m_epDesc.wMaxPacketSize) {
udccsr.ep0bit.IPR = 1;
m_fZeroPacket = FALSE;
}
else
m_fZeroPacket = (m_cur_udr.wLength > m_pCurTransfer->cbTransferred);
}
}
else
udccsr.ep0bit.IPR = 0 ; // Do not set when there is packet.
if (udccsr.ep0bit.SST) { // Stall happens.
m_pUsbDevice->IncEp0StallCounter() ;
DEBUGMSG(ZONE_TRANSFER, (_T("Stall Sent on Zero endpoint =0x%x"),m_dwEndpointIndex));
}
// Clean the status.
WriteControlStatusRegister( udccsr.ulValue);
if (m_pCurTransfer &&m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer && !m_fZeroPacket ) {// Complete anyway
PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
}
}
m_fInIST = FALSE;
Unlock();
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
DWORD BulEndpointIn::IST(DWORD dwIRBit)
{
Lock();
BOOL bContinue = TRUE;
SETFNAME();
FUNCTION_ENTER_MSG();
if ((dwIRBit & EPINT_FIFO_ERROR)!=0) { // FIFO Error. End
DWORD dwUdccsr;
dwUdccsr = ReadControlStatusRegister();
DEBUGMSG(ZONE_WARNING, (_T("FIFO Error on Endpoint IN(%d) UDCCSR=0x%x"),m_dwEndpointIndex,dwUdccsr));
}
while (bContinue)
{ // Loop until all the event clear.
bContinue = FALSE;
UDCCSR udccsr;
udccsr.ulValue = ReadControlStatusRegister();
DEBUGMSG(ZONE_TRANSFER, (_T(" IN::IST(%d) UDCCSR=0x%x"),m_dwEndpointIndex,udccsr.ulValue));
if (m_fStalled && (udccsr.epbit.PC!=0 || udccsr.epbit.TRN!=0) ) {
// Stall has been clear silently. So we generate Faking Clear Feature for Endpoint Zero
m_fStalled = FALSE;
udccsr.epbit.PC = udccsr.epbit.TRN = udccsr.epbit.FEF = 0;
WriteControlStatusRegister(udccsr.ulValue);
bContinue = TRUE;
SendFakeFeature(USB_REQUEST_CLEAR_FEATURE,USB_FEATURE_ENDPOINT_STALL);
continue;
}
if ( udccsr.epbit.PC!=0 ) { // Packet Complete.
if (udccsr.epbit.DPE!=0 ) { // Data Packet Error
WriteControlStatusRegister(udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer( UFN_NOT_COMPLETE_ERROR );
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
if ( m_pCurTransfer && !m_fZeroPacket && m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
WriteControlStatusRegister(udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
bContinue = TRUE;
}
udccsr.epbit.SP = 0;
if ( udccsr.epbit.FS!=0 && m_pCurTransfer!=NULL &&
(m_pCurTransfer->cbTransferred < m_pCurTransfer->cbBuffer || m_fZeroPacket) ) { // Include Eaqual for 0 packet.
ASSERT((m_pCurTransfer->dwFlags & USB_IN_TRANSFER)!=NULL);
DWORD dwXmitLength = (m_fZeroPacket?0:m_pCurTransfer->cbBuffer-m_pCurTransfer->cbTransferred);
dwXmitLength = XmitData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred, dwXmitLength );
m_pCurTransfer->cbTransferred += dwXmitLength;
m_fZeroPacket = FALSE;
if (dwXmitLength < m_epDesc.wMaxPacketSize) {
udccsr.epbit.SP = 1;
m_fZeroPacket = FALSE;
}
else
m_fZeroPacket = FALSE;
bContinue = TRUE;
}
if (udccsr.epbit.SST) {
DEBUGMSG(ZONE_WARNING, (_T("Stall send on In Endpoint = 0x%x"),m_dwEndpointIndex));
// We have to assume we clean stall here because this no more interrupt.
udccsr.epbit.FST = 0 ;
m_fStalled = FALSE;
bContinue = TRUE;
WriteControlStatusRegister(udccsr.ulValue);
SendFakeFeature(USB_REQUEST_CLEAR_FEATURE,USB_FEATURE_ENDPOINT_STALL);
continue;
}
WriteControlStatusRegister(udccsr.ulValue);
}
Unlock();
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
DWORD BulEndpointOut::IST(DWORD dwIRBit)
{
Lock();
BOOL bContinue = TRUE;
SETFNAME();
FUNCTION_ENTER_MSG();
if ((dwIRBit & EPINT_FIFO_ERROR)!=0) { // FIFO Error. End
DWORD dwUdccsr;
dwUdccsr = ReadControlStatusRegister();
DEBUGMSG(ZONE_WARNING, (_T("FIFO Error on Endpoint Out(%d) UDCCSR=0x%x"),m_dwEndpointIndex,dwUdccsr));
}
while (bContinue) {
bContinue = FALSE;
UDCCSR udccsr;
udccsr.ulValue = ReadControlStatusRegister();
DEBUGMSG(ZONE_TRANSFER, (_T(" Out::IST(%d) UDCCSR=0x%x"),m_dwEndpointIndex,udccsr.ulValue));
if (m_fStalled && (udccsr.epbit.PC!=0 || udccsr.epbit.TRN!=0) ) {
// Stall has been clear silently. So we generate Faking Clear Feature for Endpoint Zero
m_fStalled = FALSE;
udccsr.epbit.PC = udccsr.epbit.TRN = udccsr.epbit.FEF = 0;
WriteControlStatusRegister(udccsr.ulValue);
bContinue = TRUE;
SendFakeFeature(USB_REQUEST_CLEAR_FEATURE,USB_FEATURE_ENDPOINT_STALL);
continue;
}
// Unload in data if there is any
if ( udccsr.epbit.FS!=0 && m_pCurTransfer!=NULL &&
m_pCurTransfer->cbTransferred < m_pCurTransfer->cbBuffer) { // Include Eaqual for 0 packet.
DWORD dwReceiveLength = min (ReadByteCountRegister(),m_pCurTransfer->cbBuffer - m_pCurTransfer->cbTransferred);
dwReceiveLength = ReceiveData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred,dwReceiveLength);
m_pCurTransfer->cbTransferred += dwReceiveLength;
if (m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
WriteControlStatusRegister(udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
else
bContinue = TRUE;
}
if ( udccsr.epbit.PC!=0 ) { // Packet Complete.
if (udccsr.epbit.DPE!=0 ) { // Data Packet Error
WriteControlStatusRegister(udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer( UFN_NOT_COMPLETE_ERROR );
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
if ( m_pCurTransfer) {
BOOL fShortPacket = FALSE;
if (udccsr.epbit.BNE_BNF!=0 &&
m_pCurTransfer->cbTransferred < m_pCurTransfer->cbBuffer) { // Last Try.
DWORD dwReceiveLength = min (ReadByteCountRegister(),m_pCurTransfer->cbBuffer - m_pCurTransfer->cbTransferred);
dwReceiveLength = ReceiveData((PBYTE)m_pCurTransfer->pvBuffer + m_pCurTransfer->cbTransferred,dwReceiveLength);
m_pCurTransfer->cbTransferred += dwReceiveLength;
fShortPacket = (dwReceiveLength!=0 && dwReceiveLength<m_epDesc.wMaxPacketSize) ;
}
if (m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
WriteControlStatusRegister(udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
else if (udccsr.epbit.SP || fShortPacket ){
WriteControlStatusRegister(udccsr.ulValue);
PSTransfer pTransfer = CompleteTransfer(UFN_NO_ERROR);
Unlock();
m_pUsbDevice->MddTransferComplete(pTransfer);
Lock();
continue;
}
bContinue = TRUE;
}
else { // Not ready yet.
//m_pUsbDevice->EnableEndpointInterrupt(m_dwEndpointIndex,FALSE);
// Do not clean anything
udccsr.epbit.PC = 0;
bContinue = FALSE;
}
}
if (udccsr.epbit.SST) {
DEBUGMSG(ZONE_WARNING, (_T("Stall Sent on Out endpoint =0x%x"),m_dwEndpointIndex));
m_fStalled = TRUE;
bContinue = TRUE;
}
if (udccsr.ulValue)
WriteControlStatusRegister(udccsr.ulValue);
}
Unlock();
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
BulUsbDevice::BulUsbDevice(LPCTSTR lpActivePath )
: CRegistryEdit(lpActivePath)
, CMiniThread (0, TRUE)
{
m_pUsbDevReg = NULL;
m_hISTEvent = NULL;
m_pDCCLKReg = NULL;
m_fDoubleBuffer = TRUE;
m_pvMddContext = NULL;
m_dwCurConfigure = MAXDWORD;
m_dwCurInterface = MAXDWORD;
m_pfnNotify = NULL;
m_CurPowerState = PwrDeviceUnspecified ;
m_hParent = CreateBusAccessHandle(lpActivePath);
m_pOTGEventThread = NULL;
m_fOTGSetupFeature = FALSE;
}
BulUsbDevice::~BulUsbDevice()
{
if (m_pOTGEventThread)
delete m_pOTGEventThread;
if (m_hISTEvent) {
m_bTerminated=TRUE;
ThreadStart();
SetEvent(m_hISTEvent);
ThreadTerminated(1000);
InterruptDisable( m_dwSysIntr );
CloseHandle(m_hISTEvent);
};
for (DWORD dwIndex =0 ; dwIndex <MAX_ENDPOINT_NUMBER; dwIndex ++) {
RemoveObjectBy( dwIndex );
}
if (m_pUsbDevReg!=NULL) {
WriteIntrCtr0Register(0);
WriteIntrCtr1Register(0);
WriteControlRegister(0) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -