Page 1 of 1

TCP Connection with ENC28J60

Posted: Tue Mar 18, 2008 10:03 pm
by JWinters
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

Posted: Wed Mar 19, 2008 1:54 am
by JWinters
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.

Posted: Wed Mar 19, 2008 3:21 am
by JWinters
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!

Posted: Wed Mar 19, 2008 9:40 am
by David Barker
Thanks for posting your findings...

Posted: Wed Dec 29, 2010 5:34 am
by rubenpena
Hi jWinters, care to point me where in the TCP/IP Stack module did you made the modification?

Thanks in advance...

Ruben

Posted: Wed Dec 29, 2010 2:56 pm
by Senacharim
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?