ENC28J60 Ethernet Controller
Moderators: David Barker, Jerry Messina
I hope to have a full driver to Microchip ENC28J60 by the end of next week. I'm still waiting for my EasyPic4 addon board with this chip to do tests on real hardware.dman776 wrote:anyone making progress on an ENC28J60 library?
But you must know that a driver for this chip is NOT everything in Ethernet Networking.
I still have to write full high level layers to parse any kind of protocol .
One time I worked a lot on TCP/IP (but not on Microchip driver). My main bible was the book TCP/IP Lean http://www.iosoft.co.uk/tcplean.php .
I hope to finish a full TCP/IP Stack using Swordfish Basic by the end of AUGUST
Once I'll get something really publishable, I'll give it to anybody who wants to test it.
Regards.
Octal
Do you have some news ?octal wrote:I hope to finish a full TCP/IP Stack using Swordfish Basic by the end of AUGUST
Best regards, Florin Medrea
My UserLibrary Folder http://www.microelemente.ro/Swordfish/UserLibrary/
My UserLibrary Folder http://www.microelemente.ro/Swordfish/UserLibrary/
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
Hello,
As there was no progress emerged for such a big period, please find attached a code written back in 2006, really hope It might help someone.
Please note that I will NOT provide any kind of support . Just use it however you see fit, if you need it.
Network connections:
The ENC28J60 board is connected to a network card in PC, via a crossed cable, as the firmware only intended for this type of connection. Minimum code lines will be needed to connect the board to routers and such.
What it does:
The board was thought as a UDP server only, that will reply to incoming requests using UDP transport.
That is: it will check if the destination IP is that of this board and the protocol used is UDP, it does not check for a specific UDP port (ie will accept any port number), then if those match will send back to sender a
message (string declared in code).
Also, the board will reply to incoming ARP and ICMP requests addressed to it.
Note: your board IP should match the class of PC network card that is connected to.
Testing the board and firmware:
Programs like Ethereal ( http://www.ethereal.com ) should be used to debug the packets sent or received by the board, if that is needed.
You can Ping the board directly from Windows console.
To test the UDP (and not only), you can use a nice piece of free software from: http://www.hw-group.com/products/hercules/index_en.html.
Recommended:
Please read the ENC28J60 datasheet including erratas to your device revision to fully understand what and how
the chip does,
and also,
you might find helpful to read those RFC's involved for the protocols that you may want to use at:
http://www.rfc-editor.org/
Hardware connections:
Note: that if your PIC is running at 5V then you will need level shifters on the lines going out from ENC28J60 to PIC. There a various ways to do it, so I will not go into that.
ENC28J60_PIN
INT PORTC.0 // ENC28J60 INT Pin <--
WOL PORTC.1 // ENC28J60 WOL Pin <--
CS PORTC.2 // ENC28J60 SPI ENABLE Pin -->
SCK PORTC.3 // ENC28J60 SPI CLOCK Pin -->
SO PORTC.4 // ENC28J60 SPI Data Out Pin <--
SI PORTC.5 // ENC28J60 SPI Data In Pin -->
RESET PullUp to 3.3V // ENC28J60 Reset Pin
As there was no progress emerged for such a big period, please find attached a code written back in 2006, really hope It might help someone.
Please note that I will NOT provide any kind of support . Just use it however you see fit, if you need it.
Network connections:
The ENC28J60 board is connected to a network card in PC, via a crossed cable, as the firmware only intended for this type of connection. Minimum code lines will be needed to connect the board to routers and such.
What it does:
The board was thought as a UDP server only, that will reply to incoming requests using UDP transport.
That is: it will check if the destination IP is that of this board and the protocol used is UDP, it does not check for a specific UDP port (ie will accept any port number), then if those match will send back to sender a
message (string declared in code).
Also, the board will reply to incoming ARP and ICMP requests addressed to it.
Note: your board IP should match the class of PC network card that is connected to.
Testing the board and firmware:
Programs like Ethereal ( http://www.ethereal.com ) should be used to debug the packets sent or received by the board, if that is needed.
You can Ping the board directly from Windows console.
To test the UDP (and not only), you can use a nice piece of free software from: http://www.hw-group.com/products/hercules/index_en.html.
Recommended:
Please read the ENC28J60 datasheet including erratas to your device revision to fully understand what and how
the chip does,
and also,
you might find helpful to read those RFC's involved for the protocols that you may want to use at:
http://www.rfc-editor.org/
Hardware connections:
Note: that if your PIC is running at 5V then you will need level shifters on the lines going out from ENC28J60 to PIC. There a various ways to do it, so I will not go into that.
ENC28J60_PIN
INT PORTC.0 // ENC28J60 INT Pin <--
WOL PORTC.1 // ENC28J60 WOL Pin <--
CS PORTC.2 // ENC28J60 SPI ENABLE Pin -->
SCK PORTC.3 // ENC28J60 SPI CLOCK Pin -->
SO PORTC.4 // ENC28J60 SPI Data Out Pin <--
SI PORTC.5 // ENC28J60 SPI Data In Pin -->
RESET PullUp to 3.3V // ENC28J60 Reset Pin
Code: Select all
//******************************************************************************
// ICMP Reply
//
//******************************************************************************
Sub ICMP_REPLY()
Dim DUMB As Byte
WRITE_ETH_TX_HEADER()
ETH_CS = 0 // Enable SPI on ENC28J60
SPI(WBM_OP_CODE) // Send WBM Opcode on SPI
SPI(IP_VERS_LEN) // IP version and length
SPI(IP_TOS) // IP TOS
SPI(IP_PKT_LEN.Byte1)
SPI(IP_PKT_LEN.Byte0)
SPI(IP_ID_0) // have to check if those two bytes need changing
SPI(IP_ID_1) //
SPI(IP_FRAG_OFFSET_0) // have To check If those two bytes need changing
SPI(IP_FRAG_OFFSET_1) //
SPI(IP_TTL) // TTL
SPI(IP_PROT) // this should be ICMP Protocol
//
// now the IP Header checksum
// *** or more simple --> just use the received checksum.its the same ***
//
SPI(IP_HDR_CKSUM.Byte1) // that is the easy way
SPI(IP_HDR_CKSUM.Byte0) //
//
SPI(MYIP_3) // source IP
SPI(MYIP_2) //
SPI(MYIP_1) //
SPI(MYIP_0) //
SPI(IP_SRC_ADDR_0) // we swap the received source IP to destination
SPI(IP_SRC_ADDR_1)
SPI(IP_SRC_ADDR_2)
SPI(IP_SRC_ADDR_3)
// till here was the IP Header
SPI($0) // ICMP type , ie $0 = ECHO Reply
SPI(ICMP_CODE)
// work around to reuse requester chksum
ICMP_CKSUM = ICMP_CKSUM + $0800
//
SPI(ICMP_CKSUM.Byte1) // dma checksums not reccomended
SPI(ICMP_CKSUM.Byte0) //
SPI(ICMP_IDENT.Byte1) //
SPI(ICMP_IDENT.Byte0) //
SPI(ICMP_SEQ_NUM.Byte1) //
SPI(ICMP_SEQ_NUM.Byte0)
For DUMB = 42 To (RX_BYTE_COUNT - 1) // 42 means the location where the ICMP data starts. ie ETH_COM_PACKET#42
SPI(ETH_COM_PACKET(DUMB)) // just copy those 32 bytes from last rx IP ICMP packet
Next
ETH_CS = 1
// Example: a total of 74 bytes including : per packet byte + ethernet header (14 bytes)
NEW_TX_PACK_PNTR = NEW_TX_PACK_PNTR + RX_BYTE_COUNT //
WRITE_ETH_TX_TAIL()
End Sub
//******************************************************************************
// UDP Reply
// - in this demo we reply to UDP data on any port as proof of concept
//******************************************************************************
Sub UDP_REPLY()
Dim DUMB As Byte
Dim DUMB_BYTE As Byte
Dim UDP_REPLY_STRING As String(80) // we go for a max length of 80 bytes (ie if TX_PRE_BUFFER is 128) for UDP reply string
Dim UDP_REPLY_STRING_LEN As Byte // hold the UDP_REPLY_STRING Lenght
Dim INTER_CKSUM As LongWord // used to hold the intermediate composite (for not linear stored bytes) checksum
//***************************************************************************
{* received UDP payload data starts on ETH_COM_PACKET(42)
* so we can try a small example
*}
Select ETH_COM_PACKET(42) // check against the pointed received char
Case $46 // Client sent a "F" character over UDP to our IP
UDP_REPLY_STRING = "You have sent 'F' to ENC28J60 Board"
Case $47 // Client sent a "G" character over UDP to our IP
UDP_REPLY_STRING = "You have sent 'G' to ENC28J60 Board."
Else // Client sent anything else over UDP to our IP
UDP_REPLY_STRING = "Your command was not recognized"
EndSelect
{* Those are the strings that will be sent back to client UDP application.
* Following the example above, the strings can be arrays as well
* Also you can Alias a structure starting with ETH_COM_PACKET(42) onwards,
* so you can check incoming UDP data on that structure
* ( not like a single char as in above example)
*}
//***************************************************************************
// have to compute now the payload length in bytes
UDP_REPLY_STRING_LEN = Length(UDP_REPLY_STRING) // or we can calculate it
// now calculate the IP_PKT_LEN
IP_PKT_LEN = 20 + 8 + UDP_REPLY_STRING_LEN // 20 is the IP header, 8 is the UDP header
// prepare the packet in FSR
FSR2 = AddressOf(TX_PRE_BUF) // point at the start of our virtual buffer
// start with common style eth frame header
POSTINC2 = TX_CONTROL_BYTE // loc 0 in our virtual buffer
POSTINC2 = SRC_MAC_ADR_0 // loc 1
POSTINC2 = SRC_MAC_ADR_1 // loc 2
POSTINC2 = SRC_MAC_ADR_2 // loc 3
POSTINC2 = SRC_MAC_ADR_3 // loc 4
POSTINC2 = SRC_MAC_ADR_4 // loc 5
POSTINC2 = SRC_MAC_ADR_5 // loc 6
POSTINC2 = MYMAC_0 // loc 7
POSTINC2 = MYMAC_1 // loc 8
POSTINC2 = MYMAC_2 // loc 9
POSTINC2 = MYMAC_3 // loc 10
POSTINC2 = MYMAC_4 // loc 11
POSTINC2 = MYMAC_5 // loc 12
POSTINC2 = RX_PACKET_TYPE.Byte1 // loc 13
POSTINC2 = RX_PACKET_TYPE.Byte0 // loc 14
POSTINC2 = IP_VERS_LEN // loc 15
POSTINC2 = IP_TOS // loc 16
POSTINC2 = IP_PKT_LEN.BYTE1 // loc 17
POSTINC2 = IP_PKT_LEN.Byte0 // loc 18
POSTINC2 = IP_ID_0 // loc 19
POSTINC2 = IP_ID_1 // loc 20
POSTINC2 = IP_FRAG_OFFSET_0 // loc 21
POSTINC2 = IP_FRAG_OFFSET_1 // loc 22
POSTINC2 = IP_TTL // loc 23
POSTINC2 = IP_PROT // loc 24
// now zero the checksum place holders as we need to calculate the checksum
POSTINC2 = 0 // loc 25 -- this will be IP_HDR_CKSUM.Highbyte
POSTINC2 = 0 // loc 26 -- this will be IP_HDR_CKSUM.Lowbyte
// now the ending part of IP header
POSTINC2 = MYIP_3 // loc 27
POSTINC2 = MYIP_2 // loc 28
POSTINC2 = MYIP_1 // loc 29
POSTINC2 = MYIP_0 // loc 30
POSTINC2 = IP_SRC_ADDR_0 // loc 31
POSTINC2 = IP_SRC_ADDR_1 // loc 32
POSTINC2 = IP_SRC_ADDR_2 // loc 33
POSTINC2 = IP_SRC_ADDR_3 // loc 34
// now we can calculate the IP checksum
CALC_CKSUM_PIC(15,34) // we have now the IP CKSUM in CKSUM_PIC_WORD
FSR2 = AddressOf(TX_PRE_BUF)
FSR2 = FSR2 + 25 //point at IP_HDR_CKSUM.Highbyte
POSTINC2 = CKSUM_PIC_WORD.Byte1 // we write now the calculated checksum at their right location
POSTINC2 = CKSUM_PIC_WORD.Byte0 // in IP header
// we will write now the UDP header
FSR2 = AddressOf(TX_PRE_BUF)
FSR2 = FSR2 + 35
// UDP ports
UDP_DEST_PORT = 30303 // Choose the UDP Destination Port
POSTINC2 = UDP_DEST_PORT.Byte1 // loc 35 -- we swap UDP source/destination ports
POSTINC2 = UDP_DEST_PORT.Byte0 // loc 36
POSTINC2 = UDP_SRC_PORT.Byte1 // loc 37
POSTINC2 = UDP_SRC_PORT.Byte0 // loc 38
// now UDP Length
UDP_LEN = 8 + UDP_REPLY_STRING_LEN // 8 is the UDP header in bytes + length of the payload
POSTINC2 = UDP_LEN.Byte1 // loc 39
POSTINC2 = UDP_LEN.Byte0 // loc 40
POSTINC2 = 0 // loc 41 -- UDP_CKSUM.highbyte , we write zero as we want to compute them
POSTINC2 = 0 // loc 42 -- UDP_CKSUM.lowbyte
//
CALC_CKSUM_PIC(27,42)
INTER_CKSUM = CKSUM_PIC_WORD // add it to inter checksum accumulator
// now we write the UDP data
For DUMB = 0 To (UDP_REPLY_STRING_LEN - 1) // loc 43 ... to
POSTINC2 = UDP_REPLY_STRING(DUMB) // 43 + UDP_REPLY_STRING_LEN
Next
//
CALC_CKSUM_PIC(43, (43 + UDP_REPLY_STRING_LEN - 1))
INTER_CKSUM = INTER_CKSUM + CKSUM_PIC_WORD // add it to inter checksum accumulator
// the following have to be added as a part of UDP pseudo header (ie 12 bytes), and which have the following content:
// - Source IP .. 4 bytes
// - Destination IP .. 4 bytes
// - blanc filler .. 1 byte
// - IP Protocol .. 1 byte (ie UDP $11)
// - UDP Length .. 2 bytes (as calculated above)
POSTINC2 = 0 // blanc filler
POSTINC2 = IP_PROT // IP Protocol
POSTINC2 = UDP_LEN.Byte1 // UDP Len highbyte
POSTINC2 = UDP_LEN.Byte0 // UDP Len lowbyte
// now we calculate the UDP composite checksum for the above data
CALC_CKSUM_PIC((43 + UDP_REPLY_STRING_LEN ),(43 + UDP_REPLY_STRING_LEN + 3))
INTER_CKSUM = INTER_CKSUM + CKSUM_PIC_WORD
CKSUM_PIC_WORD = INTER_CKSUM.WORD1 + INTER_CKSUM.WORD0
//
FSR2 = AddressOf(TX_PRE_BUF)
FSR2 = FSR2 + 41 //
POSTINC2 = CKSUM_PIC_WORD.Byte1 // point at location 41 and write the UDP_CKSUM.Highbyte
POSTINC2 = CKSUM_PIC_WORD.Byte0 // and the lowbyte at location 42
// we pass now this formated data from our virtual buffer to ENC28J60 TX buffer
// first build the packet to be sent in TX Bufer
// following if...endif could be a sub-routine as it is repeating itself thru code !!!!!!!
If NEW_TX_PACK_PNTR <> TX_BUF_START Then // if its not the very first Tx packet then
WRITE_ETH_REGISTER(ADR_ETXSTL,NEW_TX_PACK_PNTR.Byte0) // set TX Buffer START Location
WRITE_ETH_REGISTER(ADR_ETXSTH,NEW_TX_PACK_PNTR.Byte1) //
//
WRITE_ETH_REGISTER(ADR_EWRPTL,NEW_TX_PACK_PNTR.Byte0) // set the Tx Write pointer
WRITE_ETH_REGISTER(ADR_EWRPTH,NEW_TX_PACK_PNTR.Byte1) //
EndIf
//
ETH_CS = 0 // Enable SPI on ENC28J60
SPI(WBM_OP_CODE) // Send WBM Opcode on SPI
FSR2 = AddressOf(TX_PRE_BUF)
DUMB_BYTE = 1 + 42 + UDP_REPLY_STRING_LEN //
For DUMB = 0 To (DUMB_BYTE - 1)
SPI(POSTINC2)
Next
ETH_CS = 1
// advance pointers
NEW_TX_PACK_PNTR = NEW_TX_PACK_PNTR + DUMB_BYTE
// add the ETH_TX_TAIL part and start transmission
WRITE_ETH_TX_TAIL()
End Sub
{
Sub TCP_STATE_PROCCESS ()
End Sub
}
//******************************************************************************
// CHECK Packet Type - SUB
//
//******************************************************************************
Sub CHECK_PACKET_TYPE()
Select RX_PACKET_TYPE
Case ARP_TYPE_HEADER //$ 0806 --> ARP type header
Select ARP_OP // check ARP Operation (ie Request or Reply)
Case ARP_OP_REQUEST // $01 --> its an ARP Request
If ARP_TIPADDR_0 = MYIP_3 Then
If ARP_TIPADDR_1 = MYIP_2 Then
If ARP_TIPADDR_2 = MYIP_1 Then
If ARP_TIPADDR_3 = MYIP_0 Then
ARP_REPLY() // reply to ARP packet if addressed to this IP
EndIf
EndIf
EndIf
EndIf
Case ARP_OP_REPLY // $02 --> its an ARP Reply
EndSelect
Case TCP_TYPE_HEADER // $0800 --> TCP Type header
Select IP_PROT
Case PROT_ICMP // $01 --> ICMP
Select ICMP_TYPE // check if it is an ICMP request
Case ICMP_ECHO_REQUEST // $08 --> so it's a ECHO Request
If IP_DEST_ADDR_0 = MYIP_3 Then // is it My IP ??
If IP_DEST_ADDR_1 = MYIP_2 Then //
If IP_DEST_ADDR_2 = MYIP_1 Then //
If IP_DEST_ADDR_3 = MYIP_0 Then //
ICMP_REPLY() // OK, its My IP, so Reply to it
EndIf
EndIf
EndIf
EndIf
Case ICMP_ECHO_REPLY // $00 --> its a ECHO Reply
// so you can do something with that
// in here if needed
EndSelect
Case PROT_UDP // $11 --> UDP
If IP_DEST_ADDR_0 = MYIP_3 Then // is it My IP ??
If IP_DEST_ADDR_1 = MYIP_2 Then //
If IP_DEST_ADDR_2 = MYIP_1 Then //
If IP_DEST_ADDR_3 = MYIP_0 Then //
// you can also check for the UDP incoming port
UDP_REPLY() // OK, its My IP, so Reply to this UDP, or Whatever action
EndIf
EndIf
EndIf
EndIf
EndSelect
EndSelect
End Sub
//******************************************************************************
// PARSE_RX_BUFFERS
//
//******************************************************************************
Sub PARSE_RX_BUFFERS()
RX_PACKET_TYPE.Byte1 = ETH_COM_PACKET(12) // Type of Packet or the Length of the Packet
RX_PACKET_TYPE.Byte0 = ETH_COM_PACKET(13) //
//******************************************************************************
//* ARP Header Layout aliases to ETH_COM_PACKET (Ethernet Packet) elements
//******************************************************************************
ARP_HW_TYPE.Byte1 = ETH_COM_PACKET(14) // ARP Hardware address space in bytes
ARP_HW_TYPE.Byte0 = ETH_COM_PACKET(15) //
ARP_PROT_TYPE.Byte1 = ETH_COM_PACKET(16) // ARP Protocol address space in bytes
ARP_PROT_TYPE.Byte0 = ETH_COM_PACKET(17) //
ARP_OP.Byte1 = ETH_COM_PACKET(20) // ARP Operations code
ARP_OP.Byte0 = ETH_COM_PACKET(21) //
//******************************************************************************
//* IP Header Layout aliases to ETH_COM_PACKET (Ethernet Packet) elements - RFC791
//* - this portion of IP Packet is common to: IP, ICMP, TCP and UDP
//******************************************************************************
IP_PKT_LEN.Byte1 = ETH_COM_PACKET(16) // IP Packet Length High Byte
IP_PKT_LEN.Byte0 = ETH_COM_PACKET(17) // IP Packet Length Low Byte //
IP_HDR_CKSUM.Byte1 = ETH_COM_PACKET(24) // IP Header Checksum High Byte
IP_HDR_CKSUM.Byte0 = ETH_COM_PACKET(25) // IP Header Checksum Low Byte
//******************************************************************************
//* ICMP Header Layout aliases To ETH_COM_PACKET (Ethernet Packet) elements - RFC792
//* - Format as per ECHO or REPLY Messages . See RFC792 pag.14
//******************************************************************************
ICMP_CKSUM.Byte1 = ETH_COM_PACKET(36) // ICMP CHECKSUM High Byte
ICMP_CKSUM.Byte0 = ETH_COM_PACKET(37) // ICMP CHECKSUM Low Byte
ICMP_IDENT.Byte1 = ETH_COM_PACKET(38) // ICMP IDENTIFIER High Byte
ICMP_IDENT.Byte0 = ETH_COM_PACKET(39) // ICMP IDENTIFIER Low Byte
ICMP_SEQ_NUM.Byte1 = ETH_COM_PACKET(40) // ICMP SEQUENCE NUMBER High Byte
ICMP_SEQ_NUM.Byte0 = ETH_COM_PACKET(41) // ICMP SEQUENCE NUMBER Low Byte. From here on ICMP data.
//******************************************************************************
//* UDP Header Layout aliases To ETH_COM_PACKET (Ethernet Packet) elements - RFC768
//******************************************************************************
UDP_SRC_PORT.Byte1 = ETH_COM_PACKET(34) // UDP SOURCE PORT High Byte
UDP_SRC_PORT.Byte0 = ETH_COM_PACKET(35) // UDP SOURCE PORT Low Byte
UDP_DEST_PORT.Byte1 = ETH_COM_PACKET(36) // UDP DESTINATION PORT High Byte
UDP_DEST_PORT.Byte0 = ETH_COM_PACKET(37) // UDP DESTINATION PORT High Byte
UDP_LEN.Byte1 = ETH_COM_PACKET(38) // UDP length in octets of this user datagram High Byte
UDP_LEN.Byte0 = ETH_COM_PACKET(39) // UDP length in octets of this user datagram Low Byte
UDP_CKSUM.Byte1 = ETH_COM_PACKET(40) // UDP CHECKSUM High Byte
UDP_CKSUM.Byte0 = ETH_COM_PACKET(41) // UDP CHECKSUM Low Byte. From here on UDP Data.
End Sub
//******************************************************************************
// Read RX BUFFERS - SUB
//
//******************************************************************************
Sub READ_RX_BUFS()
Dim DUMB As Byte
Dim DUMB_WORD As Word
ETH_CS = 0 // Enable SPI on ENC28J60
SPI(RBM_OP_CODE) // Send RBM Opcode on SPI
For DUMB = 0 To 5
RX_PACKET_HEADER(DUMB) = SPI($FF) // READ_BUFFER_MEMORY
Next
//
RX_BYTE_COUNT = RX_BYTE_COUNT - 4 // real is (RX_BYTE_COUNT - 4) i.e the last 4 CRC bytes of frame
//
For DUMB = 0 To (RX_BYTE_COUNT - 1) //
ETH_COM_PACKET(DUMB) = SPI($FF) // READ_BUFFER_MEMORY
Next
//
// Start parsing here
PARSE_RX_BUFFERS() // workaround for aliases
//
ETH_CS = 1
CHECK_PACKET_TYPE() // Check the received packet header type and act accordingly
DUMB_WORD = NEXT_PACKET_POINTER - 1
WRITE_ETH_REGISTER(ADR_ERXRDPTL, DUMB_WORD.Byte0) // update Rx Buf pointers
WRITE_ETH_REGISTER(ADR_ERXRDPTH, DUMB_WORD.Byte1)
ECON2_PKTDEC = 1 // decrement the rx packet number
SET_REGISTER_BIT(ADR_ECON2, ECON2)
WRITE_ETH_REGISTER(ADR_ERDPTL,NEXT_PACKET_POINTER.Byte0) // update Nex_Packet_Pointer
WRITE_ETH_REGISTER(ADR_ERDPTH,NEXT_PACKET_POINTER.Byte1)
End Sub
//##############################################################################
// Program start
// Testing ENC28J60 board - DEMO
//
//##############################################################################
DelayMS(100)
ADCON1 = $0F //
//------------------------------------------------------------------------------
//* PIC MSSP Register settings
SSPCON1 = $20 // Enable SPI,idle Low, Fosc/4
SSPSTAT = $40 // transmit On rising edge, sample middle
//* Configure PIC I/O pins connected To ENC28J60 device
Input(ETH_INT) // <--
Input(ETH_WOL) // <--
Output(ETH_CS) // -->
Output(ETH_SCK) // -->
Input(ETH_SO) // <--
Output(ETH_SI) // -->
//
INIT_ENC28J60() // Init the ENC28J60
DelayMS(1000)
{* Continuous DEMO -- Polling Loop
* supports ARP reply, ICMP reply and UDP reply
*}
While 1 = 1 //
EIR = READ_ETH_REGISTER(ADR_EIR) // poll the interrupts flags
If EIR_PKTIF = 1 Then // if unprocessed packets in rx buffer
READ_RX_BUFS() // call READ_RX_BUFS_SUB and parse them
EndIf
Wend
//################### END PROGRAM ########################################
Last edited by _Gabi_ on Wed Jan 16, 2008 6:52 pm, edited 1 time in total.
Regards,
Gabi
Gabi