Here you can find a step-by-step tutorial about the Bascom-8051 code to drive the
WizNet W7100 on the iMCU7100 evaluation board

Step 1. To-Do...

 

There is a new Circuit Cellar Contest going on, this time with the Wiznet W7100 microcontroller. 
A controller with a 8051 core and a build in TCPIPCore. 64 Kbytes flash, 64 Kbytes SRAM, 64 Kbytes TX/RX/TCPIP RAM, 256 Bytes data flash.
The W7100 has all Special Function Registers as a plain 8051 but there are special registers for the TCPIP-part.

What do we have to do?

We have to make a W7100.DAT file for Bascom-8051
We have to make an include-file for all W7100 registers
Get the LCD working
Get something out of the serial port
Get the three LED's blinking
Get the TCPIPCore working

 

Step 2: Creating the W7100.DAT

 

Used the existing REG51.DAT as a template.

Here the registers used in the REG51.DAT-file of Bascom-8051

REG51.DAT

Here the registers used in the W7100.DAT-file. In green the new ones.
 

W7100.DAT

In the DAT-file: In the [BIT]-section (all registers that ends with a 0 or a 8), all registers that can be manipulated by bit, and in the [BYTE]-section all others. In the [MISC]-section the name of the microcontroller:
up = W7100
a few interrupts
I_TF2 = 2B
I_INT2F = 43
I_INT3F = 4B
I_INT5F = 5B
I_WDIF = 63
the size of the internal RAM
IRAM = 256
The start of the program (jumping over the interrupt-vectors)
org = 66
and as last the clock
clockdiv = 1
 

Step 3: Getting the first test program in the W7100

 

We can test the W7100.DAT file with a small program to blink the three LEDs.

$regfile = "W7100.DAT"
$crystal = 11059200

Do
Set P0.3
Set P0.4
Set P0.5
Wait 1
Reset P0.3
Reset P0.4
Reset P0.5
Wait 1
Loop
End

We need WizISP to put the BIN or HEX file in the W7100.

Connect the iMCU7100 to a serial port on your computer, start the WizISP-program that can be found on the Wiznet-site. Put the BOOT-switch to the right (ON), power the board, select the right COM-port and open the port in the WizISP-program. When you have compiled the above example in Bascom-8051 you will have a HEX and a BIN-file. Load this file. You should see this:

With a push on AUTO your W7100 will be erased, blank checked, programmed and verified. And after all is well, it will start. You can leave the BOOT-switch to the right, but when you push the reset button the W7100 will stay in its boot loader. Putting the BOOT-switch to the left and pressing reset will restart the W7100.

If all is done correct you will see the three LEDs go on for 1 second, off for 1 second and that is repeated.

I have noticed it is very handy to minimize the WizISP program, every time you do a recompile of your Bascom-8051-program you will be noticed like this:

When you forget to switch the BOOT-switch to ON you will get an error-message. When you have, later on, HyperTerminal open, you will also get an error-message.

If you want every detail of the W7100-registers used, you could have a look here:

Tutorial Wiz810MJ I have written before.

 

Step 4: Get the LCD and serial working

 

Time for the real work, getting the LCD working. Have tested with the Bascom-8051 LCD-commands but it wasn't working. Have still to find why not. But remembered I wrote LCD-routines for the Siemens 80C535 before so used these. And also for the serial port, have to fill two registers to get it working. But don't worry you will see these are the only non-standard Bascom-8051 things to put in.


' second test with the Wiznet W7100

$regfile = "w7100.dat"
$crystal = 11059200
$baud = 115200
 

Put the next values in the registers to get the baudrate right


Tl1 = &HFC                                                                                     ' 115200 baud
Th1 = &HFE
 

Just for now, a few subroutines to drive the LCD


Declare Sub Lcd_reg(r As Byte)
Declare Sub Lcd_char(c As Byte)
Declare Sub Init_lcd

Dim R As Byte ' register
Dim C As Byte ' character
Dim D As Byte ' temporary
Dim Tekst As String * 20                                                            ' string tekst
Dim Pos As Integer
Dim Z As String * 1

Reset P0.1                                                                                    ' R/w LCD display
Reset P0.0

Call Init_lcd
 

After this line you should see something on your LCD


Print "Start"
 

And after this line you should see something on your terminal

In the next loop the three LEDs should be blinking


Do
Set P0.3
Set P0.4
Set P0.5
Wait 1
Reset P0.3
Reset P0.4
Reset P0.5
Wait 1
Print "X";
Loop
End


Sub Init_lcd
Waitms 15
Call Lcd_reg(&H30)
Waitms 4
Call Lcd_reg(&H30)
Waitms 1
Call Lcd_reg(&H30)
Waitms 4
Call Lcd_reg(&H20)
Waitms 1
Call Lcd_reg(&H20)
Call Lcd_reg(&H80)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&H80)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&Hc0)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&H10)
Waitms 1
Tekst = "W7100 and Bascom"
For Pos = 1 To Len(tekst)
Z = Mid(tekst , Pos , 1)
Call Lcd_char(asc(z))
Next Pos
End Sub

Sub Lcd_reg(r As Byte)
P2 = R
P0.2 = 1                                                                                'toggle E
Waitms 1
P0.2 = 0
End Sub


Sub Lcd_char(c As Byte)
P2 = C
P0.2 = 1
P0.0 = 1
Waitms 1
P0.2 = 0
P0.0 = 0
Waitms 1
Rotate C , Left , 4
P2 = C
P0.2 = 1
P0.0 = 1
Waitms 1
P0.2 = 0
P0.0 = 0
Waitms 1
End Sub

 

Step 5: Include-file W7100.INC

 

We have to create an Include-file with all registers of the W7100 in it. If you have seen the W5100-include file for the Wiz810MJ-module you will see a lot of similarity.

W7100.inc

If we take a look at the TCPIPCore-memory-map: we see

FE0000-FE0034 Common Registers
FE4000-FE47FF Socket Registers
FE8000-FEBFFF TX memory
FEC000-FEFFFF RX memory

8 sockets can be used on the W7100 and it is real easy to figure out which registers belongs to which socket. Have a look at a part of the W7100.INC Bascom-8051 include file.

'Socket Mode register
Const w7100_S0_mr = &H4000
Const w7100_S1_mr = &H4100
Const w7100_S2_mr = &H4200
Const w7100_S3_mr = &H4300
Const w7100_S4_mr = &H4400
Const w7100_S5_mr = &H4500
Const w7100_S6_mr = &H4600
Const w7100_S7_mr = &H4700

'Channel Sn_CR register
Const w7100_S0_cr = &H4001
Const w7100_S1_cr = &H4101
Const w7100_S2_cr = &H4201
Const w7100_S3_cr = &H4301
Const w7100_S4_cr = &H4401
Const w7100_S5_cr = &H4501
Const w7100_S6_cr = &H4601
Const w7100_S7_cr = &H4701

'Channel interrupt register
Const w7100_S0_ir = &H4002
Const w7100_S1_ir = &H4102
Const w7100_S2_ir = &H4202
Const w7100_S3_ir = &H4302
Const w7100_S4_ir = &H4402
Const w7100_S5_ir = &H4502
Const w7100_S6_ir = &H4602
Const w7100_S7_ir = &H4702

'Channel status register
Const w7100_s0_sr = &H4003
Const w7100_s1_sr = &H4103
Const w7100_s2_sr = &H4203
Const w7100_s3_sr = &H4303
Const w7100_s4_sr = &H4403
Const w7100_s5_sr = &H4503
Const w7100_s6_sr = &H4603
Const w7100_s7_sr = &H4703
 

Step 6: Two routines to read and write in the TCPIPCore registers (FE0000-FEFFFF)

 

Here you see the external RAM of the W7100, 64 Kbytes SRAM, and 64 Kbytes for the TCPIP-core (including RX/TX buffers). Going over the C-examples I have seen the register DPX0 is used to gain access to this piece of memory.

Have written two small subroutines to get access to the FE0000-FEFFFF part of the memory:

Sub W7100_write
Disable Interrupts
Dpx0 = &HFE
Out Adres , Value
Dpx0 = 0
Enable Interrupts
End Sub


Sub W7100_read
Disable Interrupts
Dpx0 = &HFE
Value = Inp(adres)
Dpx0 = 0
Enable Interrupts
End Sub

The 000000-00FFFF can be accessed through Bascom-8051 INP and OUT commands.

If you check the WIZMEMCPY.C routine on the CD, or website of Wiznet, you will see a routine to move a bulk of bytes from the lower part of RAM (Embedded RAM) to the RX/TX-buffers (TCPIPCore) and visa-versa. The adresspointers DPTR and DPTR1 are incremented or decremented simultaneous. I think the copy is done with a small routine that can be found in the boot loader. With the WCONF register access to the bootloader is managed. Registers DPX0/1, DPH0/1, DPL0/1 are used for this action.

 

Step 7: PING

 

  312 bytes!!

312 bytes, that is all you need to get PING working on the W7100.

$regfile = "w7100.dat"
$crystal = 11059200
$baud = 115200
$large

Const Common_base = 0

$include "W7100.inc"

Declare Sub Tcpipcore_init

Call Tcpipcore_init

End


Sub Tcpipcore_init
Disable Interrupts
Dpx0 = &HFE

Out Gar0 , 192
Out Gar1 , 168
Out Gar2 , 0
Out Gar3 , 1

Out Subr0 , 255
Out Subr1 , 255
Out Subr2 , 255
Out Subr3 , 0

Out Shar0 , &H0
Out Shar1 , &H8
Out Shar2 , &HDC
Out Shar3 , &H14
Out Shar4 , &H83
Out Shar5 , &HA0

Out Sipr0 , 192
Out Sipr1 , 168
Out Sipr2 , 0
Out Sipr3 , 90

Dpx0 = 0
Enable Interrupts
End Sub

 

Step 8: UDP, getting the time from a NTP-server

 

Going real fast now. W5100 code fits one-to-one in the W7100. Have made a small test routine in Bascom-8051, UDP, Socket 0. A character sent to the iMCU7100 is received in FEC0000-FEC0009, 8 byte UDP-header followed by the character in the RX-buffer of the W7100. There is a small routine to wrap the received UDP string inside the Socket 0 2 Kbytes RX-buffer.

BTW, Elektor, a Dutch Electronics Magazine, just bought Circuit Cellar.

Screencopy of IRIS the Network Sniffer.

CE C7 E4 D7 received from the TimeServer

Screencopy of IRIS the Network Sniffer.

 

' UDP.  This works, LONG received from the Timeserver


$regfile = "w7100.dat"
$crystal = 11059200
$baud = 115200
$large

Dim Adres As Word
Dim Value As Byte

Const Common_base = 0

$include "W7100.inc"

Declare Sub Lcd_reg(r As Byte)
Declare Sub Lcd_char(c As Byte)
Declare Sub Init_lcd
Declare Sub Wiz_reset
Declare Sub Tcpipcode_read
Declare Sub W7100_write
Declare Sub W7100_init
Declare Sub W7100_reset


Dim R As Byte ' register
Dim C As Byte ' character
Dim D As Byte ' temporary
Dim Text As String * 20 ' string tekst
Dim Pos As Integer
Dim Z As String * 1

Dim Myip(4) As Byte
Dim Mymsk(4) As Byte
Dim Mygw(4) As Byte
Dim Mydestip(4) As Byte
Dim Mymac(6) As Byte

Dim Pointer As Word

Dim Bpointer As Word
Dim Size As Word
Dim Epointer As Word

Dim Wtempb As Word
Dim Wtempe As Word
Dim X As Word

Lcd_rs Alias P0.0
Lcd_rw Alias P0.1
Lcd_e Alias P0.2
Led0 Alias P0.3
Led1.4 Alias P0.4
Led2 Alias P0.5

Reset Lcd_rw
Reset Lcd_rs

Myip(1) = 192
Myip(2) = 168
Myip(3) = 0
Myip(4) = 10

Mymsk(1) = 255
Mymsk(2) = 255
Mymsk(3) = 255
Mymsk(4) = 0

Mygw(1) = 192
Mygw(2) = 168
Mygw(3) = 0
Mygw(4) = 1

'Mydestip(1) = 192
'Mydestip(2) = 168
'Mydestip(3) = 0
'Mydestip(4) = 70

Mymac(1) = &H0
Mymac(2) = &H11
Mymac(3) = &H12
Mymac(4) = &H13
Mymac(5) = &H14
Mymac(6) = &H15

Call Init_lcd
Call W7100_init

Reset Led2

