📄 enc28j60.c
字号:
{
// 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 + -