📄 bul_usbfn.cpp
字号:
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;
}
// Interface Function.
DWORD BulUsbDevice::IsEndpointSupportable (DWORD dwEndpoint,UFN_BUS_SPEED Speed,PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
BYTE bConfigurationValue, BYTE bInterfaceNumber, BYTE bAlternateSetting )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s Enter. dwEndpoint:0x%x,Speed:0x%x --\r\n"), pszFname,dwEndpoint,Speed));
Lock();
if ((Speed & BS_FULL_SPEED)==BS_FULL_SPEED && pEndpointDesc &&
dwEndpoint < MAX_ENDPOINT_NUMBER && RawObjectIndex(dwEndpoint)==0 ) {
BulEndpoint *pEndpoint = NULL;
if (dwEndpoint == 0 ) // Endpoint Zero.
#if 0
pEndpoint = new BulEndpointZero(this,m_fDoubleBuffer);
#else
{
BulEndpointZero *pEndpointZero = (BulEndpointZero *)&g_bulUsbEPs[dwEndpoint][0];
pEndpointZero->BulEndpointZero::BulEndpointZero(this,m_fDoubleBuffer);
pEndpoint = pEndpointZero;
}
#endif
else {
#if 0
if ( (pEndpointDesc->bEndpointAddress & 0x80)!=0)
pEndpoint = new BulEndpointIn(this,dwEndpoint,m_fDoubleBuffer);
else
pEndpoint = new BulEndpointOut(this,dwEndpoint,m_fDoubleBuffer);
#else
if ( (pEndpointDesc->bEndpointAddress & 0x80)!=0) {
BulEndpointIn *pEndpointIn = (BulEndpointIn *)&g_bulUsbEPs[dwEndpoint][0];
pEndpointIn->BulEndpointIn::BulEndpointIn(this,dwEndpoint,m_fDoubleBuffer);
pEndpoint = pEndpointIn;
}
else {
BulEndpointOut *pEndpointOut = (BulEndpointOut *)&g_bulUsbEPs[dwEndpoint][0];
pEndpointOut->BulEndpointOut::BulEndpointOut(this,m_fDoubleBuffer);
pEndpoint = pEndpointOut;
}
#endif // 0
}
if (pEndpoint && pEndpoint->Init(pEndpointDesc,bConfigurationValue,bInterfaceNumber,bAlternateSetting)) {
dwError = ERROR_SUCCESS;
InsertObject(dwEndpoint, pEndpoint) ;
}
else {
if (pEndpoint) {
delete pEndpoint;
}
}
}
Unlock();
ASSERT(dwError == ERROR_SUCCESS);
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s return errorcode = %d --\r\n"), pszFname,dwError));
return dwError;
}
DWORD BulUsbDevice::InitEndpoint(DWORD dwEndpoint,UFN_BUS_SPEED Speed,PUSB_ENDPOINT_DESCRIPTOR pEndpointDesc,
BYTE bConfigurationValue, BYTE bInterfaceNumber, BYTE bAlternateSetting )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->InitEndpoint(Speed, pEndpointDesc);
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
};
DWORD BulUsbDevice::DeinitEndpoint(DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->DeinitEndpoint();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::StallEndpoint(DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->StallEndpoint();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::ClearEndpointStall( DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->ClearEndpointStall();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::ResetEndpoint(DWORD dwEndpoint )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->ResetEndpoint();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::IsEndpointHalted( DWORD dwEndpoint, PBOOL pfHalted )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->IsEndpointHalted(pfHalted);
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::IssueTransfer(DWORD dwEndpoint,PSTransfer pTransfer )
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->IssueTransfer(pTransfer);
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
DWORD BulUsbDevice::AbortTransfer(DWORD dwEndpoint, PSTransfer pTransfer)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
if (pTransfer) {
BulEndpoint *pEndpoint = ObjectIndex(dwEndpoint);
if (pEndpoint) {
dwError = pEndpoint->AbortTransfer(pTransfer);
pEndpoint->DeRef();
}
}
FUNCTION_LEAVE_MSG();
return dwError;
}
// Endpoint Zero Special
DWORD BulUsbDevice::SendControlStatusHandshake(DWORD dwEndpoint)
{
DWORD dwError = ERROR_INVALID_PARAMETER;
SETFNAME();
FUNCTION_ENTER_MSG();
BulEndpoint *pEndpoint = ObjectIndex(0);
if (pEndpoint) {
dwError = pEndpoint->SendControlStatusHandshake();
pEndpoint->DeRef();
}
FUNCTION_LEAVE_MSG();
return dwError;
}
// Device Function.
DWORD BulUsbDevice::Start()
{
SETFNAME();
FUNCTION_ENTER_MSG();
DWORD dwReturn = ERROR_SUCCESS;
Lock();
//ASSERT(m_pvMddContext==NULL);
m_dwCurConfigure = MAXDWORD;
m_dwCurInterface = MAXDWORD;
// Enable Device Interrupt.
WriteIntrCtr1Register( ReadIntrCtr1Register() |
(UDCISR1_IRCC | UDCISR1_IRRU | UDCISR1_IRSU |UDCISR1_IRRS ));
// Enable UDC.
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
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::PowerDown()
{
}
void BulUsbDevice::PowerUp()
{
ReInit();
}
void BulUsbDevice::SetPowerState( CEDEVICE_POWER_STATE cpsNew )
{
SETFNAME();
}
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:
break;
case IOCTL_BUS_SET_POWER_STATE:
break;
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
#ifdef DEBUG
const DWORD cISTTimeOut = 2000;
#else
const DWORD cISTTimeOut = INFINITE ;
#endif
DWORD BulUsbDevice::ThreadRun()
{
SETFNAME();
FUNCTION_ENTER_MSG();
#if 0
while (!m_bTerminated && m_hISTEvent!=NULL) {
if ( WaitForSingleObject(m_hISTEvent,cISTTimeOut) != WAIT_OBJECT_0) {
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s : Interrupt Time out dwIntr0Status=0x%x dwIntr1Status = 0x%x. dwIntr0Ctrl=0x%x, dwIntr11Ctrl=0x%x\r\n"),pszFname,
ReadIntrStatus0Register(), ReadIntrStatus1Register(),ReadIntrCtr0Register(), ReadIntrCtr1Register() ));
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s : ControlRegister() =0x%x ControlStatusRegister(0)=0x%x\r\n"),pszFname,
ReadControlRegister(), ReadUDCRegister( ENDPOINT_CONTROL_STATUS_REGISTER_OFFSET + 0 ) ));
continue;
}
#else
while (TRUE) {
BOOL fInterrupt = FALSE;
#endif
DWORD dwIntr0Status = ReadIntrStatus0Register() ;
DWORD dwIntr1Status = ReadIntrStatus1Register() ;
WriteIntrStatus0Register(dwIntr0Status) ;
WriteIntrStatus1Register(dwIntr1Status) ;
OALMSG(OAL_ETHER&&OAL_FUNC, (
_T("%s : BulUsbDevice dwIntr0Status 0x%x, dwIntr1Status 0x%x,dwIntr0Ctrl=0x%x, dwIntr11Ctrl=0x%x\r\n "), pszFname, dwIntr0Status,dwIntr1Status,ReadIntrCtr0Register(), ReadIntrCtr1Register() ));
// Check Cable in any Interrupt.
if (m_fIsCableAttached != IsCableAttached()) {
m_fIsCableAttached = IsCableAttached();
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
udccr.bit.EMCE = 0 ;
if (m_fIsCableAttached) {
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s : Attach Detected\r\n"),pszFname));
ReInit();
}
else {
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s : Detach Detected\r\n"),pszFname));
DeviceNotification( UFN_MSG_BUS_EVENTS, UFN_DETACH);
}
fInterrupt = TRUE;
}
// Processing Device Interrupt
if ( dwIntr1Status & UDCISR1_IRCC) { // Setup Config or Setup Interface has been received.
USB_DEVICE_REQUEST udr;
UDCCR udccr;
udccr.ulValue = ReadControlRegister();
OALMSG(OAL_ETHER&&OAL_FUNC, (_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);
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);
}
fInterrupt = TRUE;
}
if ( dwIntr1Status & UDCISR1_IRRU) { // Resume Detected
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s : Resume Detected\r\n"),pszFname));
fInterrupt = TRUE;
}
if (dwIntr1Status & UDCISR1_IRSU ) { // Suspend Detected.
OALMSG(OAL_ETHER&&OAL_FUNC, (_T("%s : Suspend Detected\r\n"),pszFname));
fInterrupt = TRUE;
}
if (dwIntr1Status & UDCISR1_IRRS) { // Reset Detected.
OALMSG(OAL_ETHER&&OAL_FUNC, (_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 ;
}
fInterrupt = TRUE;
}
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 ));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -