اطلاعیه

Collapse
No announcement yet.

کتابخانه ENC28j60 برای کدویژن

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    کتابخانه ENC28j60 برای کدویژن

    با عرض سلام خدمت اساتید.
    برای انجام پروژه ام به کتابخانه 28j60نیاز دارم و. تو نت و این سایت هم هر چی گشتم همش واسه winavr. bascom یا picبود و لطفا دوستانی که کتابخانه واسه کدویژن دارن راهنمایی فرمایند. با تشکر
    ضمنا آیا کتابخانه 28j60 که واسه winavr نوشته شده رو میشه برای کدویژن استفاده کرد؟

    #2
    پاسخ : کتابخانه ENC28j60 برای کدویژن

    [code=c]
    #ifndef _ETHERNET_H_
    #define _ETHERNET_H_

    #include <delay.h>

    ////////////////////////////////////////////////////////////////////////////////
    // high level functions
    ////////////////////////////////////////////////////////////////////////////////
    void ethernet_init(unsigned char *dev_mac, unsigned char *dev_ip, unsigned int port_tcp, unsigned int port_udp);
    void ethernet_process();
    unsigned int ethernet_tcp(unsigned char* request, unsigned char* response);
    unsigned char ethernet_udp(unsigned char* data, unsigned char data_len);
    unsigned int concatstr(char *buf, unsigned int pos, const char *s);
    unsigned int concatstrf(char *buf, unsigned int pos, const flash char *s);

    ////////////////////////////////////////////////////////////////////////////////
    // integer type definition
    ////////////////////////////////////////////////////////////////////////////////
    typedef unsigned char uint8_t;
    typedef signed char int8_t;
    typedef unsigned short uint16_t;
    typedef signed short int16_t;
    typedef unsigned long uint32_t;
    typedef signed long int32_t;

    #pragma used+
    ////////////////////////////////////////////////////////////////////////////////
    // enc28j60 functions
    ////////////////////////////////////////////////////////////////////////////////
    uint8_t enc28j60ReadOp(uint8_t op, uint8_t address);
    void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data);
    void enc28j60ReadBuffer(uint16_t len, uint8_t* data);
    void enc28j60WriteBuffer(uint16_t len, uint8_t* data);
    void enc28j60SetBank(uint8_t address);
    uint8_t enc28j60Read(uint8_t address);
    void enc28j60Write(uint8_t address, uint8_t data);
    void enc28j60PhyWrite(uint8_t address, uint16_t data);
    void enc28j60clkout(uint8_t clk);
    void enc28j60Init(uint8_t* macaddr);
    void enc28j60PacketSend(uint16_t len, uint8_t* packet);
    uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet);
    uint8_t enc28j60getrev(void);
    uint8_t enc28j60linkup(void);

    ////////////////////////////////////////////////////////////////////////////////
    // eth/ip/arp/udp/tcp functions
    ////////////////////////////////////////////////////////////////////////////////
    uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len);
    uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len);
    void make_arp_answer_from_request(uint8_t *buf);
    void make_echo_reply_from_request(uint8_t *buf,uint16_t len);
    void make_udp_reply_from_request(uint8_t *buf, uint8_t datalen);
    void make_tcp_synack_from_syn(uint8_t *buf);
    uint16_t get_tcp_data_pointer(uint8_t *buf);
    void make_tcp_ack_from_any(uint8_t *buf);
    void make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen);

    ////////////////////////////////////////////////////////////////////////////////
    // needed macros
    ////////////////////////////////////////////////////////////////////////////////
    #define LOBYTE(a) ((a)&0x00FF)
    #define HIBYTE(a) ((a)>>8)

    ////////////////////////////////////////////////////////////////////////////////
    // eth/ip/arp/udp/tcp definitions
    ////////////////////////////////////////////////////////////////////////////////
    // ******* ETH *******
    #define ETH_HEADER_LEN 14
    // values of certain bytes:
    #define ETHTYPE_ARP_H_V 0x08
    #define ETHTYPE_ARP_L_V 0x06
    #define ETHTYPE_IP_H_V 0x08
    #define ETHTYPE_IP_L_V 0x00
    // byte positions in the ethernet frame:
    //
    // Ethernet type field (2bytes):
    #define ETH_TYPE_H_P 12
    #define ETH_TYPE_L_P 13
    //
    #define ETH_DST_MAC 0
    #define ETH_SRC_MAC 6


    // ******* ARP *******
    #define ETH_ARP_OPCODE_REPLY_H_V 0x0
    #define ETH_ARP_OPCODE_REPLY_L_V 0x02
    // arp.opcode
    #define ETH_ARP_OPCODE_H_P 0x14
    #define ETH_ARP_OPCODE_L_P 0x15
    // arp.src.mac
    #define ETH_ARP_SRC_MAC_P 0x16
    #define ETH_ARP_SRC_IP_P 0x1c
    #define ETH_ARP_DST_MAC_P 0x20
    #define ETH_ARP_DST_IP_P 0x26

    // ******* IP *******
    #define IP_HEADER_LEN 20
    // ip.src
    #define IP_SRC_P 0x1a
    #define IP_DST_P 0x1e
    #define IP_HEADER_LEN_VER_P 0xe
    #define IP_CHECKSUM_P 0x18
    #define IP_TTL_P 0x16
    #define IP_FLAGS_P 0x14
    #define IP_P 0xe
    #define IP_TOTLEN_H_P 0x10
    #define IP_TOTLEN_L_P 0x11

    #define IP_PROTO_P 0x17

    #define IP_PROTO_ICMP_V 1
    #define IP_PROTO_TCP_V 6
    // 17=0x11
    #define IP_PROTO_UDP_V 17
    // ******* ICMP *******
    #define ICMP_TYPE_ECHOREPLY_V 0
    #define ICMP_TYPE_ECHOREQUEST_V 8
    //
    #define ICMP_TYPE_P 0x22
    #define ICMP_CHECKSUM_P 0x24

    // ******* UDP *******
    #define UDP_HEADER_LEN 8
    //
    #define UDP_SRC_PORT_H_P 0x22
    #define UDP_SRC_PORT_L_P 0x23
    #define UDP_DST_PORT_H_P 0x24
    #define UDP_DST_PORT_L_P 0x25
    //
    #define UDP_LEN_H_P 0x26
    #define UDP_LEN_L_P 0x27
    #define UDP_CHECKSUM_H_P 0x28
    #define UDP_CHECKSUM_L_P 0x29
    #define UDP_DATA_P 0x2a

    // ******* TCP *******
    #define TCP_SRC_PORT_H_P 0x22
    #define TCP_SRC_PORT_L_P 0x23
    #define TCP_DST_PORT_H_P 0x24
    #define TCP_DST_PORT_L_P 0x25
    // the tcp seq number is 4 bytes 0x26-0x29
    #define TCP_SEQ_H_P 0x26
    #define TCP_SEQACK_H_P 0x2a
    // flags: SYN=2
    #define TCP_FLAGS_P 0x2f
    #define TCP_FLAGS_SYN_V 0x02
    #define TCP_FLAGS_FIN_V 0x01
    #define TCP_FLAGS_PUSH_V 0x08
    #define TCP_FLAGS_SYNACK_V 0x12
    #define TCP_FLAGS_ACK_V 0x10
    #define TCP_FLAGS_PSHACK_V 0x18
    // plain len without the options:
    #define TCP_HEADER_LEN_PLAIN 20
    #define TCP_HEADER_LEN_P 0x2e
    #define TCP_CHECKSUM_H_P 0x32
    #define TCP_CHECKSUM_L_P 0x33
    #define TCP_OPTIONS_P 0x36


    ////////////////////////////////////////////////////////////////////////////////
    // enc28j60 definitions
    ////////////////////////////////////////////////////////////////////////////////
    // ENC28J60 Control Registers
    // Control register definitions are a combination of address,
    // bank number, and Ethernet/MAC/PHY indicator bits.
    // - Register address (bits 0-4)
    // - Bank number (bits 5-6)
    // - MAC/PHY indicator (bit 7)
    #define ADDR_MASK 0x1F
    #define BANK_MASK 0x60
    #define SPRD_MASK 0x80
    // All-bank registers
    #define EIE 0x1B
    #define EIR 0x1C
    #define ESTAT 0x1D
    #define ECON2 0x1E
    #define ECON1 0x1F
    // Bank 0 registers
    #define ERDPTL (0x00|0x00)
    #define ERDPTH (0x01|0x00)
    #define EWRPTL (0x02|0x00)
    #define EWRPTH (0x03|0x00)
    #define ETXSTL (0x04|0x00)
    #define ETXSTH (0x05|0x00)
    #define ETXNDL (0x06|0x00)
    #define ETXNDH (0x07|0x00)
    #define ERXSTL (0x08|0x00)
    #define ERXSTH (0x09|0x00)
    #define ERXNDL (0x0A|0x00)
    #define ERXNDH (0x0B|0x00)
    #define ERXRDPTL (0x0C|0x00)
    #define ERXRDPTH (0x0D|0x00)
    #define ERXWRPTL (0x0E|0x00)
    #define ERXWRPTH (0x0F|0x00)
    #define EDMASTL (0x10|0x00)
    #define EDMASTH (0x11|0x00)
    #define EDMANDL (0x12|0x00)
    #define EDMANDH (0x13|0x00)
    #define EDMADSTL (0x14|0x00)
    #define EDMADSTH (0x15|0x00)
    #define EDMACSL (0x16|0x00)
    #define EDMACSH (0x17|0x00)
    // Bank 1 registers
    #define EHT0 (0x00|0x20)
    #define EHT1 (0x01|0x20)
    #define EHT2 (0x02|0x20)
    #define EHT3 (0x03|0x20)
    #define EHT4 (0x04|0x20)
    #define EHT5 (0x05|0x20)
    #define EHT6 (0x06|0x20)
    #define EHT7 (0x07|0x20)
    #define EPMM0 (0x08|0x20)
    #define EPMM1 (0x09|0x20)
    #define EPMM2 (0x0A|0x20)
    #define EPMM3 (0x0B|0x20)
    #define EPMM4 (0x0C|0x20)
    #define EPMM5 (0x0D|0x20)
    #define EPMM6 (0x0E|0x20)
    #define EPMM7 (0x0F|0x20)
    #define EPMCSL (0x10|0x20)
    #define EPMCSH (0x11|0x20)
    #define EPMOL (0x14|0x20)
    #define EPMOH (0x15|0x20)
    #define EWOLIE (0x16|0x20)
    #define EWOLIR (0x17|0x20)
    #define ERXFCON (0x18|0x20)
    #define EPKTCNT (0x19|0x20)
    // Bank 2 registers
    #define MACON1 (0x00|0x40|0x80)
    #define MACON2 (0x01|0x40|0x80)
    #define MACON3 (0x02|0x40|0x80)
    #define MACON4 (0x03|0x40|0x80)
    #define MABBIPG (0x04|0x40|0x80)
    #define MAIPGL (0x06|0x40|0x80)
    #define MAIPGH (0x07|0x40|0x80)
    #define MACLCON1 (0x08|0x40|0x80)
    #define MACLCON2 (0x09|0x40|0x80)
    #define MAMXFLL (0x0A|0x40|0x80)
    #define MAMXFLH (0x0B|0x40|0x80)
    #define MAPHSUP (0x0D|0x40|0x80)
    #define MICON (0x11|0x40|0x80)
    #define MICMD (0x12|0x40|0x80)
    #define MIREGADR (0x14|0x40|0x80)
    #define MIWRL (0x16|0x40|0x80)
    #define MIWRH (0x17|0x40|0x80)
    #define MIRDL (0x18|0x40|0x80)
    #define MIRDH (0x19|0x40|0x80)
    // Bank 3 registers
    #define MAADR1 (0x00|0x60|0x80)
    #define MAADR0 (0x01|0x60|0x80)
    #define MAADR3 (0x02|0x60|0x80)
    #define MAADR2 (0x03|0x60|0x80)
    #define MAADR5 (0x04|0x60|0x80)
    #define MAADR4 (0x05|0x60|0x80)
    #define EBSTSD (0x06|0x60)
    #define EBSTCON (0x07|0x60)
    #define EBSTCSL (0x08|0x60)
    #define EBSTCSH (0x09|0x60)
    #define MISTAT (0x0A|0x60|0x80)
    #define EREVID (0x12|0x60)
    #define ECOCON (0x15|0x60)
    #define EFLOCON (0x17|0x60)
    #define EPAUSL (0x18|0x60)
    #define EPAUSH (0x19|0x60)
    // PHY registers
    #define PHCON1 0x00
    #define PHSTAT1 0x01
    #define PHHID1 0x02
    #define PHHID2 0x03
    #define PHCON2 0x10
    #define PHSTAT2 0x11
    #define PHIE 0x12
    #define PHIR 0x13
    #define PHLCON 0x14

    // ENC28J60 ERXFCON Register Bit Definitions
    #define ERXFCON_UCEN 0x80
    #define ERXFCON_ANDOR 0x40
    #define ERXFCON_CRCEN 0x20
    #define ERXFCON_PMEN 0x10
    #define ERXFCON_MPEN 0x08
    #define ERXFCON_HTEN 0x04
    #define ERXFCON_MCEN 0x02
    #define ERXFCON_BCEN 0x01
    // ENC28J60 EIE Register Bit Definitions
    #define EIE_INTIE 0x80
    #define EIE_PKTIE 0x40
    #define EIE_DMAIE 0x20
    #define EIE_LINKIE 0x10
    #define EIE_TXIE 0x08
    #define EIE_WOLIE 0x04
    #define EIE_TXERIE 0x02
    #define EIE_RXERIE 0x01
    // ENC28J60 EIR Register Bit Definitions
    #define EIR_PKTIF 0x40
    #define EIR_DMAIF 0x20
    #define EIR_LINKIF 0x10
    #define EIR_TXIF 0x08
    #define EIR_WOLIF 0x04
    #define EIR_TXERIF 0x02
    #define EIR_RXERIF 0x01
    // ENC28J60 ESTAT Register Bit Definitions
    #define ESTAT_INT 0x80
    #define ESTAT_LATECOL 0x10
    #define ESTAT_RXBUSY 0x04
    #define ESTAT_TXABRT 0x02
    #define ESTAT_CLKRDY 0x01
    // ENC28J60 ECON2 Register Bit Definitions
    #define ECON2_AUTOINC 0x80
    #define ECON2_PKTDEC 0x40
    #define ECON2_PWRSV 0x20
    #define ECON2_VRPS 0x08
    // ENC28J60 ECON1 Register Bit Definitions
    #define ECON1_TXRST 0x80
    #define ECON1_RXRST 0x40
    #define ECON1_DMAST 0x20
    #define ECON1_CSUMEN 0x10
    #define ECON1_TXRTS 0x08
    #define ECON1_RXEN 0x04
    #define ECON1_BSEL1 0x02
    #define ECON1_BSEL0 0x01
    // ENC28J60 MACON1 Register Bit Definitions
    #define MACON1_LOOPBK 0x10
    #define MACON1_TXPAUS 0x08
    #define MACON1_RXPAUS 0x04
    #define MACON1_PASSALL 0x02
    #define MACON1_MARXEN 0x01
    // ENC28J60 MACON2 Register Bit Definitions
    #define MACON2_MARST 0x80
    #define MACON2_RNDRST 0x40
    #define MACON2_MARXRST 0x08
    #define MACON2_RFUNRST 0x04
    #define MACON2_MATXRST 0x02
    #define MACON2_TFUNRST 0x01
    // ENC28J60 MACON3 Register Bit Definitions
    #define MACON3_PADCFG2 0x80
    #define MACON3_PADCFG1 0x40
    #define MACON3_PADCFG0 0x20
    #define MACON3_TXCRCEN 0x10
    #define MACON3_PHDRLEN 0x08
    #define MACON3_HFRMLEN 0x04
    #define MACON3_FRMLNEN 0x02
    #define MACON3_FULDPX 0x01
    // ENC28J60 MICMD Register Bit Definitions
    #define MICMD_MIISCAN 0x02
    #define MICMD_MIIRD 0x01
    // ENC28J60 MISTAT Register Bit Definitions
    #define MISTAT_NVALID 0x04
    #define MISTAT_SCAN 0x02
    #define MISTAT_BUSY 0x01
    // ENC28J60 PHY PHCON1 Register Bit Definitions
    #define PHCON1_PRST 0x8000
    #define PHCON1_PLOOPBK 0x4000
    #define PHCON1_PPWRSV 0x0800
    #define PHCON1_PDPXMD 0x0100
    // ENC28J60 PHY PHSTAT1 Register Bit Definitions
    #define PHSTAT1_PFDPX 0x1000
    #define PHSTAT1_PHDPX 0x0800
    #define PHSTAT1_LLSTAT 0x0004
    #define PHSTAT1_JBSTAT 0x0002
    // ENC28J60 PHY PHCON2 Register Bit Definitions
    #define PHCON2_FRCLINK 0x4000
    #define PHCON2_TXDIS 0x2000
    #define PHCON2_JABBER 0x0400
    #define PHCON2_HDLDIS 0x0100

    // ENC28J60 Packet Control Byte Bit Definitions
    #define PKTCTRL_PHUGEEN 0x08
    #define PKTCTRL_PPADEN 0x04
    #define PKTCTRL_PCRCEN 0x02
    #define PKTCTRL_POVERRIDE 0x01

    // SPI operation codes
    #define ENC28J60_READ_CTRL_REG 0x00
    #define ENC28J60_READ_BUF_MEM 0x3A
    #define ENC28J60_WRITE_CTRL_REG 0x40
    #define ENC28J60_WRITE_BUF_MEM 0x7A
    #define ENC28J60_BIT_FIELD_SET 0x80
    #define ENC28J60_BIT_FIELD_CLR 0xA0
    #define ENC28J60_SOFT_RESET 0xFF

    // The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
    // buffer boundaries applied to internal 8K ram
    // the entire available packet buffer space is allocated
    // start with recbuf at 0/
    #define RXSTART_INIT 0x0
    // receive buffer end
    #define RXSTOP_INIT (0x1FFF-0x0600-1)
    // start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes)
    #define TXSTART_INIT (0x1FFF-0x0600)
    // stp TX buffer at end of mem
    #define TXSTOP_INIT 0x1FFF
    // max frame length which the conroller will accept:
    #define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518)


    ////////////////////////////////////////////////////////////////////////////////
    // enc28j60 functions implementation
    ////////////////////////////////////////////////////////////////////////////////
    static uint8_t Enc28j60Bank;
    static uint16_t NextPacketPtr;

    // set CS to 0 = active
    #define CSACTIVE ENC28J60_SPI_PORT&=~(1<<ENC28J60_SPI_CS)
    // set CS to 1 = passive
    #define CSPASSIVE ENC28J60_SPI_PORT|=(1<<ENC28J60_SPI_CS)
    //
    #define SPI2X 0
    #define SPE 6
    #define MSTR 4
    #define SPIF 7
    // wait for spi operation
    #define waitspi() while(!(SPSR&(1<<SPIF)))

    uint8_t enc28j60ReadOp(uint8_t op, uint8_t 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(uint8_t op, uint8_t address, uint8_t data)
    {
    CSACTIVE;
    // issue write command
    SPDR = op | (address & ADDR_MASK);
    waitspi();
    // write data
    SPDR = data;
    waitspi();
    CSPASSIVE;
    }

    void enc28j60ReadBuffer(uint16_t len, uint8_t* 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(uint16_t len, uint8_t* data)
    {
    CSACTIVE;
    // issue write command
    SPDR = ENC28J60_WRITE_BUF_MEM;
    waitspi();
    while(len)
    {
    len--;
    // write data
    SPDR = *data;
    data++;
    waitspi();
    }
    CSPASSIVE;
    }

    void enc28j60SetBank(uint8_t 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);
    }
    }

    uint8_t enc28j60Read(uint8_t address)
    {
    // set the bank
    enc28j60SetBank(address);
    // do the read
    return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
    }

    // read upper 8 bits
    uint16_t enc28j60PhyReadH(uint8_t address)
    {
    // Set the right address and start the register read operation
    enc28j60Write(MIREGADR, address);
    enc28j60Write(MICMD, MICMD_MIIRD);
    delay_us(15);

    // wait until the PHY read completes
    while(enc28j60Read(MISTAT) & MISTAT_BUSY);

    // reset reading bit
    enc28j60Write(MICMD, 0x00);

    return (enc28j60Read(MIRDH));
    }

    void enc28j60Write(uint8_t address, uint8_t data)
    {
    // set the bank
    enc28j60SetBank(address);
    // do the write
    enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
    }

    void enc28j60PhyWrite(uint8_t address, uint16_t 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){
    delay_us(15);
    }
    }

    void enc28j60clkout(uint8_t clk)
    {
    //0->0; 1->25M; 2->12.5M; 3->8.33M; 4->6.25M; 5->3.125M;
    enc28j60Write(ECOCON, clk & 0x7);
    }
    [/code]

    دیدگاه


      #3
      پاسخ : کتابخانه ENC28j60 برای کدویژن

      [code=c]

      void enc28j60Init(uint8_t* macaddr)
      {
      // initialize I/O
      // MOSI & SCK are output & low
      // CS is output & high
      // MISO is input
      ENC28J60_SPI_DDR &= ~(1<<ENC28J60_SPI_MISO);
      ENC28J60_SPI_DDR |= (1<<ENC28J60_SPI_MOSI) | (1<<ENC28J60_SPI_SCK) | (1<<ENC28J60_SPI_CS);
      ENC28J60_SPI_PORT &= ~((1<<ENC28J60_SPI_MOSI) | (1<<ENC28J60_SPI_SCK));
      ENC28J60_SPI_PORT |= (1<<ENC28J60_SPI_CS);
      // initialize SPI interface
      // master mode and Fosc/2 clock:
      SPCR = (1<<SPE)|(1<<MSTR);
      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);

      // LEDA=links status, LEDB=receive/transmit
      enc28j60PhyWrite(PHLCON,0x0476);
      delay_ms(20);
      }

      // read the revision of the chip:
      uint8_t enc28j60getrev(void)
      {
      return(enc28j60Read(EREVID));
      }

      // link status
      uint8_t enc28j60linkup(void)
      {
      // bit 10 (= bit 3 in upper reg)
      return(enc28j60PhyReadH(PHSTAT2) && 4);
      }

      void enc28j60PacketSend(uint16_t len, uint8_t* 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.
      uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet)
      {
      uint16_t rxstat;
      uint16_t 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 |= ((uint16_t)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);
      }

      ////////////////////////////////////////////////////////////////////////////////
      // eth/ip/arp/udp/tcp functions implementation
      ////////////////////////////////////////////////////////////////////////////////

      unsigned char eth_buf[BUFFER_SIZE+1];
      static uint16_t wwwport=80;
      static uint16_t udpport=1200;
      static uint8_t macaddr[6];
      static uint8_t ipaddr[4];
      static int16_t info_hdr_len=0;
      static int16_t info_data_len=0;
      static uint8_t seqnum=0xa; // my initial tcp sequence number

      // The Ip checksum is calculated over the ip header only starting
      // with the header length field and a total length of 20 bytes
      // unitl ip.dst
      // You must set the IP checksum field to zero before you start
      // the calculation.
      // len for ip is 20.
      //
      // For UDP/TCP we do not make up the required pseudo header. Instead we
      // use the ip.src and ip.dst fields of the real packet:
      // The udp checksum calculation starts with the ip.src field
      // Ip.src=4bytes,Ip.dst=4 bytes,Udp header=8bytes + data length=16+len
      // In other words the len here is 8 + length over which you actually
      // want to calculate the checksum.
      // You must set the checksum field to zero before you start
      // the calculation.
      // len for udp is: 8 + 8 + data length
      // len for tcp is: 4+4 + 20 + option len + data length
      //
      // For more information on how this algorithm works see:
      // http://www.netfor2.com/checksum.html
      // http://www.msc.uky.edu/ken/cs471/notes/chap3.htm
      // The RFC has also a C code example: http://www.faqs.org/rfcs/rfc1071.html
      uint16_t checksum(uint8_t *buf, uint16_t len,uint8_t type){
      // type 0=ip
      // 1=udp
      // 2=tcp
      uint32_t sum = 0;

      //if(type==0){
      // // do not add anything
      //}
      if(type==1){
      sum+=IP_PROTO_UDP_V; // protocol udp
      // the length here is the length of udp (data+header len)
      // =length given to this function - (IP.scr+IP.dst length)
      sum+=len-8; // = real tcp len
      }
      if(type==2){
      sum+=IP_PROTO_TCP_V;
      // the length here is the length of tcp (data+header len)
      // =length given to this function - (IP.scr+IP.dst length)
      sum+=len-8; // = real tcp len
      }
      // build the sum of 16bit words
      while(len >1){
      sum += 0xFFFF & (((uint32_t)*buf<<8)|*(buf+1));
      buf+=2;
      len-=2;
      }
      // if there is a byte left then add it (padded with zero)
      if (len){
      sum += ((uint32_t)(0xFF & *buf))<<8;
      }
      // now calculate the sum over the bytes in the sum
      // until the result is only 16bit long
      while (sum>>16){
      sum = (sum & 0xFFFF)+(sum >> 16);
      }
      // build 1's complement:
      return( (uint16_t) sum ^ 0xFFFF);
      }

      uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len){
      uint8_t i=0;
      //
      if (len<41){
      return(0);
      }
      if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V ||
      buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V){
      return(0);
      }
      while(i<4){
      if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i]){
      return(0);
      }
      i++;
      }
      return(1);
      }

      uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len){
      uint8_t i=0;
      //eth+ip+udp header is 42
      if (len<42){
      return(0);
      }
      if(buf[ETH_TYPE_H_P]!=ETHTYPE_IP_H_V ||
      buf[ETH_TYPE_L_P]!=ETHTYPE_IP_L_V){
      return(0);
      }
      if (buf[IP_HEADER_LEN_VER_P]!=0x45){
      // must be IP V4 and 20 byte header
      return(0);
      }
      while(i<4){
      if(buf[IP_DST_P+i]!=ipaddr[i]){
      return(0);
      }
      i++;
      }
      return(1);
      }
      // make a return eth header from a received eth packet
      void make_eth(uint8_t *buf)
      {
      uint8_t i=0;
      //
      //copy the destination mac from the source and fill my mac into src
      while(i<6){
      buf[ETH_DST_MAC +i]=buf[ETH_SRC_MAC +i];
      buf[ETH_SRC_MAC +i]=macaddr[i];
      i++;
      }
      }
      void fill_ip_hdr_checksum(uint8_t *buf)
      {
      uint16_t ck;
      // clear the 2 byte checksum
      buf[IP_CHECKSUM_P]=0;
      buf[IP_CHECKSUM_P+1]=0;
      buf[IP_FLAGS_P]=0x40; // don't fragment
      buf[IP_FLAGS_P+1]=0; // fragement offset
      buf[IP_TTL_P]=64; // ttl
      // calculate the checksum:
      ck=checksum(&buf[IP_P], IP_HEADER_LEN,0);
      buf[IP_CHECKSUM_P]=ck>>8;
      buf[IP_CHECKSUM_P+1]=ck& 0xff;
      }

      // make a return ip header from a received ip packet
      void make_ip(uint8_t *buf)
      {
      uint8_t i=0;
      while(i<4){
      buf[IP_DST_P+i]=buf[IP_SRC_P+i];
      buf[IP_SRC_P+i]=ipaddr[i];
      i++;
      }
      fill_ip_hdr_checksum(buf);
      }

      // make a return tcp header from a received tcp packet
      // rel_ack_num is how much we must step the seq number received from the
      // other side. We do not send more than 255 bytes of text (=data) in the tcp packet.
      // If mss=1 then mss is included in the options list
      //
      // After calling this function you can fill in the first data byte at TCP_OPTIONS_P+4
      // If cp_seq=0 then an initial sequence number is used (should be use in synack)
      // otherwise it is copied from the packet we received
      void make_tcphead(uint8_t *buf,uint16_t rel_ack_num,uint8_t mss,uint8_t cp_seq)
      {
      uint8_t i=0;
      uint8_t tseq;

      buf[TCP_DST_PORT_H_P] = buf[TCP_SRC_PORT_H_P];
      buf[TCP_DST_PORT_L_P] = buf[TCP_SRC_PORT_L_P];
      // set source port (http):
      buf[TCP_SRC_PORT_L_P] = LOBYTE(wwwport);
      buf[TCP_SRC_PORT_H_P] = HIBYTE(wwwport);
      i=4;
      // sequence numbers:
      // add the rel ack num to SEQACK
      while(i>0){
      rel_ack_num=buf[TCP_SEQ_H_P+i-1]+rel_ack_num;
      tseq=buf[TCP_SEQACK_H_P+i-1];
      buf[TCP_SEQACK_H_P+i-1]=0xff&rel_ack_num;
      if (cp_seq){
      // copy the acknum sent to us into the sequence number
      buf[TCP_SEQ_H_P+i-1]=tseq;
      }else{
      buf[TCP_SEQ_H_P+i-1]= 0; // some preset vallue
      }
      rel_ack_num=rel_ack_num>>8;
      i--;
      }
      if (cp_seq==0){
      // put inital seq number
      buf[TCP_SEQ_H_P+0]= 0;
      buf[TCP_SEQ_H_P+1]= 0;
      // we step only the second byte, this allows us to send packts
      // with 255 bytes or 512 (if we step the initial seqnum by 2)
      buf[TCP_SEQ_H_P+2]= seqnum;
      buf[TCP_SEQ_H_P+3]= 0;
      // step the inititial seq num by something we will not use
      // during this tcp session:
      seqnum+=2;
      }
      // zero the checksum
      buf[TCP_CHECKSUM_H_P]=0;
      buf[TCP_CHECKSUM_L_P]=0;

      // The tcp header length is only a 4 bit field (the upper 4 bits).
      // It is calculated in units of 4 bytes.
      // E.g 24 bytes: 24/4=6 => 0x60=header len field
      //buf[TCP_HEADER_LEN_P]=(((TCP_HEADER_LEN_PLAIN+4)/4)) <<4; // 0x60
      if (mss){
      // the only option we set is MSS to 1408:
      // 1408 in hex is 0x580
      buf[TCP_OPTIONS_P]=2;
      buf[TCP_OPTIONS_P+1]=4;
      buf[TCP_OPTIONS_P+2]=0x05;
      buf[TCP_OPTIONS_P+3]=0x80;
      // 24 bytes:
      buf[TCP_HEADER_LEN_P]=0x60;
      }else{
      // no options:
      // 20 bytes:
      buf[TCP_HEADER_LEN_P]=0x50;
      }
      }

      void make_arp_answer_from_request(uint8_t *buf)
      {
      uint8_t i=0;
      //
      make_eth(buf);
      buf[ETH_ARP_OPCODE_H_P]=ETH_ARP_OPCODE_REPLY_H_V;
      buf[ETH_ARP_OPCODE_L_P]=ETH_ARP_OPCODE_REPLY_L_V;
      // fill the mac addresses:
      while(i<6){
      buf[ETH_ARP_DST_MAC_P+i]=buf[ETH_ARP_SRC_MAC_P+i];
      buf[ETH_ARP_SRC_MAC_P+i]=macaddr[i];
      i++;
      }
      i=0;
      while(i<4){
      buf[ETH_ARP_DST_IP_P+i]=buf[ETH_ARP_SRC_IP_P+i];
      buf[ETH_ARP_SRC_IP_P+i]=ipaddr[i];
      i++;
      }
      // eth+arp is 42 bytes:
      enc28j60PacketSend(42,buf);
      }

      void make_echo_reply_from_request(uint8_t *buf,uint16_t len)
      {
      make_eth(buf);
      make_ip(buf);
      buf[ICMP_TYPE_P]=ICMP_TYPE_ECHOREPLY_V;
      // we changed only the icmp.type field from request(=8) to reply(=0).
      // we can therefore easily correct the checksum:
      if (buf[ICMP_CHECKSUM_P] > (0xff-0x08)){
      buf[ICMP_CHECKSUM_P+1]++;
      }
      buf[ICMP_CHECKSUM_P]+=0x08;
      //
      enc28j60PacketSend(len,buf);
      }

      // you can send a max of 220 bytes of data
      void make_udp_reply_from_request(uint8_t *buf, uint8_t datalen)
      {
      uint8_t i=0;
      uint16_t ck;
      make_eth(buf);
      if (datalen>220){
      datalen=220;
      }
      // total length field in the IP header must be set:
      buf[IP_TOTLEN_H_P]=0;
      buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+UDP_HEADER_LEN+datalen;
      make_ip(buf);
      // send to port:
      //buf[UDP_DST_PORT_H_P]=port>>8;
      //buf[UDP_DST_PORT_L_P]=port & 0xff;
      // sent to port of sender and use "port" as own source:
      buf[UDP_DST_PORT_H_P]=buf[UDP_SRC_PORT_H_P];
      buf[UDP_DST_PORT_L_P]= buf[UDP_SRC_PORT_L_P];
      buf[UDP_SRC_PORT_H_P]=HIBYTE(udpport);
      buf[UDP_SRC_PORT_L_P]=LOBYTE(udpport);
      // calculte the udp length:
      buf[UDP_LEN_H_P]=0;
      buf[UDP_LEN_L_P]=UDP_HEADER_LEN+datalen;
      // zero the checksum
      buf[UDP_CHECKSUM_H_P]=0;
      buf[UDP_CHECKSUM_L_P]=0;
      /*
      // copy the data:
      while(i<datalen){
      buf[UDP_DATA_P+i]=data[i];
      i++;
      }
      */
      ck=checksum(&buf[IP_SRC_P], 16 + datalen,1);
      buf[UDP_CHECKSUM_H_P]=ck>>8;
      buf[UDP_CHECKSUM_L_P]=ck& 0xff;
      enc28j60PacketSend(UDP_HEADER_LEN+IP_HEADER_LEN+ET H_HEADER_LEN+datalen,buf);
      }

      void make_tcp_synack_from_syn(uint8_t *buf)
      {
      uint16_t ck;
      make_eth(buf);
      // total length field in the IP header must be set:
      // 20 bytes IP + 24 bytes (20tcp+4tcp options)
      buf[IP_TOTLEN_H_P]=0;
      buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4;
      make_ip(buf);
      buf[TCP_FLAGS_P]=TCP_FLAGS_SYNACK_V;
      make_tcphead(buf,1,1,0);
      // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + 4 (one option: mss)
      ck=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+4,2);
      buf[TCP_CHECKSUM_H_P]=ck>>8;
      buf[TCP_CHECKSUM_L_P]=ck& 0xff;
      // add 4 for option mss:
      enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PL AIN+4+ETH_HEADER_LEN,buf);
      }

      // get a pointer to the start of tcp data in buf
      // Returns 0 if there is no data
      uint16_t get_tcp_data_pointer(uint8_t *buf)
      {
      info_data_len=(((int16_t)buf[IP_TOTLEN_H_P])<<8)|(buf[IP_TOTLEN_L_P]&0xff);
      info_data_len-=IP_HEADER_LEN;
      info_hdr_len=(buf[TCP_HEADER_LEN_P]>>4)*4; // generate len in bytes;
      info_data_len-=info_hdr_len;
      if (info_data_len<=0){
      info_data_len=0;
      return(0);
      }
      return((uint16_t)TCP_SRC_PORT_H_P+info_hdr_len);
      }

      // concatenate string to buffer at pos and return final position
      uint16_t concatstrf(uint8_t *buf, uint16_t pos, const flash char *s)
      {
      char c;
      while ((c = *s++)!=0)
      {
      buf[pos]=c;
      pos++;
      }
      return(pos);
      }

      [/code]

      دیدگاه


        #4
        پاسخ : کتابخانه ENC28j60 برای کدویژن

        [code=c]

        // concatenate string to buffer at pos and return final position
        uint16_t concatstr(uint8_t *buf, uint16_t pos, const char *s)
        {
        char c;
        while ((c = *s++)!=0)
        {
        buf[pos]=c;
        pos++;
        }
        return(pos);
        }

        // Make just an ack packet with no tcp data inside
        // This will modify the eth/ip/tcp header
        void make_tcp_ack_from_any(uint8_t *buf)
        {
        uint16_t j;
        make_eth(buf);
        // fill the header:
        buf[TCP_FLAGS_P]=TCP_FLAGS_ACK_V;
        if (info_data_len==0){
        // if there is no data then we must still acknoledge one packet
        make_tcphead(buf,1,0,1); // no options
        }else{
        make_tcphead(buf,info_data_len,0,1); // no options
        }

        // total length field in the IP header must be set:
        // 20 bytes IP + 20 bytes tcp (when no options)
        j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN;
        buf[IP_TOTLEN_H_P]=j>>8;
        buf[IP_TOTLEN_L_P]=j& 0xff;
        make_ip(buf);
        // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len
        j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN,2);
        buf[TCP_CHECKSUM_H_P]=j>>8;
        buf[TCP_CHECKSUM_L_P]=j& 0xff;
        enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PL AIN+ETH_HEADER_LEN,buf);
        }

        // you must have called get_tcp_data_pointer at some time before calling this function
        // dlen is the amount of tcp data (http data) we send in this packet
        // You can use this function only immediately after make_tcp_ack_from_any
        // This is because this function will NOT modify the eth/ip/tcp header except for
        // length and checksum
        void make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen)
        {
        uint16_t j;
        // fill the header:
        // This code requires that we send only one data packet
        // because we keep no state information. We must therefore set
        // the fin here:
        buf[TCP_FLAGS_P]=TCP_FLAGS_ACK_V|TCP_FLAGS_PUSH_V|TCP_FLAGS_FIN_V;

        // total length field in the IP header must be set:
        // 20 bytes IP + 20 bytes tcp (when no options) + len of data
        j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen;
        buf[IP_TOTLEN_H_P]=j>>8;
        buf[IP_TOTLEN_L_P]=j& 0xff;
        fill_ip_hdr_checksum(buf);
        // zero the checksum
        buf[TCP_CHECKSUM_H_P]=0;
        buf[TCP_CHECKSUM_L_P]=0;
        // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len
        j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+dlen,2);
        buf[TCP_CHECKSUM_H_P]=j>>8;
        buf[TCP_CHECKSUM_L_P]=j& 0xff;
        enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PL AIN+dlen+ETH_HEADER_LEN,buf);
        }


        // you must call this function once before you use any of the other functions:
        void ethernet_init(unsigned char *dev_mac, unsigned char *dev_ip, unsigned int port_tcp, unsigned int port_udp)
        {
        uint8_t i=0;
        wwwport=port_tcp;
        udpport=port_udp;
        while(i<4){
        ipaddr[i]=dev_ip[i];
        i++;
        }
        i=0;
        while(i<6){
        macaddr[i]=dev_mac[i];
        i++;
        }
        // initialize enc28j60
        enc28j60Init(dev_mac);
        }

        void ethernet_process()
        {
        uint16_t plen;
        uint16_t data_p;
        uint8_t data_len;

        plen = enc28j60PacketReceive(BUFFER_SIZE, eth_buf);
        if(plen!=0)
        {
        // arp is broadcast if unknown but a host may also verify
        // the mac address by sending it to a unicast address.
        if(eth_type_is_arp_and_my_ip(eth_buf,plen))
        {
        make_arp_answer_from_request(eth_buf);
        }
        // check if ip packets are for us:
        else if(eth_type_is_ip_and_my_ip(eth_buf,plen))
        {
        if( eth_buf[IP_PROTO_P]==IP_PROTO_ICMP_V
        && eth_buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V )
        {
        // a ping packet, let's send pong
        make_echo_reply_from_request(eth_buf,plen);
        }
        // we listen to tcp port
        else if (eth_buf[IP_PROTO_P]==IP_PROTO_TCP_V
        &&eth_buf[TCP_DST_PORT_H_P]==HIBYTE(wwwport)
        &&eth_buf[TCP_DST_PORT_L_P]==LOBYTE(wwwport) )
        {
        if (eth_buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
        // make_tcp_synack_from_syn does already send the syn,ack
        make_tcp_synack_from_syn(eth_buf);
        else if (eth_buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
        {
        // we can possibly have no data, just ack:
        data_p=get_tcp_data_pointer(eth_buf);
        if (data_p==0)
        {
        // just an ack with no data, wait for next packet
        if (eth_buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
        {
        // finack, answer with ack
        make_tcp_ack_from_any(eth_buf);
        }
        }
        else
        {
        plen = ethernet_tcp( eth_buf+data_p, eth_buf+TCP_CHECKSUM_L_P+3 );
        make_tcp_ack_from_any(eth_buf); // send ack for http get
        make_tcp_ack_with_data(eth_buf, plen); // send data
        }
        }
        }
        // we listen to udp port
        else if (eth_buf[IP_PROTO_P]==IP_PROTO_UDP_V
        &&eth_buf[UDP_DST_PORT_H_P]==HIBYTE(udpport)
        &&eth_buf[UDP_DST_PORT_L_P]==LOBYTE(udpport) )
        {
        data_len = eth_buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
        data_len = ethernet_udp( eth_buf+UDP_DATA_P, data_len);
        make_udp_reply_from_request(eth_buf, data_len);
        }
        }
        }
        }

        #pragma used-

        #endif

        [/code]

        دیدگاه


          #5
          پاسخ : کتابخانه ENC28j60 برای کدویژن

          اون 3 تارو کپی کن توی یک فایل به نام ethernet.h
          این هم برنامه اصلیش

          [code=c]
          //--------------------------------------------------------------------------
          // Project : Transferring Data via Ethernet
          // Chip type : ATmega32
          // Program type : Application
          // Clock frequency : 6.250000 MHz
          // Memory model : Small
          // Data Stack size : 512
          //--------------------------------------------------------------------------
          #include <mega32.h>
          #include <stdio.h>
          #include <string.h>
          #include <delay.h>
          //--------------------------------------
          #asm // LCD Module
          .equ __lcd_port=0x15 ;PORTC
          #endasm
          #include <lcd.h>
          //--------------------------------------
          #define ENC28J60_SPI_PORT PORTB
          #define ENC28J60_SPI_DDR DDRB
          #define ENC28J60_SPI_MISO 6
          #define ENC28J60_SPI_MOSI 5
          #define ENC28J60_SPI_SCK 7
          #define ENC28J60_SPI_CS 4
          // ethernet buffer size
          #define BUFFER_SIZE 1024
          #include "ethernet.h"
          //--------------------------------------
          #define LCD_BL_ON PORTC.3 = 1
          #define LCD_BL_OFF PORTC.3 = 0
          #define DIPSWITCH (PIND>>4)
          #define PUSHBUTTON1 (!PINA.0)
          #define PUSHBUTTON2 (!PINA.1)
          //--------------------------------------
          unsigned char mymac[6] = {0x11,0x22,0x33,0x44,0x55,0x66}; // MAC
          unsigned char myip[4] = {192,168,1,10}; // IP
          unsigned char time_cs = 0; // 1/100 second counter
          unsigned int time_s = 0; // seconds counter
          unsigned int counter1 = 0; // button 1 clicks
          unsigned int counter2 = 0; // button 2 clicks
          //--------------------------------------
          interrupt [TIM1_OVF] void timer1_ovf_isr(void) // Timer 1 overflow ISR
          {
          static bit old_btn1 = 0, old_btn2 = 0;
          if (++time_cs==100) // one second elapsed
          {
          time_cs = 0;
          time_s ++;
          }
          if (PUSHBUTTON1)
          {
          if (!old_btn1)
          counter1 ++;
          old_btn1 = 1;
          }
          else
          old_btn1 = 0;
          if (PUSHBUTTON2)
          {
          if (!old_btn2)
          counter2 ++;
          old_btn2 = 1;
          }
          else
          old_btn2 = 0;
          }
          //--------------------------------------
          void main(void)
          {
          uint8_t str[20]=""; // buffer to
          // Watchdog Timer Enabled with Prescaler: OSC/512k
          WDTCR=0x0D;
          // All I/O pins are pulled up
          PORTA=0xFF;
          DDRA=0x00;
          PORTB=0xFF;
          DDRB=0x00;
          PORTC=0x00;
          DDRC=0x04;
          PORTD=0xFF;
          DDRD=0x00;
          // Timer 1 interrupts every 10 ms
          TCCR1A=0x02;
          TCCR1B=0x19;
          ICR1H=0xF4;
          ICR1L=0x23;
          // Timer(s) Interrupt(s) initialization
          TIMSK=0x04;
          // Analog Comparator: Off
          ACSR=0x80;
          // LCD module initialization
          lcd_init(16);
          LCD_BL_ON;
          #asm("wdr"
          // setting MAC & IP using dip-switch state
          mymac[0] += DIPSWITCH;
          myip[3] += DIPSWITCH;
          // initialize ethernet
          ethernet_init(mymac, myip, 80, 1200);
          // start up display
          lcd_gotoxy(0,0);
          lcd_putsf(" MAC "
          lcd_gotoxy(0,1);
          sprintf(str, " %02x%02x-%02x%02x-%02x%02x ",
          mymac[0], mymac[1], mymac[2], mymac[3], mymac[4], mymac[5]);
          lcd_puts(str);
          delay_ms(2000);
          lcd_gotoxy(0,0);
          lcd_putsf(" IP "
          lcd_gotoxy(0,1);
          sprintf(str, "%03u.%03u.%03u.%03u",
          myip[0], myip[1], myip[2], myip[3]);
          lcd_puts(str);
          delay_ms(3000);
          lcd_clear();
          // Global enable interrupts
          #asm("sei&quot
          while (1)
          {
          #asm("wdr"
          sprintf(str, "T=%u,P=%u,%u ", time_s, counter1, counter2 );
          lcd_gotoxy(0,0);
          lcd_puts(str);
          // process ethernet transactions
          ethernet_process();
          }
          }
          //--------------------------------------
          unsigned char ethernet_udp(unsigned char* data, unsigned char data_len)
          {
          unsigned char str[20];
          lcd_gotoxy(0,1);
          lcd_putsf("UDP: "
          strncpy(str, data, 11);
          lcd_gotoxy(4,1);
          lcd_puts(str);
          // response the request
          sprintf(str, "T=%u,P=%u,%u\n", time_s, counter1, counter2 );
          data_len = concatstr(data, 0, str);
          time_cs = 0;
          time_s = 0;
          return data_len;
          }
          //--------------------------------------
          unsigned int ethernet_tcp(unsigned char* request, unsigned char* response)
          {
          unsigned int len;
          unsigned char str[20];
          if (strncmpf(request, "GET /", 5)!=0)
          return 0;
          lcd_gotoxy(0,1);
          lcd_putsf("TCP: "
          strncpy(str, request+5, 11);
          lcd_gotoxy(4,1);
          lcd_puts(str);
          // response the request
          len = concatstrf(response, 0, "HTTP/1.0 200 OK\r\n"
          len = concatstrf(response, len, "Content-Type: text/html\r\n"
          len = concatstrf(response, len, "Pragma: no-cache\r\n\r\n"
          len = concatstrf(response, len,
          "<HTML><TITLE>11 AVR Projects</TITLE><BODY><CENTER>"
          len = concatstrf(response, len,
          "<P>Transferring Data via Ethernet</P>\n<HR>"
          len = concatstrf(response, len,
          "<P>Time = <FONT COLOR=#00FF00> "
          sprintf(str, "%u", time_s);
          len = concatstr(response, len, str);
          len = concatstrf(response, len, "</FONT></P>\n"
          len = concatstrf(response, len,
          "<P>Counter_1 = <FONT COLOR=#0000FF> "
          sprintf(str, "%u", counter1);
          len = concatstr(response, len, str);
          len = concatstrf(response, len, "</FONT></P>\n"
          len = concatstrf(response, len,
          "<P>Counter_2 = <FONT COLOR=#FF0000> "
          sprintf(str, "%u", counter2);
          len = concatstr(response, len, str);
          len = concatstrf(response, len, "</FONT></P>\n"
          len = concatstrf(response, len,
          "<P><A HREF=\".\">refresh</A><P></CENTER><HR>\n"
          time_cs = 0;
          time_s = 0;
          return len;
          }

          [/code]

          دیدگاه


            #6
            پاسخ : کتابخانه ENC28j60 برای کدویژن

            نوشته اصلی توسط sepehr63 نمایش پست ها
            اون 3 تارو کپی کن توی یک فایل به نام ethernet.h
            این هم برنامه اصلیش

            کد:
            //--------------------------------------------------------------------------
            // Project       : Transferring Data via Ethernet
            // Chip type      : ATmega32
            // Program type     : Application
            // Clock frequency   : 6.250000 MHz
            // Memory model     : Small
            // Data Stack size   : 512
            //--------------------------------------------------------------------------
            #include <mega32.h>
            #include <stdio.h>
            #include <string.h>
            #include <delay.h>
            //--------------------------------------
            #asm              // LCD Module
              .equ __lcd_port=0x15     ;PORTC
            #endasm
            #include <lcd.h>
            //--------------------------------------
            #define ENC28J60_SPI_PORT    PORTB
            #define ENC28J60_SPI_DDR    DDRB
            #define ENC28J60_SPI_MISO    6
            #define ENC28J60_SPI_MOSI    5
            #define ENC28J60_SPI_SCK    7
            #define ENC28J60_SPI_CS     4
            // ethernet buffer size
            #define BUFFER_SIZE       1024
            #include "ethernet.h"
            //--------------------------------------
            #define LCD_BL_ON        PORTC.3 = 1
            #define LCD_BL_OFF       PORTC.3 = 0
            #define DIPSWITCH        (PIND>>4)
            #define PUSHBUTTON1       (!PINA.0)
            #define PUSHBUTTON2       (!PINA.1)
            //--------------------------------------
            unsigned char  mymac[6] = {0x11,0x22,0x33,0x44,0x55,0x66};   // MAC
            unsigned char  myip[4] = {192,168,1,10};            // IP
            unsigned char  time_cs = 0;      // 1/100 second counter
            unsigned int  time_s = 0;       // seconds counter
            unsigned int  counter1 = 0;      // button 1 clicks
            unsigned int  counter2 = 0;      // button 2 clicks
            //--------------------------------------
            interrupt [TIM1_OVF] void timer1_ovf_isr(void) // Timer 1 overflow ISR
            {
                static bit old_btn1 = 0, old_btn2 = 0;
                if (++time_cs==100)       // one second elapsed
                {
                    time_cs = 0;
                    time_s ++;
                }
                if (PUSHBUTTON1)
                {
                    if (!old_btn1)
                        counter1 ++;
                    old_btn1 = 1;
                }
                else
                    old_btn1 = 0;
                if (PUSHBUTTON2)
                {
                    if (!old_btn2)
                        counter2 ++;
                    old_btn2 = 1;
                }
                else
                    old_btn2 = 0;
            }
            //--------------------------------------
            void main(void)
            {
                uint8_t str[20]="";   // buffer to
                // Watchdog Timer Enabled with Prescaler: OSC/512k
                WDTCR=0x0D;
                // All I/O pins are pulled up
                PORTA=0xFF;
                DDRA=0x00;
                PORTB=0xFF;
                DDRB=0x00;
                PORTC=0x00;
                DDRC=0x04;
                PORTD=0xFF;
                DDRD=0x00;
                // Timer 1 interrupts every 10 ms
                TCCR1A=0x02;
                TCCR1B=0x19;
                ICR1H=0xF4;
                ICR1L=0x23;
                // Timer(s) Interrupt(s) initialization
                TIMSK=0x04;
                // Analog Comparator: Off
                ACSR=0x80;
                // LCD module initialization
                lcd_init(16);
                LCD_BL_ON;
                #asm("wdr");
                // setting MAC & IP using dip-switch state
                mymac[0] += DIPSWITCH;
                myip[3] += DIPSWITCH;
                // initialize ethernet
                ethernet_init(mymac, myip, 80, 1200);
                // start up display
                lcd_gotoxy(0,0);
                lcd_putsf("   MAC    ");
                lcd_gotoxy(0,1);
                sprintf(str, " %02x%02x-%02x%02x-%02x%02x ",
                    mymac[0], mymac[1], mymac[2], mymac[3], mymac[4], mymac[5]);
                lcd_puts(str);
                delay_ms(2000);
                lcd_gotoxy(0,0);
                lcd_putsf("    IP    ");
                lcd_gotoxy(0,1);
                sprintf(str, "%03u.%03u.%03u.%03u",
                    myip[0], myip[1], myip[2], myip[3]);
                lcd_puts(str);
                delay_ms(3000);
                lcd_clear();
                // Global enable interrupts
                #asm("sei")
                while (1)
                {
                    #asm("wdr");
                    sprintf(str, "T=%u,P=%u,%u ", time_s, counter1, counter2 );
                    lcd_gotoxy(0,0);
                    lcd_puts(str);
                    // process ethernet transactions
                    ethernet_process();
                }
            }
            //--------------------------------------
            unsigned char ethernet_udp(unsigned char* data, unsigned char data_len)
            {
                unsigned char str[20];
                lcd_gotoxy(0,1);
                lcd_putsf("UDP:      ");
                strncpy(str, data, 11);
                lcd_gotoxy(4,1);
                lcd_puts(str);
                // response the request
                sprintf(str, "T=%u,P=%u,%u\n", time_s, counter1, counter2 );
                data_len = concatstr(data, 0, str);
                time_cs = 0;
                time_s = 0;
                return data_len;
            }
            //--------------------------------------
            unsigned int ethernet_tcp(unsigned char* request, unsigned char* response)
            {
                unsigned int len;
                unsigned char str[20];
                if (strncmpf(request, "GET /", 5)!=0)
                    return 0;
                lcd_gotoxy(0,1);
                lcd_putsf("TCP:      ");
                strncpy(str, request+5, 11);
                lcd_gotoxy(4,1);
                lcd_puts(str);
                // response the request
                len = concatstrf(response, 0, "HTTP/1.0 200 OK\r\n");
                len = concatstrf(response, len, "Content-Type: text/html\r\n");
                len = concatstrf(response, len, "Pragma: no-cache\r\n\r\n");
                len = concatstrf(response, len,
                    "<HTML><TITLE>11 AVR Projects</TITLE><BODY><CENTER>");
                len = concatstrf(response, len,
                    "<P>Transferring Data via Ethernet</P>\n<HR>");
                len = concatstrf(response, len,
                    "<P>Time = <FONT COLOR=#00FF00> ");
                sprintf(str, "%u", time_s);
                len = concatstr(response, len, str);
                len = concatstrf(response, len, "</FONT></P>\n");
                len = concatstrf(response, len,
                    "<P>Counter_1 = <FONT COLOR=#0000FF> ");
                sprintf(str, "%u", counter1);
                len = concatstr(response, len, str);
                len = concatstrf(response, len, "</FONT></P>\n");
                len = concatstrf(response, len,
                    "<P>Counter_2 = <FONT COLOR=#FF0000> ");
                sprintf(str, "%u", counter2);
                len = concatstr(response, len, str);
                len = concatstrf(response, len, "</FONT></P>\n");
                len = concatstrf(response, len,
                    "<P><A HREF=\".\">refresh</A><P></CENTER><HR>\n");
                time_cs = 0;
                time_s = 0;
                return len;
            }
            بعضی از کاراکتر ها خراب شده.
            جدیدترین ویرایش توسط mh.amiri; ۱۸:۵۵ ۱۳۹۵/۰۶/۱۵.

            دیدگاه


              #7
              پاسخ : کتابخانه ENC28j60 برای کدویژن

              خیلی ممنون. میتونید این لطفتون رو با یه توضیح در مورد چگونگی کار با این کتابخونه کامل کنید؟!
              برای ارسال و دریافت دیتا چیکار باید کرد؟ mac و ip که نوشته شده مربوط به آی سی هستش؟ مک هر آی سی منحصر بفرد نیس؟
              www.gam-co.blogsky.com

              دیدگاه


                #8
                پاسخ : کتابخانه ENC28j60 برای کدویژن

                از mac این کتابخونه استفاده نکردم ولی ظاهرا قابل تغییره!..
                تولید کننده تجهیزات برنامه پذیر اتوماسیون صنعتی

                www.intelart.ir


                ساخت کنترلر دما PID فازي با AVR [آموزشی]

                دیدگاه


                  #9
                  پاسخ : کتابخانه ENC28j60 برای کدویژن

                  سلام
                  در مورد تنطیم gateway و subnet روی ماژول enc28j60 سوال داشتم؟
                  من با codevisionavr کار میکنم ...تقریبا در ارسال و دریافت local مشکلی ندارم ولی برای استفاده توی شبکه های بزرگتر نیاز به تنظیم ادرس های subnet و gateway zپیدا کردم
                  با تشکر

                  دیدگاه

                  لطفا صبر کنید...
                  X