bul_usbfn.cpp
来自「pxa27x library for windows ce 5.0」· C++ 代码 · 共 1,704 行 · 第 1/4 页
CPP
1,704 行
bContinue = TRUE;
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 = TRUE;
}
}
else
udccsr.ep0bit.IPR = 0 ; // Do not set when there is packet.
if (udccsr.ep0bit.SST) { // Stall happens.
DEBUGMSG(ZONE_WARNING, (_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
CompleteTransfer(UFN_NO_ERROR);
}
}
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);
CompleteTransfer( UFN_NOT_COMPLETE_ERROR );
continue;
}
if ( m_pCurTransfer && !m_fZeroPacket && m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
WriteControlStatusRegister(udccsr.ulValue);
CompleteTransfer(UFN_NO_ERROR);
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));
m_fStalled = TRUE;
bContinue = TRUE;
}
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);
CompleteTransfer(UFN_NO_ERROR);
continue;
}
else
bContinue = TRUE;
}
if ( udccsr.epbit.PC!=0 ) { // Packet Complete.
if (udccsr.epbit.DPE!=0 ) { // Data Packet Error
WriteControlStatusRegister(udccsr.ulValue);
CompleteTransfer( UFN_NOT_COMPLETE_ERROR );
continue;
}
if ( m_pCurTransfer) {
if (m_pCurTransfer->cbTransferred >= m_pCurTransfer->cbBuffer) {
WriteControlStatusRegister(udccsr.ulValue);
CompleteTransfer(UFN_NO_ERROR);
continue;
}
else if (udccsr.epbit.SP ){
WriteControlStatusRegister(udccsr.ulValue);
CompleteTransfer(UFN_NO_ERROR);
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;
}
WriteControlStatusRegister(udccsr.ulValue);
}
Unlock();
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
BulUsbDevice::BulUsbDevice(LPCTSTR lpActivePath )
: CRegistryEdit(lpActivePath)
, CMiniThread (0, TRUE)
{
m_pUsbDevReg = NULL;
for (DWORD dwIndex =0 ; dwIndex <MAX_ENDPOINT_NUMBER; dwIndex ++) {
m_EndpointArray[dwIndex] = 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);
}
BulUsbDevice::~BulUsbDevice()
{
if (m_hParent)
CloseBusAccessHandle(m_hParent);
if (m_pUsbDevReg!=NULL) {
WriteIntrCtr0Register(0);
WriteIntrCtr1Register(0);
WriteControlRegister(0) ;
MmUnmapIoSpace((PVOID)m_pUsbDevReg,0UL);
}
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 ++) {
if (m_EndpointArray[dwIndex] != NULL)
delete m_EndpointArray[dwIndex];
}
if (m_pDCCLKReg) {
m_pDCCLKReg->cken &= ~XLLP_CLKEN_USBCLIENT ;
MmUnmapIoSpace(m_pDCCLKReg,0);
}
}
DWORD BulUsbDevice::Init(
PVOID pvMddContext,
PUFN_MDD_INTERFACE_INFO pMddInterfaceInfo,
PUFN_PDD_INTERFACE_INFO pPddInterfaceInfo
)
{
m_pvMddContext = pvMddContext;
m_pfnNotify = pMddInterfaceInfo->pfnNotify;
pPddInterfaceInfo->pvPddContext = this;
if ( !IsKeyOpened())
return ERROR_INVALID_DATA;
DDKISRINFO dii;
DDKWINDOWINFO dwi;
DWORD dwRet = GetWindowInfo(&dwi);
if(dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT, (_T("BulUsbDevice:: DDKReg_GetWindowInfo() failed %d\r\n"), dwRet));
return dwRet;
} else if(dwi.dwNumMemWindows != 1) {
return ERROR_INVALID_DATA;
} else if (dwi.memWindows[0].dwLen < sizeof(BULVERDE_USBD_REG)) {
DEBUGMSG(ZONE_INIT, (_T("memLen of 0x%x is less than required 0x%x\r\n"),
dwi.memWindows[0].dwLen, sizeof(BULVERDE_USBD_REG)));
return ERROR_INVALID_DATA;
}
m_fIsCableAttached = FALSE;
if (m_pDCCLKReg == NULL ) {
PHYSICAL_ADDRESS ioPhysicalBase = {BULVERDE_BASE_REG_PA_CLKMGR, 0 };
m_pDCCLKReg = (PBULVERDE_CLKMGR_REG)MmMapIoSpace(ioPhysicalBase, sizeof(BULVERDE_CLKMGR_REG),FALSE);
if (m_pDCCLKReg != NULL)
m_pDCCLKReg->cken |= XLLP_CLKEN_USBCLIENT ;
else
return ERROR_INVALID_DATA;
}
// Map Windows.
// Translate to System Address.
if (m_pUsbDevReg==NULL ) {
PHYSICAL_ADDRESS ioPhysicalBase = { dwi.memWindows[0].dwBase, 0};
m_pUsbDevReg = (PULONG) MmMapIoSpace(ioPhysicalBase, dwi.memWindows[0].dwLen,FALSE);
if (m_pUsbDevReg==NULL )
return ERROR_INVALID_DATA;
}
// get ISR configuration information
dwRet = GetIsrInfo( &dii);
if(dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT, (_T("BulUsbDevice DDKReg_GetIsrInfo() failed %d\r\n"), dwRet));
return dwRet;
} else if(dii.dwSysintr == SYSINTR_NOP){
DEBUGMSG(ZONE_INIT, (_T("BulUsbDevice no SYSINTR value specified\r\n")));
return ERROR_INVALID_DATA;
};
m_dwSysIntr = dii.dwSysintr;
m_hISTEvent= CreateEvent(0,FALSE,FALSE,NULL);
if (m_hISTEvent!=NULL)
InterruptInitialize(m_dwSysIntr,m_hISTEvent,0,0);
else
return ERROR_INVALID_DATA;
// Optional Registry.
DWORD dwDataSize = sizeof(DWORD);
DWORD dwDoubleBuffer = 1;
if (!GetRegValue(BUL_USBFUNCTION_DOUBLEBUFFER_VALNAME, (LPBYTE) &dwDoubleBuffer,dwDataSize)){
dwDoubleBuffer = 1;
};
m_fDoubleBuffer = (dwDoubleBuffer==1);
// Read the IST priority
dwDataSize = sizeof(m_dwPriority);
if (!GetRegValue(BUL_USBFUNCTION_PRIORITY_VALNAME,(LPBYTE) &m_dwPriority, dwDataSize)) {
m_dwPriority = BUL_USBFUNCTION_DEFAULT_PRIORITY;
}
CeSetPriority(m_dwPriority);
if (HardwareInit()) {
ThreadStart();
return ERROR_SUCCESS;
}
else
return ERROR_INVALID_DATA;
}
BOOL BulUsbDevice::HardwareInit()
{
BOOL bReturn = TRUE;
SETFNAME();
FUNCTION_ENTER_MSG();
Lock();
// Disable Hardware
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
udccr.bit.UDE= udccr.bit.EMCE = 0;
WriteControlRegister(udccr.ulValue);
WriteIntrCtr0Register(0);
WriteIntrCtr1Register(0);
// Ack all outstanding interrupt.
WriteIntrStatus0Register(0xffffffff);
WriteIntrStatus1Register(0xffffffff);
Unlock();
FUNCTION_LEAVE_MSG();
return bReturn;
}
BOOL BulUsbDevice::ReInit() // For Cable Detach & Attach , We have to re-init the Device Controller.
{
Lock();
HardwareInit();
for (DWORD dwIndex=0; dwIndex<MAX_ENDPOINT_NUMBER; dwIndex++)
if (m_EndpointArray[dwIndex]!=NULL)
m_EndpointArray[dwIndex]->ReInit();
//PVOID pvMddContext = m_pvMddContext;
//m_pvMddContext = NULL;
Start();
for (dwIndex=0; dwIndex<MAX_ENDPOINT_NUMBER; dwIndex++)
if (m_EndpointArray[dwIndex]!=NULL) {
EnableEndpointInterrupt(dwIndex, TRUE);
}
Unlock();
return FALSE;
}
BOOL BulUsbDevice::DeleteAllEndpoint()
{
Lock();
for (DWORD dwIndex=0; dwIndex<MAX_ENDPOINT_NUMBER; dwIndex++)
if (m_EndpointArray[dwIndex]!=NULL) {
delete m_EndpointArray[dwIndex];
m_EndpointArray[dwIndex] = NULL;
}
Unlock();
return TRUE;
}
//
#define UDCIR0_MAX 0x10
BOOL BulUsbDevice::EnableEndpointInterrupt(DWORD dwEndpointIndex,BOOL bEnable)
{
SETFNAME();
DEBUGMSG(ZONE_USB_EVENTS, (_T("%s Enter. dwEndpoint:0x%x,Enable:0x%x --\r\n"), pszFname,dwEndpointIndex,bEnable));
if (dwEndpointIndex < MAX_ENDPOINT_NUMBER ) {
Lock();
if (dwEndpointIndex <UDCIR0_MAX) {
DWORD dwIntrCtrBit = ((EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR) <<(dwEndpointIndex*2));
DWORD dwIntrCtl = ReadIntrCtr0Register() ;
if (bEnable)
dwIntrCtl |= dwIntrCtrBit;
else
dwIntrCtl &= ~dwIntrCtrBit;
WriteIntrCtr0Register(dwIntrCtl);
}
else {
dwEndpointIndex -= UDCIR0_MAX;
DWORD dwIntrCtrBit = ((EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR) <<(dwEndpointIndex*2));
DWORD dwIntrCtl = ReadIntrCtr1Register() ;
if (bEnable)
dwIntrCtl |= dwIntrCtl;
else
dwIntrCtl &= ~dwIntrCtl;
WriteIntrCtr1Register(dwIntrCtl);
}
Unlock();
return TRUE;
}
return FALSE;
}
DWORD BulUsbDevice::GetEndpointIntrStatus(DWORD dwEndpointIndex)
{
DWORD dwReturnStatus = 0;
if (dwEndpointIndex < MAX_ENDPOINT_NUMBER ) {
if (dwEndpointIndex <UDCIR0_MAX) {
dwReturnStatus = (ReadIntrStatus0Register()>>(dwEndpointIndex*2)) & (EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR);
}
else {
dwEndpointIndex -= MAX_ENDPOINT_NUMBER;
dwReturnStatus = (ReadIntrStatus1Register()>>(dwEndpointIndex*2)) & (EPINT_PACKET_COMPLETE | EPINT_FIFO_ERROR);
}
}
return dwReturnStatus;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?