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

📄 dm9000.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	DM9000_iow(DM9000_GPCR, 0x01);   /* Let GPIO0 output */
	DM9000_iow(DM9000_GPR, 0x00);   /* Enable PHY */
}

#ifdef CONFIG_DM9000_SROM
static u16 dm9000_read_srom(int offset)
{
   DM9000_iow(DM9000_EPAR, offset);
   DM9000_iow(DM9000_EPCR, 0x4);
   OALStall(200);
   DM9000_iow(DM9000_EPCR, 0x0);
   return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8));
}
#endif

static void dm9000_reset(void)
{
    OALMSGS(DM9000_DEBUG, (L"dm9000_reset\r\n"));
	
	DM9000_iow(DM9000_NCR, NCR_RST);
	OALStall(1000);      /* delay 1ms */
}

BOOL DM9000Init(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
	int i, oft, lnk;
	UINT8* pMAC = (UINT8*) mac;

	DM9000_IO = (UINT32) pAddress;
	DM9000_DATA = DM9000_IO + 4;

	OALMSGS(DM9000_DEBUG, (L"+DM9000Init I/O: 0x%08x\r\n", DM9000_IO));

	/* RESET device */
	dm9000_reset();
	dm9000_probe();

	/* NIC Type: FASTETHER, HOMERUN, LONGRUN */
//	identify_nic();

	/* GPIO0 on pre-activate PHY */
	DM9000_iow(DM9000_GPR, 0x00);   /*REG_1F bit0 activate phyxcer */

	/* Set PHY */
	dm9000_set_mode(DM9000_PHY_MODE);

	/* Program operating register */
	DM9000_iow(DM9000_NCR, 0x0);   /* only intern phy supported by now */
	DM9000_iow(DM9000_TCR, 0);   /* TX Polling clear */
//	DM9000_iow(DM9000_BPTR, 0x3f);   /* Less 3Kb, 200us */
//   DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));   /* Flow Control : High/Low Water */
//   DM9000_iow(DM9000_FCR, 0xff);   /* enable Flow Control */
	DM9000_iow(DM9000_SMCR, 0);   /* Special Mode */
	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);   /* clear TX status */
	DM9000_iow(DM9000_ISR, 0x0f);   /* Clear interrupt status */

	/* Set Node address */
	for (i = 0; i < 6; i++)
#ifdef CONFIG_DM9000_SROM
		pMAC[i] = dm9000_read_srom(i);
#else
		pMAC[i] = i;
#endif
	OALMSGS(DM9000_INFO, (L"DM9000 MAC: %02x:%02x:%02x:%02x:%02x:%02x\r\n",
				pMAC[0], pMAC[1], pMAC[2], pMAC[3], pMAC[4], pMAC[5]));
	for (i = 0, oft = 0x10; i < 6; i++, oft++)
		DM9000_iow(oft, pMAC[i]);
	for (i = 0, oft = 0x16; i < 8; i++, oft++)
		DM9000_iow(oft, 0xff);

	/* read back mac, just to be sure */
//	for (i = 0, oft = 0x10; i < 6; i++, oft++)
//		DM9000_DBG("%02x:", DM9000_ior(oft));
//	DM9000_DBG("\n");

	/* Activate DM9000 */
	DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);   /* RX enable */
    DM9000_iow(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);   /* Enable TX/RX interrupt mask */
//	DM9000_iow(DM9000_IMR, IMR_PAR);

	for( i=0; !(dm9000_phy_read(1) & 0x20); i++) {   /* autonegation complete bit */
		OALStall(1000);
		if (i == 10000) {
			OALMSGS(DM9000_ERROR, (L"DM9000 could not establish link\r\n"));
			return FALSE;
		}
	}

	/* see what we've got */
	lnk = dm9000_phy_read(17) >> 12;
	OALMSGS(DM9000_INFO, (L"DM9000 operating at %d mode\r\n", lnk));

	OALMSGS(DM9000_DEBUG, (L"-DM9000Init\r\n"));
	return TRUE;
}


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

UINT16 DM9000SendFrame(UINT8 *pBuffer, UINT32 length)
{
	u8 *data_ptr;
	u32 tmplen, i;
//	UINT32 startTime;

	/* wait for end of transmission */
    // Wait until it is sent or an error is generated.
	while( DM9000_ior(DM9000_TCR) & TCR_TXREQ);

	OALMSGS(DM9000_DEBUG, (L"+DM9000SendFrame %d bytes\r\n", length));
#ifdef CONFIG_DM9000_DEBUG
	for (i = 0; i < length; i++) {
		if (i % 8 == 0)
			DM9000_DBG("\nSend: %02x: ", (unsigned int)i);
		DM9000_DBG("%02x ", ((unsigned char *) packet)[i]);
	}
	DM9000_DBG("\n");
#endif
	/* Move data to DM9000 TX RAM */
	data_ptr = (u8 *) pBuffer;
	DM9000_outb(DM9000_MWCMD, DM9000_IO);

#ifdef CONFIG_DM9000_USE_8BIT
	/* Byte mode */
	for (i = 0; i < length; i++)
		DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA);
#endif            /*  */
#ifdef CONFIG_DM9000_USE_16BIT
	tmplen = (length + 1) / 2;
	for (i = 0; i < tmplen; i++)
		DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
#endif            /*  */
#ifdef CONFIG_DM9000_USE_32BIT
	tmplen = (length + 3) / 4;
	for (i = 0; i < tmplen; i++)
		DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
