標(biāo)題:
收藏個老外寫的ENC28J60驅(qū)動
[打印本頁]
作者:
hushe
時間:
2015-12-22 21:59
標(biāo)題:
收藏個老外寫的ENC28J60驅(qū)動
我就是伸手黨 ,自己寫不出來,就抄別人的。
/*! \file enc28j60.h \brief Microchip ENC28J60 Ethernet Interface Driver. */
//*****************************************************************************
//
// File Name : 'enc28j60.h'
// Title : Microchip ENC28J60 Ethernet Interface Driver
// Author : Pascal Stang (c)2005
// Created : 9/22/2005
// Revised : 9/22/2005
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
/// \ingroup network
/// \defgroup enc28j60 Microchip ENC28J60 Ethernet Interface Driver (enc28j60.c)
/// \code #include "net/enc28j60.h" \endcode
/// \par Overview
/// This driver provides initialization and transmit/receive
/// functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY.
/// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin
/// chip, using an SPI interface to the host processor.
///
//
//*****************************************************************************
//@{
#ifndef ENC28J60_H
#define ENC28J60_H
#include "global.h"
//#define nop() asm volatile ("nop")
// 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 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
// buffer boundaries applied to internal 8K ram
// entire available packet buffer space is allocated
#define TXSTART_INIT 0x0000 // start TX buffer at 0
#define RXSTART_INIT 0x0600 // give TX buffer space for one full ethernet frame (~1500 bytes)
#define RXSTOP_INIT 0x1FFF // receive buffer gets the rest
#define MAX_FRAMELEN 1518 // maximum ethernet frame length
// Ethernet constants
#define ETHERNET_MIN_PACKET_LENGTH 0x3C
//#define ETHERNET_HEADER_LENGTH 0x0E
// setup ports for I/O
//void ax88796SetupPorts(void);
//! do a ENC28J60 read operation
u08 enc28j60ReadOp(u08 op, u08 address);
//! do a ENC28J60 write operation
void enc28j60WriteOp(u08 op, u08 address, u08 data);
//! read the packet buffer memory
void enc28j60ReadBuffer(u16 len, u08* data);
//! write the packet buffer memory
void enc28j60WriteBuffer(u16 len, u08* data);
//! set the register bank for register at address
void enc28j60SetBank(u08 address);
//! read ax88796 register
u08 enc28j60Read(u08 address);
//! write ax88796 register
void enc28j60Write(u08 address, u08 data);
//! read a PHY register
u16 enc28j60PhyRead(u08 address);
//! write a PHY register
void enc28j60PhyWrite(u08 address, u16 data);
//! initialize the ethernet interface for transmit/receive
void enc28j60Init(void);
//! Packet transmit function.
/// Sends a packet on the network. It is assumed that the packet is headed by a valid ethernet header.
/// \param len Length of packet in bytes.
/// \param packet Pointer to packet data.
/// \param len2 Length of the secound packet in bytes, can be 0.
/// \param packet2 Pointer to the secound packet data, can be NULL.
void enc28j60PacketSend(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2);
//! Packet receive function.
/// Gets a packet from the network receive buffer, if one is available.
/// The packet will by headed by an ethernet header.
/// \param maxlen The maximum acceptable length of a retrieved packet.
/// \param packet Pointer where packet data should be stored.
/// \return Packet length in bytes if a packet was retrieved, zero otherwise.
unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet);
//! execute procedure for recovering from a receive overflow
/// this should be done when the receive memory fills up with packets
void enc28j60ReceiveOverflowRecover(void);
#endif
//@}
/*! \file enc28j60.c \brief Microchip ENC28J60 Ethernet Interface Driver. */
//*****************************************************************************
//
// File Name : 'enc28j60.c'
// Title : Microchip ENC28J60 Ethernet Interface Driver
// Author : Pascal Stang (c)2005
// Created : 9/22/2005
// Revised : 9/22/2005
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This driver provides initialization and transmit/receive
// functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY.
// This chip is novel in that it is a full MAC+PHY interface all in a 28-pin
// chip, using an SPI interface to the host processor.
//
//*****************************************************************************
#include "global-conf.h"
#include <avr/io.h>
#include <util/delay.h>
#include "global.h"
//#include "timer.h" //Note have been replaced with _delay_us() as this is more convient
#include "enc28j60.h"
#ifdef SPDR0
#define SPDR SPDR0
#define SPCR SPCR0
#define SPSR SPSR0
#define SPIF SPIF0
#define MSTR MSTR0
#define CPOL CPOL0
#define DORD DORD0
#define SPR0 SPR00
#define SPR1 SPR01
#define SPI2X SPI2X0
#define SPE SPE0
#endif
// include configuration
#include "enc28j60conf.h"
u08 Enc28j60Bank;
u16 NextPacketPtr;
/*void nicInit(void)
{
enc28j60Init();
}
void nicSend(unsigned int len, unsigned char* packet)
{
enc28j60PacketSend(len, packet);
}
unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
{
return enc28j60PacketReceive(maxlen, packet);
}*/
/*void nicRegDump(void)
{
enc28j60RegDump();
}*/
/*
void ax88796SetupPorts(void)
{
#if NIC_CONNECTION == MEMORY_MAPPED
// enable external SRAM interface - no wait states
sbi(MCUCR, SRE);
// sbi(MCUCR, SRW10);
// sbi(XMCRA, SRW00);
// sbi(XMCRA, SRW01);
// sbi(XMCRA, SRW11);
#else
// set address port to output
AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK;
// set data port to input with pull-ups
AX88796_DATA_DDR = 0x00;
AX88796_DATA_PORT = 0xFF;
// initialize the control port read and write pins to de-asserted
sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN );
sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN );
// set the read and write pins to output
sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN );
sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN );
#endif
// set reset pin to output
sbi( AX88796_RESET_DDR, AX88796_RESET_PIN );
}
*/
u08 enc28j60ReadOp(u08 op, u08 address)
{
u08 data;
// assert CS
ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
// issue read command
SPDR = op | (address & ADDR_MASK);
while(!(SPSR & (1<<SPIF)));
// read data
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
// do dummy read if needed
if(address & 0x80)
{
SPDR = 0x00;
while(!(inb(SPSR) & (1<<SPIF)));
}
data = SPDR;
// release CS
ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
return data;
}
void enc28j60WriteOp(u08 op, u08 address, u08 data)
{
// assert CS
ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
// issue write command
SPDR = op | (address & ADDR_MASK);
while(!(SPSR & (1<<SPIF)));
// write data
SPDR = data;
while(!(SPSR & (1<<SPIF)));
// release CS
ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
}
void enc28j60ReadBuffer(u16 len, u08* data)
{
// assert CS
ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
// issue read command
SPDR = ENC28J60_READ_BUF_MEM;
while(!(SPSR & (1<<SPIF)));
while(len--)
{
// read data
SPDR = 0x00;
while(!(SPSR & (1<<SPIF)));
*data++ = SPDR;
}
// release CS
ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
}
void enc28j60WriteBuffer(u16 len, u08* data)
{
// assert CS
ENC28J60_CONTROL_PORT &= ~(1<<ENC28J60_CONTROL_CS);
// issue write command
SPDR = ENC28J60_WRITE_BUF_MEM;
while(!(SPSR & (1<<SPIF)));
while(len--)
{
// write data
SPDR = *data++;
while(!(SPSR & (1<<SPIF)));
}
// release CS
ENC28J60_CONTROL_PORT |= (1<<ENC28J60_CONTROL_CS);
}
void enc28j60SetBank(u08 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);
}
}
u08 enc28j60Read(u08 address)
{
// set the bank
enc28j60SetBank(address);
// do the read
return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);
}
void enc28j60Write(u08 address, u08 data)
{
// set the bank
enc28j60SetBank(address);
// do the write
enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
}
u16 enc28j60PhyRead(u08 address)
{
u16 data;
// Set the right address and start the register read operation
enc28j60Write(MIREGADR, address);
enc28j60Write(MICMD, MICMD_MIIRD);
// wait until the PHY read completes
while(enc28j60Read(MISTAT) & MISTAT_BUSY);
// quit reading
enc28j60Write(MICMD, 0x00);
// get data value
data = enc28j60Read(MIRDL);
data |= enc28j60Read(MIRDH);
// return the data
return data;
}
void enc28j60PhyWrite(u08 address, u16 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);
}
void enc28j60Init(void)
{
// initialize I/O
sbi(ENC28J60_CONTROL_DDR, ENC28J60_CONTROL_CS);
sbi(ENC28J60_CONTROL_PORT, ENC28J60_CONTROL_CS);
// setup SPI I/O pins
sbi(ENC28J60_SPI_PORT, ENC28J60_SPI_SCK); // set SCK hi
sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SCK); // set SCK as output
cbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MISO); // set MISO as input
sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_MOSI); // set MOSI as output
sbi(ENC28J60_SPI_DDR, ENC28J60_SPI_SS); // SS must be output for Master mode to work
// initialize SPI interface
// master mode
sbi(SPCR, MSTR);
// select clock phase positive-going in middle of data
cbi(SPCR, CPOL);
// Data order MSB first
cbi(SPCR,DORD);
// switch to f/4 2X = f/2 bitrate
cbi(SPCR, SPR0);
cbi(SPCR, SPR1);
sbi(SPSR, SPI2X);
// enable SPI
sbi(SPCR, SPE);
// perform system reset
enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
// check CLKRDY bit to see if reset is complete
_delay_us(50);
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;
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);
// 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);
// 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);
// Set the maximum packet size which the controller will accept
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, ENC28J60_MAC0);
enc28j60Write(MAADR4, ENC28J60_MAC1);
enc28j60Write(MAADR3, ENC28J60_MAC2);
enc28j60Write(MAADR2, ENC28J60_MAC3);
enc28j60Write(MAADR1, ENC28J60_MAC4);
enc28j60Write(MAADR0, ENC28J60_MAC5);
// 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);
/*
enc28j60PhyWrite(PHLCON, 0x0AA2);
// setup duplex ----------------------
// Disable receive logic and abort any packets currently being transmitted
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS|ECON1_RXEN);
{
u16 temp;
// Set the PHY to the proper duplex mode
temp = enc28j60PhyRead(PHCON1);
temp &= ~PHCON1_PDPXMD;
enc28j60PhyWrite(PHCON1, temp);
// Set the MAC to the proper duplex mode
temp = enc28j60Read(MACON3);
temp &= ~MACON3_FULDPX;
enc28j60Write(MACON3, temp);
}
// Set the back-to-back inter-packet gap time to IEEE specified
// requirements. The meaning of the MABBIPG value changes with the duplex
// state, so it must be updated in this function.
// In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex
//enc28j60Write(MABBIPG, DuplexState ? 0x15 : 0x12);
// Reenable receive logic
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
// setup duplex ----------------------
*/
}
void enc28j60PacketSend(unsigned int len1, unsigned char* packet1, unsigned int len2, unsigned char* packet2)
{
//Errata: Transmit Logic reset
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST);
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST);
// 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+len1+len2));
enc28j60Write(ETXNDH, (TXSTART_INIT+len1+len2)>>8);
// write per-packet control byte
enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
// copy the packet into the transmit buffer
enc28j60WriteBuffer(len1, packet1);
if(len2>0) enc28j60WriteBuffer(len2, packet2);
// send the contents of the transmit buffer onto the network
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
}
unsigned int enc28j60PacketReceive(unsigned int maxlen, unsigned char* packet)
{
u16 rxstat;
u16 len;
// check if a packet has been received and buffered
// if( !(enc28j60Read(EIR) & EIR_PKTIF) )
if( !enc28j60Read(EPKTCNT) )
return 0;
// Make absolutely certain that any previous packet was discarded
//if( WasDiscarded == FALSE)
// MACDiscardRx();
// 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;
// read the receive status
rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;
// limit retrieve length
// (we reduce the MAC-reported length by 4 to remove the CRC)
len = MIN(len, maxlen);
// 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;
}
void enc28j60ReceiveOverflowRecover(void)
{
// receive buffer overflow handling procedure
// recovery completed
}
/*
void enc28j60RegDump(void)
{
// unsigned char macaddr[6];
// result = ax88796Read(TR);
// rprintf("Media State: ");
// if(!(result & AUTOD))
// rprintf("Autonegotiation\r\n");
// else if(result & RST_B)
// rprintf("PHY in Reset \r\n");
// else if(!(result & RST_10B))
// rprintf("10BASE-T \r\n");
// else if(!(result & RST_TXB))
// rprintf("100BASE-T \r\n");
rprintf("RevID: 0x%x\r\n", enc28j60Read(EREVID));
rprintfProgStrM("Cntrl: ECON1 ECON2 ESTAT EIR EIE\r\n");
rprintfProgStrM(" ");
rprintfu08(enc28j60Read(ECON1));
rprintfProgStrM(" ");
rprintfu08(enc28j60Read(ECON2));
rprintfProgStrM(" ");
rprintfu08(enc28j60Read(ESTAT));
rprintfProgStrM(" ");
rprintfu08(enc28j60Read(EIR));
rprintfProgStrM(" ");
rprintfu08(enc28j60Read(EIE));
rprintfCRLF();
rprintfProgStrM("MAC : MACON1 MACON2 MACON3 MACON4 MAC-Address\r\n");
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MACON1));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MACON2));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MACON3));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MACON4));
rprintfProgStrM(" ");
rprintfu08(enc28j60Read(MAADR5));
rprintfu08(enc28j60Read(MAADR4));
rprintfu08(enc28j60Read(MAADR3));
rprintfu08(enc28j60Read(MAADR2));
rprintfu08(enc28j60Read(MAADR1));
rprintfu08(enc28j60Read(MAADR0));
rprintfCRLF();
rprintfProgStrM("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\r\n");
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ERXSTH));
rprintfu08(enc28j60Read(ERXSTL));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ERXNDH));
rprintfu08(enc28j60Read(ERXNDL));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ERXWRPTH));
rprintfu08(enc28j60Read(ERXWRPTL));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ERXRDPTH));
rprintfu08(enc28j60Read(ERXRDPTL));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ERXFCON));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(EPKTCNT));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MAMXFLH));
rprintfu08(enc28j60Read(MAMXFLL));
rprintfCRLF();
rprintfProgStrM("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\r\n");
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ETXSTH));
rprintfu08(enc28j60Read(ETXSTL));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(ETXNDH));
rprintfu08(enc28j60Read(ETXNDL));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MACLCON1));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MACLCON2));
rprintfProgStrM(" 0x");
rprintfu08(enc28j60Read(MAPHSUP));
rprintfCRLF();
_delay_ms(25);
}
*/
/*! \file enc28j60conf.h \brief Microchip ENC28J60 Ethernet Interface Driver Configuration. */
//*****************************************************************************
//
// File Name : 'enc28j60conf.h'
// Title : Microchip ENC28J60 Ethernet Interface Driver Configuration
// Author : Pascal Stang
// Created : 10/5/2004
// Revised : 8/22/2005
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This driver provides initialization and transmit/receive
// functions for the ENC28J60 10Mb Ethernet Controller and PHY.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
/* USERS NOTE:
* Do not enter your hardware specific configurations here. Copy the settings
* below and define them in your baord specific directory. Remember to also
* define ENC28J60CONF_H so that these settings will not overwrite yours.
* By modifying this in your board specific directory, you should be able to
* update/upgrade your avr-uip distribution without having to modify updated
* files.
*
*
* DEVELOPERS NOTE:
* Settings entered should be something rather common, and not update too often.
*/
#ifndef ENC28J60CONF_H
#define ENC28J60CONF_H
// ENC28J60 SPI port
#define ENC28J60_SPI_PORT PORTB
#define ENC28J60_SPI_DDR DDRB
#define ENC28J60_SPI_SCK PB5
#define ENC28J60_SPI_MOSI PB3
#define ENC28J60_SPI_MISO PB4
#define ENC28J60_SPI_SS PB2
// ENC28J60 control port
#define ENC28J60_CONTROL_PORT PORTB
#define ENC28J60_CONTROL_DDR DDRB
#define ENC28J60_CONTROL_CS PB2
// MAC address for this interface
#ifdef ETHADDR0
#define ENC28J60_MAC0 ETHADDR0
#define ENC28J60_MAC1 ETHADDR1
#define ENC28J60_MAC2 ETHADDR2
#define ENC28J60_MAC3 ETHADDR3
#define ENC28J60_MAC4 ETHADDR4
#define ENC28J60_MAC5 ETHADDR5
#else
#define ENC28J60_MAC0 '0'
#define ENC28J60_MAC1 'F'
#define ENC28J60_MAC2 'F'
#define ENC28J60_MAC3 'I'
#define ENC28J60_MAC4 'C'
#define ENC28J60_MAC5 'E'
#endif
#endif
/*! \file enc28j60conf.h \brief Microchip ENC28J60 Ethernet Interface Driver Configuration. */
//*****************************************************************************
//
// File Name : 'enc28j60conf.h'
// Title : Microchip ENC28J60 Ethernet Interface Driver Configuration
// Author : Pascal Stang
// Created : 10/5/2004
// Revised : 8/22/2005
// Version : 0.1
// Target MCU : Atmel AVR series
// Editor Tabs : 4
//
// Description : This driver provides initialization and transmit/receive
// functions for the ENC28J60 10Mb Ethernet Controller and PHY.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
/* USERS NOTE:
* Do not enter your hardware specific configurations here. Copy the settings
* below and define them in your baord specific directory. Remember to also
* define ENC28J60CONF_H so that these settings will not overwrite yours.
* By modifying this in your board specific directory, you should be able to
* update/upgrade your avr-uip distribution without having to modify updated
* files.
*
*
* DEVELOPERS NOTE:
* Settings entered should be something rather common, and not update too often.
*/
#ifndef ENC28J60CONF_H
#define ENC28J60CONF_H
// ENC28J60 SPI port
#define ENC28J60_SPI_PORT PORTB
#define ENC28J60_SPI_DDR DDRB
#define ENC28J60_SPI_SCK PB5
#define ENC28J60_SPI_MOSI PB3
#define ENC28J60_SPI_MISO PB4
#define ENC28J60_SPI_SS PB2
// ENC28J60 control port
#define ENC28J60_CONTROL_PORT PORTB
#define ENC28J60_CONTROL_DDR DDRB
#define ENC28J60_CONTROL_CS PB2
// MAC address for this interface
#ifdef ETHADDR0
#define ENC28J60_MAC0 ETHADDR0
#define ENC28J60_MAC1 ETHADDR1
#define ENC28J60_MAC2 ETHADDR2
#define ENC28J60_MAC3 ETHADDR3
#define ENC28J60_MAC4 ETHADDR4
#define ENC28J60_MAC5 ETHADDR5
#else
#define ENC28J60_MAC0 '0'
#define ENC28J60_MAC1 'F'
#define ENC28J60_MAC2 'F'
#define ENC28J60_MAC3 'I'
#define ENC28J60_MAC4 'C'
#define ENC28J60_MAC5 'E'
#endif
#endif
復(fù)制代碼
作者:
綠源學(xué)習(xí)者
時間:
2016-3-9 13:52
樓主做出來沒有,我也弄一個
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1