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

📄 enc28j60.c~

📁 Control ENC28J60 codevision
💻 C~
字号:
#include "enc28j60.h"
#include "mega64.h"unsigned char Enc28j60Bank;unsigned int  NextPacketPtr;
#define  SPIE  7
#define  SPE   6
#define  DORD  5
#define  MSTR  4
#define  CPOL  3
#define  CPHA  2
#define  SPR1  1
#define  SPR0  0

#define  SPIF  7
#define  WCOL  6 
#define  SPI2X 0

#define ENC28J60_CONTROL_CS_W         PORTB.0
#define ENC28J60_CONTROL_CS_R         PINB.0
#define ENC28J60_CONTROL_CS_D         DDRB.0
#define SPI_MOSI_W                    PORTB.2
#define SPI_MOSI_R                    PINB.2
#define SPI_MOSI_D                    DDRB.2
#define SPI_MISO_W                    PORTB.3
#define SPI_MISO_R                    PINB.3
#define SPI_MISO_D                    DDRB.3
#define SPI_SCK_W                     PORTB.1
#define SPI_SCK_R                     PINB.1
#define SPI_SCK_D                     DDRB.1
// set CS to 0 = active#define CSACTIVE ENC28J60_CONTROL_CS_W=0// set CS to 1 = passive#define CSPASSIVE ENC28J60_CONTROL_CS_W=1 //#define waitspi() while(!(SPSR&(1<<SPIF)))unsigned char enc28j60ReadOp(unsigned char op, unsigned char address){        CSACTIVE;        // issue read command        SPDR = op | (address & ADDR_MASK);        waitspi();        // read data        SPDR = 0x00;        waitspi();        // do dummy read if needed (for mac and mii, see datasheet page 29)        if(address & 0x80)        {                SPDR = 0x00;                waitspi();        }        // release CS        CSPASSIVE;        return(SPDR);}void enc28j60WriteOp(unsigned char op, unsigned char address, unsigned char data){        CSACTIVE;        // issue write command        SPDR = op | (address & ADDR_MASK);        waitspi();        // write data        SPDR = data;        waitspi();        CSPASSIVE;}void enc28j60ReadBuffer(unsigned int len, unsigned char* data){        CSACTIVE;        // issue read command        SPDR = ENC28J60_READ_BUF_MEM;        waitspi();        while(len)        {                len--;                // read data                SPDR = 0x00;                waitspi();                *data = SPDR;                data++;        }        *data='\0';        CSPASSIVE;}void enc28j60WriteBuffer(unsigned int len, unsigned char* data){        CSACTIVE;        // issue write command        SPDR = ENC28J60_WRITE_BUF_MEM;        waitspi();        while(len)        {                len--;                // write data                SPDR = *data;                data++;                waitspi();        }        CSPASSIVE;}void enc28j60SetBank(unsigned char address){        // set the bank (if needed)        if((address & BANK_MASK) != Enc28j60Bank)        {                // set the bank                enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));                enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);                Enc28j60Bank = (address & BANK_MASK);        }}unsigned char enc28j60Read(unsigned char address){        // set the bank        enc28j60SetBank(address);        // do the read        return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);}void enc28j60Write(unsigned char address, unsigned char data){        // set the bank        enc28j60SetBank(address);        // do the write        enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);}void enc28j60PhyWrite(unsigned char address, unsigned int data){        // set the PHY register address        enc28j60Write(MIREGADR, address);        // write the PHY data        enc28j60Write(MIWRL, data);        enc28j60Write(MIWRH, data>>8);        // wait until the PHY write completes        while(enc28j60Read(MISTAT) & MISTAT_BUSY){                delayMicroseconds(15);        }}void enc28j60clkout(unsigned char clk){        //setup clkout: 2 is 12.5MHz:    enc28j60Write(ECOCON, clk & 0x7);}void enc28j60Init(unsigned char* macaddr){    // initialize I/O    // ss as output:    
    ENC28J60_CONTROL_CS_D=1;    CSPASSIVE; // ss=0            SPI_MOSI_D=1;        SPI_SCK_D=1;        SPI_MISO_D=0;            SPI_MOSI_W=0;        SPI_SCK_W=0;        // initialize SPI interface    // master mode and Fosc/2 clock:        SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);        SPSR |= (1<<SPI2X);    // perform system reset    enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);    delay_ms(50);    // check CLKRDY bit to see if reset is complete    // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.    //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));    // do bank 0 stuff    // initialize receive buffer    // 16-bit transfers, must write low byte first    // set receive buffer start address    NextPacketPtr = RXSTART_INIT;        // Rx start    enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);    enc28j60Write(ERXSTH, RXSTART_INIT>>8);    // set receive pointer address    enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);    enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);    // RX end    enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);    enc28j60Write(ERXNDH, RXSTOP_INIT>>8);    // TX start    enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);    enc28j60Write(ETXSTH, TXSTART_INIT>>8);    // TX end    enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF);    enc28j60Write(ETXNDH, TXSTOP_INIT>>8);    // do bank 1 stuff, packet filter:        // For broadcast packets we allow only ARP packtets        // All other packets should be unicast only for our mac (MAADR)        //        // The pattern to match on is therefore        // Type     ETH.DST        // ARP      BROADCAST        // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9        // in binary these poitions are:11 0000 0011 1111        // This is hex 303F->EPMM0=0x3f,EPMM1=0x30    enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);    enc28j60Write(EPMM0, 0x3f);    enc28j60Write(EPMM1, 0x30);    enc28j60Write(EPMCSL, 0xf9);    enc28j60Write(EPMCSH, 0xf7);        //        //    // 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 to 60bytes and CRC operations    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, 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);    // Set the maximum packet size which the controller will accept        // Do not send packets longer than MAX_FRAMELEN:    enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);        enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);    // do bank 3 stuff        // write MAC address        // NOTE: MAC address in ENC28J60 is byte-backward        enc28j60Write(MAADR5, macaddr[0]);        enc28j60Write(MAADR4, macaddr[1]);        enc28j60Write(MAADR3, macaddr[2]);        enc28j60Write(MAADR2, macaddr[3]);        enc28j60Write(MAADR1, macaddr[4]);        enc28j60Write(MAADR0, macaddr[5]);    // no loopback of transmitted frames    enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);    // switch to bank 0    enc28j60SetBank(ECON1);    // enable interrutps    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);    // enable packet reception    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);}// read the revision of the chip:unsigned char enc28j60getrev(void){    return(enc28j60Read(EREVID));}void enc28j60PacketSend(unsigned int len, unsigned char* packet){    // Set the write pointer to start of transmit buffer area    enc28j60Write(EWRPTL, TXSTART_INIT&0xFF);    enc28j60Write(EWRPTH, TXSTART_INIT>>8);    // Set the TXND pointer to correspond to the packet size given    enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF);    enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);    // write per-packet control byte (0x00 means use macon3 settings)    enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);    // copy the packet into the transmit buffer    enc28j60WriteBuffer(len, packet);    // send the contents of the transmit buffer onto the network    enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);        // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.    if( (enc28j60Read(EIR) & EIR_TXERIF) ){                enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);        }}// Gets a packet from the network receive buffer, if one is available.// The packet will by headed by an ethernet header.//      maxlen  The maximum acceptable length of a retrieved packet.//      packet  Pointer where packet data should be stored.// Returns: Packet length in bytes if a packet was retrieved, zero otherwise.unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet){    unsigned int rxstat;    unsigned int len;    // check if a packet has been received and buffered    //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){        // The above does not work. See Rev. B4 Silicon Errata point 6.    if( enc28j60Read(EPKTCNT) ==0 ){        return(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 (see datasheet page 43)    len  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);    len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;        len-=4; //remove the CRC count    // read the receive status (see datasheet page 43)    rxstat  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);    rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;    // limit retrieve length        if (len>maxlen-1){                len=maxlen-1;        }        // check CRC and symbol errors (see datasheet page 44, table 7-3):        // The ERXFCON.CRCEN is set by default. Normally we should not        // need to check this.        if ((rxstat & 0x80)==0){                // invalid                len=0;        }else{                // copy the packet from the receive buffer                enc28j60ReadBuffer(len, packet);        }    // 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);    return(len);}

⌨️ 快捷键说明

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