#endif            /*  */

	/* Set TX length to DM9000 */
	DM9000_iow(DM9000_TXPLL, length & 0xff);
	DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);

	/* Issue TX command */
	DM9000_iow(DM9000_TCR, TCR_TXREQ);   /* Cleared after TX complete */

    OALMSGS(DM9000_DEBUG, (L"-DM9000SendFrame\r\n"));
	return 0;
}

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

UINT16 DM9000GetFrame(UINT8 *pBuffer, UINT16 *pLength)
{
   u8 rxbyte, *rdptr = (u8 *) pBuffer;
   u16 IntStatus, RxStatus, RxLen = 0;
   u32 tmplen, i;

    OALMSGS(DM9000_DEBUG, (L"+DM9000GetFrame %d bytes\r\n", *pLength));

	*pLength = 0;

	IntStatus = DM9000_ior(DM9000_ISR);       /* Got ISR */
	DM9000_iow(DM9000_ISR, (u8)IntStatus);        /* Clear ISR status */
   
	/* Check packet ready or not */
	DM9000_ior(DM9000_MRCMDX);   /* Dummy read */
	rxbyte = DM9000_inb(DM9000_DATA);   /* Got most updated data */
	if (rxbyte == 0)
		return 0;

	/* Status check: this byte must be 0 or 1 */
	if (rxbyte > 1) {
		DM9000_iow(DM9000_RCR, 0x00);   /* Stop Device */
//		DM9000_iow(DM9000_ISR, 0x80);   /* Stop INT request */
	    OALMSGS(DM9000_ERROR, (L"DM9000 RX status check FAILED (0x%02x)\r\n", rxbyte));
	}

	/* A packet ready now  & Get status/length */
	DM9000_outb(DM9000_MRCMD, DM9000_IO);

#ifdef CONFIG_DM9000_USE_8BIT
	RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
	RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
#endif            /*  */
#ifdef CONFIG_DM9000_USE_16BIT
	RxStatus = DM9000_inw(DM9000_DATA);
	RxLen = DM9000_inw(DM9000_DATA);
#endif            /*  */
#ifdef CONFIG_DM9000_USE_32BIT
	tmplen = DM9000_inl(DM9000_DATA);
	RxStatus = tmplen;
	RxLen = tmplen >> 16;
#endif            /*  */
	OALMSGS(DM9000_DEBUG, (L"DM9000 RX status: 0x%04x, RX len: %d\r\n", RxStatus, RxLen));

	/* Move data from DM9000 */
	/* Read received packet from RX SRAM */
#ifdef CONFIG_DM9000_USE_8BIT
	for (i = 0; i < RxLen; i++)
		rdptr[i] = DM9000_inb(DM9000_DATA);
#endif            /*  */
#ifdef CONFIG_DM9000_USE_16BIT
	tmplen = (RxLen + 1) / 2;
	for (i = 0; i < tmplen; i++)
		((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
#endif            /*  */
#ifdef CONFIG_DM9000_USE_32BIT
	tmplen = (RxLen + 3) / 4;
	for (i = 0; i < tmplen; i++)
		((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA);
#endif            /*  */
	if ((RxStatus & 0xbf00) || (RxLen < 0x40)
				|| (RxLen > DM9000_PKT_MAX)) {
		OALMSGS(DM9000_ERROR, (L"DM9000 RX error (0x%04x)\r\n", RxStatus));
//		dm9000_reset();
	} else {
#ifdef CONFIG_DM9000_DEBUG
		for (i = 0; i < RxLen; i++) {
			if (i % 8 == 0)
				DM9000_DBG("\nRecv: %02x: ", (unsigned int)i);
			DM9000_DBG("%02x ", rdptr[i]);
		} 
		DM9000_DBG("\n");
#endif
		*pLength = RxLen;
	}
	OALMSGS(DM9000_DEBUG, (L"-DM9000GetFrame\r\n"));

	return *pLength;
}


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

VOID DM9000EnableInts()
{
    OALMSGS(DM9000_DEBUG, (L"+DM9000EnableInts\r\n"));

    DM9000_iow(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);   /* Enable TX/RX interrupt mask */

    OALMSGS(DM9000_DEBUG, (L"-DM9000EnableInts\r\n"));
}

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

VOID DM9000DisableInts()
{
    OALMSGS(DM9000_DEBUG, (L"+DM9000DisableInts\r\n"));

	DM9000_iow(DM9000_IMR, IMR_PAR);   /* Disable TX/RX interrupt mask */
	DM9000_iow(DM9000_ISR, 0xf);
    
	OALMSGS(DM9000_DEBUG, (L"-DM9000DisableInts\r\n"));
}

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

VOID DM9000CurrentPacketFilter(UINT32 filter)
{
    OALMSGS(DM9000_MISS, (L"+DM9000CurrentPacketFilter(0x%08x)\r\n", filter));
    OALMSGS(DM9000_MISS, (L"-DM9000CurrentPacketFilter\r\n"));
}

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

BOOL DM9000MulticastList(UINT8 *pAddresses, UINT32 count)
{
    OALMSGS(DM9000_MISS, (L"+DM9000MulticastList(0x%08x, %d)\r\n", pAddresses, count));
    OALMSGS(DM9000_MISS, (L"-DM9000MulticastList\r\n"));
    return TRUE;
}

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

⌨️ 快捷键说明

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