View previous topic :: View next topic |
Author |
Message |
littlethinker
Joined: 05 Oct 2013 Posts: 2
|
Posted: Sat Oct 05, 2013 3:49 pm Post subject: W5100 on Arduino with DHCP |
|
|
Hi,
i'm searching for a sample code for the W5100 Ethernet Shield with an Arduino. I have found this code on the internet (from this forum) but it has a problem:
Code: |
' DHCP on W5100 on an Arduino Duemilanove Atmega328p
' optimized for less RAM use
' works
$regfile = "m1280def.dat"
$crystal = 16000000
$baud = 57600 'put terminal on 9600 baud
$hwstack = 80
$swstack = 80
$framesize = 90
'Used global variables
Dim Arraysize As Word
Dim Size As Word
Dim Sizel As Byte At Size Overlay
Dim Sizeh As Byte At Size + 1 Overlay
Dim Adres As Word
Dim Adresl As Byte At Adres Overlay
Dim Adresh As Byte At Adres + 1 Overlay
Dim Tmp_ip (4) As Byte
Dim Value As Byte
Dim Myip (4) As Byte
Dim Subnet (4) As Byte
Dim Gateway (4) As Byte
Dim Destip (4) As Byte
Dim Myport (2) As Byte
Dim Destport (2) As Byte
Dim Dhcp (4) As Byte
Dim Dns (4) As Byte
Dim Mac (6) As Byte
Dim Char (590) As Byte
Dim Wiz5100_opcode_read As Byte : Wiz5100_opcode_read = 15
Dim Wiz5100_opcode_write As Byte : Wiz5100_opcode_write = 240
'Used Wiz5100 ports and pins
Wiz5100_cs Alias Portb.4 'Chipselect WIZ5100
'Wiz5100_int Alias Portb.1 'INT of WIZ5100
'Wiz5100_res Alias Portc.0 'Reset of WIZ5100
'Used ports and pins
Config Wiz5100_cs = Output
'Config Wiz5100_int = Input
'Config Wiz5100_res = Output
'Configuration of the SPI-bus
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0
'Init the spi pins
Spiinit
'Enable Interrupts
Mac (1) = &H00
Mac (2) = &H00
Mac (3) = &H02
Mac (4) = &H03
Mac (5) = &H04
Mac (6) = &H05
'Here we declare the used sub routines
Declare Sub Wiz5100_init
Declare Sub Wiz5100_readvalue (byval Reg As Word)
Declare Sub Wiz5100_writevalue (byval Reg As Word , Byval Value As Byte)
Declare Sub Wiz5100_reset
Declare Sub Wiz5100_dhcp_discover
Declare Sub Wiz5100_read_rcv_buf
Declare Sub Wiz5100_dhcp_request
Declare Sub Wiz5100_dhcp_ack
Declare Sub Wiz5100_setup_udp
Declare Sub Wiz5100_build_dhcp_packet
Declare Sub Wiz5100_write_xmit_buf
$include "w5100.inc"
Print "Start programma"
Begin :
Call Wiz5100_dhcp_discover
Main :
'###############################################################################
'######################## Main Program Loop #################################
Do
Call Wiz5100_readvalue (w5100_s0_ir )
Value = Value And &H04 ' mask out the data bit
If Value = 4 Then
Call Wiz5100_readvalue (w5100_s0_mr ) ' Check mode
If Value = 2 Then ' UDP - DHCP
Call Wiz5100_read_rcv_buf ' verify transaction id
If Char (13) = &H39 And Char (14) = &H03 And Char (15) = &HF3 And Char (16) = &H26 Then
Select Case Char (251)
Case 2: ' DHCP Offer
Call Wiz5100_dhcp_request
Case 5: 'DHCP ACK
Call Wiz5100_dhcp_ack
Case Else:
Goto Main ' bail- not right
End Select
Else
Goto Main ' not our message
End If
End If
End If
Loop
End
'###############################################################################
'******************** DHCP Discover *****************************
Sub Wiz5100_dhcp_discover
Local Tmp_byte As Byte
Local I As Word
Print "Routine Wiz5100_dhcp discover"
Call Wiz5100_readvalue (w5100_s0_ir )
Value = Value And &H04 ' mask out the Recv data bit
Tmp_byte = 1
For I = 1 To 4
Myip (i ) = &H00 ' zero out registers for discovery
Subnet (i ) = &H00
Gateway (i ) = &H00
Destip (i ) = &HFF ' set destip for broadcast
Next I
Myport (1) = &H00 ' Source Port 68
Myport (2) = &H44
Destport (1) = &H00 ' Destination Port 67
Destport (2) = &H43
Call Wiz5100_init ' initialize module
Call Wiz5100_setup_udp ' Open UDP Socket
' UDP provides first 8 bytes of packet
Call Wiz5100_build_dhcp_packet ' Build Packet up to magic cookie
Char (241) = &H35 ' option 53 DHCP Discover
Char (242) = &H01 ' Length
Char (243) = &H01 ' Discover Command
Char (244) = &H37 ' option 55 - Parameter list
Char (245) = &H03 ' Length of list
Char (246) = &H01 ' Subnet mask
Char (247) = &H03 ' Router(Gateway0
Char (248) = &H06 ' Domain Name Server
Char (249) = &HFF ' End of options
For I = 250 To 308 ' pad to 308 bytes
Char (i ) = &H00
Next I
Arraysize = 308
Call Wiz5100_write_xmit_buf ' write to tranmit buffer
End Sub
'*********************** Read Received Bytes *******************************
Sub Wiz5100_read_rcv_buf
Local Highbyte As Byte
Local Lowbyte As Byte
Local X As Word
Local Last_rx_pos As Word
Local Rx_pos As Word
Local Bufaddress As Word
Local Highsend As Word
Local Uppersize As Word
Local New_rx_pos As Word
Print "Routine Wiz5100_read_rcv_buf"
Waitms 10
Call Wiz5100_readvalue (w5100_s0_rx_rsr0 ) ' get number of bytes received
Sizeh = Value
'Shift , Arraysize , Left , 8 ' move to high byte
Call Wiz5100_readvalue (w5100_s0_rx_rsr1 )
Sizel = Value
Arraysize = Size And &H7FF
'Tmp_int = 1 ' for printing purposes
Waitms 10
'now read data from receive buffer
Call Wiz5100_readvalue (w5100_s0_rx_rd0 )
Last_rx_pos = Value
Shift , Last_rx_pos , Left , 8
Call Wiz5100_readvalue (w5100_s0_rx_rd1 )
Last_rx_pos = Last_rx_pos + Value
' Startpos = Last_rx_pos
Rx_pos = Last_rx_pos And &H7FF
Bufaddress = &H6000 + Rx_pos ' Gs0_rx_base
Highsend = Rx_pos + Size ' Establish highest address
'Start at next read address
If Highsend > &H7FF Then ' Size goes Over upper limit
Uppersize = &H7FF - Rx_pos
For X = 1 To Uppersize ' go to upper limit
Call Wiz5100_readvalue (bufaddress )
Char (x ) = Value
Incr Bufaddress
Next X
Bufaddress = &H6000 ' continue at beginning of memory (Gs0_rx_base)
Incr Uppersize
For X = Uppersize To Size '
Call Wiz5100_readvalue (bufaddress )
Char (x ) = Value
Incr Bufaddress
Next X
Else ' Offset does not rollover upper limit
For X = 1 To Size
Call Wiz5100_readvalue (bufaddress )
Char (x ) = Value
Incr Bufaddress
Next X
End If
New_rx_pos = Last_rx_pos + Arraysize ' Add the size we received to last known
Highbyte = High(new_rx_pos ) 'Write new position to the pointer
Call Wiz5100_writevalue (w5100_s0_rx_rd0 , Highbyte )
Lowbyte = Low(new_rx_pos )
Call Wiz5100_writevalue (w5100_s0_rx_rd1 , Lowbyte )
Call Wiz5100_writevalue (w5100_s0_cr , &H40 ) ' Send the Recv command
Call Wiz5100_writevalue (w5100_s0_ir , &H04 ) ' Clear receive interrupt bit
' for next receive
End Sub
'*************************** DHCP Request *****************************
Sub Wiz5100_dhcp_request
Local Tmp_byte As Byte
Local I As Word
Local X As Word
Print "Routine Wiz5100_dhcp request"
' set values from receive buffer data on DHCP offer
Tmp_ip (1) = Char (25)
Tmp_ip (2) = Char (26)
Tmp_ip (3) = Char (27)
Tmp_ip (4) = Char (28)
' Locate DHCP server
X = 252 ' set index to first option command
Do
Tmp_byte = Char (x ) ' get option code
Select Case Tmp_byte
Case 54: ' Option 54:DHCP Server
X = X + 2 ' go to first IP value
For I = 1 To 4
Dhcp (i ) = Char (x )
Incr X
Next I
Goto Continue
Case Else ' something else
Incr X
I = Char (x ) ' get length
X = X + I ' skip to last data byte
Incr X ' index to next option code
End Select
Loop Until Char (x ) = &HFF ' Loop until End of Options
Continue :
Call Wiz5100_build_dhcp_packet ' Build Packet up to magic cookie
Char (241) = &H35 ' option 53 DHCP Command
Char (242) = &H01 ' Length
Char (243) = &H03 ' DHCP Request
Char (244) = &H32 ' option 50 requested IP (yourIP)
Char (245) = &H04 ' Length =4
Char (246) = Tmp_ip (1) ' yourip from offer
Char (247) = Tmp_ip (2) '
Char (248) = Tmp_ip (3) '
Char (249) = Tmp_ip (4) '
Char (250) = &H36 ' Option 54:DHCP Server
Char (251) = &H04 ' Length = 4
Char (252) = Dhcp (1) ' DHCP server selected from Offer
Char (253) = Dhcp (2) '
Char (254) = Dhcp (3) '
Char (255) = Dhcp (4)
Char (256) = &H37 ' option 55 - Parameter list
Char (257) = &H03 ' Length of list
Char (258) = &H01 ' Subnet mask
Char (259) = &H03 ' Router(Gateway0
Char (260) = &H06 ' Domain Name Server (DNS)
Char (261) = &HFF ' Option 255:Options End
For I = 262 To 308 ' pad to 308
Char (i ) = &H00
Next I
Arraysize = 308
Call Wiz5100_write_xmit_buf ' write to tranmit buffer
Call Wiz5100_readvalue (w5100_s0_ir ) ' mask out the Recv data bit
Value = Value And &H04 ' to enable receive interrupt
End Sub
'*********************** DHCP Acknowledge *********************************
Sub Wiz5100_dhcp_ack
Local Tmp_byte As Byte
Local I As Word
Local X As Word
Print "Routine Wiz5100_dhcp_ack"
Myip (1) = Char (25) ' Get My IP Address
Myip (2) = Char (26)
Myip (3) = Char (27)
Myip (4) = Char (28)
Print "IP: " ; Myip (1) ; "." ; Myip (2) ; "." ; Myip (3) ; "." ; Myip (4)
'Search out Options
X = 252 ' set index to first option code - 1
Do
Tmp_byte = Char (x ) ' get option code
Select Case Tmp_byte
Case 1: 'Option 01:Subnet Mask
X = X + 2 ' skip length byte to first value
For I = 1 To 4 ' Load Subnet
Subnet (i ) = Char (x )
Incr X
Next I
Print "Subnet: " ; Subnet (1) ; "." ; Subnet (2) ; "." ; Subnet (3) ; "." ; Subnet (4)
Case 3: 'Option 03:Router IP (Gateway)
X = X + 2 ' skip length byte to first value
For I = 1 To 4 ' Load Gateway
Gateway (i ) = Char (x )
Incr X
Next I
Print "Gateway: " ; Gateway (1) ; "." ; Gateway (2) ; "." ; Gateway (3) ; "." ; Gateway (4)
Case 6: 'Option 6: DNS server
X = X + 2 ' skip length byte to first value
For I = 1 To 4 ' Load DNS Server
Dns (i ) = Char (x )
Incr X
Next I
Print "DNS Server: " ; Dns (1) ; "." ; Dns (2) ; "." ; Dns (3) ; "." ; Dns (4)
Case 54: ' Option 54:DHCP Router
X = X + 2 ' go to first IP value
For I = 1 To 4
Dhcp (i ) = Char (x )
Incr X
Next I
Print "DHCP Server: " ; Dhcp (1) ; "." ; Dhcp (2) ; "." ; Dhcp (3) ; "." ; Dhcp (4)
Case Else ' An Option we dont want - skip by it
Incr X ' go to length byte
I = Char (x )
X = X + I ' go to last byte of this option
Incr X 'index to next option code
End Select
Loop Until Char (x ) = &HFF ' Loop until End of Options
Call Wiz5100_writevalue (w5100_s0_cr , &H08 ) 'disconnect
Call Wiz5100_writevalue (w5100_s0_cr , &H08 ) 'close socket
'****************************************
Call Wiz5100_init
'****************************************
'
' This returns to Main Program loop
' Exit point from DHCP discovery - save to E2prom / switch back to tcp mode
' or whatever you are doing.
End Sub
'................Setup UDP Connection ......................
Sub Wiz5100_setup_udp
Print "Routine Wiz5100_setup_udp"
Call Wiz5100_writevalue (w5100_s0_mr , &H02 ) 'Set mode to UDP
Call Wiz5100_writevalue (w5100_s0_cr , &H01 ) 'Sn_cr_open
Waitms 100
Do
Call Wiz5100_readvalue (w5100_s0_sr )
Loop Until Value = &H22 'Wait for UDP socket
' good to go for transmission no connection required
End Sub
'********************** Build DHCP PACKET ***********************************
Sub Wiz5100_build_dhcp_packet
Local I As Word
Print "Routine Wiz5100_build_dhcp_packet"
Char (1) = &H01 ' 01 = DHCP Request
Char (2) = &H01 'HType -1 for 10Mb Ethernet
Char (3) = &H06 'HLEN - Hardware address length
Char (4) = &H00
'Hops
Char (5) = &H39 ' XID =transaction id (4 bytes)
Char (6) = &H03 ' This can be a random number, but
Char (7) = &HF3 ' remains the same throughout DHCP
Char (8) = &H26 ' process XID = 39 03 F3 26
For I = 9 To 28 ' zero fields for DHCP discovery
Char (i ) = &H00
Next I
' here's what they are
' Char(9) = &H00 'Secs
' Char(10) = &H00
' Char(11) = &H00 'Flags
' Char(12) = &H00
' Char(13) = &H00 'Client IP address
' Char(14) = &H00
' Char(15) = &H00
' Char(16) = &H00
' Char(17) = &H00 'Your IP address
' Char(1 = &H00 ' remains zeroed on outgoing packets
' Char(19) = &H00
' Char(20) = &H00
' Char(21) = &H00 'Server IP
' Char(22) = &H00
' Char(23) = &H00
' Char(24) = &H00
' Char(25) = &H00 'Gateway IP
' Char(26) = &H00
' Char(27) = &H00
' Char(2 = &H00
Char (29) = Mac (1) ' Hardware - Mac Address
Char (30) = Mac (2)
Char (31) = Mac (3)
Char (32) = Mac (4)
Char (33) = Mac (5)
Char (34) = Mac (6)
For I = 35 To 44 ' Hardware Padding
Char (i ) = &H00
Next I
For I = 45 To 236 'Send 192 bytes of &H00 (Bootp Legacy)
Char (i ) = &H00 'Zero Padding
Next I
Char (237) = &H63 ' Magic cookie
Char (238) = &H82
Char (239) = &H53
Char (240) = &H63
End Sub
'***************** Write to Transmit Buffer *******************************
Sub Wiz5100_write_xmit_buf
Local Highbyte As Byte
Local Lowbyte As Byte
Local Tmp_word As Word
Local X As Word
Local Last_tx_pos As Word
Local Bufaddress As Word
Local Highsend As Word
Local Uppersize As Word
Local Tx_pos As Word
Local New_tx_pos As Word
Print "Routine Wiz5100_write_xmit_buf"
'Free memory check not needed this application
'never will go over
Freesize :
Call Wiz5100_readvalue (w5100_s0_tx_fsr0 ) ' Make sure data room and
Tmp_word = Value * 256 ' and timing available
Call Wiz5100_readvalue (w5100_s0_tx_fsr1 )
Tmp_word = Tmp_word + Value
If Tmp_word < Arraysize Then Goto Freesize
' writes data to transmit buffer - arraysize sets variable size
'Tmp_int = 1 ' used for print statements
Size = Arraysize ' number of bytes to be sent
Call Wiz5100_readvalue (w5100_s0_tx_wr0 ) 'Locate Buffer pointer
Last_tx_pos = Value
Shift , Last_tx_pos , Left , 8 ' move to high byte
Call Wiz5100_readvalue (w5100_s0_tx_wr1 )
Last_tx_pos = Last_tx_pos + Value ' add lowbyte
'last_tx_pos = position in pointer memory + random mirror bits
Tx_pos = Last_tx_pos And &H7FF ' mask to remove all but socket memory size
Bufaddress = &H4000 + Tx_pos ' add base to tx_pos to = Physical start buffer address
Highsend = Tx_pos + Size ' Add byte count to position in socket memory
If Highsend > &H7FF Then ' Will it over flow upper limit of socket memory
Uppersize = &H7FF - Tx_pos ' Yes, split at upper limit of socket memory
For X = 1 To Uppersize ' write to upper limit
Call Wiz5100_writevalue (bufaddress , Char (x ))
Incr Bufaddress
Waitms 5 '????????????????????????????????????????????????
Next X
Bufaddress = &H4000 ' wrap back to beginning of socket memory ( Gs0_tx_base)
Incr Uppersize
For X = Uppersize To Size ' write the rest of the data
Call Wiz5100_writevalue (bufaddress , Char (x ))
Incr Bufaddress
Waitms 5 '????????????????????????????????????????????????
Next X
Else ' No, it stays within memory size
For X = 1 To Size
Call Wiz5100_writevalue (bufaddress , Char (x ))
Incr Bufaddress
Waitms 5 '????????????????????????????????????????????????
Next X
End If
'Send it out and save new pointer
New_tx_pos = Last_tx_pos + Arraysize 'add size to last xmit byte pointer
Highbyte = High(new_tx_pos )
Lowbyte = Low(new_tx_pos )
Call Wiz5100_writevalue (w5100_s0_tx_wr0 , Highbyte ) ' Save new pointer
Call Wiz5100_writevalue (w5100_s0_tx_wr1 , Lowbyte )
Call Wiz5100_writevalue (w5100_s0_cr , &H20 ) 'Sn_cr_send Send it all
Do
Call Wiz5100_readvalue (w5100_s0_cr ) ' wait for send complete
Loop Until Value = 0
End Sub
'(
'Disconnect connection: close socket, reopen socket and wait for new connection
Sub Wiz5100_disconnect
Call Wiz5100_writevalue (w5100_s0_cr , Sn_cr_close ) 'CLOSE
Call Wiz5100_writevalue (w5100_s0_cr , Sn_cr_open ) 'OPEN
Call Wiz5100_writevalue (w5100_s0_cr , Sn_cr_listen ) 'LISTEN
End Sub
')
'***************** Wiz810MJ Initialization **********************************
Sub Wiz5100_init ()
Print "Routine Wiz5100_init"
Call Wiz5100_reset 'Hardware reset
Call Wiz5100_writevalue (w5100_mr , &H80 ) ' Software reset
'Assign all 2k memory to every socket for RX
Call Wiz5100_writevalue (w5100_rmsr , &H55 ) '&H55 &B01010101
'Assign all 2k memory to every socket for TX
Call Wiz5100_writevalue (w5100_tmsr , &H55 ) '&B01010101) '&H55
Call Wiz5100_writevalue (w5100_sipr0 , Myip (1)) ' Set own IP adress
Call Wiz5100_writevalue (w5100_sipr1 , Myip (2))
Call Wiz5100_writevalue (w5100_sipr2 , Myip (3))
Call Wiz5100_writevalue (w5100_sipr3 , Myip (4))
Call Wiz5100_writevalue (w5100_s0_port0 , Myport (1)) 'My Port 68
Call Wiz5100_writevalue (w5100_s0_port1 , Myport (2))
Call Wiz5100_writevalue (w5100_subr0 , Subnet (1)) 'Set Subnetmask
Call Wiz5100_writevalue (w5100_subr1 , Subnet (2))
Call Wiz5100_writevalue (w5100_subr2 , Subnet (3))
Call Wiz5100_writevalue (w5100_subr3 , Subnet (4))
Call Wiz5100_writevalue (w5100_gar0 , Gateway (1)) 'Set gateway IP adress
Call Wiz5100_writevalue (w5100_gar1 , Gateway (2))
Call Wiz5100_writevalue (w5100_gar2 , Gateway (3))
Call Wiz5100_writevalue (w5100_gar3 , Gateway (4))
Call Wiz5100_writevalue (w5100_shar0 , Mac (1)) 'Set MAC address
Call Wiz5100_writevalue (w5100_shar1 , Mac (2))
Call Wiz5100_writevalue (w5100_shar2 , Mac (3))
Call Wiz5100_writevalue (w5100_shar3 , Mac (4))
Call Wiz5100_writevalue (w5100_shar4 , Mac (5))
Call Wiz5100_writevalue (w5100_shar5 , Mac (6))
Call Wiz5100_writevalue (w5100_s0_dipr0 , Destip (1)) ' Destination Address
Call Wiz5100_writevalue (w5100_s0_dipr1 , Destip (2))
Call Wiz5100_writevalue (w5100_s0_dipr2 , Destip (3))
Call Wiz5100_writevalue (w5100_s0_dipr3 , Destip (4))
Call Wiz5100_writevalue (w5100_s0_dport0 , Destport (1)) 'Dest Port
Call Wiz5100_writevalue (w5100_s0_dport1 , Destport (2))
Call Wiz5100_writevalue (w5100_imr , &H01 ) 'enable interrupts for socket 0
End Sub
'********************** SPI Byte Read Routine *********************************
'Subroutine to read a byte from a W5100 register using SPI
Sub Wiz5100_readvalue (reg )
Adres = Reg
Reset Wiz5100_cs
Spiout Wiz5100_opcode_read , 1
Spiout Adresh , 1
Spiout Adresl , 1
Spiin Value , 1
Set Wiz5100_cs
End Sub
'********************** SPI Byte Write Routine ******************************
'Subroutine to write a byte to a W5100 register using SPI
Sub Wiz5100_writevalue (reg , Value )
Reset Wiz5100_cs 'select Wiz5100
Adres = Reg
Spiout Wiz5100_opcode_write , 1
Spiout Adresh , 1
Spiout Adresl , 1
Spiout Value , 1
Set Wiz5100_cs 'deselect Wiz5100
End Sub
'The W5100 gets its reset from the general Arduino reset
Sub Wiz5100_reset
' Wiz5100_res = 0
' Waitus 30 'Minimum 20 µs
' Wiz5100_res = 1
End Sub |
On the code it is a statement: $include "w5100.inc"
But i don't have this include file. And i can't find it on the forum.
Can someone help me?
Best regards
littlethinker |
|
Back to top |
|
|
MAK3
Joined: 24 Sep 2010 Posts: 449 Location: Germany
|
|
Back to top |
|
|
littlethinker
Joined: 05 Oct 2013 Posts: 2
|
Posted: Sat Oct 05, 2013 5:55 pm Post subject: |
|
|
Hi,
thanks but i know these. But Bascom has no integrated commands for DHCP. I search for a code with DHCP function. Has someone a DHCP code with bascom new statements? |
|
Back to top |
|
|
bzijlstra
Joined: 30 Dec 2004 Posts: 1179 Location: Tilburg - Netherlands
|
Posted: Sun Oct 06, 2013 6:48 pm Post subject: w5100.inc |
|
|
The code came from my site
And there you can find the w5100.inc file
Have fun
Ben Zijlstra |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|