SPI Ethernet ENC24J600 Library

The ENC24J600 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 ENC24J600 meets all of the IEEE 802.3 specifications applicable to 10Base-T and 100Base-TX Ethernet. It incorporates a number of packet filtering schemes to limit incoming packets. It also provides an internal, 16-bit wide 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 10/100 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 (ENC24J600). It works with any ARM 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 ARM should be clocked by ENC24J600 clock output due to its silicon bug in SPI hardware. If you try lower ARM clock speed, there might be board hang or miss some requests.

SPI Ethernet ENC24J600 library supports:

  Important :

Library Dependency Tree

SPI Ethernet ENC24J600 Library Dependency Tree

External dependencies of SPI Ethernet ENC24J600 Library

Stellaris

The following variables must be defined in all projects using SPI Ethernet ENC24J600 Library: Description: Examples :
dim SPI_Ethernet_24j600_CS as sbit sfr external ENC24J600 chip select pin. dim SPI_Ethernet_24j600_CS as sbit at GPIO_PORTA_DATA.B1
dim SPI_Ethernet_24j600_CS_Direction as sbit sfr external Direction of the ENC24J600 chip select pin. dim SPI_Ethernet_24j600_CS_Direction as sbit at GPIO_PORTA_DIR.B1

STM32

The following variables must be defined in all projects using SPI Ethernet ENC24J600 Library: Description: Examples :
dim SPI_Ethernet_24j600_CS as sbit sfr external ENC24J600 chip select pin. dim SPI_Ethernet_24j600_CS as sbit at GPIOB_ODR.B1

The following routines must be defined in all project using SPI Ethernet ENC24J600 Library: Description: Examples :
sub function SPI_Ethernet_24j600_UserTCP(dim byref remoteHost as byte[4],
                                  dim remotePort as word,
                                  dim localPort as word,
                                  dim reqLength as word,
                                  dim byref flags as TEthj600PktFlags) as word
TCP request handler.
Refer to the library example at the bottom of this page 
		for code implementation.
sub function SPI_Ethernet_24j600_UserUDP(dim byref remoteHost as byte[4],
                              dim remotePort as word,
                              dim destPort as word,
                              dim reqLength as word, 
                              dim byref flags as TEthJ600PktFlags) as word
UDP request handler.
Refer to the library example at the bottom of this page  for code implementation.

Library Routines

SPI_Ethernet_24j600_Init

Prototype

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

Description

This is MAC module routine. It initializes ENC24J600 controller. This function is internaly splited into 2 parts to help linker when coming short of memory.

ENC24J600 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 ENC24J600 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.
  • configuration: ethernet negotiation, duplex and speed mode settings. For this purpose, predefined library constants (see the list below) can be combined using logical AND to form appropriate value :
  • Description Predefined library const
    Set Auto-negotiation SPI_Ethernet_24j600_AUTO_NEGOTIATION
    Set manual negotiation. SPI_Ethernet_24j600_MANUAL_NEGOTIATION
    Set Half duplex Mode SPI_Ethernet_24j600_HALFDUPLEX
    Set Full duplex Mode SPI_Ethernet_24j600_FULLDUPLEX
    Set transmission speed of 10Mbps SPI_Ethernet_24j600_SPD10
    Set transmission speed of 100Mbps SPI_Ethernet_24j600_SPD100
  Note :
  • It is advisable to use only the Auto-negotiation setting. If manual negotiation is used, then duplex and speed mode setting must be set also.
  • Duplex and speed mode may be set only when using manual negotiation.
Returns

Nothing.

Requires

External dependencies of the library from the top of the page must be defined before using this function.
The SPI module needs to be initialized. See the SPIx_Init and SPIx_Init_Advanced routines.

Example

Stellaris

' mE ehternet NIC pinout
dim
  SPI_Ethernet_24j600_CS  as sbit at GPIO_PORTA_DATA.B1
  SPI_Ethernet_24j600_CS_Direction as sbit at GPIO_PORTA_DIR.B1
' end ethernet NIC definitions

  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_24j600_Init(myMacAddr, myIpAddr, SPI_Ethernet_24j600_MANUAL_NEGOTIATION and SPI_Ethernet_24j600_FULLDUPLEX and SPI_Ethernet_24j600_SPD100)

STM32

' mE ehternet NIC pinout
dim
  SPI_Ethernet_24j600_CS  as sbit at GPIOB_ODR.B1
' end ethernet NIC definitions

  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_24j600_Init(myMacAddr, myIpAddr, SPI_Ethernet_24j600_MANUAL_NEGOTIATION and SPI_Ethernet_24j600_FULLDUPLEX and SPI_Ethernet_24j600_SPD100)
Notes

None.

SPI_Ethernet_24j600_Enable

Prototype

sub procedure SPI_Ethernet_24j600_Enable(dim enFlt as word)

Description

This is MAC module routine. This routine enables appropriate network traffic on the ENC24J600 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.

Advanced filtering available in the ENC24J600 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.

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 ENC24J600 module. The ENC24J600 module should be properly cofigured by the means of SPI_Ethernet_24j600_Init routine.

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_24j600_BROADCAST
    1 0x02 MAC Multicast traffic/receive filter flag. When set, MAC multicast traffic will be enabled. _SPI_Ethernet_24j600_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_24j600_CRC
    6 0x40 not used none
    7 0x80 MAC Unicast traffic/receive filter flag. When set, MAC unicast traffic will be enabled. _SPI_Ethernet_24j600_UNICAST
Returns

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
SPI_Ethernet_24j600_Enable(_SPI_Ethernet_24j600_CRC or _SPI_Ethernet_24j600_UNICAST) ' enable CRC checking and Unicast traffic
Notes

Advanced filtering available in the ENC24J600 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.

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 ENC24J600 module. The ENC24J600 module should be properly cofigured by the means of SPI_Ethernet_24j600_Init routine.

SPI_Ethernet_24j600_Disable

Prototype

sub procedure SPI_Ethernet_24j600_Disable(dim disFlt as word)

Description

This is MAC module routine. This routine disables appropriate network traffic on the ENC24J600 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_24j600_BROADCAST
    1 0x02 MAC Multicast traffic/receive filter flag. When set, MAC multicast traffic will be disabled. _SPI_Ethernet_24j600_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_24j600_CRC
    6 0x40 not used none
    7 0x80 MAC Unicast traffic/receive filter flag. When set, MAC unicast traffic will be disabled. _SPI_Ethernet_24j600_UNICAST
Returns

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
SPI_Ethernet_24j600_Disable(_SPI_Ethernet_24j600_CRC or _SPI_Ethernet_24j600_UNICAST) ' disable CRC checking and Unicast traffic
Notes

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

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 ENC24J600 module. The ENC24J600 module should be properly cofigured by the means of SPI_Ethernet_24j600_Init routine.

The ENC24J600 module should be properly cofigured by the means of SPI_Ethernet_24j600_Init routine.

SPI_Ethernet_24j600_doPacket

Prototype

sub function SPI_Ethernet_24j600_doPacket() as byte

Description

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

Parameters

None.

Returns
  • 0 - upon successful packet processing (zero packets received or received packet processed successfully).
  • 1 - upon reception error or receive buffer corruption. ENC24J600 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.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
while TRUE
  ...
  SPI_Ethernet_24j600_doPacket() ' process received packets
  ...  
wend
Notes

SPI_Ethernet_24j600_doPacket must be called as often as possible in user's code.

SPI_Ethernet_24j600_putByte

Prototype

sub procedure SPI_Ethernet_24j600_putByte(dim v as byte)

Description

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

Parameters
  • v: value to store
Returns

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim data as byte
...
SPI_Ethernet_24j600_putByte(data) ' put an byte into ENC24J600 buffer
Notes

None.

SPI_Ethernet_24j600_putBytes

Prototype

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

Description

This is MAC module routine. It stores requested number of bytes into ENC24J600 RAM starting from current ENC24J600 write pointer (EWRPT) location.

Parameters
  • ptr: RAM buffer containing bytes to be written into ENC24J600 RAM.
  • n: number of bytes to be written.
Returns

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

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

None.

SPI_Ethernet_24j600_putConstBytes

Prototype

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

Description

This is MAC module routine. It stores requested number of const bytes into ENC24J600 RAM starting from current ENC24J600 write pointer (EWRPT) location.

Parameters
  • ptr: const buffer containing bytes to be written into ENC24J600 RAM.
  • n: number of bytes to be written.
Returns

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

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

None.

SPI_Ethernet_24j600_putString

Prototype

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

Description

This is MAC module routine. It stores whole string (excluding null termination) into ENC24J600 RAM starting from current ENC24J600 write pointer (EWRPT) location.

Parameters
  • ptr: string to be written into ENC24J600 RAM.
Returns

Number of bytes written into ENC24J600 RAM.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  buffer as string[16]	 
  ...
  buffer = "mikroElektronika"	 
  ...
  SPI_Ethernet_24j600_putString(buffer) ' put a RAM string into ENC24J600 buffer
Notes

None.

SPI_Ethernet_24j600_putConstString

Prototype

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

Description

This is MAC module routine. It stores whole const string (excluding null termination) into ENC24J600 RAM starting from current ENC24J600 write pointer (EWRPT) location.

Parameters
  • ptr: const string to be written into ENC24J600 RAM.
Returns

Number of bytes written into ENC24J600 RAM.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
const 
  buffer as string[16]	 
  ...
  buffer = "mikroElektronika"	 
  ...
  SPI_Ethernet_24j600_putConstString(buffer) ' put a const string into ENC24J600 buffer
Notes

None.

SPI_Ethernet_24j600_getByte

Prototype

sub function SPI_Ethernet_24j600_getByte() as byte

Description

This is MAC module routine. It fetches a byte from address pointed to by current ENC24J600 read pointer (ERDPT).

Parameters

None.

Returns

Byte read from ENC24J600 RAM.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim buffer as byte<> 
...
buffer = SPI_Ethernet_24j600_getByte() ' read a byte from ENC24J600 buffer
Notes

None.

SPI_Ethernet_24j600_getBytes

Prototype

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

Description

This is MAC module routine. It fetches equested number of bytes from ENC24J600 RAM starting from given address. If value of 0xFFFF is passed as the address parameter, the reading will start from current ENC24J600 read pointer (ERDPT) location.

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

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

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

None.

SPI_Ethernet_24j600_UserTCP

Prototype

sub function SPI_Ethernet_24j600_UserTCP(dim byref remoteHost as byte[4], dim remotePort as word, dim localPort as word, dim reqLength as word, dim byref flags as TEthJ600PktFlags) as word

Description

This is TCP module routine. It is internally called by the library. The user accesses to the TCP request by using some of the SPI_Ethernet_24j600_get routines. The user puts data in the transmit buffer by using some of the SPI_Ethernet_24j600_put routines. The function must return the length in bytes of the TCP reply, or 0 if there is nothing to transmit. If there is no need to reply to the TCP 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 request data field length.
  • flags: structure consisted of two fields :
    structure TEthj600PktFlags
      dim canCloseTCP as boolean  ' flag which closes socket
      dim isBroadcast as boolean  ' flag which denotes that the IP package has been received via subnet broadcast address
    end structure
    
Returns
  • 0 - there should not be a reply to the request.
  • Length of TCP reply data field - otherwise.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example

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

Notes

The function source code is provided with appropriate example projects. The code should be adjusted by the user to achieve desired reply.

SPI_Ethernet_24j600_UserUDP

Prototype

sub function SPI_Ethernet_24j600_UserUDP(dim byref remoteHost as byte[4], dim remotePort as word, dim destPort as word, dim reqLength as word, dim byref flags as TEthJ600PktFlags) as word

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_24j600_get routines. The user puts data in the transmit buffer by using some of the SPI_Ethernet_24j600_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.
  • flags: structure consisted of two fields :
    structure TEthj600PktFlags
      dim canCloseTCP as boolean  ' flag which closes socket (not relevant to UDP)
      dim isBroadcast as boolean  ' flag which denotes that the IP package has been received via subnet broadcast address
    end structure
    
Returns
  • 0 - there should not be a reply to the request.
  • Length of UDP reply data field - otherwise.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example

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

Notes

The function source code is provided with appropriate example projects. The code should be adjusted by the user to achieve desired reply.

SPI_Ethernet_24j600_setUserHandlers

Prototype

sub procedure SPI_Ethernet_24j600_setUserHandlers(dim TCPHandler as ^TSPI_Ethernet_24j600_UserTCP, dim UDPHandler as ^TSPI_Ethernet_24j600_UserUDP)

Description

Sets pointers to User TCP and UDP handler function implementations, which are automatically called by SPI Ethernet ENC24J600 library.

Parameters
  • TCPHandler: TCP request handler
  • UDPHandler: UDP request handler.
Returns

Nothing.

Requires

SPI_Ethernet_24j600_UserTCP and SPI_Ethernet_24j600_UserUDP have to be previously defined.

Example
SPI_Ethernet_24j600_setUserHandlers(@SPI_Ethernet_24j600_UserTCP, @SPI_Ethernet_24j600_UserUDP)
Notes

Since all libraries are built for SSA, SSA restrictions regarding function pointers dictate that modules that use SPI_Ethernet_24j600_setUserHandlers must also be built for SSA.

SPI_Ethernet_24j600_getIpAddress

Prototype

sub function SPI_Ethernet_24j600_getIpAddress() as ^byte

Description

This routine should be used when DHCP server is present on the network to fetch assigned IP address.

Parameters

None.

Returns

Pointer to the global variable holding IP address.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  ipAddr as byte[4]  ' user IP address buffer
  ...	
  memcpy(ipAddr, SPI_Ethernet_24j600_getIpAddress(), 4)  ' fetch IP address
Notes

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!

SPI_Ethernet_24j600_getGwIpAddress

Prototype

sub function SPI_Ethernet_24j600_getGwIpAddress() as ^byte

Description

This routine should be used when DHCP server is present on the network to fetch assigned gateway IP address.

Parameters

None.

Returns

Pointer to the global variable holding gateway IP address.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  gwIpAddr as byte[4]  ' user gateway IP address buffer
  ...	
  memcpy(gwIpAddr, SPI_Ethernet_24j600_getGwIpAddress(), 4)  ' fetch gateway IP address 
Notes

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!

SPI_Ethernet_24j600_getDnsIpAddress

Prototype

sub function SPI_Ethernet_24j600_getDnsIpAddress() as ^byte

Description

This routine should be used when DHCP server is present on the network to fetch assigned DNS IP address.

Parameters

None.

Returns

Pointer to the global variable holding DNS IP address.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  dnsIpAddr as byte[4]  ' user DNS IP address buffer
  ...	
  memcpy(dnsIpAddr, SPI_Ethernet_24j600_getDnsIpAddress(), 4)  ' fetch DNS server address 
Notes

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!

SPI_Ethernet_24j600_getIpMask

Prototype

sub function SPI_Ethernet_24j600_getIpMask() as ^byte

Description

This routine should be used when DHCP server is present on the network to fetch assigned IP subnet mask.

Parameters

None.

Returns

Pointer to the global variable holding IP subnet mask.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  IpMask as byte[4]  ' user IP subnet mask buffer
  ...	
  memcpy(IpMask, SPI_Ethernet_24j600_getIpMask(), 4)  ' fetch IP subnet mask
Notes

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!

SPI_Ethernet_24j600_confNetwork

Prototype

sub procedure SPI_Ethernet_24j600_confNetwork(dim byref ipMask, gwIpAddr, dnsIpAddr as byte[4])

Description

Configures network parameters (IP subnet mask, gateway IP address, DNS IP address) when DHCP is not used.

Parameters
  • ipMask: IP subnet mask.
  • gwIpAddr gateway IP address.
  • dnsIpAddr: DNS IP address.
Returns

Nothing.

Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  ipMask    as byte[4]  ' network mask (for example : 255.255.255.0)
  gwIpAddr  as byte[4]  ' gateway (router) IP address
  dnsIpAddr as byte[4]  ' DNS server IP address
  ...	
  gwIpAddr[0]  = 192
  gwIpAddr[1]  = 168
  gwIpAddr[2]  = 20
  gwIpAddr[3]  = 6

  dnsIpAddr[0] = 192
  dnsIpAddr[1] = 168
  dnsIpAddr[2] = 20
  dnsIpAddr[3] = 100

  ipMask[0]    = 255
  ipMask[1]    = 255
  ipMask[2]    = 255
  ipMask[3]    = 0
  ...
  SPI_Ethernet_24j600_confNetwork(ipMask, gwIpAddr, dnsIpAddr) ' set network configuration parameters
Notes

The above mentioned network parameters should be set by this routine only if DHCP module is not used. Otherwise DHCP will override these settings.

SPI_Ethernet_24j600_arpResolve

Prototype

sub function SPI_Ethernet_24j600_arpResolve(dim byref ip as byte[4], dim tmax as byte) as ^byte

Description

This is ARP module routine. It sends an ARP request for given IP address and waits for ARP reply. If the requested IP address was resolved, an ARP cash entry is used for storing the configuration. ARP cash can store up to 3 entries.

Parameters
  • ip: IP address to be resolved.
  • tmax: time in seconds to wait for an reply.
Returns
  • MAC address behind the IP address - the requested IP address was resolved.
  • 0 - otherwise.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  IpAddr as byte[4]  ' IP address
  ...	
  IpAddr[0] = 192 
  IpAddr[0] = 168 
  IpAddr[0] = 1 
  IpAddr[0] = 1 
  ...
  SPI_Ethernet_24j600_arpResolve(IpAddr, 5) ' get MAC address behind the above IP address, wait 5 secs for the response
Notes

The Ethernet services are not stopped while this routine waits for ARP reply. The incoming packets will be processed normaly during this time.

SPI_Ethernet_24j600_sendUDP

Prototype

sub function SPI_Ethernet_24j600_sendUDP(dim byref destIP as byte[4], dim sourcePort, destPort as word, dim pkt as ^byte, dim pktLen as word) as byte

Description

This is UDP module routine. It sends an UDP packet on the network.

Parameters
  • destIP: remote host IP address.
  • sourcePort: local UDP source port number.
  • destPort: destination UDP port number.
  • pkt: packet to transmit.
  • pktLen: length in bytes of packet to transmit.
Returns
  • 1 - UDP packet was sent successfully.
  • 0 - otherwise.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  IpAddr as byte[4]  ' remote IP address
  ...	
  IpAddr[0] = 192 
  IpAddr[0] = 168 
  IpAddr[0] = 1 
  IpAddr[0] = 1 
  ...
  SPI_Ethernet_24j600_sendUDP(IpAddr, 10001, 10001, "Hello", 5) ' send Hello message to the above IP address, from UDP port 10001 to UDP port 10001 
Notes

None.

SPI_Ethernet_24j600_dnsResolve

Prototype

sub function SPI_Ethernet_24j600_dnsResolve(dim byref host as string, dim tmax as byte) as ^byte

Description

This is DNS module routine. It sends an DNS request for given host name and waits for DNS reply. If the requested host name was resolved, it's IP address is stored in library global variable and a pointer containing this address is returned by the routine. UDP port 53 is used as DNS port.

Parameters
  • host: host name to be resolved.
  • tmax: time in seconds to wait for an reply.
Returns
  • pointer to the location holding the IP address - the requested host name was resolved.
  • 0 - otherwise.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
dim 
  remoteHostIpAddr as string	' user host IP address buffer
  ...
  ' SNTP server:
  ' Zurich, Switzerland: Integrated Systems Lab, Swiss Fed. Inst. of Technology
  ' 129.132.2.21: swisstime.ethz.ch
  ' Service Area: Switzerland and Europe	
  memcpy(remoteHostIpAddr, SPI_Ethernet_24j600_dnsResolve("swisstime.ethz.ch", 5), 4) 
Notes

The Ethernet services are not stopped while this routine waits for DNS reply. The incoming packets will be processed normaly during this time.

User should always copy the IP address from the RAM location returned by this routine into it's own resolved host IP address buffer. These locations should not be altered by the user in any case!

SPI_Ethernet_24j600_initDHCP

Prototype

sub function SPI_Ethernet_24j600_initDHCP(dim tmax as byte) as byte

Description

This is DHCP module routine. It sends an DHCP request for network parameters (IP, gateway, DNS addresses and IP subnet mask) and waits for DHCP reply. If the requested parameters were obtained successfully, their values are stored into the library global variables.

These parameters can be fetched by using appropriate library IP get routines:

UDP port 68 is used as DHCP client port and UDP port 67 is used as DHCP server port.

Parameters
  • tmax: time in seconds to wait for an reply.
Returns
  • 1 - network parameters were obtained successfully.
  • 0 - otherwise.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
  ...	
  SPI_Ethernet_24j600_initDHCP(5) ' get network configuration from DHCP server, wait 5 sec for the response 
  ...
Notes

The Ethernet services are not stopped while this routine waits for DNS reply. The incoming packets will be processed normaly during this time.

When DHCP module is used, global library variable SPI_Ethernet_24j600_userTimerSec is used to keep track of time. It is user responsibility to increment this variable each second in it's code.

SPI_Ethernet_24j600_doDHCPLeaseTime

Prototype

sub function SPI_Ethernet_24j600_doDHCPLeaseTime() as byte

Description

This is DHCP module routine. It takes care of IP address lease time by decrementing the global lease time library counter. When this time expires, it's time to contact DHCP server and renew the lease.

Parameters

None.

Returns
  • 0 - lease time has not expired yet.
  • 1 - lease time has expired, it's time to renew it.
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
while true
  ...
  if(SPI_Ethernet_24j600_doDHCPLeaseTime() <> 0) then
    ... ' it's time to renew the IP address lease                  
  end if  
wend
Notes

None.

SPI_Ethernet_24j600_renewDHCP

Prototype

sub function SPI_Ethernet_24j600_renewDHCP(dim tmax as byte) as byte

Description

This is DHCP module routine. It sends IP address lease time renewal request to DHCP server.

Parameters
  • tmax: time in seconds to wait for an reply.
Returns
  • 1 - upon success (lease time was renewed).
  • 0 - otherwise (renewal request timed out).
Requires

Ethernet module has to be initialized. See SPI_Ethernet_24j600_Init.

Example
while true 
  ...
  if(SPI_Ethernet_24j600_doDHCPLeaseTime() <> 0) then
    SPI_Ethernet_24j600_renewDHCP(5)  ' it's time to renew the IP address lease, with 5 secs for a reply                  
  end if 
  ...  
wend
Notes

None.

Library Example

This code shows how to use the Ethernet mini library :

Stellaris

program HTTP_Demo

' ***********************************
' * RAM variables
' *

' mE ehternet NIC pinout
dim
  SPI_Ethernet_24j600_CS  as sbit at GPIO_PORTA_DATA.B1
  SPI_Ethernet_24j600_CS_Direction as sbit at GPIO_PORTA_DIR.B1
' end ethernet NIC definitions

dim myMacAddr   as byte[6]   ' my MAC address
    myIpAddr    as byte[4]   ' my IP address
    gwIpAddr    as byte[4]   ' gateway (router) IP address
    ipMask      as byte[4]   ' network mask (for example : 255.255.255.0)
    dnsIpAddr   as byte[4]   ' DNS server IP address

' ************************************************************
' * ROM constant strings
' *
const httpHeader as string[31]         = "HTTP/1.1 200 OK"+chr(10)+"Content-type: "  ' HTTP header
const httpMimeTypeHTML as string[13]   = "text/html"+chr(10)+chr(10)                 ' HTML MIME type
const httpMimeTypeScript as string[14] = "text/plain"+chr(10)+chr(10)                ' TEXT MIME type
const httpMethod as string[5]          = "GET /"
' *
' * web page, splited into 2 parts :
' * when coming short of ROM, fragmented data is handled more efficiently by linker
' *
' * this HTML page calls the boards to get its status, and builds itself with javascript
' *
const indexPage as string[767] =
                    "<meta http-equiv=" + Chr(34) + "refresh"  + Chr(34) + " content="  + Chr(34) + "3;url=http://192.168.20.60"  + Chr(34) + ">" +
                    "<HTML><HEAD></HEAD><BODY>"+
                    "<h1>ARM + ENC24J600 Mini Web Server</h1>"+
                    "<a href=/>Reload</a>"+
                    "<script src=/s></script>"+
                    "<table><tr><td valign=top><table border=1 style="+chr(34)+"font-size:20px ;font-family: terminal ;"+chr(34)+"> "+
                    "<tr><th colspan=2>ADC</th></tr>"+
                    "<tr><td>AN0</td><td><script>document.write(AN0)</script></td></tr>"+
                    "</table></td><td><table border=1 style="+chr(34)+"font-size:20px ;font-family: terminal ;"+chr(34)+"> "+
                    "<tr><th colspan=2>GPIO_PORTH</th></tr>"+
                    "<script>"+
                    "var str,i;"+
                    "str="+chr(34)+chr(34)+"; "+
                    "for(i=0;i<8;i++)"+
                    "{str+="+chr(34)+"<tr><td bgcolor=pink>BUTTON #"+chr(34)+"+i+"+chr(34)+"</td>"+chr(34)+"; "+
                    "if(GPIO_PORTH&(1<<i)){str+="+chr(34)+"<td bgcolor=red>ON"+chr(34)+";}"+
                    "else {str+="+chr(34)+"<td bgcolor=#cccccc>OFF"+chr(34)+";}"+
                    "str+="+chr(34)+"</td></tr>"+chr(34)+";}"+
                    "document.write(str) ;"+
                    "</script>"

const indexPage2 as string[470] =
                    "</table></td><td>"+
                    "<table border=1 style="+chr(34)+"font-size:20px ;font-family: terminal ;"+chr(34)+"> "+
                    "<tr><th colspan=3>GPIO_PORTD</th></tr>"+
                    "<script>"+
                    "var str,i;"+
                    "str="+chr(34)+chr(34)+"; "+
                    "for(i=0;i<8;i++)"+
                    "{str+="+chr(34)+"<tr><td bgcolor=yellow>LED #"+chr(34)+"+i+"+chr(34)+"</td>"+chr(34)+"; "+
                    "if(GPIO_PORTD&(1<<i)){str+="+chr(34)+"<td bgcolor=red>ON"+chr(34)+";}"+
                    "else {str+="+chr(34)+"<td bgcolor=#cccccc>OFF"+chr(34)+";}"+
                    "str+="+chr(34)+"</td><td><a href=/t"+chr(34)+"+i+"+chr(34)+">Toggle</a></td></tr>"+chr(34)+";}"+
                    "document.write(str) ;"+
                    "</script>"+
                    "</table></td></tr></table>"+
                    "This is HTTP request #<script>document.write(REQ)</script></BODY></HTML>"

dim    getRequest  as byte[15]   ' HTTP request buffer
       dyna        as char[30]   ' buffer for dynamic response
       httpCounter as word       ' counter of HTTP requests
       txt         as string[11]

' *******************************************
' * user defined functions
' *

' *
' * this function is called by the library
' * the user accesses to the HTTP request by successive calls to Spi_Ethernet_getByte()
' * the user puts data in the transmit buffer by successive calls to Spi_Ethernet_putByte()
' * the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit
' *
' * if you don't need to reply to HTTP requests,
' * just define this function with a return(0) as single statement
' *
' *
sub function SPI_Ethernet_24j600_UserTCP(dim byref remoteHost as byte[4],
                              dim remotePort, localPort, reqLength as word, dim byref flags as TEthj600PktFlags) as word
  dim  i as word        ' my reply length
       bitMask as byte  ' for bit mask
       txt         as string[11]
    result = 0

    ' should we close tcp socket after response is sent?
    ' library closes tcp socket by default if canClose flag is not reset here
    '  canClose = 0 ' 0 - do not close socket
                    ' otherwise - close socket

    if(localPort <> 80) then          ' I listen only to web request on port 80
      result = 0
      exit
    end if

    ' get 10 first bytes only of the request, the rest does not matter here
    for i = 0 to 10
      getRequest[i] = SPI_Ethernet_24j600_getByte()
    next i

    getRequest[i] = 0

    ' copy httpMethod to ram for use in memcmp routine
    for i = 0 to 4
      txt[i] = httpMethod[i]
    next i

    if(memcmp(@getRequest, @txt, 5) <> 0) then  ' only GET method is supported here
      result = 0
      exit
    end if

    Inc(httpCounter)                           ' one more request done

    if(getRequest[5] = "s") then               ' if request path name starts with s, store dynamic data in transmit buffer
      ' the text string replied by this request can be interpreted as javascript statements
      ' by browsers

      result = SPI_Ethernet_24j600_putConstString(@httpHeader)                    ' HTTP header
      result = result + SPI_Ethernet_24j600_putConstString(@httpMimeTypeScript)   ' with text MIME type

      ' add AN0 value to reply
      WordToStr(ADC1_Get_Sample(0), dyna)
      txt  = "var AN0="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)

      ' add GPIO_PORTB value (buttons) to reply
      txt  = "var GPIO_PORTH="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      WordToStr(GPIO_PORTH_DATA, dyna)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)

      ' add GPIO_PORTD value (LEDs) to reply
      txt  = "var GPIO_PORTD="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      WordToStr(GPIO_PORTD_DATA, dyna)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)

      ' add HTTP requests counter to reply
      WordToStr(httpCounter, dyna)
      txt  = "var REQ="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)
    else
      if(getRequest[5] = "t") then                         ' if request path name starts with t, toggle GPIO_PORTD (LED) bit number that comes after
        bitMask = 0
        if(isdigit(getRequest[6]) <> 0) then               ' if 0 <= bit number <= 9, bits 8 & 9 does not exist but does not matter
          bitMask = getRequest[6] - "0"                    ' convert ASCII to integer
          bitMask = 1 << bitMask                           ' create bit mask
          GPIO_PORTD_DATA   = GPIO_PORTD_DATA xor bitMask  ' toggle GPIO_PORTD with xor operator
        end if
      end if
    end if

    if(result = 0) then ' what do to by default
      result = SPI_Ethernet_24j600_putConstString(@httpHeader)                  ' HTTP header
      result = result + SPI_Ethernet_24j600_putConstString(@httpMimeTypeHTML)   ' with HTML MIME type
      result = result + SPI_Ethernet_24j600_putConstString(@indexPage)          ' HTML page first part
      result = result + SPI_Ethernet_24j600_putConstString(@indexPage2)         ' HTML page second part
    end if

    ' return to the library with the number of bytes to transmit
end sub

' *
' * this function is called by the library
' * the user accesses to the UDP request by successive calls to SPI_Ethernet_24j600_getByte()
' * the user puts data in the transmit buffer by successive calls to SPI_Ethernet_24j600_putByte()
' * 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 UDP requests,
' * just define this function with a return(0) as single statement
' *
' *
sub function SPI_Ethernet_24j600_UserUDP(dim byref remoteHost as byte[4],
                              dim remotePort, destPort, reqLength as word, dim byref flags as TEthj600PktFlags) as word
  dim txt as string[5]
    result = 0
    ' reply is made of the remote host IP address in human readable format
    byteToStr(remoteHost[0], dyna)            ' first IP address byte
    dyna[3] = "."
    byteToStr(remoteHost[1], txt)             ' second
    dyna[4] = txt[0]
    dyna[5] = txt[1]
    dyna[6] = txt[2]
    dyna[7] = "."
    byteToStr(remoteHost[2], txt)             ' second
    dyna[8]  = txt[0]
    dyna[9]  = txt[1]
    dyna[10] = txt[2]

    dyna[11] = "."                                                                       'ac:Serial_Ethernet_2_Board
    byteToStr(remoteHost[3], txt)             ' second
    dyna[12] = txt[0]
    dyna[13] = txt[1]
    dyna[14] = txt[2]

    dyna[15] = ":"                            ' add separator

    ' then remote host port number
    WordToStr(remotePort, txt)
    dyna[16] = txt[0]
    dyna[17] = txt[1]
    dyna[18] = txt[2]
    dyna[19] = txt[3]
    dyna[20] = txt[4]
    dyna[21] = "["
    WordToStr(destPort, txt)
    dyna[22] = txt[0]
    dyna[23] = txt[1]
    dyna[24] = txt[2]
    dyna[25] = txt[3]
    dyna[26] = txt[4]
    dyna[27] = "]"
    dyna[28] = 0

    ' the total length of the request is the length of the dynamic string plus the text of the request
    result = 28 + reqLength

    ' puts the dynamic string into the transmit buffer
    SPI_Ethernet_24j600_putBytes(@dyna, 28)

    ' then puts the request string converted into upper char into the transmit buffer
    while(reqLength <> 0)
      SPI_Ethernet_24j600_putByte(SPI_Ethernet_24j600_getByte())
      reqLength = reqLength - 1
    wend

    ' back to the library with the length of the UDP reply
end sub

main:

  httpCounter = 0

  ' set mac address
  myMacAddr[0] = 0x00
  myMacAddr[1] = 0x14
  myMacAddr[2] = 0xA5
  myMacAddr[3] = 0x76
  myMacAddr[4] = 0x19
  myMacAddr[5] = 0x3F

  ' set IP address
  myIpAddr[0] = 192
  myIpAddr[1] = 168
  myIpAddr[2] = 20
  myIpAddr[3] = 60

  ' set gateway address
  gwIpAddr[0]  = 192
  gwIpAddr[1]  = 168
  gwIpAddr[2]  = 20
  gwIpAddr[3]  = 6

  ' set dns address
  dnsIpAddr[0] = 192
  dnsIpAddr[1] = 168
  dnsIpAddr[2] = 20
  dnsIpAddr[3] = 1

  ' set subnet mask
  ipMask[0]    = 255
  ipMask[1]    = 255
  ipMask[2]    = 255
  ipMask[3]    = 0

  GPIO_Digital_Input (@GPIO_PORTH, _GPIO_PINMASK_ALL)
  GPIO_Digital_Output(@GPIO_PORTD, _GPIO_PINMASK_ALL)

  ADC1_Init()
  ADC_Set_Input_Channel(_ADC_CHANNEL_0)

  SPI0_Init()
  
  
  SPI_Ethernet_24j600_Init(myMacAddr, myIpAddr, _SPI_Ethernet_24j600_AUTO_NEGOTIATION)               ' init ethernet module
  SPI_Ethernet_24j600_setUserHandlers(@SPI_Ethernet_24j600_UserTCP, @SPI_Ethernet_24j600_UserUDP)    ' set user handlers

  ' dhcp will not be used here, so use preconfigured addresses
  SPI_Ethernet_24j600_confNetwork(ipMask, gwIpAddr, dnsIpAddr)

  while TRUE                         ' do forever
    SPI_Ethernet_24j600_doPacket()   ' process incoming Ethernet packets

'   *
'   * add your stuff here if needed
'   * SPI_Ethernet_24j600_doPacket() must be called as often as possible
'   * otherwise packets could be lost
'   *
  wend
end.

STM32

program HTTP_Demo

' ***********************************
' * RAM variables
' *

' mE ehternet NIC pinout
dim
  SPI_Ethernet_24j600_CS  as sbit at GPIOB_ODR.B1
' end ethernet NIC definitions

dim myMacAddr   as byte[6]   ' my MAC address
    myIpAddr    as byte[4]   ' my IP address
    gwIpAddr    as byte[4]   ' gateway (router) IP address
    ipMask      as byte[4]   ' network mask (for example : 255.255.255.0)
    dnsIpAddr   as byte[4]   ' DNS server IP address

' ************************************************************
' * ROM constant strings
' *
const httpHeader as string[31]         = "HTTP/1.1 200 OK"+chr(10)+"Content-type: "  ' HTTP header
const httpMimeTypeHTML as string[13]   = "text/html"+chr(10)+chr(10)                 ' HTML MIME type
const httpMimeTypeScript as string[14] = "text/plain"+chr(10)+chr(10)                ' TEXT MIME type
const httpMethod as string[5]          = "GET /"
' *
' * web page, splited into 2 parts :
' * when coming short of ROM, fragmented data is handled more efficiently by linker
' *
' * this HTML page calls the boards to get its status, and builds itself with javascript
' *
const indexPage as string[767] =
                    "<meta http-equiv=" + Chr(34) + "refresh"  + Chr(34) + " content="  + Chr(34) + "3;url=http://192.168.20.60"  + Chr(34) + ">" +
                    "<HTML><HEAD></HEAD><BODY>"+
                    "<h1>ARM + ENC24J600 Mini Web Server</h1>"+
                    "<a href=/>Reload</a>"+
                    "<script src=/s></script>"+
                    "<table><tr><td valign=top><table border=1 style="+chr(34)+"font-size:20px ;font-family: terminal ;"+chr(34)+"> "+
                    "<tr><th colspan=2>ADC</th></tr>"+
                    "<tr><td>AN3</td><td><script>document.write(AN3)</script></td></tr>"+
                    "</table></td><td><table border=1 style="+chr(34)+"font-size:20px ;font-family: terminal ;"+chr(34)+"> "+
                    "<tr><th colspan=2>PORTD</th></tr>"+
                    "<script>"+
                    "var str,i;"+
                    "str="+chr(34)+chr(34)+"; "+
                    "for(i=0;i<8;i++)"+
                    "{str+="+chr(34)+"<tr><td bgcolor=pink>BUTTON #"+chr(34)+"+i+"+chr(34)+"</td>"+chr(34)+"; "+
                    "if(PORTD&(1<<i)){str+="+chr(34)+"<td bgcolor=red>ON"+chr(34)+";}"+
                    "else {str+="+chr(34)+"<td bgcolor=#cccccc>OFF"+chr(34)+";}"+
                    "str+="+chr(34)+"</td></tr>"+chr(34)+";}"+
                    "document.write(str) ;"+
                    "</script>"

const indexPage2 as string[470] =
                    "</table></td><td>"+
                    "<table border=1 style="+chr(34)+"font-size:20px ;font-family: terminal ;"+chr(34)+"> "+
                    "<tr><th colspan=3>PORTE</th></tr>"+
                    "<script>"+
                    "var str,i;"+
                    "str="+chr(34)+chr(34)+"; "+
                    "for(i=0;i<8;i++)"+
                    "{str+="+chr(34)+"<tr><td bgcolor=yellow>LED #"+chr(34)+"+i+"+chr(34)+"</td>"+chr(34)+"; "+
                    "if(PORTE&(1<<i)){str+="+chr(34)+"<td bgcolor=red>ON"+chr(34)+";}"+
                    "else {str+="+chr(34)+"<td bgcolor=#cccccc>OFF"+chr(34)+";}"+
                    "str+="+chr(34)+"</td><td><a href=/t"+chr(34)+"+i+"+chr(34)+">Toggle</a></td></tr>"+chr(34)+";}"+
                    "document.write(str) ;"+
                    "</script>"+
                    "</table></td></tr></table>"+
                    "This is HTTP request #<script>document.write(REQ)</script></BODY></HTML>"

dim    getRequest  as byte[15]   ' HTTP request buffer
       dyna        as char[30]   ' buffer for dynamic response
       httpCounter as word       ' counter of HTTP requests
       txt         as string[11]

' *******************************************
' * user defined functions
' *

' *
' * this function is called by the library
' * the user accesses to the HTTP request by successive calls to Spi_Ethernet_getByte()
' * the user puts data in the transmit buffer by successive calls to Spi_Ethernet_putByte()
' * the function must return the length in bytes of the HTTP reply, or 0 if nothing to transmit
' *
' * if you don't need to reply to HTTP requests,
' * just define this function with a return(0) as single statement
' *
' *
sub function SPI_Ethernet_24j600_UserTCP(dim byref remoteHost as byte[4],
                              dim remotePort, localPort, reqLength as word, dim byref flags as TEthj600PktFlags) as word
  dim  i as word        ' my reply length
       bitMask as integer ' for bit mask
       txt         as string[11]
    result = 0

    ' should we close tcp socket after response is sent?
    ' library closes tcp socket by default if canClose flag is not reset here
    '  canClose = 0 ' 0 - do not close socket
                    ' otherwise - close socket

    if(localPort <> 80) then          ' I listen only to web request on port 80
      result = 0
      exit
    end if

    ' get 10 first bytes only of the request, the rest does not matter here
    for i = 0 to 10
      getRequest[i] = SPI_Ethernet_24j600_getByte()
    next i

    getRequest[i] = 0

    ' copy httpMethod to ram for use in memcmp routine
    for i = 0 to 4
      txt[i] = httpMethod[i]
    next i

    if(memcmp(@getRequest, @txt, 5) <> 0) then  ' only GET method is supported here
      result = 0
      exit
    end if

    Inc(httpCounter)                           ' one more request done

    if(getRequest[5] = "s") then               ' if request path name starts with s, store dynamic data in transmit buffer
      ' the text string replied by this request can be interpreted as javascript statements
      ' by browsers

      result = SPI_Ethernet_24j600_putConstString(@httpHeader)                    ' HTTP header
      result = result + SPI_Ethernet_24j600_putConstString(@httpMimeTypeScript)   ' with text MIME type

      ' add AN3 value to reply
      WordToStr(ADC1_Get_Sample(3), dyna)
      txt  = "var AN3="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)

      ' add PORTD value (buttons) to reply
      txt  = "var PORTD="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      WordToStr(GPIOD_IDR, dyna)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)

      ' add PORTE value (LEDs) to reply
      txt  = "var PORTE="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      WordToStr(GPIOE_ODR >> 8, dyna)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)

      ' add HTTP requests counter to reply
      WordToStr(httpCounter, dyna)
      txt  = "var REQ="
      result = result + SPI_Ethernet_24j600_putString(@txt)
      result = result + SPI_Ethernet_24j600_putString(@dyna)
      txt  = ";"
      result = result + SPI_Ethernet_24j600_putString(@txt)
    else
      if(getRequest[5] = "t") then                         ' if request path name starts with t, toggle PORTE (LED) bit number that comes after
        bitMask = 0
        if(isdigit(getRequest[6]) <> 0) then               ' if 0 <= bit number <= 9, bits 8 & 9 does not exist but does not matter
          bitMask = getRequest[6] - "0"                    ' convert ASCII to integer
          bitMask = 1 << (bitMask+8)                           ' create bit mask
          GPIOE_ODR = GPIOE_ODR xor bitMask  ' toggle PORTE with xor operator
        end if
      end if
    end if

    if(result = 0) then ' what do to by default
      result = SPI_Ethernet_24j600_putConstString(@httpHeader)                  ' HTTP header
      result = result + SPI_Ethernet_24j600_putConstString(@httpMimeTypeHTML)   ' with HTML MIME type
      result = result + SPI_Ethernet_24j600_putConstString(@indexPage)          ' HTML page first part
      result = result + SPI_Ethernet_24j600_putConstString(@indexPage2)         ' HTML page second part
    end if

    ' return to the library with the number of bytes to transmit
