Connect Ethernet controller with PIC Code
The
ENC28J60
is a stand-alone Ethernet controller with an industry standard Serial Peripheral Interface (SPI). It is designed to serve as an Ethernet network interface for any controller equipped with SPI.The
ENC28J60
meets all of the IEEE 802.3 specifications. It incorporates a number of packet filtering schemes to limit incoming packets. It also provides an internal DMA module for fast data throughput and hardware assisted IP checksum calculations. Communication with the host controller is implemented via two interrupt pins and the SPI, with data rates of up to 10 Mb/s. Two dedicated pins are used for LED link and network activity indication.This library is designed to simplify handling of the underlying hardware (
ENC28J60
). It works with any PIC with integrated SPI and more than 4 Kb ROM memory. 38 to 40 MHz clock is recommended to get from 8 to 10 Mhz SPI clock, otherwise PIC should be clocked by ENC28J60
clock output due to its silicon bug in SPI hardware. If you try lower PIC clock speed, there might be board hang or miss some requests.SPI Ethernet ENC28J60 Library supports:
- IPv4 protocol.
- ARP requests.
- ICMP echo requests.
- UDP requests.
- TCP requests (no stack, no packet reconstruction).
- ARP client with cache.
- DNS client.
- UDP client.
- DHCP client.
- packet fragmentation is NOT supported.
Important :
- Due to PIC16 RAM/Flash limitations PIC16 library does NOT have ARP, DNS, UDP and DHCP client support implemented.
- Global library variable
SPI_Ethernet_userTimerSec
is used to keep track of time for all client implementations (ARP, DNS, UDP and DHCP). It is user responsibility to increment this variable each second in it’s code if any of the clients is used. - For advanced users there are header files (
"__EthEnc28j60.h"
and"__EthEnc28j60Private.h"
) in Uses\P16 and Uses\P18 folders of the compiler with description of all routines and global variables, relevant to the user, implemented in the SPI Ethernet ENC28J60 Library. - The appropriate hardware SPI module must be initialized before using any of the SPI Ethernet ENC28J60 library routines.
- For MCUs with two SPI modules it is possible to initialize both of them and then switch by using the
SPI_Set_Active()
routine.
Library Dependency Tree
External dependencies of SPI Ethernet ENC28J60 Library
The following variables must be defined in all projects using SPI Ethernet ENC28J60 Library: | Description: | Examples : |
---|---|---|
extern sfr sbit SPI_Ethernet_CS; |
ENC28J60 chip select pin. | sbit SPI_Ethernet_CS at RC1_bit; |
extern sfr sbit SPI_Ethernet_RST; |
ENC28J60 reset pin. | sbit SPI_Ethernet_Rst at RC0_bit; |
extern sfr sbit SPI_Ethernet_CS_Direction; |
Direction of the ENC28J60 chip select pin. | sbit SPI_Ethernet_CS_Direction at TRISC1_bit; |
extern sfr sbit SPI_Ethernet_RST_Direction; |
Direction of the ENC28J60 reset pin. | sbit SPI_Ethernet_Rst_Direction at TRISC0_bit; |
The following routines must be defined in all project using SPI Ethernet ENC28J60 Library: | Description: | Examples : |
---|---|---|
unsigned int SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags); |
TCP request handler. | Refer to the library example at the bottom of this page for code implementation. |
unsigned int SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags); |
UDP request handler. | Refer to the library example at the bottom of this page for code implementation. |
Library Routines
PIC16 and PIC18:
- SPI_Ethernet_Init
- SPI_Ethernet_Enable
- SPI_Ethernet_Disable
- SPI_Ethernet_doPacket
- SPI_Ethernet_putByte
- SPI_Ethernet_putBytes
- SPI_Ethernet_putString
- SPI_Ethernet_putConstString
- SPI_Ethernet_putConstBytes
- SPI_Ethernet_getByte
- SPI_Ethernet_getBytes
- SPI_Ethernet_UserTCP
- SPI_Ethernet_UserUDP
PIC18 Only:
- SPI_Ethernet_getIpAddress
- SPI_Ethernet_getGwIpAddress
- SPI_Ethernet_getDnsIpAddress
- SPI_Ethernet_getIpMask
- SPI_Ethernet_confNetwork
- SPI_Ethernet_arpResolve
- SPI_Ethernet_sendUDP
- SPI_Ethernet_dnsResolve
- SPI_Ethernet_initDHCP
- SPI_Ethernet_doDHCPLeaseTime
- SPI_Ethernet_renewDHCP
SPI_Ethernet_Init
Prototype | void SPI_Ethernet_Init(unsigned char *mac, unsigned char *ip, unsigned char fullDuplex); |
---|---|
Returns | Nothing. |
Description | This is MAC module routine. It initializes ENC28J60 controller. This function is internaly splited into 2 parts to help linker when coming short of memory.ENC28J60 controller settings (parameters not mentioned here are set to default):
Parameters:
|
Requires | Global variables :
must be defined before using this function. |
Example |
#define SPI_Ethernet_HALFDUPLEX 0 #define SPI_Ethernet_FULLDUPLEX 1 // mE ethernet NIC pinout sfr sbit SPI_Ethernet_Rst at RC0_bit; sfr sbit SPI_Ethernet_CS at RC1_bit; sfr sbit SPI_Ethernet_Rst_Direction at TRISC0_bit; sfr sbit SPI_Ethernet_CS_Direction at TRISC1_bit; // end ethernet NIC definitions unsigned char myMacAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f}; // my MAC address unsigned char myIpAddr = {192, 168, 1, 60 }; // my IP addr SPI1_Init(); SPI_Ethernet_Init(myMacAddr, myIpAddr, SPI_Ethernet_FULLDUPLEX); |
SPI_Ethernet_Enable
Prototype | void SPI_Ethernet_Enable(unsigned char enFlt); | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Returns | Nothing. | ||||||||||||||||||||||||||||||||||||
Description | This is MAC module routine. This routine enables appropriate network traffic on the ENC28J60 module by the means of it’s receive filters (unicast, multicast, broadcast, crc). Specific type of network traffic will be enabled if a corresponding bit of this routine’s input parameter is set. Therefore, more than one type of network traffic can be enabled at the same time. For this purpose, predefined library constants (see the table below) can be ORed to form appropriate input value.Parameters:
|
||||||||||||||||||||||||||||||||||||
Requires | Ethernet module has to be initialized. See SPI_Ethernet_Init. | ||||||||||||||||||||||||||||||||||||
Example |
SPI_Ethernet_Enable(_SPI_Ethernet_CRC | _SPI_Ethernet_UNICAST); // enable CRC checking and Unicast traffic |
SPI_Ethernet_Disable
Prototype | void SPI_Ethernet_Disable(unsigned char disFlt); | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Returns | Nothing. | ||||||||||||||||||||||||||||||||||||
Description | This is MAC module routine. This routine disables appropriate network traffic on the ENC28J60 module by the means of it’s receive filters (unicast, multicast, broadcast, crc). Specific type of network traffic will be disabled if a corresponding bit of this routine’s input parameter is set. Therefore, more than one type of network traffic can be disabled at the same time. For this purpose, predefined library constants (see the table below) can be ORed to form appropriate input value.Parameters:
|
||||||||||||||||||||||||||||||||||||
Requires | Ethernet module has to be initialized. | ||||||||||||||||||||||||||||||||||||
Example |
SPI_Ethernet_Disable(_SPI_Ethernet_CRC | _SPI_Ethernet_UNICAST); // disable CRC checking and Unicast traffic |
SPI_Ethernet_doPacket
Prototype | unsigned char SPI_Ethernet_doPacket(); |
---|---|
Returns |
|
Description | This is MAC module routine. It processes next received packet if such exists. Packets are processed in the following manner:
Note :
SPI_Ethernet_doPacket must be called as often as possible in user’s code. |
Requires | Ethernet module has to be initialized. |
Example |
if (SPI_Ethernet_doPacket() == 0)(1) { // process received packets ... } |
SPI_Ethernet_putByte
Prototype | void SPI_Ethernet_putByte(unsigned char v); |
---|---|
Returns | Nothing. |
Description | This is MAC module routine. It stores one byte to address pointed by the current ENC28J60 write pointer (EWRPT ).Parameters:
|
Requires | Ethernet module has to be initialized. |
Example |
char data_; ... SPI_Ethernet_putByte(data); // put an byte into ENC28J60 buffer |
SPI_Ethernet_putBytes
Prototype | void SPI_Ethernet_putBytes(unsigned char *ptr, unsigned int n); |
---|---|
Returns | Nothing. |
Description | This is MAC module routine. It stores requested number of bytes into ENC28J60 RAM starting from current ENC28J60 write pointer (EWRPT ) location.Parameters:
|
Requires | Ethernet module has to be initialized. |
Example |
char *buffer = "mikroElektronika"; ... SPI_Ethernet_putBytes(buffer, 16); // put an RAM array into ENC28J60 buffer |
SPI_Ethernet_putConstBytes
Prototype | void SPI_Ethernet_putConstBytes(const unsigned char *ptr, unsigned int n); |
---|---|
Returns | Nothing. |
Description | This is MAC module routine. It stores requested number of const bytes into ENC28J60 RAM starting from current ENC28J60 write pointer (EWRPT ) location.Parameters:
|
Requires | Ethernet module has to be initialized. |
Example |
const char *buffer = "mikroElektronika"; ... SPI_Ethernet_putConstBytes(buffer, 16); // put a const array into ENC28J60 buffer |
SPI_Ethernet_putString
Prototype | unsigned int SPI_Ethernet_putString(unsigned char *ptr); |
---|---|
Returns | Number of bytes written into ENC28J60 RAM. |
Description | This is MAC module routine. It stores whole string (excluding null termination) into ENC28J60 RAM starting from current ENC28J60 write pointer (EWRPT ) location.Parameters:
|
Requires | Ethernet module has to be initialized. |
Example |
char *buffer = "mikroElektronika"; ... SPI_Ethernet_putString(buffer); // put a RAM string into ENC28J60 buffer |
SPI_Ethernet_putConstString
Prototype | unsigned int SPI_Ethernet_putConstString(const unsigned char *ptr); |
---|---|
Returns | Number of bytes written into ENC28J60 RAM. |
Description | This is MAC module routine. It stores whole const string (excluding null termination) into ENC28J60 RAM starting from current ENC28J60 write pointer (EWRPT ) location.Parameters:
|
Requires | Ethernet module has to be initialized. |
Example |
const char *buffer = "mikroElektronika"; ... SPI_Ethernet_putConstString(buffer); // put a const string into ENC28J60 buffer |
SPI_Ethernet_getByte
Prototype | unsigned char SPI_Ethernet_getByte(); |
---|---|
Returns | Byte read from ENC28J60 RAM. |
Description | This is MAC module routine. It fetches a byte from address pointed to by current ENC28J60 read pointer (ERDPT ). |
Requires | Ethernet module has to be initialized. |
Example |
char buffer; ... buffer = SPI_Ethernet_getByte(); // read a byte from ENC28J60 buffer |
SPI_Ethernet_getBytes
Prototype | void SPI_Ethernet_getBytes(unsigned char *ptr, unsigned int addr, unsigned int n); |
---|---|
Returns | Nothing. |
Description | This is MAC module routine. It fetches equested number of bytes from ENC28J60 RAM starting from given address. If value of 0xFFFF is passed as the address parameter, the reading will start from current ENC28J60 read pointer (ERDPT ) location.Parameters:
|
Requires | Ethernet module has to be initialized. |
Example |
char buffer[16]; ... SPI_Ethernet_getBytes(buffer, 0x100, 16); // read 16 bytes, starting from address 0x100 |
SPI_Ethernet_UserTCP
Prototype | unsigned int SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags); |
---|---|
Returns |
|
Description | This is TCP module routine. It is internally called by the library. The user accesses to the TCP/HTTP request by using some of the SPI_Ethernet_get routines. The user puts data in the transmit buffer by using some of the SPI_Ethernet_put routines. The function must return the length in bytes of the TCP/HTTP reply, or 0 if there is nothing to transmit. If there is no need to reply to the TCP/HTTP requests, just define this function with return(0) as a single statement. Parameters:
Note : The function source code is provided with appropriate example projects. The code should be adjusted by the user to achieve desired reply.
|
Requires | Ethernet module has to be initialized. |
Example | This function is internally called by the library and should not be called by the user’s code. |
SPI_Ethernet_UserUDP
Prototype | unsigned int SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags); |
---|---|
Returns |
|
Description | This is UDP module routine. It is internally called by the library. The user accesses to the UDP request by using some of the SPI_Ethernet_get routines. The user puts data in the transmit buffer by using some of the SPI_Ethernet_put routines. The function must return the length in bytes of the UDP reply, or 0 if nothing to transmit. If you don’t need to reply to the UDP requests, just define this function with a return(0) as single statement. Parameters:
|
Requires | Ethernet module has to be initialized. |
Example | This function is internally called by the library and should not be called by the user’s code. |
SPI_Ethernet_getIpAddress
Prototype | unsigned char * SPI_Ethernet_getIpAddress(); |
---|---|
Returns | Pointer to the global variable holding IP address. |
Description | This routine should be used when DHCP server is present on the network to fetch assigned IP address.
Note : User should always copy the IP address from the RAM location returned by this routine into it’s own IP address buffer. These locations should not be altered by the user in any case!
|
Requires | Ethernet module has to be initialized. Available for PIC18 family MCUs only. |
Example |
unsigned char ipAddr[4]; // user IP address buffer ... memcpy(ipAddr, SPI_Ethernet_getIpAddress(), 4); // fetch IP address |
SPI_Ethernet_getGwIpAddress
Prototype | unsigned char * SPI_Ethernet_getGwIpAddress(); |
---|---|
Returns | Pointer to the global variable holding gateway IP address. |
Description | This routine should be used when DHCP server is present on the network to fetch assigned gateway IP address.
Note : User should always copy the IP address from the RAM location returned by this routine into it’s own gateway IP address buffer. These locations should not be altered by the user in any case!
|
Requires | Ethernet module has to be initialized. Available for PIC18 family MCUs only. |
Example |
unsigned char gwIpAddr[4]; // user gateway IP address buffer ... memcpy(gwIpAddr, SPI_Ethernet_getGwIpAddress(), 4); // fetch gateway IP address |
SPI_Ethernet_getDnsIpAddress
Prototype | unsigned char * SPI_Ethernet_getDnsIpAddress() |
---|---|
Returns | Pointer to the global variable holding DNS IP address. |
Description | his routine should be used when DHCP server is present on the network to fetch assigned DNS IP address.
Note : User should always copy the IP address from the RAM location returned by this routine into it’s own DNS IP address buffer. These locations should not be altered by the user in any case!
|
Requires | Ethernet module has to be initialized. Available for PIC18 family MCUs only. |
Example |
unsigned char dnsIpAddr[4]; // user DNS IP address buffer ... memcpy(dnsIpAddr, SPI_Ethernet_getDnsIpAddress(), 4); // fetch DNS server address |
SPI_Ethernet_getIpMask
Prototype | unsigned char * SPI_Ethernet_getIpMask() |
---|---|
Returns | Pointer to the global variable holding IP subnet mask. |
Description | This routine should be used when DHCP server is present on the network to fetch assigned IP subnet mask.
Note : User should always copy the IP address from the RAM location returned by this routine into it’s own IP subnet mask buffer. These locations should not be altered by the user in any case!
|
Requires | Ethernet module has to be initialized. Available for PIC18 family MCUs only. |
Example |
unsigned char IpMask[4]; // user IP subnet mask buffer ... memcpy(IpMask, SPI_Ethernet_getIpMask(), 4); // fetch IP subnet mask |
SPI_Ethernet_confNetwork
Prototype | void SPI_Ethernet_confNetwork(char *ipMask, char *gwIpAddr, char *dnsIpAddr); |
---|---|
Returns | Nothing. |
Description | Configures network parameters (IP subnet mask, gateway IP address, DNS IP address) when DHCP is not used. Parameters:
|
For more detail: Connect Ethernet controller with PIC Code
JLCPCB: Prototype 10 PCBs for $2 (2-layer,100*100mm)
China’s Largest PCB Prototype Manufacturer, 290,000+ Customers & 8,000+ Online Orders Per Day
PCB Pricing: https://jlcpcb.com/quote
Current Project / Post can also be found using:
- ethernet pic
- SPI_Ethernet_UserUDP