From Swordfish Wiki

SwordfishUser: EthernetICMP

This sample program uses the ICMP module to ping a remote host. The first example program requires you to enter a numeric IP address. In the second code example, the DNS module is used to resolve a hostname (for example, www.microchip.com) before pinging. Here's what you need to do.

If all goes well, something like the following should be displayed in the Serial Communicator window

 Waiting for DHCP...
 Host Name     : SWORDFISH      
 MAC Address   : $00 $04 $A3 $00 $00 $00 
 IP address    : 192.123.223.1
 Mask          : 255.255.255.0
 Gateway       : 192.123.223.254

Now enter a numeric IP address and press enter. For example,

 88.221.127.45

which should return something like

 Ping...40 ms

Sample Code - No DNS

// device and clock - code will work on an 18F452 as well...
Device = 18F4680
Clock = 20

// important configurations...
#option ENC28J60_CS = PORTD.6
#option NET_ICMP = true   // enable ping 
#option NET_DHCP = true   // enable Dynamic Host Configuration Protocol (DHCP)
#option NET_NBNS = true   // enable NETBIOS
Include "NETApp.bas"      // always first!

// TCPIP stack specifics...
Include "NETTypes.bas"
Include "NETUtils.bas"
Include "Tick.bas"
Include "ICMP.bas"

// program helpers...
Include "NETAppDisplay.bas"
Include "usart.bas"
Include "convert.bas"
Include "ISRRX.bas"

// state machine constants...
Const
   SM_HOME = 0,
   SM_GET_RESPONSE = 1,
   SM_FINISHED = 2

// ping variables...   
Dim 
   PingState As Byte,
   PingTimer As TICK
{
****************************************************************************
* Name    : Init                                                           *
* Purpose : Initialise timer and state machine                             *
****************************************************************************
}
Sub Init()
   PingTimer = 0
   PingState = SM_HOME
End Sub
{
****************************************************************************
* Name    : Ping                                                           *
* Purpose : Start a ping                                                   *
****************************************************************************
}
Sub Ping(ByRef pIP As String)
   Dim PingIP As IP_ADDR
   If PingState = SM_HOME Then
	  If ICMPBeginUsage() Then
	     NETUtils.StringToIPAddress(@pIP, PingIP)	     
	     ICMPSendPing(PingIP.Val)
         PingState = SM_GET_RESPONSE
	     PingTimer = TickGet()         
      EndIf 
   EndIf  
End Sub
{
****************************************************************************
* Name    : PingTask                                                       *
* Purpose : Process a ping task                                            *
****************************************************************************
}
Function PingTask() As SHORT
   Result = -2 // do nothing...

   // ping has been started, now wait for ping response...
   If PingState = SM_GET_RESPONSE Then
      Result = ICMPGetReply() 

      // the request timed out...
      If Result <> - 2 Then
         PingState = SM_FINISHED
      EndIf
   EndIf

   // wait at least one second before another ping - remove the ping timer
   // code if you do not need this functionality...
   If PingState = SM_FINISHED And (TickGet() - PingTimer) > 1000 Then
      PingState = SM_HOME
      ICMPEndUsage()
   EndIf
End Function 
{
****************************************************************************
* Name    : OnData                                                         *
* Purpose : The TCPIP stack is a co-operative state machine. Therefore, we *
*         : cannot wait around for USART data and use a buffered interrupt *
*         : instead. When a CR is received, set a ReadyToRead flag to true *
****************************************************************************
}
Dim ReadyToRead As Boolean
Event OnData()
   If ISRRX.DataChar = #13 Then
      ReadyToRead = true
   EndIf 
End Event

// main program variables...
Dim Result As SHORT
Dim StrIP As String(80)

// program start...
SetBaudrate(br115200)
Init()
#if NET_DHCP
Write("Waiting for DHCP...",13,10)
#else
DisplayConfig
#endif

// use interrupt buffered USART...
ReadyToRead = false
USART.ReadTerminator = 13
ISRRX.Initialize(OnData)

// loop forever...
While true

   // This task performs normal stack task including checking for incoming 
   // packet, type of packet and calling appropriate stack entity to process it.
   NETApp.Task

   // If the ready to read flag has been set, read a string from the interrupt
   // buffer and start the ping...
   If ReadyToRead Then
      ReadyToRead = false
      ISRRX.ReadStr(StrIP,13)
      USART.Write("Ping...")
      Ping(StrIP)
   EndIf

   // Process the ping task state machine...
   Result = PingTask()
   If Result >= 0 Then
      USART.Write(DecToStr(Result), " ms", 13,10)
   ElseIf Result = -1 Then
      USART.Write("timed out",13,10)
   EndIf      		 

   // If DHCP is enabled, display configuration when a DHCP event
   // has occurred...
   #if NET_DHCP
   If NETApp.DHCPEvent() Then
      DisplayConfig()
   EndIf
   #endif     
Wend

The next code example is pretty much the same as the above, except it uses the DNS module to resolve a hostname. This means you do not have to enter a numeric IP address. For example,

 www.microchip.com

which should return something like

 Ping...40 ms

Sample Code with DNS

// device and clock - code will work on an 18F452 as well...
Device = 18F4680
Clock = 20

