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

📄 enc28j60.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}#ifdef CONFIG_USE_IRQ	/* set global interrupt enable bit in enc28j60 */	m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);#endif}static void encRx (void){	unsigned short pkt_len;	unsigned short copy_len;	unsigned short status;	unsigned char eir_reg;	unsigned char pkt_cnt = 0;	unsigned short rxbuf_rdpt;	/* switch to bank 0 */	m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));	m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);	m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);	do {		m_nic_read_data (6, buffer);		next_pointer_lsb = buffer[0];		next_pointer_msb = buffer[1];		pkt_len = buffer[2];		pkt_len |= (unsigned short) buffer[3] << 8;		status = buffer[4];		status |= (unsigned short) buffer[5] << 8;		if (pkt_len <= ENC_MAX_FRM_LEN)			copy_len = pkt_len;		else			copy_len = 0;		if ((status & (1L << 7)) == 0) /* check Received Ok bit */			copy_len = 0;		/* taken from the Linux driver */		/* check if next pointer is resonable */		if ((((unsigned int)next_pointer_msb << 8) |			(unsigned int)next_pointer_lsb) >= ENC_TX_BUF_START)			copy_len = 0;		if (copy_len > 0) {			m_nic_read_data (copy_len, buffer);		}		/* advance read pointer to next pointer */		m_nic_write (CTL_REG_ERDPTL, next_pointer_lsb);		m_nic_write (CTL_REG_ERDPTH, next_pointer_msb);		/* decrease packet counter */		m_nic_bfs (CTL_REG_ECON2, ENC_ECON2_PKTDEC);		/* taken from the Linux driver */		/* Only odd values should be written to ERXRDPTL,		 * see errata B4 pt.13		 */		rxbuf_rdpt = (next_pointer_msb << 8 | next_pointer_lsb) - 1;		if ((rxbuf_rdpt < (m_nic_read(CTL_REG_ERXSTH) << 8 |				m_nic_read(CTL_REG_ERXSTL))) || (rxbuf_rdpt >				(m_nic_read(CTL_REG_ERXNDH) << 8 |				m_nic_read(CTL_REG_ERXNDL)))) {			m_nic_write(CTL_REG_ERXRDPTL, m_nic_read(CTL_REG_ERXNDL));			m_nic_write(CTL_REG_ERXRDPTH, m_nic_read(CTL_REG_ERXNDH));		} else {			m_nic_write(CTL_REG_ERXRDPTL, rxbuf_rdpt & 0xFF);			m_nic_write(CTL_REG_ERXRDPTH, rxbuf_rdpt >> 8);		}		/* move to bank 1 */		m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL1);		m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL0);		/* read pktcnt */		pkt_cnt = m_nic_read (CTL_REG_EPKTCNT);		/* switch to bank 0 */		m_nic_bfc (CTL_REG_ECON1,			   (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));		if (copy_len == 0) {			eir_reg = m_nic_read (CTL_REG_EIR);			encReceiverReset ();			printf ("eth_rx: copy_len=0\n");			continue;		}		NetReceive ((unsigned char *) buffer, pkt_len);		eir_reg = m_nic_read (CTL_REG_EIR);	} while (pkt_cnt);	/* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */}static void encWriteReg (unsigned char regNo, unsigned char data){	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0x40 | regNo);	/* write in regNo */	spi_write (data);	enc_disable ();	enc_enable ();	spi_write (0x1f);	/* write reg 0x1f */	enc_disable ();	spi_unlock ();}static void encWriteRegRetry (unsigned char regNo, unsigned char data, int c){	unsigned char readback;	int i;	spi_lock ();	for (i = 0; i < c; i++) {		enc_cfg_spi ();		enc_enable ();		spi_write (0x40 | regNo);	/* write in regNo */		spi_write (data);		enc_disable ();		enc_enable ();		spi_write (0x1f);	/* write reg 0x1f */		enc_disable ();		spi_unlock ();	/* we must unlock spi first */		readback = encReadReg (regNo);		spi_lock ();		if (readback == data)			break;	}	spi_unlock ();	if (i == c) {		printf ("enc28j60: write reg %d failed\n", regNo);	}}static unsigned char encReadReg (unsigned char regNo){	unsigned char rxByte;	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0x1f);	/* read reg 0x1f */	bank = spi_read () & 0x3;	enc_disable ();	enc_enable ();	spi_write (regNo);	rxByte = spi_read ();	/* check if MAC or MII register */	if (((bank == 2) && (regNo <= 0x1a)) ||	    ((bank == 3) && (regNo <= 0x05 || regNo == 0x0a))) {		/* ignore first byte and read another byte */		rxByte = spi_read ();	}	enc_disable ();	spi_unlock ();	return rxByte;}static void encReadBuff (unsigned short length, unsigned char *pBuff){	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0x20 | 0x1a);	/* read buffer memory */	while (length--) {		if (pBuff != NULL)			*pBuff++ = spi_read ();		else			spi_write (0);	}	enc_disable ();	spi_unlock ();}static void encWriteBuff (unsigned short length, unsigned char *pBuff){	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0x60 | 0x1a);	/* write buffer memory */	spi_write (0x00);	/* control byte */	while (length--)		spi_write (*pBuff++);	enc_disable ();	spi_unlock ();}static void encBitSet (unsigned char regNo, unsigned char data){	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0x80 | regNo);	/* bit field set */	spi_write (data);	enc_disable ();	spi_unlock ();}static void encBitClr (unsigned char regNo, unsigned char data){	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0xA0 | regNo);	/* bit field clear */	spi_write (data);	enc_disable ();	spi_unlock ();}static void encReset (void){	spi_lock ();	enc_cfg_spi ();	enc_enable ();	spi_write (0xff);	/* soft reset */	enc_disable ();	spi_unlock ();	/* sleep 1 ms. See errata pt. 2 */	udelay (1000);}static void encInit (unsigned char *pEthAddr){	unsigned short phid1 = 0;	unsigned short phid2 = 0;	/* switch to bank 0 */	m_nic_bfc (CTL_REG_ECON1, (ENC_ECON1_BSEL1 | ENC_ECON1_BSEL0));	/*	 * Setup the buffer space. The reset values are valid for the	 * other pointers.	 */	/* We shall not write to ERXST, see errata pt. 5. Instead we	   have to make sure that ENC_RX_BUS_START is 0. */	m_nic_write_retry (CTL_REG_ERXSTL, (ENC_RX_BUF_START & 0xFF), 1);	m_nic_write_retry (CTL_REG_ERXSTH, (ENC_RX_BUF_START >> 8), 1);	/* taken from the Linux driver */	m_nic_write_retry (CTL_REG_ERXNDL, (ENC_RX_BUF_END & 0xFF), 1);	m_nic_write_retry (CTL_REG_ERXNDH, (ENC_RX_BUF_END >> 8), 1);	m_nic_write_retry (CTL_REG_ERDPTL, (ENC_RX_BUF_START & 0xFF), 1);	m_nic_write_retry (CTL_REG_ERDPTH, (ENC_RX_BUF_START >> 8), 1);	next_pointer_lsb = (ENC_RX_BUF_START & 0xFF);	next_pointer_msb = (ENC_RX_BUF_START >> 8);	/* verify identification */	phid1 = phyRead (PHY_REG_PHID1);	phid2 = phyRead (PHY_REG_PHID2);	if (phid1 != ENC_PHID1_VALUE	    || (phid2 & ENC_PHID2_MASK) != ENC_PHID2_VALUE) {		printf ("ERROR: failed to identify controller\n");		printf ("phid1 = %x, phid2 = %x\n",			phid1, (phid2 & ENC_PHID2_MASK));		printf ("should be phid1 = %x, phid2 = %x\n",			ENC_PHID1_VALUE, ENC_PHID2_VALUE);	}	/*	 * --- MAC Initialization ---	 */	/* Pull MAC out of Reset */	/* switch to bank 2 */	m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);	m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);	/* enable MAC to receive frames */	/* added some bits from the Linux driver */	m_nic_write_retry (CTL_REG_MACON1		,(ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS)		,10);	/* configure pad, tx-crc and duplex */	/* added a bit from the Linux driver */	m_nic_write_retry (CTL_REG_MACON3		,(ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN | ENC_MACON3_FRMLNEN)		,10);	/* added 4 new lines from the Linux driver */	/* Allow infinite deferals if the medium is continously busy */	m_nic_write_retry(CTL_REG_MACON4, (1<<6) /*ENC_MACON4_DEFER*/, 10);	/* Late collisions occur beyond 63 bytes */	m_nic_write_retry(CTL_REG_MACLCON2, 63, 10);	/* Set (low byte) Non-Back-to_Back Inter-Packet Gap. Recommended 0x12 */	m_nic_write_retry(CTL_REG_MAIPGL, 0x12, 10);	/*	* Set (high byte) Non-Back-to_Back Inter-Packet Gap. Recommended	* 0x0c for half-duplex. Nothing for full-duplex	*/	m_nic_write_retry(CTL_REG_MAIPGH, 0x0C, 10);	/* set maximum frame length */	m_nic_write_retry (CTL_REG_MAMXFLL, (ENC_MAX_FRM_LEN & 0xff), 10);	m_nic_write_retry (CTL_REG_MAMXFLH, (ENC_MAX_FRM_LEN >> 8), 10);	/*	 * Set MAC back-to-back inter-packet gap. Recommended 0x12 for half duplex	 * and 0x15 for full duplex.	 */	m_nic_write_retry (CTL_REG_MABBIPG, 0x12, 10);	/* set MAC address */	/* switch to bank 3 */	m_nic_bfs (CTL_REG_ECON1, (ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1));	m_nic_write_retry (CTL_REG_MAADR0, pEthAddr[5], 1);	m_nic_write_retry (CTL_REG_MAADR1, pEthAddr[4], 1);	m_nic_write_retry (CTL_REG_MAADR2, pEthAddr[3], 1);	m_nic_write_retry (CTL_REG_MAADR3, pEthAddr[2], 1);	m_nic_write_retry (CTL_REG_MAADR4, pEthAddr[1], 1);	m_nic_write_retry (CTL_REG_MAADR5, pEthAddr[0], 1);	/*	* PHY Initialization taken from the Linux driver	 */	/* Prevent automatic loopback of data beeing transmitted by setting	   ENC_PHCON2_HDLDIS */	phyWrite(PHY_REG_PHCON2, (1<<8));	/* LEDs configuration	 * LEDA: LACFG = 0100 -> display link status	 * LEDB: LBCFG = 0111 -> display TX & RX activity	 * STRCH = 1 -> LED pulses	 */	phyWrite(PHY_REG_PHLCON, 0x0472);	/* Reset PDPXMD-bit => half duplex */	phyWrite(PHY_REG_PHCON1, 0);	/*	 * Receive settings	 */#ifdef CONFIG_USE_IRQ	/* enable interrupts */	m_nic_bfs (CTL_REG_EIE, ENC_EIE_PKTIE);	m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXIE);	m_nic_bfs (CTL_REG_EIE, ENC_EIE_RXERIE);	m_nic_bfs (CTL_REG_EIE, ENC_EIE_TXERIE);	m_nic_bfs (CTL_REG_EIE, ENC_EIE_INTIE);#endif}/***************************************************************************** * * Description: *    Read PHY registers. * *    NOTE! This function will change to Bank 2. * * Params: *    [in] addr address of the register to read * * Returns: *    The value in the register */static unsigned short phyRead (unsigned char addr){	unsigned short ret = 0;	/* move to bank 2 */	m_nic_bfc (CTL_REG_ECON1, ENC_ECON1_BSEL0);	m_nic_bfs (CTL_REG_ECON1, ENC_ECON1_BSEL1);	/* write address to MIREGADR */	m_nic_write (CTL_REG_MIREGADR, addr);	/* set MICMD.MIIRD */	m_nic_write (CTL_REG_MICMD, ENC_MICMD_MIIRD);	/* taken from the Linux driver */	/* move to bank 3 */	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0);	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);	/* poll MISTAT.BUSY bit until operation is complete */	while ((m_nic_read (CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {		static int cnt = 0;		if (cnt++ >= 1000) {			/* GJ - this seems extremely dangerous! */			/* printf("#"); */			cnt = 0;		}	}	/* taken from the Linux driver */	/* move to bank 2 */	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0);	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);	/* clear MICMD.MIIRD */	m_nic_write (CTL_REG_MICMD, 0);	ret = (m_nic_read (CTL_REG_MIRDH) << 8);	ret |= (m_nic_read (CTL_REG_MIRDL) & 0xFF);	return ret;}/***************************************************************************** * * Taken from the Linux driver. * Description: * Write PHY registers. * * NOTE! This function will change to Bank 3. * * Params: * [in] addr address of the register to write to * [in] data to be written * * Returns: *    None */static void phyWrite(unsigned char addr, unsigned short data){	/* move to bank 2 */	m_nic_bfc(CTL_REG_ECON1, ENC_ECON1_BSEL0);	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);	/* write address to MIREGADR */	m_nic_write(CTL_REG_MIREGADR, addr);	m_nic_write(CTL_REG_MIWRL, data & 0xff);	m_nic_write(CTL_REG_MIWRH, data >> 8);	/* move to bank 3 */	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL0);	m_nic_bfs(CTL_REG_ECON1, ENC_ECON1_BSEL1);	/* poll MISTAT.BUSY bit until operation is complete */	while((m_nic_read(CTL_REG_MISTAT) & ENC_MISTAT_BUSY) != 0) {		static int cnt = 0;		if(cnt++ >= 1000) {			cnt = 0;		}	}}#endif /* CONFIG_ENC28J60 */

⌨️ 快捷键说明

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