SPI Ethernet Library

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 8051 MCU with integrated SPI and more than 4 Kb ROM memory.

SPI Ethernet library supports:

Notes:

External dependencies of SPI Ethernet Library

The following variables must be defined in all projects using SPI Ethernet Library: Description: Examples :
dim SPI_Ethernet_CS as sbit bdata sfr external
ENC28J60 chip select pin.
dim SPI_Ethernet_CS as sbit at P1_1_bit
dim SPI_Ethernet_RST as sbit bdata sfr external
ENC28J60 reset pin.
dim SPI_Ethernet_RST as sbit at P1_0_bit
The following routines must be defined in all project using SPI Ethernet Library: Description: Examples :
sub function SPI_Ethernet_UserTCP(dim remoteHost as ^byte,
                                  dim remotePort as word,
                                  dim localPort as word,
                                  dim reqLength as word) as word
TCP request handler.
Refer to the library example at the bottom of this page 
		for code implementation.
sub function SPI_Ethernet_UserUDP(dim remoteHost as ^byte,
                              dim remotePort as word,
                              dim destPort as word,
                              dim reqLength as word) as word
UDP request handler.
Refer to the library example at the bottom of this page 
		for code implementation.

Library Routines

These routines are private and used by the compiler only :

SPI_Ethernet_Init

Prototype

sub procedure SPI_Ethernet_Init(dim mac as ^byte, dim ip as ^byte, dim fullDuplex as byte)

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):

  • receive buffer start address : 0x0000.
  • receive buffer end address : 0x19AD.
  • transmit buffer start address: 0x19AE.
  • transmit buffer end address : 0x1FFF.
  • RAM buffer read/write pointers in auto-increment mode.
  • receive filters set to default: CRC + MAC Unicast + MAC Broadcast in OR mode.
  • flow control with TX and RX pause frames in full duplex mode.
  • frames are padded to 60 bytes + CRC.
  • maximum packet size is set to 1518.
  • Back-to-Back Inter-Packet Gap: 0x15 in full duplex mode; 0x12 in half duplex mode.
  • Non-Back-to-Back Inter-Packet Gap: 0x0012 in full duplex mode; 0x0C12 in half duplex mode.
  • Collision window is set to 63 in half duplex mode to accomodate some ENC28J60 revisions silicon bugs.
  • CLKOUT output is disabled to reduce EMI generation.
  • half duplex loopback disabled.
  • LED configuration: default (LEDA-link status, LEDB-link activity).

Parameters:

  • mac: RAM buffer containing valid MAC address.
  • ip: RAM buffer containing valid IP address.
  • fullDuplex: ethernet duplex mode switch. Valid values: 0 (half duplex mode) and 1 (full duplex mode).
Requires

The appropriate hardware SPI module must be previously initialized.

Example
const SPI_Ethernet_HALFDUPLEX = 0;
const SPI_Ethernet_FULLDUPLEX = 1;


  myMacAddr as byte[6] ' my MAC address	
  myIpAddr  as byte[4] ' my IP addr
  ...
  myMacAddr[0] = 0x00
  myMacAddr[1] = 0x14
  myMacAddr[2] = 0xA5
  myMacAddr[3] = 0x76
  myMacAddr[4] = 0x19
  myMacAddr[5] = 0x3F

  myIpAddr[0]  = 192
  myIpAddr[1]  = 168
  myIpAddr[2]  = 20
  myIpAddr[3]  = 60
  
  SPI1_Init()	
  SPI_Ethernet_Init(myMacAddr, myIpAddr, SPI_Ethernet_FULLDUPLEX)

SPI_Ethernet_Enable

Prototype

sub procedure SPI_Ethernet_Enable(dim enFlt as byte)

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:

  • enFlt: network traffic/receive filter flags. Each bit corresponds to the appropriate network traffic/receive filter:
  • Bit Mask Description Predefined library const
    0 0x01 MAC Broadcast traffic/receive filter flag. When set, MAC broadcast traffic will be enabled. _SPI_Ethernet_BROADCAST
    1 0x02 MAC Multicast traffic/receive filter flag. When set, MAC multicast traffic will be enabled. _SPI_Ethernet_MULTICAST
    2 0x04 not used none
    3 0x08 not used none
    4 0x10 not used none
    5 0x20 CRC check flag. When set, packets with invalid CRC field will be discarded. _SPI_Ethernet_CRC
    6 0x40 not used none
    7 0x80 MAC Unicast traffic/receive filter flag. When set, MAC unicast traffic will be enabled. _SPI_Ethernet_UNICAST

    Note: Advanced filtering available in the ENC28J60 module such as Pattern Match, Magic Packet and Hash Table can not be enabled by this routine. Additionaly, all filters, except CRC, enabled with this routine will work in OR mode, which means that packet will be received if any of the enabled filters accepts it.

    Note: This routine will change receive filter configuration on-the-fly. It will not, in any way, mess with enabling/disabling receive/transmit logic or any other part of the ENC28J60 module. The ENC28J60 module should be properly cofigured by the means of SPI_Ethernet_Init routine.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
SPI_Ethernet_Enable(_SPI_Ethernet_CRC or _SPI_Ethernet_UNICAST) ' enable CRC checking and Unicast traffic

SPI_Ethernet_Disable

Prototype

sub procedure SPI_Ethernet_Disable(dim disFlt as byte)

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:

  • disFlt: network traffic/receive filter flags. Each bit corresponds to the appropriate network traffic/receive filter:
  • Bit Mask Description Predefined library const
    0 0x01 MAC Broadcast traffic/receive filter flag. When set, MAC broadcast traffic will be disabled. _SPI_Ethernet_BROADCAST
    1 0x02 MAC Multicast traffic/receive filter flag. When set, MAC multicast traffic will be disabled. _SPI_Ethernet_MULTICAST
    2 0x04 not used none
    3 0x08 not used none
    4 0x10 not used none
    5 0x20 CRC check flag. When set, CRC check will be disabled and packets with invalid CRC field will be accepted. _SPI_Ethernet_CRC
    6 0x40 not used none
    7 0x80 MAC Unicast traffic/receive filter flag. When set, MAC unicast traffic will be disabled. _SPI_Ethernet_UNICAST

    Note: Advanced filtering available in the ENC28J60 module such as Pattern Match, Magic Packet and Hash Table can not be disabled by this routine.

    Note: This routine will change receive filter configuration on-the-fly. It will not, in any way, mess with enabling/disabling receive/transmit logic or any other part of the ENC28J60 module. The ENC28J60 module should be properly cofigured by the means of SPI_Ethernet_Init routine.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
SPI_Ethernet_Disable(_SPI_Ethernet_CRC or _SPI_Ethernet_UNICAST) ' disable CRC checking and Unicast traffic

SPI_Ethernet_doPacket

Prototype

sub function SPI_Ethernet_doPacket() as byte

Returns

  • 0 - upon successful packet processing (zero packets received or received packet processed successfully).
  • 1 - upon reception error or receive buffer corruption. ENC28J60 controller needs to be restarted.
  • 2 - received packet was not sent to us (not our IP, nor IP broadcast address).
  • 3 - received IP packet was not IPv4.
  • 4 - received packet was of type unknown to the library.

Description

This is MAC module routine. It processes next received packet if such exists. Packets are processed in the following manner:

  • ARP & ICMP requests are replied automatically.
  • upon TCP request the SPI_Ethernet_UserTCP function is called for further processing.
  • upon UDP request the SPI_Ethernet_UserUDP function is called for further processing.

Note: SPI_Ethernet_doPacket must be called as often as possible in user's code.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
while TRUE
  ...
  SPI_Ethernet_doPacket() ' process received packets
  ...  
wend

SPI_Ethernet_putByte

Prototype

sub procedure SPI_Ethernet_putByte(dim v as byte)

Returns

Nothing.

Description

This is MAC module routine. It stores one byte to address pointed by the current ENC28J60 write pointer (EWRPT).

Parameters:

  • v: value to store
Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
dim data as byte
...
SPI_Ethernet_putByte(data) ' put an byte into ENC28J60 buffer

SPI_Ethernet_putBytes

Prototype

sub procedure SPI_Ethernet_putBytes(dim ptr as ^byte, dim n as byte)

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:

  • ptr: RAM buffer containing bytes to be written into ENC28J60 RAM.
  • n: number of bytes to be written.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
dim 
  buffer as byte[17]	 
  ...
  buffer = "mikroElektronika"	 
  ...
  SPI_Ethernet_putBytes(buffer, 16) ' put an RAM array into ENC28J60 buffer

SPI_Ethernet_putConstBytes

Prototype

sub procedure SPI_Ethernet_putConstBytes(const ptr as ^byte, dim n as byte)

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:

  • ptr: const buffer containing bytes to be written into ENC28J60 RAM.
  • n: number of bytes to be written.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
const 
  buffer as byte[17]	 
  ...
  buffer = "mikroElektronika"	 
  ...
  SPI_Ethernet_putConstBytes(buffer, 16) ' put a const array into ENC28J60 buffer

SPI_Ethernet_putString

Prototype

sub function SPI_Ethernet_putString(dim ptr as ^byte) as word

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:

  • ptr: string to be written into ENC28J60 RAM.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
dim 
  buffer as string[16]	 
  ...
  buffer = "mikroElektronika"	 
  ...
  SPI_Ethernet_putString(buffer) ' put a RAM string into ENC28J60 buffer

SPI_Ethernet_putConstString

Prototype

sub function SPI_Ethernet_putConstString(const ptr as ^byte) as word

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:

  • ptr: const string to be written into ENC28J60 RAM.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
const 
  buffer as string[16]	 
  ...
  buffer = "mikroElektronika"	 
  ...
  SPI_Ethernet_putConstString(buffer) ' put a const string into ENC28J60 buffer

SPI_Ethernet_getByte

Prototype

sub function SPI_Ethernet_getByte() as byte

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. See SPI_Ethernet_Init.

Example
dim buffer as byte<> 
...
buffer = SPI_Ethernet_getByte() ' read a byte from ENC28J60 buffer

SPI_Ethernet_getBytes

Prototype

sub procedure SPI_Ethernet_getBytes(dim ptr as ^byte, dim addr as word, dim n as byte)

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:

  • ptr: buffer for storing bytes read from ENC28J60 RAM.
  • addr: ENC28J60 RAM start address. Valid values: 0..8192.
  • n: number of bytes to be read.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_Init.

Example
dim 
  buffer as byte[16] 
  ...
  SPI_Ethernet_getBytes(buffer, 0x100, 16) ' read 16 bytes, starting from address 0x100

SPI_Ethernet_UserTCP

Prototype

sub function SPI_Ethernet_UserTCP(dim remoteHost as ^byte, dim remotePort as word, dim localPort as word, dim reqLength as word) as word

Returns

  • 0 - there should not be a reply to the request.
  • Length of TCP/HTTP reply data field - otherwise.

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:

  • remoteHost: client's IP address.
  • remotePort: client's TCP port.
  • localPort: port to which the request is sent.
  • reqLength: TCP/HTTP request data field length.

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. See SPI_Ethernet_Init.

Example

This function is internally called by the library and should not be called by the user's code.

SPI_Ethernet_UserUDP

Prototype

sub function SPI_Ethernet_UserUDP(dim remoteHost as ^byte, dim remotePort as word, dim destPort as word, dim reqLength as word) as word

Returns

  • 0 - there should not be a reply to the request.
  • Length of UDP reply data field - otherwise.

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:

  • remoteHost: client's IP address.
  • remotePort: client's port.
  • destPort: port to which the request is sent.
  • reqLength: UDP request data field length.

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. See SPI_Ethernet_Init.

Example

This function is internally called by the library and should not be called by the user's code.

Library Example

This code shows how to use the 8051 mini Ethernet library :


HW Connection

SPI Ethernet Connection Scheme

Copyright (c) 2002-2013 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code