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

📄 cs8900a2413.c

📁 支持三星原产的S3C2413开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
	UINT32 count;

	OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
		L"+CS8900ASendFrame(0x%08x, %d)\r\n", pData, length
	));

	// Send Command
	#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
	IOWRITE(IO_TX_CMD, TX_CMD_START_ALL);
	IOWRITE(IO_TX_LENGTH, length);
	#else
	OUTPORT16(&g_pCS8900->TXCMD, TX_CMD_START_ALL);
	OUTPORT16(&g_pCS8900->TXLENGTH, length);
	#endif

	count = RETRY_COUNT;
	while (count-- > 0) {
		//RETAILMSG(MSG_ON, (TEXT("x")));
		if ((ReadPacketPage(BUS_ST) & BUS_ST_TX_RDY) != 0) break;
	}
	if (count == 0) goto cleanUp;
	
	length = (length + 1) >> 1;	// because half word write...
	while (length-- > 0) {
		#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
		//RETAILMSG(MSG_ON, (TEXT("IOW[%x]\n"),  *(UINT16*)pData));
		IOWRITE(IO_RX_TX_DATA_0, *(UINT16*)pData);
		#else
		OUTPORT16(&g_pCS8900->DATA0, *(UINT16*)pData);
		#endif
		pData += sizeof(UINT16);
	}

	rc = TRUE;

cleanUp:
	OALMSGS(OAL_ETHER&&OAL_VERBOSE, (L"-CS8900ASendFrame(rc = %d)\r\n", !rc));
	return !rc;
}

//------------------------------------------------------------------------------
//
//  Function:  CS8900AGetFrame
//
UINT16 CS8900AGetFrame(UINT8 *pData, UINT16 *pLength)
{
	UINT16 isq, length, status, count, data;

	OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
		L"+CS8900AGetFrame(0x%08x, %d)\r\n", pData, *pLength
	));

	length = 0;
	#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
	isq = IOREAD(IO_ISQ);			// ((USHORT)*((volatile USHORT *)(dwEthernetIOBase + ((o)<<1) )))
	#else
	isq = INPORT16(&g_pCS8900->ISQ);	// *(volatile USHORT * const) x;
	#endif
	if ((isq & ISQ_ID_MASK) == RX_EVENT_ID && (isq & RX_EVENT_RX_OK) != 0) {

		// Get RxStatus and length
		#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
		status = IOREAD(IO_RX_TX_DATA_0);
		length = IOREAD(IO_RX_TX_DATA_0);
		#else
		status = INPORT16(&g_pCS8900->DATA0);
		length = INPORT16(&g_pCS8900->DATA0);
		#endif

		if (length > *pLength) {
			// If packet doesn't fit in buffer, skip it
			data = ReadPacketPage(RX_CFG);
			WritePacketPage(RX_CFG, data | RX_CFG_SKIP_1);
			length = 0;
		} else {
			// Read packet data
			count = length;
			while (count > 1) {
				#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
				data = IOREAD(IO_RX_TX_DATA_0);
				#else
				data = INPORT16(&g_pCS8900->DATA0);
				#endif
				*(UINT16*)pData = data;
				pData += sizeof(UINT16);
				count -= sizeof(UINT16);
			}

			// Read last one byte
			if (count > 0) {
				#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
				data = IOREAD(IO_RX_TX_DATA_0);
				#else
				data = INPORT16(&g_pCS8900->DATA0);
				#endif
				*pData = (UINT8)data;
			}
		}
	}

	// Return packet size
	*pLength = length;

	OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
		L"-CS8900AGetFrame(length = %d)\r\n", length
	));
	return length;
}

//------------------------------------------------------------------------------
//
//  Function:  CS8900AEnableInts
//
VOID CS8900AEnableInts()
{
	UINT16 data;

	OALMSGS(OAL_ETHER&&OAL_FUNC, (L"+CS8900AEnableInts\r\n"));
	data = ReadPacketPage(BUS_CTL);
	WritePacketPage(BUS_CTL, data | BUS_CTL_ENABLE_IRQ);
	OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-CS8900AEnableInts\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  CS8900ADisableInts
//
VOID CS8900ADisableInts()
{
	UINT16 data;

	OALMSGS(OAL_ETHER&&OAL_FUNC, (L"+CS8900ADisableInts\r\n"));
	data = ReadPacketPage(BUS_CTL);
	WritePacketPage(BUS_CTL, data & ~BUS_CTL_ENABLE_IRQ);
	OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-CS8900ADisableInts\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  CS8900ACurrentPacketFilter
//
VOID CS8900ACurrentPacketFilter(UINT32 filter)
{
	UINT16 rxCtl;

	OALMSGS(OAL_ETHER&&OAL_FUNC, (
		L"+CS8900ACurrentPacketFilter(0x%08x)\r\n", filter
	));

	// Read current filter
	rxCtl = ReadPacketPage(RX_CTL);

	if ((filter & PACKET_TYPE_ALL_MULTICAST) != 0) {
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 0, 0xFFFF);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 2, 0xFFFF);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 4, 0xFFFF);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 6, 0xFFFF);
	} else {
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 0, g_hash[0]);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 2, g_hash[1]);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 4, g_hash[2]);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 6, g_hash[3]);
	}

	if (
		(filter & PACKET_TYPE_MULTICAST) != 0 ||
		(filter & PACKET_TYPE_ALL_MULTICAST) != 0
	) {
		rxCtl |= RX_CTL_MULTICAST;
	} else {
		rxCtl &= ~RX_CTL_MULTICAST;
	}

	if ((filter & PACKET_TYPE_PROMISCUOUS) != 0) {
		rxCtl |= RX_CTL_PROMISCUOUS;
	} else {
		rxCtl &= ~RX_CTL_PROMISCUOUS;
	}

	WritePacketPage(RX_CTL, rxCtl);

	// Save actual filter
	g_filter = filter;

	OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-CS8900ACurrentPacketFilter\r\n"));
}

//------------------------------------------------------------------------------
//
//  Function:  CS8900AMulticastList
//
BOOL CS8900AMulticastList(UINT8 *pAddresses, UINT32 count)
{
	UINT32 i, j, crc, data, bit;

	OALMSGS(OAL_ETHER&&OAL_FUNC, (
		L"+RTL8139MulticastList(0x%08x, %d)\r\n", pAddresses, count
	));

	g_hash[0] = g_hash[1] = g_hash[2] = g_hash[3] = 0;
	for (i = 0; i < count; i++) {
		data = crc = ComputeCRC(pAddresses, 6);
		for (j = 0, bit = 0; j < 6; j++) {
			bit <<= 1;
			bit |= (data & 1);
			data >>= 1;
		}
		g_hash[bit >> 4] |= 1 << (bit & 0x0f);
		pAddresses += 6;
	}

	// But update only if all multicast mode isn't active
	if ((g_filter & PACKET_TYPE_ALL_MULTICAST) == 0) {		
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 0, g_hash[0]);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 2, g_hash[1]);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 4, g_hash[2]);
		WritePacketPage(LOGICAL_ADDR_FILTER_BASE + 6, g_hash[3]);
	}

	OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-CS8900AMulticastList(rc = 1)\r\n"));
	return TRUE;
}

//------------------------------------------------------------------------------

static UINT16 ReadPacketPage(UINT16 address)
{
#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
	IOWRITE(IO_PACKET_PAGE_POINTER, address);
	return IOREAD(IO_PACKET_PAGE_DATA_0);
#else
	OUTREG16(&g_pCS8900->PAGEIX, address);	// (*(volatile unsigned short * const)(reg)) = (val)
	return INREG16(&g_pCS8900->PAGE0);			// (*(volatile unsigned short * const)(reg))
#endif
}


static VOID WritePacketPage(UINT16 address, UINT16 data)
{
#if (BSP_SMDK2413==1 && !SMDK2413_REV14)
	IOWRITE(IO_PACKET_PAGE_POINTER, address);
	IOWRITE(IO_PACKET_PAGE_DATA_0 , data);
	//RETAILMSG(MSG_ON, (TEXT("WrPktPage[%x<-%x]\n"), address, data));
 #else
	OUTREG16(&g_pCS8900->PAGEIX, address);
	OUTREG16(&g_pCS8900->PAGE0, data);
#endif
}


//------------------------------------------------------------------------------

static UINT32 ComputeCRC(UINT8 *pBuffer, UINT32 length)
{
	UINT32 crc, carry, i, j;
	UINT8 byte;

	crc = 0xffffffff;
	for (i = 0; i < length; i++) {
		byte = pBuffer[i];
		for (j = 0; j < 8; j++) {
			carry = ((crc & 0x80000000) ? 1 : 0) ^ (byte & 0x01);
			crc <<= 1;
			byte >>= 1;
			if (carry) crc = (crc ^ 0x04c11db6) | carry;
		}
	}
	return crc;
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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