|
楼主 |
发表于 2005-12-30 12:59:39
|
显示全部楼层
把BASCOM-AVR控制TCP/IP的程序集中一下,方便大家特别是想做TCP/IP的网友参考。
这个程序是我转贴的,我没有测试,请懂得这个东西的朋友们测试,谢谢!!
'----------------------------------------------------------------------------------
' Embedded UDP&WebServer - Atmega32 and RTL8019AS - Embedded UDP&WebServer
'----------------------------------------------------------------------------------
'
' Version X - April 1 2005 - Ben Zijlstra - Netherlands - http://members.home.nl/bzijlstra
' history:
'
' 03-06-2004 Added some extra LCD-routines
' 05-06-2004 HTTP shows portstatus on LCD
' PCF8574 or PCF8574A for LCD can be chosen
' 06-06-2004 Idle-time for the LCD-display
' Added 24LC256 testroutine
' Added LM76 testroutine
' 01-10-2004 Small alteration so Linux browsers do work (tcp_psh-routine)
' 02-10-2004 Tested with Bascom-AVR 1.11.77 running well
' 20-10-2005 Optimized some LCD-routines and misc.
' 21-10-2005 Tested with Bascom-AVR 1.11.79 running well
'
'
'
' Fusebits:
' A987:1111 = Crystal/Boden enabled
' H: 1 = JTAG disabled
' G: 0 = Preserve EEprom when chip erase
'
' Hardware:
'
' PA0 - SD0 - Databus
' PA1 - SD1
' PA2 - SD2
' PA3 - SD3
' PA4 - SD4
' PA5 - SD5
' PA6 - SD6
' PA7 - SD7
' PB0 - SA0 - Addressbus
' PB1 - SA1
' PB2 - SA2
' PB3 - SA3
' PB4 - SA4
' PB5 - MOSI
' PB6 - MISO
' PB7 - SCK
' PC0 - I2c SLC
' PC1 - I2c SDA
' PC2 - PC2
' PC3 - PC3
' PC4 - PC4
' PC5 - PC5
' PC6 - PC6
' PC7 - PC7
' PD0 - RXD
' PD1 - TXD
' PD2 - INT0
' PD3 - LE - Latch Enable
' PD4 - RSTDRV
' PD5 - EEDO
' PD6 - IORB
' PD7 - IOWB
' In the EEPROM:
'
' 00 = .0 - 0 if LCD present (2 x 20)
' 00 = .1
' 00 = .2
' 00 = .3
' 00 = .4
' 00 = .5
' 00 = .6
' 00 = .7
' 01 = IP-number msb
' 02 = IP-number
' 03 = IP-number
' 04 = IP-number lsb
' 05 = MAC-address
' 06 = MAC-address
' 07 = MAC-address
' 08 = MAC-address
' 09 = MAC-address
' 10 = MAC-address
' 11 = Portnumber
' 12 = Portnumber
' 13 = Length URL-refresh string
' 14 = start of URL-refresh string
' .... upto end of URL-refresh string
'100 = address of PCF8574 or PCF8574A
$crystal = 7372800
$regfile = "M32def.dat"
$baud = 57600
$hwstack = 64
$swstack = 64
$framesize = 64
Declare Sub Write_rtl8019as(byval Regaddr As Byte , Byval Regdata As Byte)
Declare Sub Read_rtl8019as(byval Regaddr As Byte)
Declare Sub Init_rtl8019as
Declare Sub Getpacket
Declare Sub Overrun
Declare Sub Arp
Declare Sub Icmp
Declare Sub Icmp_checksum
Declare Sub Write_dest_mac
Declare Sub Packetshape
Declare Sub Echopacket
Declare Sub Setipaddrs
Declare Sub Ip_header_checksum
Declare Sub Udp
Declare Sub Udp_checksum
'
Declare Sub General_part_checksum(byval Val1 As Byte , Byval Val2 As Word)
'
'
Declare Sub Lcd_init
Declare Sub Lcd_char(byval Lcd_c As Byte)
Declare Sub Lcd_txt
Declare Sub Lcdhome ' CLS/Home
Declare Sub Firstline ' goto 0/0 of LCD
Declare Sub Secondline
Declare Sub Setup_packet
Declare Sub Assemble_ack
Declare Sub Relayon(byval X As Byte)
Declare Sub Relayoff(byval X As Byte)
Declare Sub Status
Declare Sub Configure
Declare Sub Read_mac
Declare Sub Print_ip
Declare Sub Read_ip
Declare Sub Print_mac
Declare Sub Default_message
Dim Val1 As Byte
Dim Val2 As Word ' up to 65535 characters
Dim Val3 As Byte
Dim Val4 As Byte
Dim Regaddr As Byte
Dim Regdata As Byte
'Ethernet header layout
Dim Byte_read As Byte
Dim Hulp1 As Byte
Dim Mymac(6) As Byte
Dim I As Integer
Dim Rxlen As Word
Dim Hulp2 As Word
Dim Hulp3 As Word
Dim Hulp4 As Byte
Dim Data_l As Byte
Dim Data_h As Byte
'RTL8019AS
Dim Txlen As Word
Dim I_header_length As Word
Dim I_odd As Byte
Dim I_chksum32 As Long
Dim I_x As Word
Dim I_checksum16 As Word
Dim Resend As Byte
Dim T As Byte
'variables with overlays
Dim Hulp6 As Word
Dim Hulp6h As Byte At Hulp6 + 1 Overlay
Dim Hulp6l As Byte At Hulp6 Overlay
Dim I_value16 As Word
Dim I_value16h As Byte At I_value16 + 1 Overlay
Dim I_value16l As Byte At I_value16 Overlay
Dim Result16 As Word
Dim Result16h As Byte At Result16 + 1 Overlay
Dim Result16l As Byte At Result16 Overlay
Dim Hulp5 As Word
Dim Hulp5h As Byte At Hulp5 + 1 Overlay
Dim Hulp5l As Byte At Hulp5 Overlay
Dim Myip(4) As Byte
Dim My_ip As Long At Myip Overlay
Dim Pageheader(4) As Byte
Dim T_enetpacketlenl As Byte At Pageheader + 2 Overlay
Dim T_enetpacketlenh As Byte At Pageheader + 3 Overlay
Dim Packet(1000) As Byte At &HC0
'Ethernet packet destination
Dim T_enetpacketdest0 As Byte At &HC0 Overlay
Dim T_enetpacketdest1 As Byte At &HC1 Overlay
Dim T_enetpacketdest2 As Byte At &HC2 Overlay
Dim T_enetpacketdest3 As Byte At &HC3 Overlay
Dim T_enetpacketdest4 As Byte At &HC4 Overlay
Dim T_enetpacketdest5 As Byte At &HC5 Overlay
'Ethernet packet source
Dim T_enetpacketsrc0 As Byte At &HC6 Overlay
Dim T_enetpacketsrc1 As Byte At &HC7 Overlay
Dim T_enetpacketsrc2 As Byte At &HC8 Overlay
Dim T_enetpacketsrc3 As Byte At &HC9 Overlay
Dim T_enetpacketsrc4 As Byte At &HCA Overlay
Dim T_enetpacketsrc5 As Byte At &HCB Overlay
'Ethernet packet type
Dim T_enetpackettype As Word At &HCC Overlay
Dim T_arp_hwtype1 As Byte At &HCF Overlay
'Arp
Dim T_arp_prttype1 As Byte At &HD1 Overlay
Dim T_arp_hwlen As Byte At &HD2 Overlay
Dim T_arp_prlen As Byte At &HD3 Overlay
Dim T_arp_op1 As Byte At &HD5 Overlay
'arp source ip address
Dim T_arp_sipaddr0 As Byte At &HDC Overlay
Dim T_arp_sipaddr1 As Byte At &HDD Overlay
Dim T_arp_sipaddr2 As Byte At &HDE Overlay
Dim T_arp_sipaddr3 As Byte At &HDF Overlay
'arp target IP address
Dim T_arp_tipaddr As Long At &HE6 Overlay
'IP header layout IP version and header length
Dim T_ip_vers_len As Byte At &HCE Overlay
'packet length
Dim T_ip_pktlen0 As Byte At &HD0 Overlay
Dim T_ip_pktlen1 As Byte At &HD1 Overlay
'protocol (ICMP=1, TCP=6, UDP=11)
Dim T_ip_proto As Byte At &HD7 Overlay
'header checksum
Dim T_ip_hdr_cksum0 As Byte At &HD8 Overlay
Dim T_ip_hdr_cksum1 As Byte At &HD9 Overlay
Dim T_ip_hdr_cksum As Word At &HD8 Overlay
'IP address of source
Dim T_ip_srcaddr0 As Byte At &HDA Overlay
Dim T_ip_srcaddr1 As Byte At &HDB Overlay
Dim T_ip_srcaddr2 As Byte At &HDC Overlay
Dim T_ip_srcaddr3 As Byte At &HDD Overlay
Dim T_ip_srcaddr As Long At &HDA Overlay
'IP address of destination
Dim T_ip_destaddr0 As Byte At &HDE Overlay
Dim T_ip_destaddr1 As Byte At &HDF Overlay
Dim T_ip_destaddr2 As Byte At &HE0 Overlay
Dim T_ip_destaddr3 As Byte At &HE1 Overlay
Dim T_ip_destaddr As Long At &HDE Overlay
Dim T_icmp_type As Byte At &HE2 Overlay
Dim T_icmp_code As Byte At &HE3 Overlay
Dim T_icmp_cksum0 As Byte At &HE4 Overlay
Dim T_icmp_cksum1 As Byte At &HE5 Overlay
Dim T_icmp_cksum As Word At &HE4 Overlay
'UDP header
Dim T_udp_srcport0 As Byte At &HE2 Overlay
Dim T_udp_srcport1 As Byte At &HE3 Overlay
Dim T_udp_destport0 As Byte At &HE4 Overlay
Dim T_udp_destport1 As Byte At &HE5 Overlay
Dim T_udp_destport As Word At &HE4 Overlay
Dim T_udp_len0 As Byte At &HE6 Overlay
Dim T_udp_len1 As Byte At &HE7 Overlay
Dim T_udp_chksum0 As Byte At &HE8 Overlay
Dim T_udp_chksum1 As Byte At &HE9 Overlay
'LCD variables
Dim Temparray(80) As Byte
Dim Lcd_t As String * 80 At Temparray Overlay
Dim Temparray2(4) As Byte
Dim Lcd_tempstr As String * 1
Dim Lcd_temp As Byte
Dim Lcd_x As Byte
Dim Lcd_hulp As Byte
Dim Lcd_h As Byte
Dim Lcdpresent As Byte
Dim Msg_temp As String * 80
Dim Y As Word
Dim Tempstring1 As String * 1
Dim Triggerstr As String * 80
'idle time
Dim Idletime As Long
Dim Yn As String * 1
Dim Mymacs(6) As String * 2
Dim Pcf8574 As Byte
Const Debug = 0 ' put 1 for debug, 0 for no debug
Const Rstport = &H18
Const Isr = &H07
Const Msg_initfail = "Init failed"
Const Cr = &H00
Const Dcrval = &H58
Const Dcr = &H0E
Const Rbcr0 = &H0A
Const Rbcr1 = &H0B
Const Rcr = &H0C
Const Tpsr = &H04
Const Txtstart = &H40
Const Tcr = &H0D
Const Pstart = &H01
Const Rxstart = &H46
Const Bnry = &H03
Const Pstop = &H02
Const Rxstop = &H60
Const Curr = &H07
Const Imr = &H0F
Const Imrval = &H11
Const Tcrval = &H00
Const Rdmaport = &H10
Const Rsar0 = &H08
Const Rsar1 = &H09
Const Tbcr0 = &H05
Const Tbcr1 = &H06
'IP protocol types
'icmp
Const Prot_icmp = &H01
'udp
Const Prot_udp = &H11
'LCD
Const Rs = 4
Const E = 7
'RTL8019AS ISR Register definitions
Const Rdc = &H40
Config Int0 = Rising
'I2c
Config Scl = Portc.0
Config Sda = Portc.1
Config I2cdelay = 20
#if Debug = 1
Print "Hello world"
#endif
Databus Alias Porta
_databus Alias Pina
Rtldata Alias Porta
Databus_ddr Alias Ddra
Addrbus Alias Portb
Addrbus_ddr Alias Ddrb
Resetport Alias Portd
Eeprom Alias Portd
Ior_pin Alias Portd.6
Iow_pin Alias Portd.7
Resetport_ddr Alias Ddrd
Inputport1 Alias Pinc
Inputport2 Alias Portc
Latch Alias Portd.3
Resetport_ddr = &HF8 ' leave RXD and TXD
' Main program
'
Main:
Reset Latch
Databus_ddr = &HFF
Databus = 0 ' put zero's on relays-port
Set Latch
Reset Latch
'Relaystatus = 0 ' put zero's in the relaystatus byte
Readeeprom Pcf8574 , 100
Readeeprom Hulp1 , 0 ' Should I put something on the LCD?
If Hulp1.0 = 0 Then
Lcdpresent = 1
Call Lcd_init
Lcd_t = "VA3TO/EIO-board"
Call Lcd_txt
Call Secondline
Lcd_t = "UDP-server/client"
Call Lcd_txt
End If
Call Configure
Call Default_message
Call Init_rtl8019as
'Call Showregs
Enable Interrupts
Enable Int0
On Int0 Rtl8019as_interrupt
'start the NIC
Call Write_rtl8019as(cr , &H22)
Do
If Lcdpresent = 1 Then
'idle-time
Incr Idletime
If Idletime > 5000000 Then
Disable Int0
Lcd_t = "*VA3TO/EIO-Board#Idle..."
Call Lcd_txt
Enable Int0
Idletime = 0
End If
End If
Loop
End
' Routine to handle an interrupt on the RTL8019AS
'
Rtl8019as_interrupt:
#if Debug = 1
Print "Interrupt from RTL8019as"
#endif
Disable Int0
'read the interrupt status register
Call Read_rtl8019as(isr)
'if the receive buffer has been overrun
If Byte_read.4 = 1 Then
Call Overrun
End If
'if the receive buffer holds a good packet
If Byte_read.0 = 1 Then
Call Getpacket
End If
'make sure the receive buffer ring is empty. If BNRY = CURR, the buffer is empty
Call Read_rtl8019as(bnry)
Data_l = Byte_read
Call Write_rtl8019as(cr , &H62)
Call Read_rtl8019as(curr)
Data_h = Byte_read
Call Write_rtl8019as(cr , &H22)
'buffer is not empty, get next packet
If Data_l <> Data_h Then
Call Getpacket
End If
'reset the interrupts bits
Call Write_rtl8019as(isr , &HFF)
Call Write_rtl8019as(cr , &H22)
Enable Int0
Return
' Routine to Write to NIC Control register
'
Sub Write_rtl8019as(regaddr , Regdata)
Addrbus = Regaddr
Databus = Regdata
Databus_ddr = &HFF
nop
Reset Iow_pin
nop
Set Iow_pin
nop
Databus_ddr = &H00
Databus = &HFF
End Sub
' Routine to read from NIC Control register
'
Sub Read_rtl8019as(regaddr)
Databus_ddr = &H00
Databus = &HFF
Addrbus = Regaddr
Reset Ior_pin
nop
Byte_read = Pina
nop
Set Ior_pin
nop
End Sub
' Routine to initialise the RTL8019AS ethernetchip
'
Sub Init_rtl8019as
Databus_ddr = &H00
Databus = &HFF
Addrbus_ddr = &HFF
Addrbus = &H00
Resetport_ddr = &HF8
Reset Eeprom.5
Set Iow_pin
Set Ior_pin
Set Resetport.4
Waitms 2
Reset Resetport.4
Call Read_rtl8019as(rstport)
Call Write_rtl8019as(rstport , Byte_read)
Waitms 10
'check for good soft reset
Call Read_rtl8019as(isr)
If Byte_read.7 = 0 Then
Print Msg_initfail
End If
Call Write_rtl8019as(cr , &H21)
Waitms 2
Call Write_rtl8019as(dcr , Dcrval)
Call Write_rtl8019as(rbcr0 , &H00)
Call Write_rtl8019as(rbcr1 , &H00)
Call Write_rtl8019as(rcr , &H04)
Call Write_rtl8019as(tpsr , Txtstart)
Call Write_rtl8019as(tcr , &H02)
Call Write_rtl8019as(pstart , Rxstart)
Call Write_rtl8019as(bnry , Rxstart)
Call Write_rtl8019as(pstop , Rxstop)
Call Write_rtl8019as(cr , &H61)
Waitms 2
Call Write_rtl8019as(curr , Rxstart)
For Hulp1 = 1 To 6
Call Write_rtl8019as(hulp1 , Mymac(hulp1))
Next Hulp1
Call Write_rtl8019as(cr , &H21)
Call Write_rtl8019as(dcr , Dcrval)
Call Write_rtl8019as(cr , &H22)
Call Write_rtl8019as(isr , &HFF)
Call Write_rtl8019as(imr , Imrval)
Call Write_rtl8019as(tcr , Tcrval)
End Sub
Sub Overrun
Call Read_rtl8019as(cr)
Data_l = Byte_read
Call Write_rtl8019as(cr , &H21)
Waitms 2
Call Write_rtl8019as(rbcr0 , &H00)
Call Write_rtl8019as(rbcr1 , &H00)
Hulp1 = Data_l And &H04
If Hulp1 <> 0 Then
Resend = 0
Else
If Hulp1 = 0 Then
Call Read_rtl8019as(isr)
Data_l = Byte_read
Hulp1 = Data_l And &H02
Hulp4 = Data_l And &H08
Hulp3 = Hulp1 Or Hulp4
If Hulp3 > 0 Then
Resend = 0
Else
Resend = 1
End If
End If
End If
Call Write_rtl8019as(tcr , &H02)
Call Write_rtl8019as(cr , &H22)
Call Write_rtl8019as(bnry , Rxstart)
Call Write_rtl8019as(cr , &H62)
Call Write_rtl8019as(curr , Rxstart)
Call Write_rtl8019as(cr , &H22)
Call Write_rtl8019as(isr , &H10)
Call Write_rtl8019as(tcr , Tcrval)
End Sub
' Routine to execute send packet command to retrieve the packet
'
Sub Getpacket
Call Write_rtl8019as(cr , &H1A)
For I = 0 To 4
Call Read_rtl8019as(rdmaport)
Pageheader(i + 1) = Byte_read
Next I
'watch it. overlay variables
Result16h = T_enetpacketlenh
Result16l = T_enetpacketlenl
Rxlen = Result16
Hulp2 = Rxlen + 1
For I = 1 To Hulp2
Call Read_rtl8019as(rdmaport)
'dump any bytes that will overrun the receive buffer
If I < 1000 Then
Packet(i + 1) = Byte_read
End If
Next I
Hulp1 = Byte_read And Rdc
If Hulp1 <> 64 Then
Call Read_rtl8019as(isr)
End If
Call Write_rtl8019as(isr , &HFF)
' Routine to process an ARP packet
'
If T_enetpackettype = &H0608 Then
If T_arp_hwtype1 = &H01 Then
If T_arp_prttype1 = &H00 Then
If T_arp_hwlen = &H06 Then
If T_arp_prlen = &H04 Then
If T_arp_op1 = &H01 Then
If My_ip = T_arp_tipaddr Then
Call Arp
End If
End If
End If
End If
End If
End If
End If
' Routine to go ahead with icmp or udp
'
If T_enetpackettype = &H0008 Then
If T_ip_destaddr = My_ip Then
Select Case T_ip_proto
Case Prot_icmp : Call Icmp
'Case Prot_tcp : Call Tcp
Case Prot_udp : Call Udp
End Select
End If
End If
End Sub
' Routine to handle ARP-traffic
'
Sub Arp
'Start the NIC
Call Write_rtl8019as(cr , &H22)
'load beginning page for transmit buffer
Call Write_rtl8019as(tpsr , Txtstart)
'set start address for remote DMA operation
Call Write_rtl8019as(rsar0 , &H00)
Call Write_rtl8019as(rsar1 , &H40)
'clear the interrupts
Call Write_rtl8019as(isr , &HFF)
'load data byte count for remote DMA
Call Write_rtl8019as(rbcr0 , &H3C)
Call Write_rtl8019as(rbcr1 , &H00)
'do remote write operation
Call Write_rtl8019as(cr , &H12)
'write destination MAC address
Call Write_dest_mac
'write source address
For I = 1 To 6
Call Write_rtl8019as(rdmaport , Mymac(i))
Next I
'arp target IP address
'arp_op1 = packet(&h16)
Packet(&H16) = &H02
For I = 0 To 9
Hulp1 = &HCC + I
T = Peek(hulp1)
Call Write_rtl8019as(rdmaport , T)
Next I
'write ethernet module mac address
For I = 1 To 6
Call Write_rtl8019as(rdmaport , Mymac(i))
Next I
'write myip
For I = 1 To 4
Call Write_rtl8019as(rdmaport , Myip(i))
Next I
'write remote mac address
Call Write_dest_mac
'write remote IP address
Call Write_rtl8019as(rdmaport , T_arp_sipaddr0)
Call Write_rtl8019as(rdmaport , T_arp_sipaddr1)
Call Write_rtl8019as(rdmaport , T_arp_sipaddr2)
Call Write_rtl8019as(rdmaport , T_arp_sipaddr3)
'write som pad characters to fill out the packet to the minimum length
For I = 0 To &H11
Call Write_rtl8019as(rdmaport , &H00)
Next I
'make sure the DMA operation has succesfully completed
Byte_read = 0
Do
Hulp1 = Byte_read And Rdc
Call Read_rtl8019as(isr)
Loop Until Hulp1 = 0
'load numbers of bytes to be transmitted
Call Write_rtl8019as(tbcr0 , &H3C)
Call Write_rtl8019as(tbcr1 , &H00)
'send the contents of the transmit buffer onto the network
Call Write_rtl8019as(cr , &H24)
End Sub
Sub Write_dest_mac
Call Write_rtl8019as(rdmaport , T_enetpacketsrc0)
Call Write_rtl8019as(rdmaport , T_enetpacketsrc1)
Call Write_rtl8019as(rdmaport , T_enetpacketsrc2)
Call Write_rtl8019as(rdmaport , T_enetpacketsrc3)
Call Write_rtl8019as(rdmaport , T_enetpacketsrc4)
Call Write_rtl8019as(rdmaport , T_enetpacketsrc5)
End Sub
Sub Icmp
'set echo reply
T_icmp_type = &H00
T_icmp_code = &H00
'setup the IP-header
Call Setipaddrs
Call Icmp_checksum
Call Echopacket
End Sub
' Routine to handle the source/destination address
'
Sub Setipaddrs
T_ip_destaddr = T_ip_srcaddr
'make ethernet module IP address source address
T_ip_srcaddr = My_ip
Call Packetshape
Call Ip_header_checksum
End Sub
' Routine to echo a complete packet
'
Sub Echopacket
Call Write_rtl8019as(cr , &H22)
Call Write_rtl8019as(tpsr , Txtstart)
Call Write_rtl8019as(rsar0 , &H00)
Call Write_rtl8019as(rsar1 , &H40)
Call Write_rtl8019as(isr , &HFF)
Hulp1 = T_enetpacketlenl - 4
Call Write_rtl8019as(rbcr0 , Hulp1)
Call Write_rtl8019as(rbcr1 , T_enetpacketlenh)
Call Write_rtl8019as(cr , &H12)
Result16h = T_enetpacketlenh
Result16l = T_enetpacketlenl
Result16 = Result16 - 4
Txlen = Result16
'write the complete packet to the RTL8019AS from packet(1) to packet(txlen+1)
Hulp2 = Txlen + 1
For I = 1 To Hulp2
Call Write_rtl8019as(rdmaport , Packet(i))
Next I
Byte_read = 0
While Hulp1 <> 0
Hulp1 = Byte_read And Rdc
Call Read_rtl8019as(isr)
Wend
Hulp1 = T_enetpacketlenl - 4
Call Write_rtl8019as(tbcr0 , Hulp1)
Call Write_rtl8019as(tbcr1 , T_enetpacketlenh)
Call Write_rtl8019as(cr , &H24)
End Sub
Sub Packetshape
'move hardware source address to destination address
T_enetpacketdest0 = T_enetpacketsrc0
T_enetpacketdest1 = T_enetpacketsrc1
T_enetpacketdest2 = T_enetpacketsrc2
T_enetpacketdest3 = T_enetpacketsrc3
T_enetpacketdest4 = T_enetpacketsrc4
T_enetpacketdest5 = T_enetpacketsrc5
' 'Make ethernet module mac address the source address
T_enetpacketsrc0 = Mymac(1)
T_enetpacketsrc1 = Mymac(2)
T_enetpacketsrc2 = Mymac(3)
T_enetpacketsrc3 = Mymac(4)
T_enetpacketsrc4 = Mymac(5)
T_enetpacketsrc5 = Mymac(6)
End Sub
' Routine to calculate a ICMP-checksum
'
Sub Icmp_checksum
'clear the ICMP checksum
T_icmp_cksum = &H00
'calculate the ICMP checksum
I_header_length = T_ip_pktlen1 - 20
'I_header_length = I_header_length - 20
I_odd = I_header_length Mod 2
'14 for MAC-part
'20 for IP-header
'start on 35
'ip_pktlen = 00 3c (60)
'icmp-packetlengte = ip_pktlen - ip_header
I_chksum32 = 0
'Total packetlength - ip_header - 1
Hulp6h = T_ip_pktlen0
Hulp6l = T_ip_pktlen1
Val1 = 35
Val2 = Hulp6 + 13
Call General_part_checksum(val1 , Val2)
T_icmp_cksum0 = Val3
T_icmp_cksum1 = Val4
End Sub
' Routine to calculate a IP-header checksum
'
Sub Ip_header_checksum
Local Ip_x As Byte
Local Ip_hulp1 As Byte
Local Ip_chksum32 As Long
Local Ip_checksum16 As Word
Local Ip_temp16 As Word
Local Ip_header_length As Byte
'calculate the IP header checksum
T_ip_hdr_cksum = &H00
I_chksum32 = 0
Ip_header_length = T_ip_vers_len And &H0F
Ip_header_length = 4 * Ip_header_length
I_chksum32 = 0
I_odd = 0
Val1 = 15
Val2 = &H0E + Ip_header_length
Call General_part_checksum(val1 , Val2)
T_ip_hdr_cksum0 = Val3
T_ip_hdr_cksum1 = Val4
End Sub
' Routine to handle UDP-traffic
'
Sub Udp
Local Udp_port As Word
Local Udp_porth As Byte
Local Udp_portl As Byte
Local Lhulp1 As Word
Local Lhulp2 As Word
Local Lhulp3 As Word
Local Lhulp4 As Word
Readeeprom Udp_porth , 11
Readeeprom Udp_portl , 12
Udp_port = Udp_porth
Shift Udp_port , Left , 8
Udp_port = Udp_port + Udp_portl
'From within a VB-program
If T_udp_destport = Udp_port Then
Triggerstr = ""
Lhulp1 = &HEA
Lhulp3 = Lhulp1 + T_udp_len1
Decr Lhulp3
'remove header
Lhulp3 = Lhulp3 - 8
For Lhulp2 = Lhulp1 To Lhulp3
Lhulp4 = Inp(lhulp2)
Triggerstr = Triggerstr + Chr(lhulp4)
Next Lhulp2
Lcd_t = "*" + Triggerstr
Call Lcd_txt
Print Triggerstr
'Build The Ip Header
Call Setipaddrs
'swap the UDP source and destinations port
Swap T_udp_srcport0 , T_udp_destport0
Swap T_udp_srcport1 , T_udp_destport1
Call Udp_checksum
Call Write_rtl8019as(cr , &H22)
Call Echopacket
End If
End Sub
' Routine to calculate the Udp-checksum
'
Sub Udp_checksum
T_udp_chksum0 = &H00
T_udp_chksum1 = &H00
'checksum TCP header
I_chksum32 = 0
I_value16h = T_ip_srcaddr0
I_value16l = T_ip_srcaddr1
I_chksum32 = I_chksum32 + I_value16
I_value16h = T_ip_srcaddr2
I_value16l = T_ip_srcaddr3
I_chksum32 = I_chksum32 + I_value16
I_value16h = T_ip_destaddr0
I_value16l = T_ip_destaddr1
I_chksum32 = I_chksum32 + I_value16
I_value16h = T_ip_destaddr2
I_value16l = T_ip_destaddr3
I_chksum32 = I_chksum32 + I_value16
'proto
I_chksum32 = I_chksum32 + T_ip_proto
'packet length
I_value16h = T_udp_len0
I_value16l = T_udp_len1
I_chksum32 = I_chksum32 + I_value16
I_odd = T_udp_len1 Mod 2
Result16h = T_udp_len0
Result16l = T_udp_len1
Val1 = &H23
Val2 = &H23 + Result16
Val2 = Val2 - 2
Call General_part_checksum(val1 , Val2)
T_udp_chksum0 = Val3
T_udp_chksum1 = Val4
End Sub
Sub General_part_checksum(byval Val1 As Byte , Byval Val2 As Word)
For I_x = Val1 To Val2 Step 2
I_value16h = Packet(i_x)
Hulp3 = I_x + 1
I_value16l = Packet(hulp3)
I_chksum32 = I_chksum32 + I_value16
Next I_x
If I_odd = 1 Then
Incr Val2
I_value16h = Packet(val2)
I_value16l = 0
I_chksum32 = I_chksum32 + I_value16
End If
I_checksum16 = Highw(i_chksum32)
I_checksum16 = I_checksum16 + I_chksum32 ' only 16 lower bits of i_chksum32 is taken...
I_checksum16 = Not I_checksum16
Val3 = High(i_checksum16)
Val4 = Low(i_checksum16)
End Sub
'Subroutine to initialize the LCD-display
Sub Lcd_init
Waitms 15
'set 8-bit mode (attention)
'toggle the E -line
'set 8-bit mode (attention)
'set 8-bit mode (attention)
'set 4-bit operation
Temparray(1) = &B10000011
Temparray(2) = &B00000011
Temparray(3) = &B10000011
Temparray(4) = &B00000011
Temparray(5) = &B10000011
Temparray(6) = &B00000011
Temparray(7) = &B10000010
Temparray(8) = &B00000010
Temparray(9) = &B10000010
Temparray(10) = &B00000010
Temparray(11) = &B10001000
Temparray(12) = &B00001000
Temparray(13) = &B10000000
Temparray(14) = &B00000000
Temparray(15) = &B10001000
Temparray(16) = &B00001000
Temparray(17) = &B10000000
Temparray(18) = &B00000000
Temparray(19) = &B10001100
Temparray(20) = &B00001100
Temparray(21) = &B10000000
Temparray(22) = &B00000000
Temparray(23) = &B10000001
Temparray(24) = &B00001001
I2csend Pcf8574 , Temparray(1) , 24
End Sub
' Routine to send a character to the LCD-display
'
Sub Lcd_char(lcd_c As Byte)
If Lcd_c = 42 Then '* CLS/HOME
Call Lcdhome
Elseif Lcd_c = 35 Then '# second line
Call Secondline
Else
Lcd_temp = Lcd_c And &HF0
Rotate Lcd_temp , Right , 4
I2csend Pcf8574 , Lcd_temp
Set Lcd_temp.e
Set Lcd_temp.rs
Temparray2(1) = Lcd_temp
Reset Lcd_temp.e
Reset Lcd_temp.rs
Temparray2(2) = Lcd_temp
I2csend Pcf8574 , Temparray2(1) , 2
Lcd_temp = Lcd_c And &H0F
I2csend Pcf8574 , Lcd_temp
Set Lcd_temp.e
Set Lcd_temp.rs
Temparray2(1) = Lcd_temp
Reset Lcd_temp.e
Reset Lcd_temp.rs
Temparray2(2) = Lcd_temp
I2csend Pcf8574 , Temparray2(1) , 2
End If
End Sub
' Routine to send a string to the LCD-display
'
' Fill lcd_t with the text and call lcd_txt
'
Sub Lcd_txt
Lcd_hulp = Len(lcd_t)
For Lcd_x = 1 To Lcd_hulp
Lcd_tempstr = Mid(lcd_t , Lcd_x , 1)
Lcd_temp = Asc(lcd_tempstr)
Call Lcd_char(lcd_temp)
Next Lcd_x
End Sub
Sub Lcdhome
Temparray2(1) = &B10000000
Temparray2(2) = &B00000000
Temparray2(3) = &B10000001
Temparray2(4) = &B00000001
I2csend Pcf8574 , Temparray2(1) , 4
Waitms 2
End Sub
Sub Secondline
Call Firstline
For Lcd_h = 1 To 40
Temparray2(1) = &B10000001
Temparray2(2) = &B00000001
Temparray2(3) = &B10000100
Temparray2(4) = &B00000100
I2csend Pcf8574 , Temparray2(1) , 4
Next Lcd_h
End Sub
Sub Firstline
Temparray2(1) = &B10000000
Temparray2(2) = &B00000000
Temparray2(3) = &B10000010
Temparray2(4) = &B00000010
I2csend Pcf8574 , Temparray2(1) , 4
End Sub
Sub Setup_packet
'Move IP source address to destination address
T_ip_destaddr = T_ip_srcaddr
'Make ethernet module IP address source address
T_ip_srcaddr = My_ip
'Move hardware source address to destinatin address
Call Packetshape
Call Ip_header_checksum
End Sub
' Routine to get a configuration-screen on the RS232 port
'
Sub Configure
Local Adr As Word
Local Row As Byte
Local Ipnr As String * 15
Local Dot1 As Byte
Local Dot2 As Byte
Local Dot3 As Byte
Local Dot4 As Byte
Local Dot5 As Byte
Local Iptemp As String * 1
Local Ippart As String * 3
Local Macadr As String * 20
Print Chr(&H1b) ; "[2J"; ' ANSI goto 0/0
Print "VA3TO Atmega32 Loader Version 1.20"
Print
Print "Source written by Ben Zijlstra october 2005"
Print
Print "Present configuration:"
Print
Print "Network:"
Print
Print "IP-number: ";
Call Read_ip
Call Print_ip
Call Read_mac
Print
Print "MAC-address: ";
Print Hex(mymac(1)) ; "-" ; Hex(mymac(2)) ; "-" ; Hex(mymac(3)) ; "-" ; Hex(mymac(4)) ; "-" ; Hex(mymac(5)) ; "-" ; Hex(mymac(6))
Print
Print
Print "Press 'y' to get into configuration mode"
Test:
Incr Hulp3
If Hulp3 = 65000 Then
Incr Hulp1
Hulp3 = 0
End If
If Hulp1 = 25 Then
Goto Noresponse
End If
sbis USR,7
rjmp test
Configuremode:
If Lcdpresent = 1 Then
Call Lcd_init
Lcd_t = "Configure-mode"
Call Lcd_txt
End If
Print Chr(&H1b) ; "[2J"; ' ANSI goto 0/0 Print
Print "Configure mode:"
Print
Print "Network:"
Print
Print "IP-number: ";
Call Print_ip
Input "Change IP-number (y/n) " , Yn
If Yn = "y" Then
Print
Print "Input IP-numbers as decimals, seperated by a dot (like 192.168.1.106)"
Print
Input Ipnr
Hulp1 = Len(ipnr)
For Hulp2 = 1 To Hulp1
Incr Dot1
Iptemp = Mid(ipnr , Hulp2 , 1)
If Iptemp = "." Then
Exit For
End If
Next
Dot2 = Dot1
Incr Dot1
For Hulp2 = Dot1 To Hulp1
Incr Dot2
Iptemp = Mid(ipnr , Hulp2 , 1)
If Iptemp = "." Then
Exit For
End If
Next
Dot3 = Dot2
Incr Dot2
For Hulp2 = Dot2 To Hulp1
Incr Dot3
Iptemp = Mid(ipnr , Hulp2 , 1)
If Iptemp = "." Then
Exit For
End If
Next
Incr Dot3
Ippart = Mid(ipnr , 1 , Dot1)
Myip(1) = Val(ippart)
Hulp1 = Dot2 - Dot1
Ippart = Mid(ipnr , Dot1 , Hulp1)
Myip(2) = Val(ippart)
Hulp1 = Dot3 - Dot2
Ippart = Mid(ipnr , Dot2 , Hulp1)
Myip(3) = Val(ippart)
Ippart = Mid(ipnr , Dot3)
Myip(4) = Val(ippart)
Print
Print "New IP-number: ";
Call Print_ip
Print
Input "Accept IP-number (y/n) " , Yn
If Yn = "y" Then
Writeeeprom Myip(1) , 1 : Writeeeprom Myip(2) , 2
Writeeeprom Myip(3) , 3 : Writeeeprom Myip(4) , 4
End If
Print
Print "IP-number: ";
Call Read_ip
Call Print_ip
End If
Print
Input "Change MAC-address (y/n) " , Yn
If Yn = "y" Then
Mac:
Print
Print "Input MAC-address in hexadecimals, seperated by a - (like 00-34-35-36-37-48)"
Print
Input Macadr
If Len(macadr) <> 17 Then Goto Mac
Mymacs(1) = Mid(macadr , 1 , 2)
Mymacs(2) = Mid(macadr , 4 , 2)
Mymacs(3) = Mid(macadr , 7 , 2)
Mymacs(4) = Mid(macadr , 10 , 2)
Mymacs(5) = Mid(macadr , 13 , 2)
Mymacs(6) = Mid(macadr , 16 , 2)
Mymac(1) = Hexval(mymacs(1))
Mymac(2) = Hexval(mymacs(2))
Mymac(3) = Hexval(mymacs(3))
Mymac(4) = Hexval(mymacs(4))
Mymac(5) = Hexval(mymacs(5))
Mymac(6) = Hexval(mymacs(6))
Print
Print "New MAC-address: ";
Call Print_mac
Print
Input "Accept MAC-address (y/n) " , Yn
If Yn = "y" Then
Writeeeprom Mymac(1) , 5 : Writeeeprom Mymac(2) , 6
Writeeeprom Mymac(3) , 7 : Writeeeprom Mymac(4) , 8
Writeeeprom Mymac(5) , 9 : Writeeeprom Mymac(6) , 10
End If
Print
Print "MAC-address: ";
Call Read_mac
Call Print_mac
End If
Print
Input "Would you like to use it's own IP-number as refresh-URL (y/n) " , Yn
If Yn = "y" Then
Hulp1 = 255
Writeeeprom Hulp1 , 13
Else
Print
Input "Would you like to have another refresh-URL (y/n) " , Yn
If Yn = "y" Then
Input "Type the complete refresh URL " , Msg_temp
Print
Print "Refresh URL " ; Msg_temp
Print
Input "Accept Refresh-URL (y/n) " , Yn
If Yn = "y" Then
Hulp2 = Len(msg_temp)
Writeeeprom Hulp2 , 13 ' write length of Refresh URL
For Y = 1 To Hulp2
Hulp1 = Y + 13
Tempstring1 = Mid(msg_temp , Y , 1)
Hulp2 = Asc(tempstring1)
Writeeeprom Hulp2 , Hulp1
Next Y
End If
End If
End If
Print
Hulp5 = 5000
Writeeeprom Hulp5h , 12 ' &h1388 = 5000 dec = 19 high, 136 low.
Writeeeprom Hulp5l , 11
Input "Would you like to change to UDP Portnumber. It's default is 5000 (y/n) " , Yn
If Yn = "y" Then
Print
Input "Type the portnumber < 65536 as decimal " , Hulp5
Print
Print "Portnumber UDP " ; Hulp5
Print
Input "Accept Portnumber UDP (y/n) " , Yn
If Yn = "y" Then
Writeeeprom Hulp5h , 12
Writeeeprom Hulp5l , 11
End If
End If
Print
Print Chr(&H1b) ; "[2J"; ' ANSI goto 0/0 Print
Input "Would you like to see all devices on the I2c-bus (y/n) " , Yn
If Yn = "y" Then
Print "I2c-device locator 1 = no device 0 = device"
Print
Print " 0 2 4 6 8 A C E"
Print " 0000 ";
For Adr = 0 To 254 Step 2
Row = Adr Mod 16 ' addresses
If Row = 0 And Adr > 0 Then
Print ' end of line?
Print " " ; Hex(adr) ; " ";
End If
I2cstart ' generate start
I2cwbyte Adr
Print " " ; Err ; " "; ' 1 no device, 0 device
I2cstop
Next Adr
Print
End If
Print
Input "Any key to continue...." , Yn
Print
Input "Would you like to use a LCD-display? " , Yn
Readeeprom Hulp1 , 0
If Yn = "y" Then
Hulp1.0 = 0
Writeeeprom Hulp1 , 0
Print
Print "There are two kinds of PCF8574 I2c-I/O-ports"
Print
Print "The PCF8574 has base address 40"
Print "The PCF8574A has base address 70"
Print
Inputhex "At what address is the I2c-PCF8574x located : " , Pcf8574
Writeeeprom Pcf8574 , 100
Print
Call Lcd_init
Lcd_t = "LCD Testmessage"
Call Lcd_txt
Else
Hulp1.0 = 1
Writeeeprom Hulp1 , 0
End If
Noresponse:
Print Chr(&H1b) ; "[2J"; ' ANSI goto 0/0
Print "Summary:"
Print
Print "Network:"
Print
Print "IP-number : " ; Myip(1) ; "." ; Myip(2) ; "." ; Myip(3) ; "." ; Myip(4)
Print
Print "Mac-address: " ; Hex(mymac(1)) ; "-" ; Hex(mymac(2)) ; "-" ; Hex(mymac(3)) ; "-" ; Hex(mymac(4)) ; "-" ; Hex(mymac(5)) ; "-" ; Hex(mymac(6))
Print
Print "URL-refresh: ";
Readeeprom Hulp1 , 13
If Hulp1 = &HFF Then
Print "http://" ; Myip(1) ; "." ; Myip(2) ; "." ; Myip(3) ; "." ; Myip(4)
Else
Msg_temp = ""
For Y = 1 To Hulp1
Hulp3 = Y + 13
Readeeprom Hulp2 , Hulp3
Msg_temp = Msg_temp + Chr(hulp2)
Next Y
Print Msg_temp
End If
Print
Print "UDP-port : ";
Readeeprom Hulp5h , 12
Readeeprom Hulp5l , 11
Print Hulp5
Print
If Lcdpresent = 0 Then
Print "LCD-display: not used"
Else
Print "LCD-display: used"
Print
Readeeprom Pcf8574 , 100
Print "Address hex: " ; Hex(pcf8574)
End If
Print
Print
Print "Running..."
End Sub
' Routine to read the IP-numbers from the EEPROM
'
Sub Read_ip
Readeeprom Myip(1) , 1 : Readeeprom Myip(2) , 2
Readeeprom Myip(3) , 3 : Readeeprom Myip(4) , 4
End Sub
' Routine to print the IP-number
'
Sub Print_ip
Print Myip(1) ; "." ; Myip(2) ; "." ; Myip(3) ; "." ; Myip(4)
End Sub
' Routine to read the MAC-address from the EEPROM
'
Sub Read_mac
Readeeprom Mymac(1) , 5 : Readeeprom Mymac(2) , 6
Readeeprom Mymac(3) , 7 : Readeeprom Mymac(4) , 8
Readeeprom Mymac(5) , 9 : Readeeprom Mymac(6) , 10
End Sub
' Routine to print the MAC-address
'
Sub Print_mac
Print Hex(mymac(1)) ; "-" ; Hex(mymac(2)) ; "-" ; Hex(mymac(3)) ; "-" ; Hex(mymac(4)) ; "-" ; Hex(mymac(5)) ; "-" ; Hex(mymac(6))
End Sub
' Routine to send a default-message to the LCD
'
Sub Default_message
Call Read_ip
If Lcdpresent = 1 Then
Call Lcd_init
Lcd_t = "Embedded Server#IP: "
Call Lcd_txt
Lcd_t = Str(myip(1)) + "." + Str(myip(2)) + "." + Str(myip(3)) + "." + Str(myip(4))
Call Lcd_txt
End If
End Sub |
|