📄 sc2440pdd.cpp
字号:
}
pContext->Ep0State = EP0_STATE_IDLE;
pContext->pfnNotify(pContext->pvMddContext, UFN_MSG_BUS_EVENTS, UFN_RESET);
// Enable the Suspend interrupt...
// SetClearReg(pContext, USB_INT_EN_REG_OFFSET, USB_SUSPEND_INTR, SET);
}
FUNCTION_LEAVE_MSG();
}
// Process a SC2440 interrupt.
static
VOID
HandleUSBEvent(
PCTRLR_PDD_CONTEXT pContext
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
ValidateContext(pContext);
BYTE bEpIrqStat = ReadReg(pContext, EP_INT_REG_OFFSET);
BYTE bUSBBusIrqStat = ReadReg(pContext, USB_INT_REG_OFFSET);
// RETAILMSG(1, (TEXT(" Hnt\r\n")));
// while (bEpIrqStat || bUSBBusIrqStat) {
if (bUSBBusIrqStat) {
DEBUGMSG(ZONE_COMMENT, (_T("%s USB_INT_REG = 0x%02x\r\n"),
pszFname, bUSBBusIrqStat));
HandleUSBBusIrq(pContext, bUSBBusIrqStat);
}
if (bEpIrqStat) {
DEBUGMSG(ZONE_COMMENT, (_T("%s EP_INT_REG = 0x%02x\r\n"),
pszFname, bEpIrqStat));
if (bEpIrqStat & EP0_INT_INTR) {
HandleEndpoint0Event(pContext);
}
// Process All Other (besides EP0) Endpoints
for (DWORD dwEndpoint = 1; dwEndpoint < ENDPOINT_COUNT; ++dwEndpoint) {
// Check the Interrupt Mask
// Check the Interrupt Status
BYTE bEpBit = EpToIrqStatBit(dwEndpoint);
if (bEpIrqStat & bEpBit) {
HandleEndpointEvent(pContext, dwEndpoint, bEpIrqStat);
}
}
}
bEpIrqStat = ReadReg(pContext, EP_INT_REG_OFFSET);
bUSBBusIrqStat = ReadReg(pContext, USB_INT_REG_OFFSET);
// }
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
)
{
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
EnableEndpointInterrupt(pContext, 0);
while (TRUE) {
DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);
if (pContext->fExitIST || pContext->fRestartIST) {
break;
}
if (dwWait == WAIT_OBJECT_0) {
HandleUSBEvent(pContext);
InterruptDone(pContext->dwSysIntr);
}
else {
DEBUGMSG(ZONE_INIT, (_T("%s WaitForMultipleObjects failed. Exiting IST.\r\n"),
pszFname));
break;
}
}
// 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();
DEBUGCHK(pContext);
PREFAST_DEBUGCHK(peps);
DEBUGCHK(!peps->pTransfer);
ValidateTransferDirection(pContext, peps, pTransfer);
LOCK_ENDPOINT(peps);
FUNCTION_ENTER_MSG();
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);
if (peps->dwEndpointNumber == 0) {
if ( (pTransfer->cbBuffer < pContext->udr.wLength) &&
(pTransfer->cbBuffer != 0) &&
( (pTransfer->cbBuffer % peps->dwPacketSizeAssigned) == 0 ) ) {
// This transfer will need a 0-length packet to terminate it.
pTransfer->pvPddData = (PVOID) 1;
}
BYTE bEP0IrqStatus = ReadIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET);
// Write 0 to SEND_STALL and SENT_STALL to clear them, so we need to
// leave them unchanged by default.
BYTE bEp0CsrToWrite = (bEP0IrqStatus & EP0_STALL_BITS);
if (bEP0IrqStatus & EP0_OUT_PACKET_RDY) {
bEp0CsrToWrite |= SERVICED_OUT_PKY_RDY;
DEBUGMSG(ZONE_COMMENT, (_T("%s Writing 0x%02x to EP0_CSR_REG\r\n"), pszFname, bEp0CsrToWrite));
WriteIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET, bEp0CsrToWrite);
bEp0CsrToWrite &= ~SERVICED_OUT_PKY_RDY;
}
bEp0CsrToWrite |= HandleTx(pContext, peps, 0);
DEBUGMSG(ZONE_COMMENT, (_T("%s Writing 0x%02x to EP0_CSR_REG\r\n"), pszFname, bEp0CsrToWrite));
WriteIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET, bEp0CsrToWrite);
}
else {
BYTE bIrqStatus = ReadIndexedReg(pContext, 0, IN_CSR1_REG_OFFSET);
// Write 0 to SEND_STALL and SENT_STALL to clear them, so we need to
// leave them unchanged by default.
BYTE bEpStatToWrite = (bIrqStatus & (IN_SENT_STALL & IN_SEND_STALL));
bEpStatToWrite |= HandleTx(pContext, peps, 1);
DEBUGMSG(ZONE_COMMENT, (_T("%s Writing 0x%02x to IN_CSR1_REG\r\n"), pszFname));
WriteIndexedReg(pContext, peps->dwEndpointNumber,
IN_CSR1_REG_OFFSET, bEpStatToWrite);
}
}
else {
if (peps->dwEndpointNumber == 0) {
BYTE bEP0IrqStatus = ReadIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET);
// Write 0 to SEND_STALL and SENT_STALL to clear them, so we need to
// leave them unchanged by default.
BYTE bEp0CsrToWrite = (bEP0IrqStatus & EP0_STALL_BITS);
// Mark that we are done with the setup packet. The IST will take care
// of the data transfer.
if (bEP0IrqStatus & EP0_OUT_PACKET_RDY) {
bEp0CsrToWrite |= SERVICED_OUT_PKY_RDY;
DEBUGMSG(ZONE_COMMENT, (_T("%s Writing 0x%02x to EP0_CSR_REG\r\n"), pszFname, bEp0CsrToWrite));
WriteIndexedReg(pContext, 0, EP0_CSR_REG_OFFSET, bEp0CsrToWrite);
}
}
else {
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) {
BOOL fCompleted;
DWORD dwStatus;
BYTE bToWrite = HandleRx(pContext, peps, &fCompleted, &dwStatus);
DEBUGMSG(ZONE_COMMENT, (_T("%s Writing 0x%02x to OUT_CSR1_REG\r\n"), pszFname,
bToWrite));
// There should be no double-buffering
DEBUGCHK(ReadIndexedReg(pContext, peps->dwEndpointNumber, OUT_FIFO_CNT1_REG_OFFSET) == 0);
if (fCompleted) {
// Disable transfer interrupts until another transfer is issued.
DisableEndpointInterrupt(pContext, peps->dwEndpointNumber);
}
WriteIndexedReg(pContext, peps->dwEndpointNumber, OUT_CSR1_REG_OFFSET, bToWrite);
if (fCompleted) {
CompleteTransfer(pContext, peps, dwStatus);
}
}
}
}
FUNCTION_LEAVE_MSG();
UNLOCK_ENDPOINT(peps);
}
DWORD
WINAPI
UfnPdd_IssueTransfer(
PVOID pvPddContext,
DWORD dwEndpoint,
PSTransfer pTransfer
)
{
SETFNAME();
FUNCTION_ENTER_MSG();
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);
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);
if (dwEndpoint == 0) {
pContext->Ep0State = EP0_STATE_IDLE;
}
ResetEndpoint( pContext,peps);
UNLOCK_ENDPOINT(peps);
FUNCTION_LEAVE_MSG();
return ERROR_SUCCESS;
}
/////////////////////////////// jassi ////////////////////////////////
#define CLKCON_USBD (1<<7)
volatile S3C2440A_CLKPWR_REG *pCLKPWR = NULL; // Clock power registers (needed to enable I2S and SPI clocks)
volatile S3C2440A_IOPORT_REG *pIOPregs = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -