⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lan9118.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
FUNCTION: Lan_EnableInterrupt
  Enables bits in INT_EN according to the set bits in dwMask
  WARNING this has thread synchronization issues. Use with caution.
*/
void Lan_EnableInterrupt(const LAN9118_DATA * const pLan9118Data, const DWORD dwMask)
{
	DWORD dwTemp;

	SMSC_ASSERT(pLan9118Data);
	SMSC_WARNING0("Lan_EnableInterrupt ()\n");
	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		dwTemp = GetRegDW(pLan9118Data->dwLanBase, INT_EN);
		dwTemp |= dwMask;
		SetRegDW(pLan9118Data->dwLanBase, INT_EN, dwTemp);
	}
}

/*
FUNCTION: Lan_DisableInterrupt
  Disables bits in INT_EN according to the set bits in dwMask
  WARNING this has thread synchronization issues. Use with caution.
*/
void Lan_DisableInterrupt(const LAN9118_DATA * const pLan9118Data, const DWORD dwMask)
{
	DWORD dwTemp;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		dwTemp = GetRegDW(pLan9118Data->dwLanBase, INT_EN);
		dwTemp &= (~dwMask);
		SetRegDW(pLan9118Data->dwLanBase, INT_EN, dwTemp);
	}
}

/*
FUNCTION: Lan_GetInterruptStatus
  Reads and returns the value in the INT_STS register.
*/
DWORD Lan_GetInterruptStatus(const LAN9118_DATA * const pLan9118Data)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		return GetRegDW(pLan9118Data->dwLanBase, INT_STS);
	}
	return 0xFFFFFFFFUL;
}

/*
FUNCTION: Lan_EnableIRQ
  Sets IRQ_EN in the INT_CFG registers.
  WARNING this has thread synchronization issues. Use with caution.
*/
void Lan_EnableIRQ(const LAN9118_DATA * const pLan9118Data)
{
	DWORD dwRegVal = 0UL;

	SMSC_ASSERT(pLan9118Data);
SMSC_WARNING0("Lan_EnableIRQ ()\n");
	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		dwRegVal = GetRegDW(pLan9118Data->dwLanBase, INT_CFG);
		dwRegVal |= INT_CFG_IRQ_EN_;
		SetRegDW(pLan9118Data->dwLanBase, INT_CFG, dwRegVal);
	}
}

/*
FUNCTION: Lan_DisableIRQ
  Clears IRQ_EN in the INT_CFG registers.
  WARNING this has thread sychronization issues. Use with caution.
*/
void Lan_DisableIRQ(const LAN9118_DATA * const pLan9118Data)
{
	DWORD dwRegVal = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		dwRegVal = GetRegDW(pLan9118Data->dwLanBase, INT_CFG);
		dwRegVal &= ~(INT_CFG_IRQ_EN_);
		SetRegDW(pLan9118Data->dwLanBase, INT_CFG, dwRegVal);
	}
}

/*
FUNCTION: Lan_ClearInterruptStatus
  Clears the bits in INT_STS according to the bits set in dwMask
*/
void Lan_ClearInterruptStatus(const LAN9118_DATA * const pLan9118Data, const DWORD dwMask)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		SetRegDW(pLan9118Data->dwLanBase, INT_STS, dwMask);
	}
}

/*
FUNCTION: Lan_InitializeInterrupts
  Should be called after Lan_Initialize
  Should be called before the ISR is registered.
*/
void Lan_InitializeInterrupts(LAN9118_DATA * const pLan9118Data, DWORD dwIntCfg)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		SMSC_ASSERT(pLan9118Data->LanInitialized == TRUE);

		SetRegDW(pLan9118Data->dwLanBase, INT_EN, 0UL);
		SetRegDW(pLan9118Data->dwLanBase, INT_STS, 0xFFFFFFFFUL);
		dwIntCfg |= INT_CFG_IRQ_EN_;
		SetRegDW(pLan9118Data->dwLanBase, INT_CFG, dwIntCfg);
		pLan9118Data->InterruptsInitialized = (BOOLEAN)TRUE;
	}
}

/*
FUNCTION: Lan_EnableSoftwareInterrupt
  Clears a flag in the LAN9118_DATA structure
  Sets the SW_INT_EN bit of the INT_EN register
  WARNING this has thread sychronization issues. Use with caution.
*/
void Lan_EnableSoftwareInterrupt(PLAN9118_DATA pLan9118Data)
{
	DWORD dwTemp = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		pLan9118Data->SoftwareInterruptSignal = (BOOLEAN)FALSE;
		dwTemp = GetRegDW(pLan9118Data->dwLanBase, INT_EN);
		dwTemp |= INT_EN_SW_INT_EN_;
		SetRegDW(pLan9118Data->dwLanBase, INT_EN, dwTemp);
	}
}