end sub

' *
' * this function is called by the library
' * the user accesses to the UDP request by successive calls to SPI_Ethernet_24j600_getByte()
' * the user puts data in the transmit buffer by successive calls to SPI_Ethernet_24j600_putByte()
' * 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 UDP requests,
' * just define this function with a return(0) as single statement
' *
' *
sub function SPI_Ethernet_24j600_UserUDP(dim byref remoteHost as byte[4],
                              dim remotePort, destPort, reqLength as word, dim byref flags as TEthj600PktFlags) as word
  dim txt as string[5]
    result = 0
    ' reply is made of the remote host IP address in human readable format
    byteToStr(remoteHost[0], dyna)            ' first IP address byte
    dyna[3] = "."
    byteToStr(remoteHost[1], txt)             ' second
    dyna[4] = txt[0]
    dyna[5] = txt[1]
    dyna[6] = txt[2]
    dyna[7] = "."
    byteToStr(remoteHost[2], txt)             ' second
    dyna[8]  = txt[0]
    dyna[9]  = txt[1]
    dyna[10] = txt[2]

    dyna[11] = "."                                                                       'ac:Serial_Ethernet_2_Board
    byteToStr(remoteHost[3], txt)             ' second
    dyna[12] = txt[0]
    dyna[13] = txt[1]
    dyna[14] = txt[2]

    dyna[15] = ":"                            ' add separator

    ' then remote host port number
    WordToStr(remotePort, txt)
    dyna[16] = txt[0]
    dyna[17] = txt[1]
    dyna[18] = txt[2]
    dyna[19] = txt[3]
    dyna[20] = txt[4]
    dyna[21] = "["
    WordToStr(destPort, txt)
    dyna[22] = txt[0]
    dyna[23] = txt[1]
    dyna[24] = txt[2]
    dyna[25] = txt[3]
    dyna[26] = txt[4]
    dyna[27] = "]"
    dyna[28] = 0

    ' the total length of the request is the length of the dynamic string plus the text of the request
    result = 28 + reqLength

    ' puts the dynamic string into the transmit buffer
    SPI_Ethernet_24j600_putBytes(@dyna, 28)

    ' then puts the request string converted into upper char into the transmit buffer
    while(reqLength <> 0)
      SPI_Ethernet_24j600_putByte(toupper(SPI_Ethernet_24j600_getByte()))
      reqLength = reqLength - 1
    wend

    ' back to the library with the length of the UDP reply
end sub

main:

  httpCounter = 0

  ' set mac address
  myMacAddr[0] = 0x00
  myMacAddr[1] = 0x14
  myMacAddr[2] = 0xA5
  myMacAddr[3] = 0x76
  myMacAddr[4] = 0x19
  myMacAddr[5] = 0x3F

  ' set IP address
  myIpAddr[0] = 192
  myIpAddr[1] = 168
  myIpAddr[2] = 20
  myIpAddr[3] = 60

  ' set gateway address
  gwIpAddr[0]  = 192
  gwIpAddr[1]  = 168
  gwIpAddr[2]  = 20
  gwIpAddr[3]  = 6

  ' set dns address
  dnsIpAddr[0] = 192
  dnsIpAddr[1] = 168
  dnsIpAddr[2] = 20
  dnsIpAddr[3] = 1

  ' set subnet mask
  ipMask[0]    = 255
  ipMask[1]    = 255
  ipMask[2]    = 255
  ipMask[3]    = 0

  GPIO_Digital_Input(@GPIOD_BASE, _GPIO_PINMASK_ALL)
  GPIO_Digital_Output(@GPIOE_BASE, _GPIO_PINMASK_ALL)

  ADC1_Init()
  ADC_Set_Input_Channel(_ADC_CHANNEL_3)

  SPI3_Init_Advanced(_SPI_FPCLK_DIV16, _SPI_MASTER  or _SPI_8_BIT or
                     _SPI_CLK_IDLE_LOW or _SPI_FIRST_CLK_EDGE_TRANSITION or
                     _SPI_MSB_FIRST or _SPI_SS_DISABLE or _SPI_SSM_ENABLE or _SPI_SSI_1,
                     @_GPIO_MODULE_SPI3_PB345)
  GPIO_Alternate_Function_Enable(@_GPIO_MODULE_SWJ_JTAGDISABLE)


  SPI_Ethernet_24j600_Init(myMacAddr, myIpAddr, _SPI_Ethernet_24j600_AUTO_NEGOTIATION) ' init ethernet board
  SPI_Ethernet_24j600_setUserHandlers(@SPI_Ethernet_24j600_UserTCP, @SPI_Ethernet_24j600_UserUDP)    ' set user handlers
  ' dhcp will not be used here, so use preconfigured addresses
  SPI_Ethernet_24j600_confNetwork(ipMask, gwIpAddr, dnsIpAddr)

  while TRUE                         ' do forever
    SPI_Ethernet_24j600_doPacket()   ' process incoming Ethernet packets

'   *
'   * add your stuff here if needed
'   * SPI_Ethernet_24j600_doPacket() must be called as often as possible
'   * otherwise packets could be lost
'   *
  wend
end.
Copyright (c) 2002-2012 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