📄 pdd.c
字号:
}
// Deattach device
CLRREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_PULLUP_EN);
pPdd->m_NewPowerState = prevPowerState;
UpdateDevicePower(pPdd);
// Done
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_DeinitEndpoint
//
// This function is called when pipe to endpoint is closed. For OMAP7XX we
// will stop points in UfnPdd_DeregisterDevice.
//
DWORD WINAPI UfnPdd_DeinitEndpoint(VOID *pPddContext, DWORD endPoint)
{
USBFN_PDD *pPdd = pPddContext;
OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
DWORD epNum;
DEBUGMSG(ZONE_PDD, (L"UfnPdd_DeinitEndpoint: %d\r\n", endPoint));
// Select EP
epNum = USBD_EP_NUM & endPoint;
SelectEp(pPdd, epNum);
// Clear EP
OUTREG32(&pUSBDRegs->CTRL, USBD_CTRL_CLR_EP);
// Deselect EP
DeselectEp(pPdd, epNum);
// Done
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_InitEndpoint
//
// This function is called when pipe to endpoint is created. For OMAP7XX
// all initialization must be done in UfnPdd_RegisterDevice.
//
DWORD WINAPI UfnPdd_InitEndpoint(VOID *pContext,
DWORD endPoint,
UFN_BUS_SPEED speed,
USB_ENDPOINT_DESCRIPTOR *pEPDesc,
VOID *pReserved,
UCHAR configValue,
UCHAR interfaceNumber,
UCHAR alternateSetting)
{
DEBUGMSG(ZONE_PDD, (L"UfnPdd_InitEndpoint: %d\r\n", endPoint));
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_SetAddress
//
// This function is called by MDD when configuration process assigned address
// to device. For OMAP7xx this is managed by hardware.
//
DWORD WINAPI UfnPdd_SetAddress(VOID *pPddContext, UCHAR address)
{
DEBUGMSG(ZONE_PDD, (L"UfnPdd_SetAddress(0x%08X, 0x%02X)\r\n", pPddContext, address));
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_Start
//
// This function is called after UfnPdd_RegisterDevice. It should attach
// device to USB bus.
//
DWORD WINAPI UfnPdd_Start(VOID *pPddContext)
{
DWORD rv;
DEBUGMSG(ZONE_FUNCTION, (L"UfnPdd_Start() - START\r\n"));
if (pPddContext == NULL)
{
DEBUGMSG(ZONE_ERROR, (L"UfnPdd_Start() - "
L"Invalid Parameter: pPddContext is NULL\r\n"));
rv = ERROR_INVALID_PARAMETER;
}
else
{
USBFN_PDD * pPdd = pPddContext;
OMAP2420_USBD_REGS * pUSBDRegs = pPdd->pUSBDRegs;
pPdd->m_NewPowerState = D2;
UpdateDevicePower(pPdd);
// Enable interrupts
OUTREG32(&pUSBDRegs->IRQ_EN, USBD_IRQ_MASK);
// Attach device to bus (it has no effect when OTG controller is used)
SETREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_PULLUP_EN);
// Set fake device change flag which on first interrupt force
// device state change handler even if it isn't indicated by hardware
pPdd->fakeDsChange = TRUE;
rv = ERROR_SUCCESS;
}
DEBUGMSG(ZONE_FUNCTION, (L"UfnPdd_Start() - END\r\n"));
// Done
return rv;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_RegisterDevice
//
// This function is called by MDD after device configuration was sucessfully
// verified by UfnPdd_IsEndpointSupportable and
// UfnPdd_IsConfigurationSupportable. It should initialize hardware for given
// configuration. Depending on hardware endpoints can be initialized later in
// UfnPdd_InitEndpoint. For OMAP7xx it isn't a case, so we should do all
// initialization there.
//
DWORD WINAPI UfnPdd_RegisterDevice(VOID *pPddContext,
const USB_DEVICE_DESCRIPTOR *pHighSpeedDeviceDesc,
const UFN_CONFIGURATION *pHighSpeedConfig,
const USB_CONFIGURATION_DESCRIPTOR *pHighSpeedConfigDesc,
const USB_DEVICE_DESCRIPTOR *pFullSpeedDeviceDesc,
const UFN_CONFIGURATION *pFullSpeedConfig,
const USB_CONFIGURATION_DESCRIPTOR *pFullSpeedConfigDesc,
const UFN_STRING_SET *pStringSets,
DWORD stringSets)
{
DWORD rc = ERROR_INVALID_PARAMETER;
USBFN_PDD *pPdd = pPddContext;
OMAP2420_USBD_REGS *pUSBDRegs = pPdd->pUSBDRegs;
UFN_INTERFACE *pIFC;
UFN_ENDPOINT *pEP;
DWORD offset, ep;
DWORD ifc, epx;
DWORD cfg;
DEBUGMSG(ZONE_FUNCTION, (L"UfnPdd_RegisterDevice() - START\r\n"));
// Remember self powered flag
pPdd->selfPowered = ((pFullSpeedConfig->Descriptor.bmAttributes & 0x20) != 0);
// Unlock configuration
CLRREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_CFG_LOCK);
DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - "
L"Configuring EndPoint 00 (RX)\r\n"));
// Configure EP0
offset = 8;
cfg = (Log2(pFullSpeedDeviceDesc->bMaxPacketSize0 >> 3) << 12);
cfg |= offset >> 3;
OUTREG32(&pUSBDRegs->EP0, cfg);
pPdd->ep[0].maxPacketSize = pFullSpeedDeviceDesc->bMaxPacketSize0;
offset += pFullSpeedDeviceDesc->bMaxPacketSize0;
// Configure Rx EPs
for (ifc = 0; ifc < pFullSpeedConfig->Descriptor.bNumInterfaces; ifc++)
{
// For each endpoint in interface...
pIFC = &pFullSpeedConfig->pInterfaces[ifc];
for (epx = 0; epx < pIFC->Descriptor.bNumEndpoints; epx++)
{
pEP = &pIFC->pEndpoints[epx];
// If it is Tx EP skip it
if ((pEP->Descriptor.bEndpointAddress & 0x80) != 0)
{
continue;
}
DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - "
L"Configuring Interface %02u EndPoint %02u (RX)\r\n", ifc, epx));
// Get EP address
ep = pEP->Descriptor.bEndpointAddress & 0x0F;
// Save max packet size & direction
pPdd->ep[ep].maxPacketSize = pEP->Descriptor.wMaxPacketSize;
pPdd->ep[ep].dirRx = TRUE;
// Create EP config
cfg = USBD_EP_VALID;
cfg |= (Log2(pEP->Descriptor.wMaxPacketSize >> 3) << 12);
if ((pEP->Descriptor.bmAttributes & 0x03) == 0x01)
{
cfg |= USBD_EP_ISO;
}
cfg |= offset >> 3;
if (ep > 0)
OUTREG32(&pUSBDRegs->EP_RX[ep - 1], cfg);
else
DEBUGMSG(ZONE_PDD, (L"USBFN:: UfnPdd_RegisterDevice EP_RX = %d\r\n", ep - 1));
// Update offset
offset += pEP->Descriptor.wMaxPacketSize;
}
}
// Configure Tx EPs
for (ifc = 0; ifc < pFullSpeedConfig->Descriptor.bNumInterfaces; ifc++)
{
// For each endpoint in interface
pIFC = &pFullSpeedConfig->pInterfaces[ifc];
for (epx = 0; epx < pIFC->Descriptor.bNumEndpoints; epx++)
{
pEP = &pIFC->pEndpoints[epx];
// If it is Rx EP skip it
if ((pEP->Descriptor.bEndpointAddress & 0x80) == 0)
{
continue;
}
DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - "
L"Configuring Interface %02u EndPoint %02u (TX)\r\n", ifc, epx));
// Get EP address
ep = pEP->Descriptor.bEndpointAddress & 0x0F;
// Save max packet size & direction
pPdd->ep[ep].maxPacketSize = pEP->Descriptor.wMaxPacketSize;
pPdd->ep[ep].dirRx = FALSE;
// Create EP config
cfg = USBD_EP_VALID;
cfg |= (Log2(pEP->Descriptor.wMaxPacketSize >> 3) << 12);
if ((pEP->Descriptor.bmAttributes & 0x03) == 0x01)
{
cfg |= USBD_EP_ISO;
}
cfg |= offset >> 3;
if (ep > 0)
OUTREG32(&pUSBDRegs->EP_TX[ep - 1], cfg);
else
DEBUGMSG(ZONE_PDD, (L"USBFN:: UfnPdd_RegisterDevice "
L"EP_TX = %d\r\n", ep - 1));
// Update offset
offset += pEP->Descriptor.wMaxPacketSize;
}
}
// Lock configuration
SETREG32(&pUSBDRegs->SYSCON1, USBD_SYSCON1_CFG_LOCK);
DEBUGMSG(ZONE_PDD, (L"UfnPdd_RegisterDevice() - END\r\n"));
// Done
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_IsEndpointSupportable
//
// This function is called by MDD to verify if EP can be supported on
// hardware. It is called after UfnPdd_IsConfigurationSupportable. We must
// verify configuration in this function, so we already know that EPs
// are valid. Only information we can update there is maximal packet
// size for EP0.
//
DWORD WINAPI UfnPdd_IsEndpointSupportable(VOID *pPddContext,
DWORD endPoint,
UFN_BUS_SPEED speed,
USB_ENDPOINT_DESCRIPTOR *pEPDesc,
UCHAR configurationValue,
UCHAR interfaceNumber,
UCHAR alternateSetting)
{
USBFN_PDD *pPdd = pPddContext;
// Update maximal packet size for EP0
if (endPoint == 0)
{
DEBUGCHK(pEPDesc->wMaxPacketSize <= 64);
DEBUGCHK(pEPDesc->bmAttributes == USB_ENDPOINT_TYPE_CONTROL);
pEPDesc->wMaxPacketSize = 64;
}
// Done
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_IsConfigurationSupportable
//
// This function is called before UfnPdd_RegisterDevice. It should verify
// that USB device configuration can be supported on hardware. Function can
// modify EP size and/or EP address.
//
// For OMAP7xx we should check if total descriptor size is smaller
/// than 2040 bytes and round EP sizes. Unfortunately we don't get information
// about EP0 max packet size. So we will assume maximal 64 byte size.
//
DWORD WINAPI UfnPdd_IsConfigurationSupportable(VOID * pPddContext,
UFN_BUS_SPEED speed,
UFN_CONFIGURATION * pConfig)
{
DWORD rc = ERROR_INVALID_PARAMETER;
USBFN_PDD *pPdd = pPddContext;
UFN_INTERFACE *pIFC;
UFN_ENDPOINT *pEP;
DWORD ifc, epx, count;
DWORD offset, size;
// TODO: Update self power bit & maxPower
// We must start with offset 8 + 64 (config plus EP0 size)
offset = 8 + 64;
// Clear number of end points
count = 0;
// For each interface in configuration
for (ifc = 0; ifc < pConfig->Descriptor.bNumInterfaces; ifc++)
{
// For each endpoint in interface
pIFC = &pConfig->pInterfaces[ifc];
for (epx = 0; epx < pIFC->Descriptor.bNumEndpoints; epx++)
{
pEP = &pIFC->pEndpoints[epx];
// We support maximal sizes 8, 16, 32 and 64 bytes for non-ISO
size = pEP->Descriptor.wMaxPacketSize;
// First round size to supported sizes
size = 1 << Log2(size);
// Is it ISO end point?
if ((pEP->Descriptor.bmAttributes & 0x03) != 0x01)
{
// Non-ISO, max size is 64 bytes
if (size > 64)
{
size = 64;
}
}
else
{
// ISO edpoint, maximal size is 512 bytes
if (size > 512)
{
size = 512;
}
}
// Update EP size
pEP->Descriptor.wMaxPacketSize = (USHORT)size;
// Calculate total buffer size
offset += size;
}
// Add number of end points to total count
count += pIFC->Descriptor.bNumEndpoints;
}
// Can we support this configuration?
if (count < USBD_EP_COUNT && offset <= 2048)
{
rc = ERROR_SUCCESS;
}
// Done
return rc;
}
//------------------------------------------------------------------------------
//
// Function: UfnPdd_Init
//
// This function is called by MDD on driver load. It should reset driver,
// fill PDD interface structure. It can also get SYSINTR, initialize interrupt
// threa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -