EthernetICMP
SwordfishUser.EthernetICMP History
Hide minor edits - Show changes to output
Added lines 1-31:
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.
*Plug a network cable into your board and connect to your network. For example, just plug your Ethernet board into your broadband router, which will act as a DHCP server.
*Compile and then program the code into your device.
*Start the Swordfish Serial Communicator plugin, and a connect to your MCUs USART at 115200 baud.
*Reset the MCU.
If all goes well, something like the following should be displayed in the Serial Communicator window
>>default bgcolor=#f5f5f5<<
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,
>>default bgcolor=#f5f5f5<<
88.221.127.45
>><<
which should return something like
>>default bgcolor=#f5f5f5<<
Ping...40 ms
>><<
!!!Sample Code - No DNS
*Plug a network cable into your board and connect to your network. For example, just plug your Ethernet board into your broadband router, which will act as a DHCP server.
*Compile and then program the code into your device.
*Start the Swordfish Serial Communicator plugin, and a connect to your MCUs USART at 115200 baud.
*Reset the MCU.
If all goes well, something like the following should be displayed in the Serial Communicator window
>>default bgcolor=#f5f5f5<<
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,
>>default bgcolor=#f5f5f5<<
88.221.127.45
>><<
which should return something like
>>default bgcolor=#f5f5f5<<
Ping...40 ms
>><<
!!!Sample Code - No DNS
Changed lines 186-188 from:
to:
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,
>>default bgcolor=#f5f5f5<<
www.microchip.com
>><<
which should return something like
>>default bgcolor=#f5f5f5<<
Ping...40 ms
>><<
!!!Sample Code with DNS
>>default bgcolor=#f5f5f5<<
www.microchip.com
>><<
which should return something like
>>default bgcolor=#f5f5f5<<
Ping...40 ms
>><<
!!!Sample Code with DNS
Added lines 1-351:
=code [=
// 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
=]
=code [=
// 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
=]
// 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
=]
=code [=
// 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
=]