// important configurations...
#option ENC28J60_CS = PORTD.6
#option NET_ICMP = true   // enable ping 
#option NET_DHCP = true   // enable Dynamic Host Configuration Protocol (DHCP)
#option NET_NBNS = true   // enable NETBIOS
#option NET_DNS = true    // enable Domain Name Service (DNS)
Include "NETApp.bas"      // always first!

// TCPIP stack specifics...
Include "NETTypes.bas"
Include "NETUtils.bas"
Include "Tick.bas"
Include "ICMP.bas"
Include "DNS.bas"

// program helpers...
Include "NETAppDisplay.bas"
Include "usart.bas"
Include "convert.bas"
Include "ISRRX.bas"

// state machine constants...
Const
   SM_HOME = 0,
   SM_RESOLVING = 1,
   SM_PING = 2,
   SM_GET_RESPONSE = 3,
   SM_FINISHED = 4

// ping variables...   
Dim 
   PingState As Byte,
   PingTimer As TICK,
   PingIP As IP_ADDR
{
****************************************************************************
* Name    : Init                                                           *
* Purpose : Initialise timer and state machine                             *
****************************************************************************
}
Sub Init()
   PingTimer = 0
   PingState = SM_HOME
End Sub
{
****************************************************************************
* Name    : Ping                                                           *
* Purpose : Start a ping                                                   *
****************************************************************************
}
Sub Ping(ByRef pHostname As String)
   If PingState = SM_HOME Then
      If DNSBeginUsage() Then
         DNSResolve(@pHostName, DNS_TYPE_A)
         PingState = SM_RESOLVING
      EndIf    
   EndIf     
End Sub
{
****************************************************************************
* Name    : PingTask                                                       *
* Purpose : Process a ping task                                            *
****************************************************************************
}
Function PingTask() As SHORT
   Dim PingResult As SHORT

   // default result is 0
   Result = 0

   // resolve hostname to an IP address...
   If PingState = SM_RESOLVING Then
      PingIP.Val = 0
      If DNSIsResolved(PingIP) Then
         DNSEndUsage

         // resolved, start ping...
         If PingIP.Val <> 0 Then
            PingState = SM_PING

         // unable to resolve, abort...
         Else
            Result = -1
            PingState = SM_HOME
         EndIf
      EndIf
   EndIf 

   // hostname has been resolved, start ping using
   // the IP address obtained from the DNS server...
   If PingState = SM_PING Then
	  If ICMPBeginUsage() Then
	     ICMPSendPing(PingIP.Val)
         PingState = SM_GET_RESPONSE
	     PingTimer = TickGet()         
      EndIf 
   EndIf     

   // ping has been started, now wait for ping response...
   If PingState = SM_GET_RESPONSE Then
      PingResult = ICMPGetReply() 

      // the request timed out...
      If PingResult = -1 Then
         Result = -2
         PingState = SM_FINISHED

      // echo received, time elapsed is stored in result (units of TICK)
      ElseIf PingResult >= 0 Then
		 Result = PingResult
		 PingState = SM_FINISHED
      EndIf
   EndIf

   // wait at least one second before another ping - remove the ping timer
   // code if you do not need this functionality...
   If PingState = SM_FINISHED And (TickGet() - PingTimer) > 1000 Then
      PingState = SM_HOME
      ICMPEndUsage()
   EndIf
End Function 
{
****************************************************************************
* Name    : OnData                                                         *
* Purpose : The TCPIP stack is a co-operative state machine. Therefore, we *
*         : cannot wait around for USART data and use a buffered interrupt *
*         : instead. When a CR is received, set a ReadyToRead flag to true *
****************************************************************************
}
Dim ReadyToRead As Boolean
Event OnData()
   If ISRRX.DataChar = #13 Then
      ReadyToRead = true
   EndIf 
End Event

// main program variables...
Dim Result As SHORT
Dim StrHostname As String(80)

// program start...
SetBaudrate(br115200)
Init()
#if NET_DHCP
Write("Waiting for DHCP...",13,10)
#else
DisplayConfig
#endif

// use interrupt buffered USART...
ReadyToRead = false
USART.ReadTerminator = 13
ISRRX.Initialize(OnData)

// loop forever...
While true

   // This task performs normal stack task including checking for incoming 
   // packet, type of packet and calling appropriate stack entity to process it.
   NETApp.Task

   // If the ready to read flag has been set, read a string from the interrupt
   // buffer and start the ping...
   If ReadyToRead Then
      ReadyToRead = false
      ISRRX.ReadStr(StrHostname,13)
      USART.Write("Ping...")
      Ping(StrHostname)
   EndIf

   // Process the ping task state machine...
   Result = PingTask()
   If Result > 0 Then
      USART.Write(DecToStr(Result), " ms", 13,10)
   ElseIf Result = -1 Then
      USART.Write("Unable to resolve ", StrHostname, 13,10)
   ElseIf Result = -2 Then
      USART.Write("timed out",13,10)
   EndIf      		 

   // If DHCP is enabled, display configuration when a DHCP event
   // has occurred...
   #if NET_DHCP
   If NETApp.DHCPEvent() Then
      DisplayConfig()
   EndIf
   #endif     
Wend
Retrieved from https://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.EthernetICMP
Page last modified on February 06, 2008, at 09:42 AM