📄 sc2413pdd.cpp-ori
字号:
{
// HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
}
else
{
ClearEndpointInterrupt(pContext, dwEndpoint);
// break;
}
#else
ClearEndpointInterrupt(pContext, dwEndpoint);
HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
#endif
}
}
FUNCTION_LEAVE_MSG();
}
/****************************************************************
@doc INTERNAL
@func VOID | SerUSB_InternalMapRegisterAddresses |
This routine maps the ASIC registers.
It's an artifact of this
implementation.
@rdesc None.
****************************************************************/
static
DWORD MapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(g_pUDCBase == NULL);
PBYTE pVMem;
DWORD dwRet = ERROR_SUCCESS;
// Map CSR registers.
pVMem = (PBYTE)VirtualAlloc(0, PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (pVMem) {
BOOL fSuccess = VirtualCopy(pVMem, (LPVOID)pContext->dwIOBase,
pContext->dwIOLen, PAGE_READWRITE | PAGE_NOCACHE);
if (!fSuccess) {
VirtualFree(pVMem, 0, MEM_RELEASE);
dwRet = GetLastError();
DEBUGMSG(ZONE_ERROR, (_T("%s Virtual Copy: FAILED\r\n"), pszFname));
}
else {
g_pUDCBase = pVMem + BASE_REGISTER_OFFSET;
DEBUGMSG(ZONE_INIT, (_T("%s VirtualCopy Succeeded, pVMem:%x\r\n"),
pszFname, pVMem));
}
}
else {
dwRet = GetLastError();
DEBUGMSG(ZONE_ERROR, (_T("%s Virtual Alloc: FAILED\r\n"), pszFname));
}
FUNCTION_LEAVE_MSG();
return dwRet;
}
/*++
Routine Description:
Deallocate register space.
Arguments:
None.
Return Value:
None.
--*/
static
VOID
UnmapRegisterSet(PCTRLR_PDD_CONTEXT pContext)
{
// Unmap any memory areas that we may have mapped.
if (g_pUDCBase) {
VirtualFree((PVOID) g_pUDCBase, 0, MEM_RELEASE);
g_pUDCBase = NULL;
}
}
// interrupt service routine.
static
DWORD
WINAPI
ISTMain(
LPVOID lpParameter
)
{
static WORD wcnt = 0;
static DWORD dwtimeout;
SETFNAME();
FUNCTION_ENTER_MSG();
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) lpParameter;
ValidateContext(pContext);
CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);
while (!pContext->fExitIST) {
pContext->fRestartIST = FALSE;
// Enable Suspend Mode in the Power Register
SetClearReg(pContext, PWR_REG_OFFSET, SUSPEND_MODE_ENABLE_CTRL, SET);
// Disable All Endpoint interrupts
WriteReg(pContext, EP_INT_EN_REG_OFFSET, 0); // Disable All
// Enable Device interrupts
WriteReg(pContext, USB_INT_EN_REG_OFFSET, (USB_RESET_INTR | USB_SUSPEND_INTR));
// Enable Endpoint interrupt 0
BYTE irqEnBit = EpToIrqStatBit(0);
SetClearReg(pContext, EP_INT_EN_REG_OFFSET, irqEnBit, SET);
// Initialize Index, 050827
// WriteReg(pContext, IDXADDR_REG_OFFSET, (BYTE) 0);
dwtimeout = INFINITE;
// dwtimeout = 1000;
while (TRUE) {
DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, dwtimeout);
if (pContext->fExitIST || pContext->fRestartIST) {
break;
}
#if 0
// hmseo
if (dwWait == WAIT_OBJECT_0) {
wcnt = 0;
}
else
{
wcnt ++;
}
if ( wcnt >= 100 )
dwtimeout = 1000;
// dwtimeout = INFINITE;
else
dwtimeout = 10;
#endif
HandleUSBEvent(pContext);
InterruptDone(pContext->dwSysIntr);
}
// Disable Device interrupts - write Zeros to Disable
WriteReg(pContext, USB_INT_EN_REG_OFFSET, 0 );
// Disable endpoint interrupts - write Zeros to Disable
WriteReg(pContext, EP_INT_EN_REG_OFFSET, 0);
// Clear any outstanding device & endpoint interrupts
// USB Device Interrupt Status - Write a '1' to Clear
WriteReg(pContext, USB_INT_REG_OFFSET,
(USB_RESET_INTR | USB_RESUME_INTR | USB_SUSPEND_INTR));
// End point Interrupt Status - Write a '1' to Clear
WriteReg(pContext, EP_INT_REG_OFFSET, CLEAR_ALL_EP_INTRS);
// Send detach
pContext->pfnNotify(pContext->pvMddContext,
UFN_MSG_BUS_EVENTS, UFN_DETACH);
pContext->fSpeedReported = FALSE;
pContext->attachedState = UFN_DETACH;
}
FUNCTION_LEAVE_MSG();
return 0;
}
static
VOID
StartTransfer(
PCTRLR_PDD_CONTEXT pContext,
PEP_STATUS peps,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(pContext);
PREFAST_DEBUGCHK(peps);
DEBUGCHK(!peps->pTransfer);
ValidateTransferDirection(pContext, peps, pTransfer);
DEBUGMSG(ZONE_TRANSFER, (_T("%s Setting up %s transfer on ep %u for %u bytes\r\n"),
pszFname, (pTransfer->dwFlags == USB_IN_TRANSFER) ? _T("in") : _T("out"),
peps->dwEndPointNumber, pTransfer->cbBuffer));
// Enable transfer interrupts.
peps->pTransfer = pTransfer;
if (pTransfer->dwFlags == USB_IN_TRANSFER) {
// Must Clear both Send and Sent Stall - the HW is setting this bit
// during the Endpoint initialization process. It must be cleared here
// to insure proper operation.
SetClearIndexedReg(pContext, peps->dwEndPointNumber, IN_CSR1_REG_OFFSET, (IN_SEND_STALL | IN_SENT_STALL), CLEAR);
HandleTx(pContext, peps, 1);
}
else {
// Set the Max Packet Size Register
BYTE maxPacketBits = (BYTE) (peps->dwPacketSizeAssigned >> 3);
WriteIndexedReg(pContext, peps->dwEndPointNumber, MAX_PKT_SIZE_REG_OFFSET, maxPacketBits);
EnableEndpointInterrupt(pContext,peps->dwEndPointNumber);
// There may be a packet available. If so process it...
BYTE bEpIrqStat = ReadIndexedReg(pContext, peps->dwEndPointNumber, OUT_CSR1_REG_OFFSET);
if (bEpIrqStat & OUT_PACKET_READY) {
HandleRx(pContext, peps);
}
}
FUNCTION_LEAVE_MSG();
}
DWORD
WINAPI
UfnPdd_IssueTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
// return 1; // 050828
SETFNAME();
FUNCTION_ENTER_MSG();
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
// RETAILMSG(1,(TEXT("\nPDD "))); // 050828
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
DEBUGCHK(peps->fInitialized);
DEBUGCHK(pTransfer->cbTransferred == 0);
DWORD dwRet = ERROR_SUCCESS;
// Note For the HW NAKs IN requests and DOES NOT let SW
// know that the Host is trying to send a request. SO... Start the Transfer
// In Now!
// Start the Transfer
DEBUGCHK(peps->pTransfer == NULL);
StartTransfer(pContext, peps, pTransfer);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return dwRet;
}
DWORD
WINAPI
UfnPdd_AbortTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
PREFAST_DEBUGCHK(pTransfer);
DEBUGCHK(EP_VALID(dwEndpoint));
PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
ValidateContext(pContext);
PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
LOCK_ENDPOINT(peps);
DEBUGCHK(peps->fInitialized);
ValidateTransferDirection(pContext, peps, pTransfer);
DEBUGCHK(pTransfer == peps->pTransfer);
CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);
peps->dwEpState = EP_STATE_IDLE;
ResetEndpoint( pContext,peps);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
#define CLKCON_USBD (1<<7)
volatile S3C2413_CLKPWR_REG *pCLKPWR = NULL; // Clock power registers (needed to enable I2S and SPI clocks)
volatile S3C2413_IOPORT_REG *pIOPregs = NULL;
BOOL HW_USBClocks(CEDEVICE_POWER_STATE cpsNew)
{
pCLKPWR = (volatile S3C2413_CLKPWR_REG*)VirtualAlloc(0, sizeof(S3C2413_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
if (!pCLKPWR)
{
DEBUGMSG(1, (TEXT("pCLKPWR: VirtualAlloc failed!\r\n")));
return(FALSE);
}
if (!VirtualCopy((PVOID)pCLKPWR, (PVOID)(S3C2413_BASE_REG_PA_CLOCK_POWER >> 8), sizeof(S3C2413_CLKPWR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
DEBUGMSG(1, (TEXT("pCLKPWR: VirtualCopy failed!\r\n")));
return(FALSE);
}
pIOPregs = (volatile S3C2413_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2413_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if(!pIOPregs) {
DEBUGMSG(1, (TEXT("pIOPregs: VirtualAlloc failed!\r\n")));
return(FALSE);
}
if(!VirtualCopy((PVOID)pIOPregs, (PVOID)(S3C2413_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2413_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
DEBUGMSG(1, (TEXT("pIOPregs: VirtualCopy failed!\r\n")));
return(FALSE);
}
if (cpsNew == D0)
{
//RETAILMSG(1, (TEXT("HW_USBClocks::D0 \r\n")));
// Enable the USB Clocks
pCLKPWR->CLKCON |= (CLKCON_USBD);
// MISCCR: USBD Pads, Normal mode
pIOPregs->MISCCR &= ~((1<<13)|(1<<3)); // SUSPND1 : normal mode, Use USBPAD as Device.
// Enable USB_PULLUP on GPIO PIN (tied to USB D+) & set high
pIOPregs->GPFCON &= ~(3<<4); // clear GPF2
pIOPregs->GPFCON |= (1<<4); // config as output
pIOPregs->GPFDN |= (1<<2); // pulldown disabled
pIOPregs->GPFDAT |= (1<<2); // set high
}
else if (cpsNew == D4)
{
//RETAILMSG(1, (TEXT("HW_USBClocks::D4 \r\n")));
// Disable the USB Clocks
pCLKPWR->CLKCON &= ~(CLKCON_USBD);
// MISCCR: USBD Pads, Suspend mode
pIOPregs->MISCCR |= (3<<12);
// Disable USB_PULLUP to remove us from the bus
pIOPregs->GPFCON &= ~(3<<4); // clear GPF2
pIOPregs->GPFCON |= (1<<4); // config as output
pIOPregs->GPFDN |= (1<<2); // pulldown disabled
pIOPregs->GPFDAT &= ~(1<<2); // set low
}
if (pIOPregs)
{
VirtualFree((PVOID)pIOPregs, 0, MEM_RELEASE);
pIOPregs = NULL;
}
if (pCLKPWR)
{
VirtualFree((PVOID)pCLKPWR, 0), MEM_RELEASE);
pCLKPWR = NULL;
}
return TRUE;
}
/////////////////////////////// jassi ////////////////////////////////
// This does not do much because there is not any way to control
// power on this controller.
static
CEDEVICE_POWER_STATE
SetPowerState(
PCTRLR_PDD_CONTEXT pContext,
CEDEVICE_POWER_STATE cpsNew
)
{
SETFNAME();
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(VALID_DX(cpsNew));
ValidateContext(pContext);
// RETAILMSG(1, (TEXT("SetPowerState.")));
// Adjust cpsNew.
if (cpsNew != pContext->cpsCurrent) {
if (cpsNew == D1 || cpsNew == D2) {
// D1 and D2 are not supported.
cpsNew = D0;
}
else if (pContext->cpsCurrent == D4) {
// D4 can only go to D0.
//cpsNew = D0;
}
}
if (cpsNew != pContext->cpsCurrent) {
DEBUGMSG(ZONE_POWER, (_T("%s Going from D%u to D%u\r\n"),
pszFname, pContext->cpsCurrent, cpsNew));
if ( (cpsNew < pContext->cpsCurrent) && pContext->hBusAccess ) {
SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
}
switch (cpsNew) {
case D0:
HW_USBClocks(D0);
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr,
sizeof(pContext->dwSysIntr), NULL, 0, NULL);
if (pContext->fRunning) {
// Cause the IST to restart.
pContext->fRestartIST = TRUE;
//RETAILMSG(1, (TEXT("USB::SetInterruptEvent \r\n")));
SetInterruptEvent(pContext->dwSysIntr);
}
break;
case D3:
KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &pContext->dwSysIntr,
sizeof(pContext->dwSysIntr), NULL, 0, NULL);
break;
case D4:
HW_USBClocks(D4);
KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr,
sizeof(pContext->dwSysIntr), NULL, 0, NULL);
break;
}
if ( (cpsNew > pContext->cpsCurrent) && pContext->hBusAccess ) {
SetDevicePowerState(pContext->hBusAccess, cpsNew, NULL);
}
pContext->cpsCurrent = cpsNew;
}
return pContext->cpsCurrent;
}
static
VOID
FreeCtrlrContext(
PCTRLR_PDD_CONTEXT pContext
)
{
PREFAST_DEBUGCHK(pContext);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -