TCP Connection with ENC28J60

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
User avatar
JWinters
Posts: 106
Joined: Mon Feb 04, 2008 4:56 pm
Location: North Carolina, USA
Contact:

TCP Connection with ENC28J60

Post by JWinters » Tue Mar 18, 2008 10:03 pm

I'm trying to make a TCP connection using the ENC28J60 TCP/IP stack and a 18F2620. Basically I want the PIC to automatically connect to a remote host if a network connection is present. And if the network connection drops, it will connect again when the network comes back up. The code I have works for the most part. The only problem is that it seems to take a long time (minutes) to get the initial TCP connection up. DHCP isn't the problem since the PIC gets an IP immediately on startup. The odd thing is that once the initial TCP connection has been made, I can do whatever I want to the network (unplug the ethernet cable, close the TCP connection, etc) and the PIC makes that connection again really quickly once the network is back. It's almost like the ENC28J60 has to warm up before it will work properly.

Take a look at my code and see if you can tell me what I'm doing wrong.

Code: Select all

Program TCPconnector

Device = 18F2620
Clock = 25

// important configurations...
#option ENC28J60_CS = PORTB.3
#option ENC28J60_RST = PORTB.4
#option NET_ICMP = true   // enable ping 
#option NET_DHCP = true   // enable Dynamic Host Configuration Protocol (DHCP)
#option NET_NBNS = true   // enable NETBIOS
#option NET_TCP = true    // enable TCP
#option STACK_CLIENT_MODE = true

Include "NETApp.bas"      // always first!

// TCPIP stack specifics...
Include "NETTypes.bas"
Include "NETUtils.bas"
Include "Tick.bas"
Include "TCP.bas"
Include "DNS.bas"
Include "ARP.bas"
Include "MAC.bas"

// program helpers...

Include "NETAppDisplay.bas"
Include "SUART.bas"
Include "convert.bas" 

Dim MySocket As TCP_SOCKET
Dim RemoteHost As NODE_INFO
Dim RemotePort As Word
Dim IPString As String
Dim OnlineState As Boolean

Dim i As Word

Dim ConnectFlag As Boolean

ConnectFlag = False
IPString = "192.168.1.2"
RemotePort = 9090

// program start...
UART.SetBaudrate(sbr9600)
UART.SetTX(PORTC.6)
UART.SetMode(umInverted)

StringToIPAddress(@IPString, RemoteHost.IPAddr)

DelayMS(100)
OnlineState = false
MySocket = INVALID_SOCKET

// 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 NETApp.DHCPEvent() Then
       If MACIsLinked = true Then
            OnlineState = true
            Write("Network connection.",#13,#10)
       Else
            OnlineState = false
            Write("Lost connection",#13,#10)
       End If
   End If
   
   If OnlineState = True Then
        If TCPIsConnected(MySocket) = False Then
            ARPResolve(RemoteHost.IPAddr)       
            Repeat
                NETApp.Task
                DelayMS(20)
            Until ARPIsResolved(RemoteHost.IPAddr, RemoteHost.MACAddr) = true
            
            Write("MAC Resolved",#13,#10)
            
            Repeat
                MySocket = TCPConnect(RemoteHost, RemotePort)
            Until MySocket <> INVALID_SOCKET
            
            Repeat                 
                 NETApp.Task
                 TCPTick()
                 DelayMS(10)
            Until TCPIsConnected(MySocket) = True
            
            Write("TCP Connection",#13,#10) 
        
        Else
 
            Repeat   'all is good. process traffic here 
                NETApp.Task
                DelayMS(100)
            Until TCPIsConnected(MySocket) = false Or MACIsLinked = false
            
            Write("TCP Disconnect",#13,#10)
            
            If MACIsLinked = False Then
                OnlineState = False
            End If
            
            Clear(MySocket)
            TCPFlush(MySocket)            
        
        End If
   End If
Wend

User avatar
JWinters
Posts: 106
Joined: Mon Feb 04, 2008 4:56 pm
Location: North Carolina, USA
Contact:

Post by JWinters » Wed Mar 19, 2008 1:54 am

Using Wireshark to sniff the packets on my network, it looks like it has something to do with the fact that the PIC always starts at 1024 for local ports and increments from there. So whenever the PIC is powered off without properly closing the TCP connection, it tries to connect again using the same local port. This appears to confuse the server side. Maybe if i keep track in of the local port in the EEPROM then I can increment to the next port on the next power cycle.

There still could be something wrong with my code... I'm just thinking out loud.

User avatar
JWinters
Posts: 106
Joined: Mon Feb 04, 2008 4:56 pm
Location: North Carolina, USA
Contact:

Post by JWinters » Wed Mar 19, 2008 3:21 am

yes, that was the problem. The TCP connection wasn't closing cleanly on a power failure. I modified the TCP/IP stack to track the local port numbers in the EEPROM instead of always starting at 1024. It works great now!

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Post by David Barker » Wed Mar 19, 2008 9:40 am

Thanks for posting your findings...

rubenpena
Registered User
Registered User
Posts: 32
Joined: Sun Mar 25, 2007 2:07 am
Location: Monterrey,Mexico

Post by rubenpena » Wed Dec 29, 2010 5:34 am

Hi jWinters, care to point me where in the TCP/IP Stack module did you made the modification?

Thanks in advance...

Ruben

User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

Post by Senacharim » Wed Dec 29, 2010 2:56 pm

Thank you for posting your findings!

Adding ethernet functionality has been on my list for awhile.

If you don't mind my inquiry, how much ram/flash does adding such tend to take up?
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

Post Reply