void CTimer::InterruptHandler (void) { DataMemBarrier (); assert (read32 (ARM_SYSTIMER_CS) & (1 << 3)); u32 nCompare = read32 (ARM_SYSTIMER_C3) + CLOCKHZ / HZ; write32 (ARM_SYSTIMER_C3, nCompare); if (nCompare < read32 (ARM_SYSTIMER_CLO)) // time may drift { nCompare = read32 (ARM_SYSTIMER_CLO) + CLOCKHZ / HZ; write32 (ARM_SYSTIMER_C3, nCompare); } write32 (ARM_SYSTIMER_CS, 1 << 3); DataMemBarrier (); #ifndef NDEBUG //debug_click (); #endif m_TimeSpinLock.Acquire (); if (++m_nTicks % HZ == 0) { m_nTime++; } m_TimeSpinLock.Release (); PollKernelTimers (); }
void CPWMOutput::Start (void) { assert (!m_bActive); assert (1 <= m_nDivider && m_nDivider <= 4095); m_Clock.Start (m_nDivider); CTimer::SimpleusDelay (2000); DataMemBarrier (); write32 (ARM_PWM_RNG1, m_nRange); write32 (ARM_PWM_RNG2, m_nRange); u32 nControl = ARM_PWM_CTL_PWEN1 | ARM_PWM_CTL_PWEN2; if (m_bMSMode) { nControl |= ARM_PWM_CTL_MSEN1 | ARM_PWM_CTL_MSEN2; } write32 (ARM_PWM_CTL, nControl); CTimer::SimpleusDelay (2000); DataMemBarrier (); m_bActive = TRUE; }
void TimerInterruptHandler (void *pParam) { TTimer *pThis = (TTimer *) pParam; assert (pThis != 0); DataMemBarrier (); assert (read32 (ARM_SYSTIMER_CS) & (1 << 3)); u32 nCompare = read32 (ARM_SYSTIMER_C3) + CLOCKHZ / HZ; write32 (ARM_SYSTIMER_C3, nCompare); if (nCompare < read32 (ARM_SYSTIMER_CLO)) // time may drift { nCompare = read32 (ARM_SYSTIMER_CLO) + CLOCKHZ / HZ; write32 (ARM_SYSTIMER_C3, nCompare); } write32 (ARM_SYSTIMER_CS, 1 << 3); DataMemBarrier (); if (++pThis->m_nTicks % HZ == 0) { pThis->m_nTime++; } TimerPollKernelTimers (pThis); }
boolean CInterruptSystem::Initialize (void) { TExceptionTable *pTable = (TExceptionTable *) ARM_EXCEPTION_TABLE_BASE; pTable->IRQ = ARM_OPCODE_BRANCH (ARM_DISTANCE (pTable->IRQ, IRQStub)); CleanDataCache (); DataSyncBarrier (); InvalidateInstructionCache (); FlushBranchTargetCache (); DataSyncBarrier (); InstructionSyncBarrier (); #ifndef USE_RPI_STUB_AT DataMemBarrier (); write32 (ARM_IC_FIQ_CONTROL, 0); write32 (ARM_IC_DISABLE_IRQS_1, (u32) -1); write32 (ARM_IC_DISABLE_IRQS_2, (u32) -1); write32 (ARM_IC_DISABLE_BASIC_IRQS, (u32) -1); DataMemBarrier (); #endif EnableInterrupts (); return TRUE; }
unsigned CTimer::GetClockTicks (void) const { DataMemBarrier (); unsigned nResult = read32 (ARM_SYSTIMER_CLO); DataMemBarrier (); return nResult; }
void CInterruptSystem::DisableIRQ (unsigned nIRQ) { DataMemBarrier (); assert (nIRQ < IRQ_LINES); write32 (ARM_IC_IRQS_DISABLE (nIRQ), ARM_IRQ_MASK (nIRQ)); DataMemBarrier (); }
void CSPIMaster::SetClock (unsigned nClockSpeed) { m_nClockSpeed = nClockSpeed; DataMemBarrier (); assert (4000 <= m_nClockSpeed && m_nClockSpeed <= 125000000); write32 (ARM_SPI0_CLK, m_nCoreClockRate / m_nClockSpeed); DataMemBarrier (); }
unsigned TimerGetClockTicks (TTimer *pThis) { assert (pThis != 0); DataMemBarrier (); unsigned nResult = read32 (ARM_SYSTIMER_CLO); DataMemBarrier (); return nResult; }
void CDWHCIDevice::InterruptHandler (void) { #ifndef NDEBUG //debug_click (); #endif DataMemBarrier (); CDWHCIRegister IntStatus (DWHCI_CORE_INT_STAT); IntStatus.Read (); if (IntStatus.Get () & DWHCI_CORE_INT_STAT_HC_INTR) { CDWHCIRegister AllChanInterrupt (DWHCI_HOST_ALLCHAN_INT); AllChanInterrupt.Read (); AllChanInterrupt.Write (); unsigned nChannelMask = 1; for (unsigned nChannel = 0; nChannel < m_nChannels; nChannel++) { if (AllChanInterrupt.Get () & nChannelMask) { CDWHCIRegister ChanInterruptMask (DWHCI_HOST_CHAN_INT_MASK(nChannel), 0); ChanInterruptMask.Write (); ChannelInterruptHandler (nChannel); } nChannelMask <<= 1; } } #if 0 if (IntStatus.Get () & DWHCI_CORE_INT_STAT_PORT_INTR) { CDWHCIRegister HostPort (DWHCI_HOST_PORT); HostPort.Read (); CLogger::Get ()->Write (FromDWHCI, LogDebug, "Port interrupt (status 0x%08X)", HostPort.Get ()); HostPort.And (~DWHCI_HOST_PORT_ENABLE); HostPort.Or ( DWHCI_HOST_PORT_CONNECT_CHANGED | DWHCI_HOST_PORT_ENABLE_CHANGED | DWHCI_HOST_PORT_OVERCURRENT_CHANGED); HostPort.Write (); IntStatus.Or (DWHCI_CORE_INT_STAT_PORT_INTR); } #endif IntStatus.Write (); DataMemBarrier (); }
void CSPIMaster::SetMode (unsigned CPOL, unsigned CPHA) { m_CPOL = CPOL; m_CPHA = CPHA; DataMemBarrier (); assert (m_CPOL <= 1); assert (m_CPHA <= 1); write32 (ARM_SPI0_CS, (m_CPOL << CS_CPOL__SHIFT) | (m_CPHA << CS_CPHA__SHIFT)); DataMemBarrier (); }
boolean CSPIMaster::Initialize (void) { DataMemBarrier (); assert (4000 <= m_nClockSpeed && m_nClockSpeed <= 125000000); write32 (ARM_SPI0_CLK, m_nCoreClockRate / m_nClockSpeed); assert (m_CPOL <= 1); assert (m_CPHA <= 1); write32 (ARM_SPI0_CS, (m_CPOL << CS_CPOL__SHIFT) | (m_CPHA << CS_CPHA__SHIFT)); DataMemBarrier (); return TRUE; }
void CPWMOutput::Stop (void) { assert (m_bActive); m_bActive = FALSE; m_Clock.Stop (); CTimer::SimpleusDelay (2000); DataMemBarrier (); write32 (ARM_PWM_CTL, 0); CTimer::SimpleusDelay (2000); DataMemBarrier (); }
int CScreenDevice::Write (const void *pBuffer, unsigned nCount) { m_SpinLock.Acquire (); m_bUpdated = TRUE; InvertCursor (); const char *pChar = (const char *) pBuffer; int nResult = 0; while (nCount--) { Write (*pChar++); nResult++; } InvertCursor (); m_bUpdated = FALSE; m_SpinLock.Release (); DataMemBarrier (); return nResult; }
boolean CTimer::Initialize (void) { assert (m_pInterruptSystem != 0); m_pInterruptSystem->ConnectIRQ (ARM_IRQ_TIMER3, InterruptHandler, this); DataMemBarrier (); write32 (ARM_SYSTIMER_CLO, -(30 * CLOCKHZ)); // timer wraps soon, to check for problems write32 (ARM_SYSTIMER_C3, read32 (ARM_SYSTIMER_CLO) + CLOCKHZ / HZ); TuneMsDelay (); DataMemBarrier (); return TRUE; }
void CTimer::SimpleusDelay (unsigned nMicroSeconds) { if (nMicroSeconds > 0) { unsigned nTicks = nMicroSeconds * (CLOCKHZ / 1000000); DataMemBarrier (); unsigned nStartTicks = read32 (ARM_SYSTIMER_CLO); while (read32 (ARM_SYSTIMER_CLO) - nStartTicks < nTicks) { // do nothing } DataMemBarrier (); } }
void CGPIOManager::InterruptHandler (void) { assert (m_bIRQConnected); DataMemBarrier (); unsigned nEventStatus = read32 (ARM_GPIO_GPEDS0); unsigned nPin = 0; while (nPin < GPIO_PINS) { if (nEventStatus & 1) { break; } nEventStatus >>= 1; if (++nPin % 32 == 0) { nEventStatus = read32 (ARM_GPIO_GPEDS0 + 4); } } if (nPin < GPIO_PINS) { unsigned nMask = 1 << (nPin % 32); if (m_apPin[nPin] != 0) { m_apPin[nPin]->InterruptHandler (); } else { // disable all interrupt sources unsigned nReg = ARM_GPIO_GPREN0 + (nPin / 32) * 4; for (; nReg < ARM_GPIO_GPAFEN0 + 4; nReg += 12) { write32 (nReg, read32 (nReg) & ~nMask); } } write32 (ARM_GPIO_GPEDS0 + (nPin / 32) * 4, nMask); } DataMemBarrier (); }
boolean CDWHCIDevice::SubmitAsyncRequest (CUSBRequest *pURB) { DataMemBarrier (); assert (pURB != 0); assert ( pURB->GetEndpoint ()->GetType () == EndpointTypeBulk || pURB->GetEndpoint ()->GetType () == EndpointTypeInterrupt); assert (pURB->GetBufLen () > 0); pURB->SetStatus (0); boolean bOK = TransferStageAsync (pURB, pURB->GetEndpoint ()->IsDirectionIn (), FALSE); DataMemBarrier (); return bOK; }
void CDWHCIDevice::DumpRegister (const char *pName, u32 nAddress) { CDWHCIRegister Register (nAddress); DataMemBarrier (); CLogger::Get ()->Write (FromDWHCI, LogDebug, "0x%08X %s", Register.Read (), pName); }
unsigned CBcmMailBox::WriteRead (unsigned nData) { DataMemBarrier (); m_SpinLock.Acquire (); Flush (); Write (nData); unsigned nResult = Read (); m_SpinLock.Release (); DataMemBarrier (); return nResult; }
boolean TimerInitialize (TTimer *pThis) { assert (pThis != 0); assert (pThis->m_pInterruptSystem != 0); InterruptSystemConnectIRQ (pThis->m_pInterruptSystem, ARM_IRQ_TIMER3, TimerInterruptHandler, pThis); DataMemBarrier (); write32 (ARM_SYSTIMER_CLO, -(30 * CLOCKHZ)); // timer wraps soon, to check for problems write32 (ARM_SYSTIMER_C3, read32 (ARM_SYSTIMER_CLO) + CLOCKHZ / HZ); TimerTuneMsDelay (pThis); DataMemBarrier (); return TRUE; }
static void TimerInterruptHandler (void *pParam) { DataMemBarrier (); assert (read32 (ARM_SYSTIMER_CS) & (1 << 3)); u32 nCompare = read32 (ARM_SYSTIMER_C3) + CLOCKHZ / HZ; if (nCompare < read32 (ARM_SYSTIMER_CLO)) // time may drift { nCompare = read32 (ARM_SYSTIMER_CLO) + CLOCKHZ / HZ; } write32 (ARM_SYSTIMER_C3, nCompare); write32 (ARM_SYSTIMER_CS, 1 << 3); DataMemBarrier (); if (++m_nTicks % HZ == 0) { m_nTime++; } uspi_EnterCritical (); for (unsigned hTimer = 0; hTimer < KERNEL_TIMERS; hTimer++) { volatile TKernelTimer *pTimer = &m_KernelTimer[hTimer]; TKernelTimerHandler *pHandler = pTimer->m_pHandler; if (pHandler != 0) { if ((int) (pTimer->m_nElapsesAt-m_nTicks) <= 0) { pTimer->m_pHandler = 0; (*pHandler) (hTimer+1, pTimer->m_pParam, pTimer->m_pContext); } } } uspi_LeaveCritical (); }
void reboot (void) // by PlutoniumBob@raspi-forum { DataMemBarrier (); write32 (ARM_PM_WDOG, ARM_PM_PASSWD | 1); // set some timeout #define PM_RSTC_WRCFG_FULL_RESET 0x20 write32 (ARM_PM_RSTC, ARM_PM_PASSWD | PM_RSTC_WRCFG_FULL_RESET); for (;;); // wait for reset }
void CPWMOutput::Write (unsigned nChannel, unsigned nValue) { assert (m_bActive); assert ( nChannel == PWM_CHANNEL1 || nChannel == PWM_CHANNEL2); assert (nValue <= m_nRange); m_SpinLock.Acquire (); DataMemBarrier (); if (read32 (ARM_PWM_STA) & ARM_PWM_STA_BERR) { write32 (ARM_PWM_STA, ARM_PWM_STA_BERR); } write32 (nChannel == PWM_CHANNEL1 ? ARM_PWM_DAT1 : ARM_PWM_DAT2, nValue); DataMemBarrier (); m_SpinLock.Release (); }
void CDWHCIDevice::TimerHandler (CDWHCITransferStageData *pStageData) { DataMemBarrier (); assert (pStageData != 0); assert (pStageData->GetState () == StageStatePeriodicDelay); if (pStageData->IsSplit ()) { pStageData->SetState (StageStateStartSplit); pStageData->SetSplitComplete (FALSE); pStageData->GetFrameScheduler ()->StartSplit (); } else { pStageData->SetState (StageStateNoSplitTransfer); } StartTransaction (pStageData); DataMemBarrier (); }
boolean CScreenDevice::SetStatus (TScreenStatus Status) { if ( m_nSize != Status.nSize || m_nPitch != m_nWidth) { return FALSE; } m_SpinLock.Acquire (); if ( m_bUpdated || Status.bUpdated) { m_SpinLock.Release (); return FALSE; } memcpyblk (m_pBuffer, Status.pContent, m_nSize); m_nState = Status.nState; m_nScrollStart = Status.nScrollStart; m_nScrollEnd = Status.nScrollEnd; m_nCursorX = Status.nCursorX; m_nCursorY = Status.nCursorY; m_bCursorOn = Status.bCursorOn; m_Color = Status.Color; m_bInsertOn = Status.bInsertOn; m_nParam1 = Status.nParam1; m_nParam2 = Status.nParam2; m_SpinLock.Release (); DataMemBarrier (); return TRUE; }
boolean CBcmPropertyTags::GetTags (void *pTags, unsigned nTagsSize) { assert (pTags != 0); assert (nTagsSize >= sizeof (TPropertyTagSimple)); unsigned nBufferSize = sizeof (TPropertyBuffer) + nTagsSize + sizeof (u32); assert ((nBufferSize & 3) == 0); TPropertyBuffer *pBuffer = (TPropertyBuffer *) CMemorySystem::GetCoherentPage (COHERENT_SLOT_PROP_MAILBOX); pBuffer->nBufferSize = nBufferSize; pBuffer->nCode = CODE_REQUEST; memcpy (pBuffer->Tags, pTags, nTagsSize); u32 *pEndTag = (u32 *) (pBuffer->Tags + nTagsSize); *pEndTag = PROPTAG_END; DataSyncBarrier (); u32 nBufferAddress = GPU_MEM_BASE + (u32) pBuffer; if (m_MailBox.WriteRead (nBufferAddress) != nBufferAddress) { return FALSE; } DataMemBarrier (); if (pBuffer->nCode != CODE_RESPONSE_SUCCESS) { return FALSE; } memcpy (pTags, pBuffer->Tags, nTagsSize); return TRUE; }
boolean CDWHCIDevice::Initialize (void) { DataMemBarrier (); assert (m_pInterruptSystem != 0); assert (m_pTimer != 0); CDWHCIRegister VendorId (DWHCI_CORE_VENDOR_ID); if (VendorId.Read () != 0x4F54280A) { CLogger::Get ()->Write (FromDWHCI, LogError, "Unknown vendor 0x%0X", VendorId.Get ()); return FALSE; } if (!PowerOn ()) { CLogger::Get ()->Write (FromDWHCI, LogError, "Cannot power on"); return FALSE; } // Disable all interrupts CDWHCIRegister AHBConfig (DWHCI_CORE_AHB_CFG); AHBConfig.Read (); AHBConfig.And (~DWHCI_CORE_AHB_CFG_GLOBALINT_MASK); AHBConfig.Write (); assert (m_pInterruptSystem != 0); m_pInterruptSystem->ConnectIRQ (ARM_IRQ_USB, InterruptStub, this); if (!InitCore ()) { CLogger::Get ()->Write (FromDWHCI, LogError, "Cannot initialize core"); return FALSE; } EnableGlobalInterrupts (); if (!InitHost ()) { CLogger::Get ()->Write (FromDWHCI, LogError, "Cannot initialize host"); return FALSE; } // The following calls will fail if there is no device or no supported device connected // to root port. This is not an error because the system may run without an USB device. if (!EnableRootPort ()) { CLogger::Get ()->Write (FromDWHCI, LogWarning, "No device connected to root port"); return TRUE; } if (!m_RootPort.Initialize ()) { CLogger::Get ()->Write (FromDWHCI, LogWarning, "Cannot initialize root port"); return TRUE; } DataMemBarrier (); return TRUE; }
void CDWHCIDevice::ChannelInterruptHandler (unsigned nChannel) { CDWHCITransferStageData *pStageData = m_pStageData[nChannel]; assert (pStageData != 0); CUSBRequest *pURB = pStageData->GetURB (); assert (pURB != 0); switch (pStageData->GetSubState ()) { case StageSubStateWaitForChannelDisable: StartChannel (pStageData); return; case StageSubStateWaitForTransactionComplete: { CleanDataCache (); InvalidateDataCache (); DataMemBarrier (); CDWHCIRegister TransferSize (DWHCI_HOST_CHAN_XFER_SIZ (nChannel)); TransferSize.Read (); CDWHCIRegister ChanInterrupt (DWHCI_HOST_CHAN_INT (nChannel)); assert ( !pStageData->IsPeriodic () || DWHCI_HOST_CHAN_XFER_SIZ_PID (TransferSize.Get ()) != DWHCI_HOST_CHAN_XFER_SIZ_PID_MDATA); pStageData->TransactionComplete (ChanInterrupt.Read (), DWHCI_HOST_CHAN_XFER_SIZ_PACKETS (TransferSize.Get ()), TransferSize.Get () & DWHCI_HOST_CHAN_XFER_SIZ_BYTES__MASK); } break; default: assert (0); break; } unsigned nStatus; switch (pStageData->GetState ()) { case StageStateNoSplitTransfer: nStatus = pStageData->GetTransactionStatus (); if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK) { CLogger::Get ()->Write (FromDWHCI, LogError, "Transaction failed (status 0x%X)", nStatus); pURB->SetStatus (0); } else if ( (nStatus & (DWHCI_HOST_CHAN_INT_NAK | DWHCI_HOST_CHAN_INT_NYET)) && pStageData->IsPeriodic ()) { pStageData->SetState (StageStatePeriodicDelay); unsigned nInterval = pURB->GetEndpoint ()->GetInterval (); m_pTimer->StartKernelTimer (MSEC2HZ (nInterval), TimerStub, pStageData, this); break; } else { if (!pStageData->IsStatusStage ()) { pURB->SetResultLen (pStageData->GetResultLen ()); } pURB->SetStatus (1); } DisableChannelInterrupt (nChannel); delete pStageData; m_pStageData[nChannel] = 0; FreeChannel (nChannel); pURB->CallCompletionRoutine (); break; case StageStateStartSplit: nStatus = pStageData->GetTransactionStatus (); if ( (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK) || (nStatus & DWHCI_HOST_CHAN_INT_NAK) || (nStatus & DWHCI_HOST_CHAN_INT_NYET)) { CLogger::Get ()->Write (FromDWHCI, LogError, "Transaction failed (status 0x%X)", nStatus); pURB->SetStatus (0); DisableChannelInterrupt (nChannel); delete pStageData; m_pStageData[nChannel] = 0; FreeChannel (nChannel); pURB->CallCompletionRoutine (); break; } pStageData->GetFrameScheduler ()->TransactionComplete (nStatus); pStageData->SetState (StageStateCompleteSplit); pStageData->SetSplitComplete (TRUE); if (!pStageData->GetFrameScheduler ()->CompleteSplit ()) { goto LeaveCompleteSplit; } StartTransaction (pStageData); break; case StageStateCompleteSplit: nStatus = pStageData->GetTransactionStatus (); if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK) { CLogger::Get ()->Write (FromDWHCI, LogError, "Transaction failed (status 0x%X)", nStatus); pURB->SetStatus (0); DisableChannelInterrupt (nChannel); delete pStageData; m_pStageData[nChannel] = 0; FreeChannel (nChannel); pURB->CallCompletionRoutine (); break; } pStageData->GetFrameScheduler ()->TransactionComplete (nStatus); if (pStageData->GetFrameScheduler ()->CompleteSplit ()) { StartTransaction (pStageData); break; } LeaveCompleteSplit: if (!pStageData->IsStageComplete ()) { if (!pStageData->BeginSplitCycle ()) { pURB->SetStatus (0); DisableChannelInterrupt (nChannel); delete pStageData; m_pStageData[nChannel] = 0; FreeChannel (nChannel); pURB->CallCompletionRoutine (); break; } if (!pStageData->IsPeriodic ()) { pStageData->SetState (StageStateStartSplit); pStageData->SetSplitComplete (FALSE); pStageData->GetFrameScheduler ()->StartSplit (); StartTransaction (pStageData); } else { pStageData->SetState (StageStatePeriodicDelay); unsigned nInterval = pURB->GetEndpoint ()->GetInterval (); m_pTimer->StartKernelTimer (MSEC2HZ (nInterval), TimerStub, pStageData, this); } break; } DisableChannelInterrupt (nChannel); if (!pStageData->IsStatusStage ()) { pURB->SetResultLen (pStageData->GetResultLen ()); } pURB->SetStatus (1); delete pStageData; m_pStageData[nChannel] = 0; FreeChannel (nChannel); pURB->CallCompletionRoutine (); break; default: assert (0); break; } }
void CDWHCIDevice::StartChannel (CDWHCITransferStageData *pStageData) { assert (pStageData != 0); unsigned nChannel = pStageData->GetChannelNumber (); assert (nChannel < m_nChannels); pStageData->SetSubState (StageSubStateWaitForTransactionComplete); // reset all pending channel interrupts CDWHCIRegister ChanInterrupt (DWHCI_HOST_CHAN_INT (nChannel)); ChanInterrupt.SetAll (); ChanInterrupt.Write (); // set transfer size, packet count and pid CDWHCIRegister TransferSize (DWHCI_HOST_CHAN_XFER_SIZ (nChannel), 0); TransferSize.Or (pStageData->GetBytesToTransfer () & DWHCI_HOST_CHAN_XFER_SIZ_BYTES__MASK); TransferSize.Or ((pStageData->GetPacketsToTransfer () << DWHCI_HOST_CHAN_XFER_SIZ_PACKETS__SHIFT) & DWHCI_HOST_CHAN_XFER_SIZ_PACKETS__MASK); TransferSize.Or (pStageData->GetPID () << DWHCI_HOST_CHAN_XFER_SIZ_PID__SHIFT); TransferSize.Write (); // set DMA address CDWHCIRegister DMAAddress (DWHCI_HOST_CHAN_DMA_ADDR (nChannel), pStageData->GetDMAAddress () + GPU_MEM_BASE); DMAAddress.Write (); CleanDataCache (); InvalidateDataCache (); DataMemBarrier (); // set split control CDWHCIRegister SplitControl (DWHCI_HOST_CHAN_SPLIT_CTRL (nChannel), 0); if (pStageData->IsSplit ()) { SplitControl.Or (pStageData->GetHubPortAddress ()); SplitControl.Or ( pStageData->GetHubAddress () << DWHCI_HOST_CHAN_SPLIT_CTRL_HUB_ADDRESS__SHIFT); SplitControl.Or ( pStageData->GetSplitPosition () << DWHCI_HOST_CHAN_SPLIT_CTRL_XACT_POS__SHIFT); if (pStageData->IsSplitComplete ()) { SplitControl.Or (DWHCI_HOST_CHAN_SPLIT_CTRL_COMPLETE_SPLIT); } SplitControl.Or (DWHCI_HOST_CHAN_SPLIT_CTRL_SPLIT_ENABLE); } SplitControl.Write (); // set channel parameters CDWHCIRegister Character (DWHCI_HOST_CHAN_CHARACTER (nChannel)); Character.Read (); Character.And (~DWHCI_HOST_CHAN_CHARACTER_MAX_PKT_SIZ__MASK); Character.Or (pStageData->GetMaxPacketSize () & DWHCI_HOST_CHAN_CHARACTER_MAX_PKT_SIZ__MASK); Character.And (~DWHCI_HOST_CHAN_CHARACTER_MULTI_CNT__MASK); Character.Or (1 << DWHCI_HOST_CHAN_CHARACTER_MULTI_CNT__SHIFT); // TODO: optimize if (pStageData->IsDirectionIn ()) { Character.Or (DWHCI_HOST_CHAN_CHARACTER_EP_DIRECTION_IN); } else { Character.And (~DWHCI_HOST_CHAN_CHARACTER_EP_DIRECTION_IN); } if (pStageData->GetSpeed () == USBSpeedLow) { Character.Or (DWHCI_HOST_CHAN_CHARACTER_LOW_SPEED_DEVICE); } else { Character.And (~DWHCI_HOST_CHAN_CHARACTER_LOW_SPEED_DEVICE); } Character.And (~DWHCI_HOST_CHAN_CHARACTER_DEVICE_ADDRESS__MASK); Character.Or (pStageData->GetDeviceAddress () << DWHCI_HOST_CHAN_CHARACTER_DEVICE_ADDRESS__SHIFT); Character.And (~DWHCI_HOST_CHAN_CHARACTER_EP_TYPE__MASK); Character.Or (pStageData->GetEndpointType () << DWHCI_HOST_CHAN_CHARACTER_EP_TYPE__SHIFT); Character.And (~DWHCI_HOST_CHAN_CHARACTER_EP_NUMBER__MASK); Character.Or (pStageData->GetEndpointNumber () << DWHCI_HOST_CHAN_CHARACTER_EP_NUMBER__SHIFT); CDWHCIFrameScheduler *pFrameScheduler = pStageData->GetFrameScheduler (); if (pFrameScheduler != 0) { pFrameScheduler->WaitForFrame (); if (pFrameScheduler->IsOddFrame ()) { Character.Or (DWHCI_HOST_CHAN_CHARACTER_PER_ODD_FRAME); } else { Character.And (~DWHCI_HOST_CHAN_CHARACTER_PER_ODD_FRAME); } } CDWHCIRegister ChanInterruptMask (DWHCI_HOST_CHAN_INT_MASK(nChannel)); ChanInterruptMask.Set (pStageData->GetStatusMask ()); ChanInterruptMask.Write (); Character.Or (DWHCI_HOST_CHAN_CHARACTER_ENABLE); Character.And (~DWHCI_HOST_CHAN_CHARACTER_DISABLE); Character.Write (); }
boolean CDWHCIDevice::SubmitBlockingRequest (CUSBRequest *pURB) { DataMemBarrier (); assert (pURB != 0); pURB->SetStatus (0); if (pURB->GetEndpoint ()->GetType () == EndpointTypeControl) { TSetupData *pSetup = pURB->GetSetupData (); assert (pSetup != 0); if (pSetup->bmRequestType & REQUEST_IN) { assert (pURB->GetBufLen () > 0); if ( !TransferStage (pURB, FALSE, FALSE) || !TransferStage (pURB, TRUE, FALSE) || !TransferStage (pURB, FALSE, TRUE)) { return FALSE; } } else { if (pURB->GetBufLen () == 0) { if ( !TransferStage (pURB, FALSE, FALSE) || !TransferStage (pURB, TRUE, TRUE)) { return FALSE; } } else { if ( !TransferStage (pURB, FALSE, FALSE) || !TransferStage (pURB, FALSE, FALSE) || !TransferStage (pURB, TRUE, TRUE)) { return FALSE; } } } } else { assert ( pURB->GetEndpoint ()->GetType () == EndpointTypeBulk || pURB->GetEndpoint ()->GetType () == EndpointTypeInterrupt); assert (pURB->GetBufLen () > 0); if (!TransferStage (pURB, pURB->GetEndpoint ()->IsDirectionIn (), FALSE)) { return FALSE; } } DataMemBarrier (); return TRUE; }