Print Chr(&H1b) ; "[2J"; ' ANSI goto 0/0
Print "********************************"
Print "* Network summary *"
Print "********************************"
Print
Print "IP-number: ";
Adres = Sipr0 : Call W7100_read
Print Value ; ".";
Adres = Sipr1 : Call W7100_read
Print Value ; ".";
Adres = Sipr2 : Call W7100_read
Print Value ; ".";
Adres = Sipr3 : Call W7100_read
Print Value
Print
Print "Netmask: ";
Adres = Subr0 : Call W7100_read
Print Value ; ".";
Adres = Subr1 : Call W7100_read
Print Value ; ".";
Adres = Subr2 : Call W7100_read
Print Value ; ".";
Adres = Subr3 : Call W7100_read
Print Value
Print
Print "Gateway: ";
Adres = Gar0 : Call W7100_read
Print Value ; ".";
Adres = Gar1 : Call W7100_read
Print Value ; ".";
Adres = Gar2 : Call W7100_read
Print Value ; ".";
Adres = Gar3 : Call W7100_read
Print Value
Print
Print "MAC-addres: ";
Adres = Shar0 : Call W7100_read
Printhex Value ; ":";
Adres = Shar1 : Call W7100_read
Printhex Value ; ":";
Adres = Shar2 : Call W7100_read
Printhex Value ; ":";
Adres = Shar3 : Call W7100_read
Printhex Value ; ":";
Adres = Shar4 : Call W7100_read
Printhex Value ; ":";
Adres = Shar5 : Call W7100_read
Printhex Value
Print
Print "********************************"

'Get NTP-time
 

Protocol UDP


'protocol udp on socket 0
Adres = W7100_s0_mr
Value = Sn_mr_udp
Call W7100_write
 

destination port &H25 or 37


'destination port
Adres = W7100_s0_dport0
Value = &H0
Call W7100_write

'destination port
Adres = W7100_s0_dport1
Value = &H25
Call W7100_write
 

source port


'source port (&H1388 or 5000)
Adres = W7100_s0_port0
Value = &H13
Call W7100_write

Adres = W7100_s0_port1
Value = &H88
Call W7100_write
 

IP-number of a NTP-server in Holland


'ip-number NTP-server in Holland
Adres = W7100_s0_dipr0
Value = 193
Call W7100_write

Adres = W7100_s0_dipr1
Value = 67
Call W7100_write

Adres = W7100_s0_dipr2
Value = 79
Call W7100_write

Adres = W7100_s0_dipr3
Value = 202
Call W7100_write
 

Write something, here X followed by CR/LF


Adres = &H8000
Value = 88
Call W7100_write

Adres = &H8001
Value = &H0D
Call W7100_write

Adres = &H8002
Value = &H0A
Call W7100_write
 

Size to sent


Adres = W7100_s0_tx_wr0
Value = 0
Call W7100_write

Adres = W7100_s0_tx_wr1
Value = 3
Call W7100_write

'Give The Open Command
Adres = W7100_s0_cr
Value = Sn_cr_open
Call W7100_write


Wait 1
Adres = W7100_s0_cr
Value = Sn_cr_send
Call W7100_write


Do
Adres = W7100_s0_cr
Call W7100_read
Loop Until Value = 0

Print "X CR/LF should have been send"
Print


'check on RECV
Do
Adres = W7100_s0_ir
Call W7100_read
If Value.2 = 1 Then
Print "Received something on Socket 0"
Print

'read the Read Pointer
Adres = W7100_s0_rx_rd0
Call W7100_read
High(pointer) = Value

'read the Read Pointer
Adres = W7100_s0_rx_rd1
Call W7100_read
Low(pointer) = Value

Bpointer = Pointer

'Socket 0 RX Received Size
Adres = W7100_s0_rx_rsr0
Call W7100_read
High(size) = Value

Adres = W7100_s0_rx_rsr1
Call W7100_read
Low(size) = Value

Pointer = Pointer + Size
Epointer = Pointer

Print "Begin is " ; Bpointer
Print "End is " ; Epointer
Print "Size is " ; Size

Adres = W7100_s0_rx_rd0
Call W7100_read
Print "sn_rx_rd0 = " ; Value

Adres = W7100_s0_rx_rd1
Call W7100_read
Print "sn_rx_rd1 = " ; Value

Wtempb = &HC000 + Bpointer
Wtempe = Wtempb + Size

Wtempb = Wtempb + 8
Decr Wtempe

Print "Received UDP-string"
Print
For X = Wtempb To Wtempe
Adres = X
Call W7100_read
Printhex Value
Next X
Print
Print

'update pointer
Adres = W7100_s0_rx_rd0
Value = High(pointer)
Call W7100_write

Adres = W7100_s0_rx_rd1
Value = Low(pointer)
Call W7100_write

Adres = W7100_s0_cr
Value = Sn_cr_recv
Call W7100_write


'reset interrupt
Adres = W7100_s0_ir
Value = &B100
Call W7100_write

Exit Do
End If
Loop

End


Sub Init_lcd
Waitms 15
Call Lcd_reg(&H30)
Waitms 4
Call Lcd_reg(&H30)
Waitms 1
Call Lcd_reg(&H30)
Waitms 4
Call Lcd_reg(&H20)
Waitms 1
Call Lcd_reg(&H20)
Call Lcd_reg(&H80)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&H80)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&Hc0)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&H10)
Waitms 1

Text = "W7100 and Bascom"
For Pos = 1 To Len(text)
Z = Mid(text , Pos , 1)
Call Lcd_char(asc(z))
Next Pos
End Sub

Sub Lcd_reg(r As Byte)
P2 = R
Lcd_e = 1 'toggle E
Waitms 1
Lcd_e = 0
End Sub


Sub Lcd_char(c As Byte)
P2 = C
Lcd_e = 1
Lcd_rs = 1
Waitms 1
Lcd_e = 0
Lcd_rs = 0
Waitms 1
Rotate C , Left , 4
P2 = C
Lcd_e = 1
Lcd_rs = 1
Waitms 1
Lcd_e = 0
Lcd_rs = 0
Waitms 1
End Sub


Sub W7100_reset
Adres = Mr
Value = Mr_rst
Call W7100_write
Waitms 5
End Sub


Sub W7100_init
'specific registers
Tl1 = &HFC ' 115200 baud
Th1 = &HFE

Disable Interrupts
Dpx0 = &HFE

Out Gar0 , Mygw(1)
Out Gar1 , Mygw(2)
Out Gar2 , Mygw(3)
Out Gar3 , Mygw(4)

Out Subr0 , Mymsk(1)
Out Subr1 , Mymsk(2)
Out Subr2 , Mymsk(3)
Out Subr3 , Mymsk(4)

Out Shar0 , Mymac(1)
Out Shar1 , Mymac(2)
Out Shar2 , Mymac(3)
Out Shar3 , Mymac(4)
Out Shar4 , Mymac(5)
Out Shar5 , Mymac(6)

Out Sipr0 , Myip(1)
Out Sipr1 , Myip(2)
Out Sipr2 , Myip(3)
Out Sipr3 , Myip(4)

Dpx0 = 0
Enable Interrupts
End Sub



Sub W7100_write
Disable Interrupts
Dpx0 = &HFE
Out Adres , Value
Dpx0 = 0
Enable Interrupts
End Sub



Sub W7100_read
Disable Interrupts
Dpx0 = &HFE
Value = Inp(adres)
Dpx0 = 0
Enable Interrupts
End Sub

Made the same routine on the Wiz810MJ (W5100) with an Atmega168 microcontroller. Written in Bascom-AVR. In Bascom-AVR there is a datetime.lbx library to convert this LONG from a NTP-server to real Date and Time. There isn't such a library in Bascom-8051.

 

Step 10: HTTP with buttons

 


$regfile = "w7100.dat"
$crystal = 11059200
$baud = 115200
$large

Dim Adres As Word
Dim Value As Byte

Const Common_base = 0

$include "W7100.inc"

Declare Sub Lcd_reg(r As Byte)
Declare Sub Lcd_char(c As Byte)
Declare Sub Init_lcd
Declare Sub W7100_write(adres As Word , Value As Byte)
Declare Sub W7100_read(adres As Word)
Declare Sub W7100_init
Declare Sub W7100_reset
Declare Sub W7100_disconnect
Declare Sub W7100_receive
Declare Sub W7100_send
Declare Sub Led0
Declare Sub Led1
Declare Sub Led2

Dim R As Byte                                                                                   ' register
Dim C As Byte                                                                                   ' character
Dim D As Byte                                                                                   ' temporary
Dim Pos As Integer
Dim Z As String * 1

Dim Status As Byte
Dim Oldstatus As Byte

Dim Buffer As String * 124

Dim Pointer As Word
Dim X As Integer

Dim I As Word
Dim Top As Word
Dim Bytes_rcv As Word

Dim Sendsize As Integer
Dim Pos_tx As Word
Dim Freesize As Word
Dim Offset As Word
Dim Tx_wr As Word
Dim Startadress As Word
Dim Offsend As Word
Dim Uppersize As Word
Dim Glaenge As Word
Dim Startpos As Word
Dim Website As Byte
Dim Tmp_str As String * 1
Dim Tmp_value As Byte
Dim Highbyte As Byte
Dim Lowbyte As Byte

Dim Temp As Byte
Dim Wtemp As String * 8

Dim Char As Byte
Dim Xtemp As Byte
Dim Whulp1 As Word
Dim Whulp2 As Word

Lcd_rs Alias P0.0
Lcd_rw Alias P0.1
Lcd_e Alias P0.2
Led0 Alias P0.3
Led1 Alias P0.4
Led2 Alias P0.5

Reset Lcd_rw
Reset Lcd_rs

Call Init_lcd
Call W7100_init

Print Chr(&H1b) ; "[2J"; ' ANSI goto 0/0
Print "********************************"
Print "* Network summary *"
Print "********************************"
Print
Print "IP-number: ";
Call W7100_read(sipr0)
Print Value ; ".";
Call W7100_read(sipr1)
Print Value ; ".";
Call W7100_read(sipr2)
Print Value ; ".";
Call W7100_read(sipr3)
Print Value
Print
Print "Netmask: ";
Call W7100_read(subr0)
Print Value ; ".";
Call W7100_read(subr1)
Print Value ; ".";
Call W7100_read(subr2)
Print Value ; ".";
Call W7100_read(subr3)
Print Value
Print
Print "Gateway: ";
Call W7100_read(gar0)
Print Value ; ".";
Call W7100_read(gar1)
Print Value ; ".";
Call W7100_read(gar2)
Print Value ; ".";
Call W7100_read(gar3)
Print Value
Print
Print "MAC-addres: ";
Call W7100_read(shar0)
Printhex Value ; ":";
Call W7100_read(shar1)
Printhex Value ; ":";
Call W7100_read(shar2)
Printhex Value ; ":";
Call W7100_read(shar3)
Printhex Value ; ":";
Call W7100_read(shar4)
Printhex Value ; ":";
Call W7100_read(shar5)
Printhex Value
Print
Print "********************************"
Print
Print "Start HTTP-part"
Print

Do
' get socket status
Call W7100_read(w7100_s0_sr)
Status = Value

If Status <> Oldstatus Then
Oldstatus = Status
End If

'connection was closed, we start the socket new
If Status = &H0 Or Status = &H1C Then
Call W7100_disconnect
End If

'as long as connection is established (&H17) we will look if client send new data
If Status = &H17 Then
Buffer = ""
'
Wait 1                                                            ' this one is very important to get the complete packet
'
Call W7100_receive
End If
Loop
End


Sub Init_lcd
Waitms 15
Call Lcd_reg(&H30)
Waitms 4
Call Lcd_reg(&H30)
Waitms 1
Call Lcd_reg(&H30)
Waitms 4
Call Lcd_reg(&H20)
Waitms 1
Call Lcd_reg(&H20)
Call Lcd_reg(&H80)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&H80)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&Hc0)
Waitms 1
Call Lcd_reg(&H00)
Call Lcd_reg(&H10)
Waitms 1

Buffer = "W7100 and Bascom"
For Pos = 1 To Len(buffer)
Z = Mid(buffer , Pos , 1)
Call Lcd_char(asc(z))
Next Pos
Buffer = ""
End Sub

Sub Lcd_reg(r As Byte)
P2 = R
Lcd_e = 1                                                                        'toggle E
Waitms 1
Lcd_e = 0
End Sub


Sub Lcd_char(c As Byte)
P2 = C
Lcd_e = 1
Lcd_rs = 1
Waitms 1
Lcd_e = 0
Lcd_rs = 0
Waitms 1
Rotate C , Left , 4
P2 = C
Lcd_e = 1
Lcd_rs = 1
Waitms 1
Lcd_e = 0
Lcd_rs = 0
Waitms 1
End Sub


Sub W7100_reset
Call W7100_write(mr , Mr_rst)
Waitms 5
End Sub


Sub W7100_init
'specific registers
Tl1 = &HFC '115200 baud
Th1 = &HFE

Call W7100_write(w7100_s0_mr , Mr_rst)

Disable Interrupts
Dpx0 = &HFE

Out Gar0 , 192
Out Gar1 , 168
Out Gar2 , 0
Out Gar3 , 1

Out Subr0 , 255
Out Subr1 , 255
Out Subr2 , 255
Out Subr3 , 0

Out Shar0 , &H00
Out Shar1 , &H11
Out Shar2 , &H12
Out Shar3 , &H13
Out Shar4 , &H14
Out Shar5 , &H15

Out Sipr0 , 192
Out Sipr1 , 168
Out Sipr2 , 0
Out Sipr3 , 10

Dpx0 = 0
Enable Interrupts

'for HTTP

'initialize socket 0 with TCP on Port 80
Call W7100_write(w7100_s0_mr , Sn_mr_tcp)

Call W7100_write(w7100_s0_port0 , 0)

Call W7100_write(w7100_s0_port1 , &H50)

Call W7100_disconnect

End Sub


Sub W7100_write(adres , Value)
Disable Interrupts
Dpx0 = &HFE
Out Adres , Value
Dpx0 = 0
Enable Interrupts
End Sub


Sub W7100_read
Disable Interrupts
Dpx0 = &HFE
Value = Inp(adres)
Dpx0 = 0
Enable Interrupts
End Sub

Sub W7100_disconnect
Call W7100_write(w7100_s0_cr , Sn_cr_close)
Call W7100_write(w7100_s0_cr , Sn_cr_open)
Call W7100_write(w7100_s0_cr , Sn_cr_listen)
End Sub


Sub W7100_receive
'check for new incoming data
Call W7100_read(w7100_s0_rx_rsr0)
Bytes_rcv = Value
Shift , Bytes_rcv , Left , 8
Call W7100_read(w7100_s0_rx_rsr1)
Bytes_rcv = Bytes_rcv + Value

If Bytes_rcv > 0 Then

For I = 0 To Bytes_rcv
Top = I + &HC000 'rx memory socket 0
Call W7100_read(top)
'store complete packet in XRAM
Out I , Value
Next I

'proces the complete packet

Buffer = ""
For I = 0 To 63
Xtemp = Inp(i)
Buffer = Buffer + Chr(xtemp)
Next I

Wtemp = "POST /"
Temp = Instr(buffer , Wtemp)
If Temp > 0 Then

Buffer = ""

' get the last 60 characters of the packet
Whulp1 = Bytes_rcv - 60
Whulp2 = Bytes_rcv
For I = Whulp1 To Whulp2
Xtemp = Inp(i)
Buffer = Buffer + Chr(xtemp)
Next I

Wtemp = "LED0=0"
Temp = Instr(buffer , Wtemp)
If Temp > 0 Then
Call Led0
End If

Wtemp = "LED1=0"
Temp = Instr(buffer , Wtemp)
If Temp > 0 Then
Call Led1
End If

Wtemp = "LED2=0"
Temp = Instr(buffer , Wtemp)
If Temp > 0 Then
Call Led2
End If

Buffer = ""
End If

'set RECV flag
Call W7100_write(w7100_s0_sr , &H40)

Website = 0
Call W7100_send

End If
End Sub


Sub W7100_send
Restore Websiteok

Do
Read Buffer

'look for the end of a website
If Buffer = "%END%" Then
Exit Do
End If

If Buffer = "%IP%" Then
'here we show the client IP-adress
Call W7100_read(w7100_s0_dipr0)
Buffer = Str(value) + "."

'here we show the client IP-adress
Call W7100_read(w7100_s0_dipr1)
Buffer = Buffer + Str(value) + "."

'here we show the client IP-adress
Call W7100_read(w7100_s0_dipr2)
Buffer = Buffer + Str(value) + "."

'here we show the client IP-adress
Call W7100_read(w7100_s0_dipr3)
Buffer = Buffer + Str(value)

End If

If Buffer = "%LED0%" Then
Call Part1
Buffer = Buffer + "LED0"
Call Part2
Buffer = Buffer + "0" + Chr(34) + "/></form>"
End If

If Buffer = "%LED1%" Then
Call Part1
Buffer = Buffer + "LED1"
Call Part2
Buffer = Buffer + "1" + Chr(34) + "/></form>"
End If

If Buffer = "%LED2%" Then
Call Part1
Buffer = Buffer + "LED2"
Call Part2
Buffer = Buffer + "2" + Chr(34) + "/></form>"
End If

Sendsize = Len(buffer)

Freesize:
Call W7100_read(w7100_s0_tx_fsr0)
Freesize = Value
Shift Freesize , Left , 8
Call W7100_read(w7100_s0_tx_fsr1)
Freesize = Freesize + Value

If Freesize < Sendsize Then
Goto Freesize
End If

Call W7100_read(w7100_s0_tx_wr0)
Tx_wr = Value
Shift Tx_wr , Left , 8
Call W7100_read(w7100_s0_tx_wr1)
Tx_wr = Tx_wr + Value

Startpos = Tx_wr

Offset = Tx_wr And &H7FF
Startadress = &H8000 + Offset
Offsend = Offset + Sendsize
Pointer = Startadress