/*
FUNCTION: Lan_HandleSoftwareInterrupt
  Disables the SW_INT_EN bit of the INT_EN register,
  Clears the SW_INT in the INT_STS,
  Sets a flag in the LAN9118_DATA structure
*/
void Lan_HandleSoftwareInterrupt(PLAN9118_DATA pLan9118Data)
{
	DWORD dwTemp = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		dwTemp = GetRegDW(pLan9118Data->dwLanBase, INT_EN);
		dwTemp &= ~(INT_EN_SW_INT_EN_);
		SetRegDW(pLan9118Data->dwLanBase, INT_EN, dwTemp);
		SetRegDW(pLan9118Data->dwLanBase, INT_STS, INT_STS_SW_INT_);
		pLan9118Data->SoftwareInterruptSignal = (BOOLEAN)TRUE;
	}
}

/*
FUNCTION: Lan_IsSoftwareInterruptSignaled
  returns the set/cleared state of the flag used in
	Lan_EnableSoftwareInterrupt
	Lan_HandleSoftwareInterrupt
*/
BOOLEAN Lan_IsSoftwareInterruptSignaled(const LAN9118_DATA * const pLan9118Data)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		return pLan9118Data->SoftwareInterruptSignal;
	}
	else
	{
		return (BOOLEAN)FALSE;
	}
}

void Lan_SetMacAddress(PLAN9118_DATA const pLan9118Data, const DWORD dwHigh16, const DWORD dwLow32)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		Lan_SetMacRegDW(pLan9118Data->dwLanBase, ADDRH, dwHigh16);
		Lan_SetMacRegDW(pLan9118Data->dwLanBase, ADDRL, dwLow32);
		pLan9118Data->dwMacAddrHigh16 = dwHigh16;
		pLan9118Data->dwMacAddrLow32 = dwLow32;
	}
}

void Lan_GetMacAddress(PLAN9118_DATA const pLan9118Data, DWORD * const dwHigh16,DWORD * const dwLow32)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		*dwHigh16 = pLan9118Data->dwMacAddrHigh16=
						Lan_GetMacRegDW(pLan9118Data->dwLanBase, ADDRH);
		*dwLow32 = pLan9118Data->dwMacAddrLow32=
						Lan_GetMacRegDW(pLan9118Data->dwLanBase, ADDRL);
	}
}

void Lan_InitializeTx(PLAN9118_DATA const pLan9118Data)
{
	DWORD dwRegVal = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		SMSC_ASSERT(pLan9118Data->InterruptsInitialized == TRUE);
		SMSC_ASSERT(pLan9118Data->PhyInitialized == TRUE);

		// setup MAC for TX
		dwRegVal = Lan_GetMacRegDW(pLan9118Data->dwLanBase, MAC_CR);
		dwRegVal |= (MAC_CR_TXEN_ | MAC_CR_HBDIS_);
		Lan_SetMacRegDW(pLan9118Data->dwLanBase, MAC_CR, dwRegVal);

		//setup TLI store-and-forward, and preserve TxFifo size
		dwRegVal = GetRegDW(pLan9118Data->dwLanBase, HW_CFG);
		// some chips (may) use bit 11~0 
		dwRegVal &= (HW_CFG_TX_FIF_SZ_ | 0xFFFUL);
		dwRegVal |= HW_CFG_SF_;
		SetRegDW(pLan9118Data->dwLanBase, HW_CFG, dwRegVal);

		SetRegDW(pLan9118Data->dwLanBase, TX_CFG, TX_CFG_TX_ON_);

		SetRegDW(pLan9118Data->dwLanBase, FIFO_INT, 0xFF000000UL);
		Lan_EnableInterrupt(pLan9118Data, 
					INT_EN_TDFU_EN_ | INT_EN_TDFO_EN_ | INT_EN_TDFA_EN_);

		pLan9118Data->TxInitialized = (BOOLEAN)TRUE;
	}
}

void Lan_StartTx(const LAN9118_DATA * const pLan9118Data, const DWORD dwTxCmdA, const DWORD dwTxCmdB)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		
		SMSC_ASSERT(pLan9118Data->TxInitialized == TRUE);
		SetRegDW(pLan9118Data->dwLanBase, TX_DATA_FIFO_PORT ,dwTxCmdA);
		SetRegDW(pLan9118Data->dwLanBase, TX_DATA_FIFO_PORT, dwTxCmdB);
	}
}

void Lan_SendPacketPIO(const LAN9118_DATA * const pLan9118Data, const WORD wPacketTag, const WORD wPacketLength, BYTE * pbPacketData)
{
	DWORD dwTxCmdA;
	DWORD dwTxCmdB;

	SMSC_ASSERT(pLan9118Data);
	
	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		SMSC_ASSERT(pLan9118Data->TxInitialized == TRUE);
		if(wPacketTag == 0)
		{
			SMSC_WARNING0("Lan_SendPacketPIO(wPacketTag==0) Zero is reserved\n");
		}

		dwTxCmdA=(
			((((DWORD)pbPacketData)&0x03UL)<<16) | //DWORD alignment adjustment
			TX_CMD_A_INT_FIRST_SEG_ | TX_CMD_A_INT_LAST_SEG_ | 
			((DWORD)wPacketLength));
		dwTxCmdB=
			(((DWORD)wPacketTag)<<16) | 
			((DWORD)wPacketLength);
		SetRegDW(pLan9118Data->dwLanBase,TX_DATA_FIFO_PORT,dwTxCmdA);
		SetRegDW(pLan9118Data->dwLanBase,TX_DATA_FIFO_PORT,dwTxCmdB);
		Lan_WriteTxFifo(
			pLan9118Data->dwLanBase,
			(DWORD *)(((DWORD)pbPacketData)&0xFFFFFFFCUL),
			((DWORD)wPacketLength+3UL+
			(((DWORD)pbPacketData)&0x03UL))>>2);
	}
}

DWORD Lan_CompleteTx(const LAN9118_DATA * const pLan9118Data)
{
	DWORD result = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase!=0UL);
		SMSC_ASSERT(pLan9118Data->TxInitialized==TRUE);

		result = GetRegDW(pLan9118Data->dwLanBase,TX_FIFO_INF);
		result &= TX_FIFO_INF_TSUSED_;
		if(result != 0x00000000UL) {
			result = GetRegDW(pLan9118Data->dwLanBase,TX_STATUS_FIFO_PORT);
		} else {
			result = 0UL;
		}
	}
	return result;
}

DWORD Lan_GetTxDataFreeSpace(const LAN9118_DATA * const pLan9118Data)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		return GetRegDW(pLan9118Data->dwLanBase,TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;
	}
	else
	{
		return 0x0UL;
	}
}

DWORD Lan_GetTxStatusCount(const LAN9118_DATA * const pLan9118Data)
{
	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		return ((GetRegDW(pLan9118Data->dwLanBase,TX_FIFO_INF) & (TX_FIFO_INF_TSUSED_)) >> 16) & 0xFFFFUL;
	}
	else
	{
		return 0x0UL;
	}
}


void Lan_InitializeRx(CPCLAN9118_DATA pLan9118Data, const DWORD dwRxCfg, const DWORD dw)
{
	DWORD dwRegVal = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);
		SMSC_ASSERT(pLan9118Data->InterruptsInitialized == TRUE);
		SMSC_ASSERT(pLan9118Data->PhyInitialized == TRUE);

		//set receive configuration
		SetRegDW(pLan9118Data->dwLanBase, RX_CFG, dwRxCfg);

		//set the interrupt levels to zero
		dwRegVal = GetRegDW(pLan9118Data->dwLanBase, FIFO_INT);
		dwRegVal &= 0xFFFF0000UL;
		dwRegVal |= (dw & 0x0000FFFFUL);
		SetRegDW(pLan9118Data->dwLanBase, FIFO_INT, dwRegVal);

		//enable interrupt
		Lan_EnableInterrupt(pLan9118Data, INT_EN_RSFL_EN_);
	}
}


DWORD Lan_PopRxStatus(CPCLAN9118_DATA pLan9118Data)
{
	DWORD result = 0UL;

	SMSC_ASSERT(pLan9118Data);

	if (pLan9118Data)
	{
		SMSC_ASSERT(pLan9118Data->dwLanBase != 0UL);

		result = GetRegDW(pLan9118Data->dwLanBase, RX_FIFO_INF);
		if(result & 0x00FF0000UL) {
			//Rx status is available, read it
			result = GetRegDW(pLan9118Data->dwLanBase,RX_STATUS_FIFO_PORT);
		} else {
			result = 0UL;
		}
	}
	return result;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -