MCS Electronics developed a new product for BASCOM-AVR : Easy
TCP/IP
MCS Electronics developed a new product for BASCOM-AVR : Easy
TCP/IP
While it is nice to control your home from the internet, it also means that
you need to have a PC running day and night.
Easy TCP/IP allows you to connect to a LAN and/or the internet via Ethernet.
The W3100A chip from www.iinchip.com
is
used for the tcp/ip handling.
Since most of the tcp/ip handling is done by the chip, it means that you
micro processor only have to spend limited RAM and ROM for the tcp/ip.
The Easy TCP/IP PCB is designed by 'Electronic Designs' for MCS
Electronics.
I should mention that the cooperation with Marco Haufe from 'Electronic Designs'
worked out great. I just provided the circuit parts, and the resulting PCB
you can find below.
Important : Look at the difference
between IIM7000 and IIM7000A
Downloads
The PCB was developed to get you started quick and easy. You can
incorporate the W3100A chip in your own circuit of course.
The W3100A is a SMD chip so the Easy TCP/IP PCB uses the IIM7000A module that
can be soldered like any other normal chip.
The specs of the Easy TCP/IP PCB:
- DB-9 connector for serial communications
|
- DB-25 connector with integrated Sample Electronics programmer
|
- Optional LCD in pin mode can be fitted above the micro and IIM7000 module
|
- Leds for Link, 10 MB and 100 MB network detection.
|
- Header for port B and D. (P1/P3)
|
- Board suited for an AVR (Mega8515/Mega161L etc.) or for a 8051(89S8252)
|
|
The TCP/IP Libary is included with BASCOM-AVR.
The following items are available from MCS Electronics:
- Easy TCP/IP PCB (bare board)
|
- IIM7000A module with RJ-45 magnetic connector.
|
- BASCOM-AVR tcp/ip library(the library is shipped for free when you order
the IIM7000 or PCB)
|
The libraries allow you to open a socket connection in client or server mode,
write and read data. A few sample programs were created : SMTP mailer, POP3
email header reader and HTTP webserver with authentication.
The W3100A allows to have 4 different socket connections open at the same
time!
The buffer memory is inside the W3100A. This means that your program has only
a little bit of overhead for the internal ram and the code.
UDP was also added to the library.
A Simple Smtp Send Program:
'-------------------------------------------------------------------------------
' SMTP.BAS
' (c) 2002 MCS Electronics
' sample that show how to send an email with SMTP protocol
'-------------------------------------------------------------------------------
$regfile = "m161def.dat" ' used processor
$crystal = 3579545 ' used crystal
$baud = 19200 ' baud rate
$lib "tcpip.lib" ' specify the name of the tcp ip lib
'W3100A constants
Const Sock_stream = $01 ' Tcp
Const Sock_dgram = $02 ' Udp
Const Sock_ipl_raw = $03 ' Ip Layer Raw Sock
Const Sock_macl_raw = $04 ' Mac Layer Raw Sock
Const Sel_control = 0 ' Confirm Socket Status
Const Sel_send = 1 ' Confirm Tx Free Buffer Size
Const Sel_recv = 2 ' Confirm Rx Data Size
'socket status
Const Sock_closed = $00 ' Status Of Connection Closed
Const Sock_arp = $01 ' Status Of Arp
Const Sock_listen = $02 ' Status Of Waiting For Tcp Connection Setup
Const Sock_synsent = $03 ' Status Of Setting Up Tcp Connection
Const Sock_synsent_ack = $04 ' Status Of Setting Up Tcp Connection
Const Sock_synrecv = $05 ' Status Of Setting Up Tcp Connection
Const Sock_established = $06 ' Status Of Tcp Connection Established
Const Sock_close_wait = $07 ' Status Of Closing Tcp Connection
Const Sock_last_ack = $08 ' Status Of Closing Tcp Connection
Const Sock_fin_wait1 = $09 ' Status Of Closing Tcp Connection
Const Sock_fin_wait2 = $0a ' Status Of Closing Tcp Connection
Const Sock_closing = $0b ' Status Of Closing Tcp Connection
Const Sock_time_wait = $0c ' Status Of Closing Tcp Connection
Const Sock_reset = $0d ' Status Of Closing Tcp Connection
Const Sock_init = $0e ' Status Of Socket Initialization
Const Sock_udp = $0f ' Status Of Udp
Const Sock_raw = $10 ' Status of IP RAW
Const Debug = -1 ' for sending feeback to the terminal
#if Debug
Print "Start of SMTP demo"
#endif
Enable Interrupts ' enable interrupts
'specify MAC, IP,
submask and gateway
'local port value will be used when you do not specify a
port value while creating a connection
'TX and RX are setup to use 4 connections each with a 2KB
buffer
Config Tcpip = Int0 , Mac = 00.00.12.34.56.78 , Ip = 192.168.0.10 , Submask = 255.255.255.0 , Gateway = 192.168.0.0 , Localport = 1000 , Tx = $55 , Rx = $55
'dim the used variables
Dim S As String * 150 , I As Byte , J As Byte , Tempw As Word
#if Debug
Print "setup of W3100A complete"
#endif
'First we need a socket
I = Getsocket(0 , Sock_stream , 5000 , 0)
' ^
socket numer ^ port
#if Debug
Print "Socket : " ; I
'the socket must
return the asked socket number. It returns 255 if there was an error
#endif
If I = 0 Then ' all ok
'connect to smtp
server
J = Socketconnect(i , 194.109.0.0 , 25) ' smtp server and SMTP port 25
' ^socket
' ^ ip address of the smtp
server
' ^ port 25 for smtp
#if Debug
Print "Connection : " ; J
Print S_status(1)
#endif
If J = 0 Then ' all ok
#if Debug
Print "Connected"
#endif
' now depending
on the smtp server, it can take some time until a reply is received
Do
Tempw = Socketstat(i , 0) ' get status
Select Case Tempw
Case Sock_established ' connection established
Tempw = Tcpread(i , S) ' read line
#if Debug
Print S ' show info from smtp server
#endif
If Left(s , 3) = "220" Then ' ok
Tempw = Tcpwrite(i , "HELO user{013}{010}" ) ' send username
#if Debug
Print Tempw ; " bytes written" ' number of bytes
actual send
#endif
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S ' show response
#endif
If Left(s , 3) = "250" Then ' ok
Tempw = Tcpwrite(i , "MAIL FROM:<tcpip@mcselec.com>{013}{010}") ' send from address
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
If Left(s , 3) = "250" Then ' ok
Tempw = Tcpwrite(i , "RCPT TO:<tcpip@mcselec.com>{013}{010}") ' send TO address
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
If Left(s , 3) = "250" Then ' ok
Tempw = Tcpwrite(i , "DATA{013}{010}") ' speicfy that we are going to send data
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
If Left(s , 3) = "354" Then ' ok
Tempw = Tcpwrite(i , "From: tcpip@mcselec.com{013}{010}")
Tempw = Tcpwrite(i , "To: tcpip@mcselec.com{013}{010}")
Tempw = Tcpwrite(i , "Subject: BASCOM SMTP test{013}{010}")
Tempw = Tcpwrite(i , "X-Mailer: BASCOM SMTP{013}{010}")
Tempw = Tcpwrite(i , "{013}{010}")
Tempw = Tcpwrite(i , "This is a test email from BASCOM SMTP{013}{010}")
Tempw = Tcpwrite(i , "Add more lines as needed{013}{010}")
Tempw = Tcpwrite(i , ".{013}{010}") ' end with a single dot
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
If Left(s , 3) = "250" Then ' ok
Tempw = Tcpwrite(i , "QUIT{013}{010}") ' quit connection
Tempw = Tcpread(i , S)
#if Debug
Print S
#endif
End If
End If
End If
End If
End If
End If
Case Sock_close_wait
Print "CLOSE_WAIT"
Closesocket I ' close the connection
Case Sock_closed
Print "Socket
CLOSED" ' socket is closed
End
End Select
Loop
End If
End If
End 'end program
A simple POP3 read program:
'-------------------------------------------------------------------------------
' POP3.BAS
' (c) 2002 MCS Electronics
' sample that show how to read an email with POP3 protocol
'-------------------------------------------------------------------------------
$regfile = "m161def.dat"
$crystal = 3579545
$baud = 19200
$lib "tcpip.lib"
Const Sock_stream = $01 ' Tcp
Const Sock_dgram = $02 ' Udp
Const Sock_ipl_raw = $03 ' Ip Layer Raw Sock
Const Sock_macl_raw = $04 ' Mac Layer Raw Sock
Const Sel_control = 0 ' Confirm Socket Status
Const Sel_send = 1 ' Confirm Tx Free Buffer Size
Const Sel_recv = 2 ' Confirm Rx Data Size
'socket status
Const Sock_closed = $00 ' Status Of Connection Closed
Const Sock_arp = $01 ' Status Of Arp
Const Sock_listen = $02 ' Status Of Waiting For Tcp Connection Setup
Const Sock_synsent = $03 ' Status Of Setting Up Tcp Connection
Const Sock_synsent_ack = $04 ' Status Of Setting Up Tcp Connection
Const Sock_synrecv = $05 ' Status Of Setting Up Tcp Connection
Const Sock_established = $06 ' Status Of Tcp Connection Established
Const Sock_close_wait = $07 ' Status Of Closing Tcp Connection
Const Sock_last_ack = $08 ' Status Of Closing Tcp Connection
Const Sock_fin_wait1 = $09 ' Status Of Closing Tcp Connection
Const Sock_fin_wait2 = $0a ' Status Of Closing Tcp Connection
Const Sock_closing = $0b ' Status Of Closing Tcp Connection
Const Sock_time_wait = $0c ' Status Of Closing Tcp Connection
Const Sock_reset = $0d ' Status Of Closing Tcp Connection
Const Sock_init = $0e ' Status Of Socket Initialization
Const Sock_udp = $0f ' Status Of Udp
Const Sock_raw = $10 ' Status of IP RAW
Const Debug = 1
#if Debug
Print "Init system"
#endif
Config Lcd = 16 * 2 ' lcd we use
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
Cls ' clear LCD
Enable Interrupts
Config Tcpip = Int0 , Mac = 00.00.12.34.56.78 , Ip = 192.168.0.10 , Submask = 255.255.255.0 , Gateway = 192.168.0.0 , Localport = 1000 , Tx = $55 , Rx = $55
'dim variables
Dim S As String * 150 , I As Byte , J As Byte , Tempw As Word , P As Byte , Ilp As Word , Imsg As Word
#if Debug
Print "Ready"
#endif
'get a socket
I = Getsocket(0 , Sock_stream , 5000 , 0)
#if Debug
Print "socket : " ; I
#endif
If I <> 255 Then ' all ok
'connect to pop3
server
J = Socketconnect(i , 64.77.0.0 , 110) ' smtp server and POP3 port 110
#if Debug
Print "Connection : " ; J
Print S_status(1)
#endif
If J = 0 Then ' all ok
#if Debug
Print "Connected"
#endif
Do
Tempw = Socketstat(i , 0) ' get status
Select Case Tempw
Case Sock_established
Tempw = Tcpread(i , S) ' get line
#if Debug
Print S
#endif
If Left(s , 3) = "+OK" Then ' ok
Tempw = Tcpwrite(i , "USER user{013}{010}" ) ' send username
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
If Left(s , 3) = "+OK" Then ' ok
Tempw = Tcpwrite(i , "PASS pwd{013}{010}") ' send password
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
If Left(s , 3) = "+OK" Then ' ok
Do
Tempw = Socketstat(i , 2) ' get number of received bytes
If Tempw > 0 Then
Tempw = Tcpread(i , S) ' get response
#if Debug
Print S
#endif
Else
Exit Do ' no more data
End If
Loop
Tempw = Tcpwrite(i , "STAT{013}{010}") 'get stats
Tempw = Tcpread(i , S)
#if Debug
Print S
#endif
If Left(s , 3) = "+OK" Then ' ok
'+OK 10 1204
S = Mid(s , 5) ' stop +ok
P = Instr(s , " ")
P = P - 1 ' find space
S = Left(s , P)
Cls ' clear LCD
Lcd "Emails :
" ; S
Imsg = Val(s) ' number of messages
For Ilp = 1 To Imsg
S = "TOP " + Str(ilp) + " 0{013}{010}"
J = Len(s)
Tempw = Tcpwrite(i , S , J) ' ask for top
lines(0) which will respond with only the header
Do
Tempw = Tcpread(i , S)
If Left(s , 8) = "Subject:" Then ' check for subject
S = Mid(s , 10)
Home Lower : Lcd S ' show header
#if Debug
Print S
#endif
End If
Loop Until S = "." ' end of
data
Waitms 1000 'some time to
read the display
Next
Tempw = Tcpwrite(i , "QUIT{013}{010}") ' quit
Tempw = Tcpread(i , S)
End If
End If
End If
End If
Case Sock_close_wait
#if Debug
Print "CLOSE_WAIT"
#endif
Closesocket I ' close connection
Case Sock_closed
#if Debug
Print "CLOSED" ' we are done
#endif
End
End Select
Loop
End If
End If
End 'end
program
A simple HTTP server program:
'------------------------------------------------------------------------------
' webserver.bas
' simple webserver demo
' (c) 2002 MCS Electronics
' You can access the server via
http://213.84.110.248:5000/index.htm
' http://213.84.110.248:5000/post.htm
' http://213.84.110.248:5000/notfound.htm
' any other name will return the not found page
'Note that the server is not always active
'------------------------------------------------------------------------------
$regfile = "m161def.dat"
$crystal = 3579545
$baud = 19200
'used constants
Const Sock_stream = $01 ' Tcp
Const Sock_dgram = $02 ' Udp
Const Sock_ipl_raw = $03 ' Ip Layer Raw Sock
Const Sock_macl_raw = $04 ' Mac Layer Raw
Sock
Const Sel_control = 0 ' Confirm Socket Status
Const Sel_send = 1 ' Confirm Tx Free Buffer Size
Const Sel_recv = 2 ' Confirm Rx Data
Size
'socket status
Const Sock_closed = $00 ' Status Of Connection Closed
Const Sock_arp = $01 ' Status Of Arp
Const Sock_listen = $02 ' Status Of Waiting For Tcp Connection Setup
Const Sock_synsent = $03 ' Status Of Setting Up Tcp Connection
Const Sock_synsent_ack = $04 ' Status Of Setting Up Tcp Connection
Const Sock_synrecv = $05 ' Status Of Setting Up Tcp Connection
Const Sock_established = $06 ' Status Of Tcp Connection Established
Const Sock_close_wait = $07 ' Status Of Closing Tcp Connection
Const Sock_last_ack = $08 ' Status Of Closing Tcp Connection
Const Sock_fin_wait1 = $09 ' Status Of Closing Tcp Connection
Const Sock_fin_wait2 = $0a ' Status Of Closing Tcp Connection
Const Sock_closing = $0b ' Status Of Closing Tcp Connection
Const Sock_time_wait = $0c ' Status Of Closing Tcp Connection
Const Sock_reset = $0d ' Status Of Closing Tcp Connection
Const Sock_init = $0e ' Status Of Socket Initialization
Const Sock_udp = $0f ' Status Of Udp
Const Sock_raw = $10 ' Status of IP RAW
'in debug mode to send some info to the terminal
Const Debug = 1
$lib "tcpip.lib"
$eepleave ' do not delete the EEP file since we generated it with the
converter tool
#if Debug
Print "init W3100A"
#endif
Enable Interrupts
Config Tcpip = Int0 , Mac = 00.00.12.34.56.78 , Ip = 192.168.0.10 , Submask = 255.255.255.0 , Gateway = 192.168.0.1 , Localport = 1000 , Tx = $55 , Rx = $55
'dim used variables
Dim S As String * 140 At &H100 , Shtml As String * 15 , Sheader As String * 30
Dim Buf(120) As Byte At &H100 Overlay ' this is the same data as S but we can treat it as an array now
Dim Tempw As Word
Dim I As Byte , Bcmd As Byte , P1 As Byte , P2 As Byte , Size As Word
Dim Bcontent As Byte
I = Getsocket(0 , Sock_stream , 5000 , 0) 'get a socket
#if Debug
Print "socket : " ; I
#endif
Socketlisten I ' server mode
#if Debug
Print "listening"
#endif
Do
Tempw = Socketstat(i , 0) ' get status
Select Case Tempw
Case Sock_established
#if Debug
Print "sock_est"
#endif
Tempw = Socketstat(i , Sel_recv) ' get received bytes
#if Debug
Print "receive
buffer size : " ; Tempw
#endif
If Tempw > 0 Then ' if there is something received
Bcmd = 0
Do
Tempw = Tcpread(i , S) ' read a line
If Left(s , 3) = "GET" Then '
Bcmd = 1 ' GET /index.htm HTTP/1.1
Gosub Page
Elseif Left(s , 4) = "HEAD" Then
Bcmd = 2
Gosub Page
Elseif Left(s , 4) = "POST" Then
Bcmd = 3
Elseif Left(s , 15) = "Content-Length:" Then ' for post
S = Mid(s , 16) : Bcontent = Val(s)
Else
#if Debug
Print S
#endif
End If
Loop Until S = "" ' wait until we get an empty line
Tempw = Tcpwrite(i , "HTTP/1.0 200 OK{013}{010}")
If Bcmd = 3 Then
#if Debug
Print "Posted
data"
#endif
Tempw = Tcpread(i , Buf(1) , Bcontent) ' read data
#if Debug
Bcontent = Bcontent + 1
Buf(bcontent) = 0 ' put string terminator at end of data so we can handle it
as a string
Print S
#endif
Shtml = "/redirect.htm" ' redirect to
www.mcselec.com
End If
Gosub Stuur ' GET or HEAD or POST feedback so send it
Print "closing
socket"
Closesocket I ' close the
connection
Print "done"
End If
Case Sock_close_wait
#if Debug
Print "CLOSE_WAIT"
#endif
Closesocket I ' we need to close
Case Sock_closed
#if Debug
Print "CLOSED"
#endif
I = Getsocket(0 , Sock_stream , 5000 , 0) ' get a new socket
Socketlisten I ' listen
#if Debug
Print "Listening on
socket : " ; I
#endif
End Select
Loop
End
'get html page out of data
Page:
P1 = Instr(s , " ") ' find first space
P1 = P1 + 1 ' 4
P2 = Instr(p1 , S , " ") ' find second space
P2 = P2 - P1
Shtml = Mid(s , P1 , P2) ' dont use too long page names
Shtml = Lcase(shtml) ' make lower case
#if Debug
Print "HTML page:" ; Shtml
#endif
Return
'send data
Stuur:
Dim Woffset As Word , Bcontenttype As Byte , Wsize As Word , Bgenerate As Bit , Ihitcounter As Integer
Bgenerate = 0 ' by default
Select Case Shtml
Case "/index.htm"
Bcontenttype = 0 : Bgenerate = 1
Case "/redirect.htm"
Bcontenttype = 0 : Bgenerate = 1
Case "/post.htm" : Wsize = 277
bContentType = 0 : wOffset = 0
Case "/notfound.htm" : Wsize = 123
Bcontenttype = 0 : Woffset = 277
Case Else ' not found
Bcontenttype = 0 : Woffset = 277 : Wsize = 123
End Select
Select Case
Bcontenttype
Case 0: ' text
Tempw = Tcpwrite(i , "Content-Type: text/html{013}{010}")
Case 1: ' gif
End Select
If Bgenerate = 0 Then ' data from eeprom
S = "Content-Length: " + Str(wsize) + "{013}{010}"
Tempw = Tcpwritestr(i , S , 255) ' add additional CR and LF
Tempw = Tcpwrite(i , Eeprom , Woffset , Wsize) ' write data
Else ' we generate the data
If Shtml = "/index.htm" Then
S = "<html><head><title>Easy
TCP/IP</title></head><body><p><b>MCS webserver
test<br></b>Hits : " + Str(ihitcounter) + "</p><p> </p><p> </p></body></html>"
Incr Ihitcounter 'increase hitcounter
Else
S = "<html><head><title</title></head><body
onload='window.location.href=" + Chr(34) + "http://www.mcselec.com" + Chr(34) + "'></body></html>"
End If
Wsize = Len(s) ' size of body
Sheader = "Content-Length: " + Str(wsize) + "{013}{010}"
Tempw = Tcpwritestr(i , Sheader , 255) ' add
additional CR and LF
Tempw = Tcpwrite(i , S , Wsize) ' send body
End If
Return
Note that the samples were kept simple on
purpose. An actual webserver will use 4 connections so 4 clients at the same
time can be served. |