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

📄 enc28j60.c

📁 网卡的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
{
//  printk("xmit called!\n");
    // Set the write pointer to start of transmit buffer area
    enc28j60Write(EWRPTL, TXSTART_INIT);
    enc28j60Write(EWRPTH, TXSTART_INIT>>8);
    // Set the TXND pointer to correspond to the packet size given
    enc28j60Write(ETXNDL, (TXSTART_INIT+skb->len));
    enc28j60Write(ETXNDH, (TXSTART_INIT+skb->len)>>8);
    //Set ETXST
    enc28j60Write(ETXSTL, TXSTART_INIT);
    enc28j60Write(ETXSTH, TXSTART_INIT>>8);
    // write per-packet control byte
    enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);

    // copy the packet into the transmit buffer
    enc28j60WriteBuffer(skb->len, skb->data);
    if(enc28j60Read(EIR) & EIR_TXERIF)
    {	
    	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
    	enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
    }
    enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF|EIR_TXIF);
    // send the contents of the transmit buffer onto the network
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
		dev_kfree_skb(skb);
    udelay(2300);

	return 0;
}

static void
enc28j60_Interrupt(int irq, void *dev_id, struct pt_regs * regs)
{

    struct sk_buff *skb;
    struct net_device *dev = dev_id;
    u16 rxstat;
    u16 len=0;
    unsigned char initpacket[3000];
    unsigned char* packet=initpacket;
    int counter;
    int loop=1;
    printk("0x%02x ",enc28j60Read(EPKTCNT)); 
    if(enc28j60Read(EPKTCNT) ==0)
    {
    	printk("!!!!!!! Exception called!!!!!!!!!!!!\n");
    	/*enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXRST);
    	while(ResetCounter--);
    	enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXRST);
    	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);*/
    	return 0;
    }
   // printk("interrupt called!\n");
    // check if a packet has been received and buffered
//    if( !(enc28j60Read(EIR) & EIR_PKTIF) )
//        return ;
		//if(enc28j60Read(EPKTCNT) !=0){
	//	enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIE, EIE_PKTIE);
    //while (enc28j60Read(EPKTCNT) !=0) {
			
    // Set the read pointer to the start of the received packet
    enc28j60Write(ERDPTL, (NextPacketPtr));
    enc28j60Write(ERDPTH, (NextPacketPtr)>>8);
    // read the next packet pointer
    NextPacketPtr  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
    // read the packet length
    len  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
//    printk("receive size is: %d\n",len);
    // read the receive status
    rxstat  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;

    skb = dev_alloc_skb(len);
    skb->dev = dev;
    skb_put(skb,len);

    // copy the packet from the receive buffer
    enc28j60ReadBuffer(len, skb->data);

    // Move the RX read pointer to the start of the next received packet
    // This frees the memory we just read out
    enc28j60Write(ERXRDPTL, (NextPacketPtr));
    enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8);

// decrement the packet counter indicate we are done with this packet
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);

    skb->protocol= eth_type_trans(skb,dev);
    skb->ip_summed = CHECKSUM_UNNECESSARY;
    netif_rx(skb);


//}
/*while (enc28j60Read(EIR) & EIR_PKTIF)
{
	//enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
	printk("!!!!!!! Exception called!!!!!!!!!!!!\n");
	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
	enc28j60Write(EPKTCNT, 0);
}*/
	
/*while (enc28j60Read(EIR) & EIR_RXERIF){
	printk("!!!!!!! called!!!!!!!!!!!!\n");
	printk("!!!!!!! called!!!!!!!!!!!!\n");
	printk("!!!!!!! called!!!!!!!!!!!!\n");
	NextPacketPtr  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
    enc28j60Write(ERXRDPTL, (NextPacketPtr));
    enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8);
	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
	//enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_RXERIF);
	//enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_PKTIF);
	//enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EPKTCNT, 0);
	enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_RXERIF);
}*/
//enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE);
printk("0x%02x  ",enc28j60Read(EIR));
    //printk("0x%02x\n\n",enc28j60Read(EIE));
   printk("0x%02x ",enc28j60Read(EPKTCNT)); 
	return;
}

int enc28j60_init (struct net_device *dev)
{
	int result;
	static struct net_device_stats enc28j60_netstats;
	dev->priv = &enc28j60_netstats ;
	memset(dev->priv, 0, sizeof(struct net_device_stats));
	dev->get_stats = get_stats;

	dev->open = enc28j60_open;
	dev->stop = enc28j60_release;
	dev->hard_start_xmit = enc28j60_xmit;

	dev->dev_addr[0] = ENC28J60_MAC0;
	dev->dev_addr[1] = ENC28J60_MAC1;
	dev->dev_addr[2] = ENC28J60_MAC2;
	dev->dev_addr[3] = ENC28J60_MAC3;
	dev->dev_addr[4] = ENC28J60_MAC4;
	dev->dev_addr[5] = ENC28J60_MAC5;

	ether_setup(dev);

//    	printk("dev->hard_header_len: 0x%02x\n",dev->hard_header_len);
		printk("MAC address:  %02x:%02x:%02x:%02x:%02x:%02x\n", 
				dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2], 
				dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]);

	result =  request_irq(IRQ_EINT8,enc28j60_Interrupt , 0, "enc28j60" , dev);
	printk("request_irq returned: %d\n",result);

    printk("starting enc28j60 init process!\n");
	return 0;
}

struct net_device enc28j60 = {init: enc28j60_init};

int enc28j60_init_module (void)
{
	int result,i;
	unsigned long tmpval;

	strcpy (enc28j60.name, "eth%d");
	if ((result = register_netdev (&enc28j60))) {
		printk ("enc28j60: Error %d  initializing enc28j60 based device",result);
		return result;
	}

	//these hardware specific inits should be moved to a generic file
	//configure GPG5,GPG6,GPG7 for SPI1 interface and GPG0 as output
	
	// jack: GPE13-->SCLK, GPE12-->SMOSI0; GPE11<--SMISO0
//	printk("starting init hardware pins.\n");
//	printk("GPECON=0X%0X\n",GPECON);
	GPECON |= (2<<22);	//GPECON |= GPIO_MODE_SPIMISO;
	GPECON |= (2<<24);	//GPIO_MODE_SPIMOSI;
	GPECON |= (2<<26);	//GPIO_MODE_SPICLK;
//	printk("GPECON=0X%0X\n",GPECON);
	//disable the pullup resistors for GPE11,GPE12,GPE13
	GPEUP |= (1<<11) | (1<<12) | (1<<13);

	// configure GPB6 as output, GPB6-->cs
	GPBCON |= (1<<12);			//GPBCON |= GPIO_MODE_OUT;
//	printk("GPBCON=0X%0X\n",GPBCON);
	// disable pullup resisters for GPB6
	GPBUP |= (1<<6);
	
	//configure GPG0 as inputs (later GPG0 will be an irq--EINT8)
	GPGCON |= (2<<0);	//GPIO_MODE_EINT;
//	printk("GPGCON=0X%0X\n",GPGCON);
	//disable pullup resistors for GPFG0
	GPGUP |= (1<<0) ;

	// //configure GPF7 as inputs (later GPF7 will be an irq--EINT7)
	GPFCON |= (2<<14);	//GPIO_MODE_EINT;
//		printk("GPFCON=0X%0X\n",GPFCON);
	//disable pullup resistors for GPF7
	GPFUP |= (1<<7) ;
	 
	//configure the SPI prescaler for 10mhz baud rate
	SPPRE0 = 0x1;	//??

	//configure the SPI for master and turn it on
	SPCON0 = 0x18;	//POLLING MODE,enable SCLK,master

	for (i=0;i<10;i++)
       	  SPTDAT0 = 0XFF;

	enc28j60ChipSelect(1);

	while(!(SPSTA0 & 0X01));	//wait until REDY=1
//	printk("spi tx is ready.\n");
	enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
	udelay(50);
	while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
	
	// set bank 0
    enc28j60SetBank(ECON1);

    // do bank 0 stuff
    // initialize receive buffer
    // 16-bit transfers, must write low byte first
    // set receive buffer start address
    NextPacketPtr = RXSTART_INIT;
    enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
    enc28j60Write(ERXSTH, RXSTART_INIT>>8);
    // set receive pointer address
    enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
    enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
    // set receive buffer end
    // ERXND defaults to 0x1FFF (end of ram)
    enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
    enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
    // set transmit buffer start
    // ETXST defaults to 0x0000 (beginnging of ram)
    enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
    enc28j60Write(ETXSTH, TXSTART_INIT>>8);

//    printk("bank2 enc28j60 init process!\n");

    // do bank 2 stuff
    // enable MAC receive
    enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
    // bring MAC out of reset
    enc28j60Write(MACON2, 0x00);
    // enable automatic padding and CRC operations
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN|MACON3_FULDPX);
    enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
    // set inter-frame gap (non-back-to-back)
    enc28j60Write(MAIPGL, 0x12);
   // enc28j60Write(MAIPGH, 0x0C);
    // set inter-frame gap (back-to-back)
   // enc28j60Write(MABBIPG, 0x12);
    enc28j60Write(MABBIPG, 0x15);       //by bt
    // Set the maximum packet size which the controller will accept
    enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);
    enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);

//    printk("bank3 enc28j60 init process!\n");
    // do bank 3 stuff
    // write MAC address
    // NOTE: MAC address in ENC28J60 is byte-backward
    enc28j60Write(MAADR5, ENC28J60_MAC0);
    enc28j60Write(MAADR4, ENC28J60_MAC1);
    enc28j60Write(MAADR3, ENC28J60_MAC2);
    enc28j60Write(MAADR2, ENC28J60_MAC3);
    enc28j60Write(MAADR1, ENC28J60_MAC4);
    enc28j60Write(MAADR0, ENC28J60_MAC5);

	enc28j60PhyWrite(PHLCON, 0x0aa2); //0x0122
	enc28j60PhyWrite(PHCON1, PHCON1_PDPXMD);
	printk("PHLCON=0X%0X\n",enc28j60PhyRead(PHLCON));
    // no loopback of transmitted frames
//    printk("phy enc28j60 init process!\n");
    enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);

	// switch to bank 0
	enc28j60SetBank(ECON1);

    // enable packet reception
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
	enc28j60Write(ERXFCON, 0x00);
    	// enable interrutps
//    printk("enabling interupts!\n");
    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);//|EIE_RXERIE);

    // Reenable receive logic
  //  enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);

	printk ("enc28j60 device initialized\n");

return 0;

}

void enc28j60_cleanup (void)
{
	printk ("Cleaning Up the Module\n");
	enc28j60PhyWrite(PHLCON, 0x0492);	//0x0992
	unregister_netdev (&enc28j60);
	return;
}

module_init (enc28j60_init_module);
module_exit (enc28j60_cleanup);
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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