If Offsend > &H800 Then
Uppersize = &H800 - Offset

For X = 1 To Uppersize
Tmp_str = Mid(buffer , X , 1)
Tmp_value = Asc(tmp_str)
Call W7100_write(pointer , Tmp_value)
Incr Pointer
Next X

Pointer = &H8000
Incr Uppersize

For X = Uppersize To Sendsize
Tmp_str = Mid(buffer , X , 1)
Tmp_value = Asc(tmp_str)
Call W7100_write(pointer , Tmp_value)
Incr Pointer
Next X
Else
For X = 1 To Sendsize
Tmp_str = Mid(buffer , X , 1)
Tmp_value = Asc(tmp_str)
Call W7100_write(pointer , Tmp_value)
Incr Pointer
Next X
End If

Call W7100_read(w7100_s0_tx_wr0)
Startpos = Value
Shift Startpos , Left , 8
Call W7100_read(w7100_s0_tx_wr1)
Startpos = Startpos + Value
Glaenge = Startpos + Sendsize

'send site
Highbyte = High(glaenge)
Call W7100_write(w7100_s0_tx_wr0 , Highbyte)

Lowbyte = Low(glaenge)
Call W7100_write(w7100_s0_tx_wr1 , Lowbyte)

'set send flag
Call W7100_write(w7100_s0_cr , &H20)
Loop

'set DISCON flag
Call W7100_write(w7100_s0_cr , &H8)
End Sub

Sub Led0
Reset Led0
Waitms 500
Set Led0
End Sub

Sub Led1
Reset Led1
Waitms 500
Set Led1
End Sub

Sub Led2
Reset Led2
Waitms 500
Set Led2
End Sub

Sub Part1
Buffer = "<br/><form action=" + Chr(34) + "/" + Chr(34) + " method=" + Chr(34) + "POST" + Chr(34) + ">"
Buffer = Buffer + "<input type=" + Chr(34) + "hidden" + Chr(34) + " name=" + Chr(34)
End Sub

Sub Part2
Buffer = Buffer + Chr(34) + " value=" + Chr(34) + "0" + Chr(34) + ">"
Buffer = Buffer + "<input type=" + Chr(34) + "submit" + Chr(34) + " value=" + Chr(34) + "LED"
End Sub


'A Variable must stand alone in a separate Line !!!
Websiteok:
Data "HTTP/1.0 200 Document follows" , $0d , $0a , "Server: webserver" , $0d , $0a , "Content-Type: text/html" , $0d , $0a , $0d , $0a
Data "<html><head><meta http-equiv=" , $22 , "Pragma" , $22 , " Content=" , $22 , "no-cache" , $22 , " >"
Data "<title>W7100 Blinky</title></head><body><center>"
Data "<table width=" , $22 , "300" , $22 , "><tr><td align=" , $22 , "center" , $22 , "><font face=" , $22 , "verdana" , $22
Data " color=" , $22 , "#000000" , $22 , ">"
Data "<H1>W7100-blinky</H1><br>Blink"
Data "%LED0%"
Data "<br>Blink"
Data "%LED1%"
Data "<br>Blink"
Data "%LED2%"
Data "<br><br><font face" , $3d , $22 , "verdana" , $22 , " color" , $3d , $22 , "#000000" , $22 , ">Your IP-number is: <b>"
Data "%IP%"
Data "<br><hr><br>benshobbycorner.nl"
Data "</a></font></center></body></html>"
Data "%END%"

 

The complete TCP/IP-packet is stored in XRAM, the first 60 bytes is examined for the POST / command and if it is found, the last 60 bytes is checked for the commands LED0=0, LED1=0 or LED2=0

Again, check the tutorial for the WIZ810MJ for all details on registers.

 

Good luck with the Circuit Cellar contest!!!

 

 

Thanks to:


Thanks to Mark Alberts
the creator of Bascom-8051
www.mcselec.com

Bought my copy of Bascom-8051 in 1995
a few years later Bascom-AVR
Great stuff!!!

 

Thanks to Thomas Heldt
He created the first Bascom-AVR-code for the WIZ810MJ
https://mikrocontroller.heldt.eu
(Held is hero in Dutch)

 

Thanks to Wiznet - South Korea.
Worked with the W5100, W5300, W610wi
and now with the W7100. Great chips!!

 

Flags can be downloaded at www.3DFlags.com

 

Ben Zijlstra - Ben's HobbyCorner - 2010