Exemplo n.º 1
0
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 ();
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
unsigned CTimer::GetClockTicks (void) const
{
	DataMemBarrier ();

	unsigned nResult = read32 (ARM_SYSTIMER_CLO);

	DataMemBarrier ();

	return nResult;
}
Exemplo n.º 6
0
void CInterruptSystem::DisableIRQ (unsigned nIRQ)
{
	DataMemBarrier ();

	assert (nIRQ < IRQ_LINES);

	write32 (ARM_IC_IRQS_DISABLE (nIRQ), ARM_IRQ_MASK (nIRQ));

	DataMemBarrier ();
}
Exemplo n.º 7
0
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 ();
}
Exemplo n.º 8
0
unsigned TimerGetClockTicks (TTimer *pThis)
{
	assert (pThis != 0);

	DataMemBarrier ();

	unsigned nResult = read32 (ARM_SYSTIMER_CLO);

	DataMemBarrier ();

	return nResult;
}
Exemplo n.º 9
0
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 ();
}
Exemplo n.º 10
0
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 ();
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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 ();
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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 ();
	}
}
Exemplo n.º 16
0
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 ();
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
void CDWHCIDevice::DumpRegister (const char *pName, u32 nAddress)
{
	CDWHCIRegister Register (nAddress);

	DataMemBarrier ();

	CLogger::Get ()->Write (FromDWHCI, LogDebug, "0x%08X %s", Register.Read (), pName);
}
Exemplo n.º 19
0
unsigned CBcmMailBox::WriteRead (unsigned nData)
{
	DataMemBarrier ();

	m_SpinLock.Acquire ();

	Flush ();

	Write (nData);

	unsigned nResult = Read ();

	m_SpinLock.Release ();

	DataMemBarrier ();

	return nResult;
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
0
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 ();
}
Exemplo n.º 22
0
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
}
Exemplo n.º 23
0
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 ();
}
Exemplo n.º 24
0
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 ();
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
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;
}
Exemplo n.º 28
0
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;
	}
}
Exemplo n.º 29
0
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 ();
}
Exemplo n.º 30
0
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;
}