'---------------------------------------------------------------------------------- ' Embedded UDP&WebServer - Atmega32 and RTL8019AS - Embedded UDP&WebServer '---------------------------------------------------------------------------------- ' ' Version 1 - April 1 2005 - Ben Zijlstra - Netherlands - https://benshobbycorner.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 ' ' ' ' 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 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 Showregs Declare Sub Getpacket Declare Sub Overrun Declare Sub Arp Declare Sub Icmp Declare Sub Icmp_checksum Declare Sub Tcp 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 Http Declare Sub Tcp_checksum Declare Sub Send_tcp_packet Declare Sub Setup_packet Declare Sub Assemble_ack Declare Sub Tcpseqtomyseq 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 Myip(4) As Byte At &H64 Dim My_ip As Long At &H64 Overlay Dim Client_seqnum As Long At &H8E Dim Client_seqnum0 As Byte At &H8E Overlay Dim Client_seqnum1 As Byte At &H8F Overlay Dim Client_seqnum2 As Byte At &H90 Overlay Dim Client_seqnum3 As Byte At &H91 Overlay Dim Incoming_ack As Long At &H92 Dim Incoming_ack0 As Byte At &H92 Overlay Dim Incoming_ack1 As Byte At &H93 Overlay Dim Incoming_ack2 As Byte At &H94 Overlay Dim Incoming_ack3 As Byte At &H95 Overlay Dim My_seqnum As Long At &HB7 Dim My_seqnum0 As Byte At &HB7 Overlay Dim My_seqnum1 As Byte At &HB8 Overlay Dim My_seqnum2 As Byte At &HB9 Overlay Dim My_seqnum3 As Byte At &HBA Overlay ' Dim Tempword As Word At &H60 Dim Tempwordh As Byte At &H61 Overlay Dim Tempwordl As Byte At &H60 Overlay 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 Hulp5 As Word At &H7E Dim Hulp5h As Byte At &H7F Overlay Dim Hulp5l As Byte At &H7E Overlay Dim Data_l As Byte Dim Data_h As Byte 'RTL8019AS Dim Txstart As Byte Dim Txlen As Word Dim I_header_length As Word Dim I_odd As Byte Dim I_chksum32 As Long Dim Hulp6 As Word At &HAF Dim Hulp6h As Byte At &HB0 Overlay Dim Hulp6l As Byte At &HAF Overlay Dim I_x As Word Dim I_checksum16 As Word Dim I_value16 As Word At &HB1 Dim I_value16h As Byte At &HB2 Overlay Dim I_value16l As Byte At &HB1 Overlay Dim Result16 As Word At &HB5 Dim Result16h As Byte At &HB6 Overlay Dim Result16l As Byte At &HB5 Overlay 'variables with overlays Dim Pageheader(4) As Byte At &HAB Dim T_enetpacketlenl As Byte At &HAD Overlay Dim T_enetpacketlenh As Byte At &HAE Overlay Dim Resend As Byte Dim T As Byte Dim Packet(1500) 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 Dim Tcp_srcporth As Byte At &HE2 Overlay Dim Tcp_srcportl As Byte At &HE3 Overlay Dim Tcp_destporth As Byte At &HE4 Overlay Dim Tcp_destportl As Byte At &HE5 Overlay Dim Tcp_seqnum3 As Byte At &HE6 Overlay Dim Tcp_seqnum2 As Byte At &HE7 Overlay Dim Tcp_seqnum1 As Byte At &HE8 Overlay Dim Tcp_seqnum0 As Byte At &HE9 Overlay Dim Tcp_acknum3 As Byte At &HEA Overlay Dim Tcp_acknum2 As Byte At &HEB Overlay Dim Tcp_acknum1 As Byte At &HEC Overlay Dim Tcp_acknum0 As Byte At &HED Overlay Dim Tcp_hdr As Byte At &HEE Overlay Dim Tcp_flags As Byte At &HEF Overlay Dim Tcp_cksumh As Byte At &HF2 Overlay Dim Tcp_cksuml As Byte At &HF3 Overlay Dim Tcp_cksum As Word At &HF2 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 Dim T_udp_data As Byte At &HEA Overlay 'LCD variables Dim Lcd_t As String * 40 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 Bit Dim Tcp_fin As Bit Dim Tcp_syn As Bit Dim Tcp_rst As Bit Dim Tcp_psh As Bit Dim Tcp_ack As Bit Dim Tcp_urg As Bit Dim Tcpdatalen_in As Word Dim Tcpdatalen_out As Word Dim Ip_packet_len As Word Dim Flags As Byte Dim Msg_temp As String * 55 Dim Y As Word Dim Tempstring1 As String * 1 Dim Expected_ack As Long Dim Triggerstr As String * 20 Dim Tempstring As String * 10 Dim Portpntr As Byte At &HEA Overlay Dim Portval As String * 4 At &HEB Overlay Dim Relaypntr As Byte At &HEF Overlay Dim Relval As String * 4 At &HF0 Overlay 'Dim Temppntr As Byte At &HF4 Overlay 'Dim Tempval As String * 5 At &HF5 Overlay Dim Relaystatus As Byte '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 'tcp Const Prot_tcp = &H06 'udp Const Prot_udp = &H11 Const Synflag = 0 Const Finflag = 1 'LCD Const Rs = 4 Const E = 7 Const Triggerstring = "SEND INFORMATION NOW" 'RTL8019AS ISR Register definitions Const Rdc = &H40 Config Int0 = Rising 'I2c Config Scl = Portc.0 Config Sda = Portc.1 #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: 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 = "Tutorial" 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 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 '( ' Routine show the contents of the RTL8019as registers ' Sub Showregs Local Cntr1 As Byte Local Cntr2 As Byte Call Write_rtl8019as(cr , &H21) Print Print "Realtek 8019AS Register dump" Print Print "REG Page0 Page1 Page2 Page3" Print For Cntr1 = 0 To 15 Cntr2 = Cntr1 Print Hex(cntr2); Print " "; Call Write_rtl8019as(cr , &H21) Cntr2 = Cntr1 Call Read_rtl8019as(cntr2) Print Hex(byte_read); Print " "; Call Write_rtl8019as(cr , &H61) Cntr2 = Cntr1 Call Read_rtl8019as(cntr2) Print Hex(byte_read); Print " "; Call Write_rtl8019as(cr , &HA1) Cntr2 = Cntr1 Call Read_rtl8019as(cntr2) Print Hex(byte_read); Print " "; Call Write_rtl8019as(cr , &HE1) Cntr2 = Cntr1 Call Read_rtl8019as(cntr2) Print Hex(byte_read) Next Cntr1 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 < 1500 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 ' Hdr_chksum = 0 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 Readeeprom Udp_porth , 11 Readeeprom Udp_portl , 12 Udp_port = Udp_porth Shift Udp_port , Left , 8 Udp_port = Udp_port + Udp_portl Triggerstr = "" Hulp1 = &HEA For Hulp2 = 1 To 20 Hulp3 = Peek(hulp1) Triggerstr = Triggerstr + Chr(hulp3) Incr Hulp1 Next Hulp2 'From within a VB-program If T_udp_destport = Udp_port Then Select Case T_udp_data Case &H01 : Call Relayon(1) Case &H02 : Call Relayon(2) Case &H03 : Call Relayon(3) Case &H04 : Call Relayon(4) Case &HA1 : Call Relayoff(5) Case &HA2 : Call Relayoff(6) Case &HA3 : Call Relayoff(7) Case &HA4 : Call Relayoff(8) End Select If Triggerstr = Triggerstring Then If Lcdpresent = 1 Then Lcd_t = "*UDP request#Sending: " Call Lcd_txt End If Portpntr = Asc( "P") Tempstring = Bin(inputport1) Portval = Left(tempstring , 4) If Lcdpresent = 1 Then Lcd_t = "P" + Portval End If Relaypntr = Asc( "R") Tempstring = Bin(relaystatus) Relval = Right(tempstring , 4) If Lcdpresent = 1 Then Lcd_t = Lcd_t + "R" Lcd_t = Lcd_t + Relval Call Lcd_txt Idletime = 0 End If '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 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 'udp_srcport0 = packet(&h23) 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 I2csend Pcf8574 , &B10000011 I2csend Pcf8574 , &B00000011 Waitms 4 'set 8-bit mode (attention) I2csend Pcf8574 , &B10000011 I2csend Pcf8574 , &B00000011 Waitms 1 'set 8-bit mode (attention) I2csend Pcf8574 , &B10000011 I2csend Pcf8574 , &B00000011 Waitms 4 'set 4-bit operation I2csend Pcf8574 , &B10000010 I2csend Pcf8574 , &B00000010 Waitms 1 'set 8-bit mode (attention) I2csend Pcf8574 , &B10000010 I2csend Pcf8574 , &B00000010 I2csend Pcf8574 , &B10001000 I2csend Pcf8574 , &B00001000 Waitms 1 I2csend Pcf8574 , &B10000000 I2csend Pcf8574 , &B00000000 'Display off, cursor off, blink off I2csend Pcf8574 , &B10001000 I2csend Pcf8574 , &B00001000 Waitms 1 I2csend Pcf8574 , &B10000000 I2csend Pcf8574 , &B00000000 'display on, cursor off, blinking off I2csend Pcf8574 , &B10001100 I2csend Pcf8574 , &B00001100 Waitms 1 I2csend Pcf8574 , &B10000000 I2csend Pcf8574 , &B00000000 'clear display and send cursor to address 0 I2csend Pcf8574 , &B10000001 I2csend Pcf8574 , &B00000001 Waitms 1 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 I2csend Pcf8574 , Lcd_temp Reset Lcd_temp.e Reset Lcd_temp.rs I2csend Pcf8574 , Lcd_temp Lcd_temp = Lcd_c And &H0F I2csend Pcf8574 , Lcd_temp Set Lcd_temp.e Set Lcd_temp.rs I2csend Pcf8574 , Lcd_temp Reset Lcd_temp.e Reset Lcd_temp.rs I2csend Pcf8574 , Lcd_temp 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 I2csend Pcf8574 , &B10000000 I2csend Pcf8574 , &B00000000 Waitms 2 I2csend Pcf8574 , &B10000001 I2csend Pcf8574 , &B00000001 Waitms 2 End Sub Sub Secondline Call Firstline For Lcd_h = 1 To 40 I2csend Pcf8574 , &B10000001 I2csend Pcf8574 , &B00000001 Waitms 2 I2csend Pcf8574 , &B10000100 I2csend Pcf8574 , &B00000100 Waitms 2 Next Lcd_h End Sub Sub Firstline I2csend Pcf8574 , &B10000000 I2csend Pcf8574 , &B00000000 Waitms 2 I2csend Pcf8574 , &B10000010 I2csend Pcf8574 , &B00000010 Waitms 2 End Sub ' TCP ' Sub Tcp Local Work As Byte Work = Tcp_flags Tcp_fin = Work.0 Tcp_syn = Work.1 Tcp_rst = Work.2 Tcp_psh = Work.3 Tcp_ack = Work.4 Tcp_urg = Work.5 If Tcp_destporth = 0 Then Select Case Tcp_destportl Case 80 : Call Http End Select End If End Sub Sub Http #if Debug = 1 Print "HTTP" Print Print "Destination port low " ; Tcp_destportl Print "Destination port high " ; Tcp_destporth Print Print "TCPdatalen_in " ; Tcpdatalen_in Print Print "Flags:" Print "FIN " ; Tcp_fin Print "SYN " ; Tcp_syn Print "RST " ; Tcp_rst Print "PSH " ; Tcp_psh Print "ACK " ; Tcp_ack Print "URG " ; Tcp_urg Print Print "Incoming:" Print "Tcp_seqnum3 " ; Hex(tcp_seqnum3) Print "Tcp_seqnum2 " ; Hex(tcp_seqnum2) Print "Tcp_seqnum1 " ; Hex(tcp_seqnum1) Print "Tcp_seqnum0 " ; Hex(tcp_seqnum0) Print Print "Tcp_acknum3 " ; Hex(tcp_acknum3) Print "Tcp_acknum2 " ; Hex(tcp_acknum2) Print "Tcp_acknum1 " ; Hex(tcp_acknum1) Print "Tcp_acknum0 " ; Hex(tcp_acknum0) #endif Local Msg_temp2 As String * 10 Local Tempword3 As Word Local Z As Word Local Ztemp As Word Local Tempstring2 As String * 5 Local Templong1 As Long Result16h = T_ip_pktlen0 Result16l = T_ip_pktlen1 ' ' calculate IP header length ' MSN is version (IPv4) ' LSN is length Hulp1 = T_ip_vers_len And &H0F Hulp1 = Hulp1 * 4 ' calculate TCP header length ' MSN is length / 4 Hulp2 = Tcp_hdr And &HF0 Shift Hulp2 , Right , 4 Hulp2 = Hulp2 * 4 Tcpdatalen_in = Result16 - Hulp1 Tcpdatalen_in = Tcpdatalen_in - Hulp2 ' If an ACK is received and the destination port address is valid ' and no data is in the packet If Tcp_ack = 1 Then If Tcpdatalen_in = 0 Then Incoming_ack0 = Tcp_acknum0 Incoming_ack1 = Tcp_acknum1 Incoming_ack2 = Tcp_acknum2 Incoming_ack3 = Tcp_acknum3 If Flags.synflag = 1 Then Reset Flags.synflag My_seqnum = Incoming_ack Tempword3 = &H37 If Lcdpresent = 1 Then Lcd_t = "*HTTP request" Call Lcd_txt Call Secondline Lcd_t = "Sending: " Call Lcd_txt Tempstring = Bin(inputport1) Lcd_t = "P" + Left(tempstring , 4) Call Lcd_txt Tempstring = Bin(relaystatus) Lcd_t = "R" + Right(tempstring , 4) Call Lcd_txt Idletime = 0 End If Restore Htmlcode Do Read Msg_temp Msg_temp2 = Right(msg_temp , 8) If Msg_temp2 = "endblock" Then Exit Do End If If Msg_temp2 = "get-ipnr" Then Readeeprom Hulp1 , 13 If Hulp1 = &HFF Then Msg_temp = "http://" + Str(myip(1)) Msg_temp = Msg_temp + "." + Str(myip(2)) Msg_temp = Msg_temp + "." + Str(myip(3)) Msg_temp = Msg_temp + "." + Str(myip(4)) Else Msg_temp = "" For Y = 1 To Hulp1 Hulp3 = Y + 13 Readeeprom Hulp2 , Hulp3 Msg_temp = Msg_temp + Chr(hulp2) Next Y End If End If If Msg_temp2 = "get-info" Then If Inputport1.4 = 0 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Inputport1.5 = 0 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Inputport1.6 = 0 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Inputport1.7 = 0 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Relaystatus.0 = 1 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Relaystatus.1 = 1 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Relaystatus.2 = 1 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y If Relaystatus.3 = 1 Then Msg_temp = "on" Else Msg_temp = "off" End If For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y Else For Y = 1 To Len(msg_temp) Tempstring1 = Mid(msg_temp , Y , 1) Packet(tempword3) = Asc(tempstring1) Incr Tempword3 Next Y End If Loop Tcpdatalen_out = Tempword3 - 55 'minus headerlength ' expect to get an acknowledgment of the message Expected_ack = My_seqnum + Tcpdatalen_out ' send the TCP/IP packet Call Send_tcp_packet End If End If End If ' This code segment processes the incoming SYN from the Tenet client ' and sends back the initial sequence number (ISN) and acknowledges ' the incoming SYN packet If Tcp_syn = 1 Then #if Debug = 1 Print "Tcp_syn = 1" #endif Tcpdatalen_in = 1 Set Flags.synflag Call Setup_packet Swap Tcp_srcportl , Tcp_destportl Swap Tcp_srcporth , Tcp_destporth Call Assemble_ack Call Tcpseqtomyseq Tcp_flags = 0 Set Tcp_flags.1 Set Tcp_flags.4 Call Tcp_checksum Call Echopacket End If If Tcp_fin = 1 Then Set Flags.finflag Incr Tcpdatalen_in Incoming_ack0 = Tcp_acknum0 Incoming_ack1 = Tcp_acknum1 Incoming_ack2 = Tcp_acknum2 Incoming_ack3 = Tcp_acknum3 'Call Incomacqtotcpack If Incoming_ack <= Expected_ack Then Templong1 = Expected_ack - Incoming_ack My_seqnum = Expected_ack - Templong1 End If Expected_ack = My_seqnum + Tcpdatalen_out Call Send_tcp_packet End If If Tcp_psh = 1 Then #if Debug = 1 Print "Tcp_psh = 1" #endif ' walk through the packet until GET / is found For Z = 40 To 255 Ztemp = Z Tempstring2 = Chr(packet(ztemp)) Incr Ztemp Tempstring2 = Tempstring2 + Chr(packet(ztemp)) Incr Ztemp Tempstring2 = Tempstring2 + Chr(packet(ztemp)) Incr Ztemp Tempstring2 = Tempstring2 + Chr(packet(ztemp)) Incr Ztemp Tempstring2 = Tempstring2 + Chr(packet(ztemp)) If Tempstring2 = "GET /" Then Ztemp = Ztemp + 301 Exit For End If #if Debug = 1 Print "/GET gevonden" #endif Next Z 'ztemp > 300 when GET / is found 'ztemp <= 300 when GET / not found 'when found ztemp has the pointer to it (plus 300) If Ztemp > 300 Then Ztemp = Ztemp - 300 If Chr(packet(ztemp)) = "R" Then Incr Ztemp Hulp1 = Val(packet(ztemp)) Select Case Hulp1 Case 1 To 4 : Call Relayon(hulp1) Case 5 To 8 : Call Relayoff(hulp1) End Select End If End If End If End Sub Sub Tcp_checksum Local Whulp1 As Word Local Whulp2 As Word Local Whulp3 As Word Local Tempword2 As Word Tcp_cksum = 0 I_chksum32 = 0 Tempwordh = T_ip_srcaddr0 Tempwordl = T_ip_srcaddr1 I_chksum32 = Tempword Tempwordh = T_ip_srcaddr2 Tempwordl = T_ip_srcaddr3 I_chksum32 = I_chksum32 + Tempword Tempwordh = T_ip_destaddr0 Tempwordl = T_ip_destaddr1 I_chksum32 = I_chksum32 + Tempword Tempwordh = T_ip_destaddr2 Tempwordl = T_ip_destaddr3 I_chksum32 = I_chksum32 + Tempword I_chksum32 = I_chksum32 + T_ip_proto Tempwordh = T_ip_pktlen0 Tempwordl = T_ip_pktlen1 Tempword2 = T_ip_vers_len And &H0F Tempword2 = Tempword2 * 4 I_chksum32 = I_chksum32 + Tempword I_chksum32 = I_chksum32 - Tempword2 Whulp2 = Tempword - 20 Whulp2 = Whulp2 + &H23 Whulp2 = Whulp2 - 2 Val1 = &H23 Val2 = Whulp2 I_odd = Val2 - Val1 I_odd = I_odd Mod 2 Call General_part_checksum(val1 , Val2) Tcp_cksumh = Val3 Tcp_cksuml = Val4 End Sub ' Send the TCP-packet, a bit different then echopacket ' Sub Send_tcp_packet Ip_packet_len = 40 + Tcpdatalen_out T_ip_pktlen1 = Low(ip_packet_len) T_ip_pktlen0 = High(ip_packet_len) Call Setup_packet Swap Tcp_srcporth , Tcp_destporth Swap Tcp_srcportl , Tcp_destportl Call Assemble_ack Call Tcpseqtomyseq Tcp_flags = 0 'fin_out Set Tcp_flags.0 ' piggyback FIN onto the page date 'ack_out Set Tcp_flags.4 If Flags.finflag = 1 Then 'fin_out Set Tcp_flags.0 'clr_finflag Reset Flags.finflag End If Call Tcp_checksum Txlen = Ip_packet_len + 14 If Txlen < 60 Then Txlen = 60 End If Call Write_rtl8019as(cr , &H22) Call Write_rtl8019as(tpsr , Txstart) Call Write_rtl8019as(rsar0 , &H00) Call Write_rtl8019as(rsar1 , &H40) Call Write_rtl8019as(isr , &HFF) Hulp1 = Low(txlen) Call Write_rtl8019as(rbcr0 , Hulp1) Hulp1 = High(txlen) Call Write_rtl8019as(rbcr1 , Hulp1) Call Write_rtl8019as(cr , &H12) For I = 1 To Txlen Call Write_rtl8019as(rdmaport , Packet(i)) Next '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 Hulp1 = Low(txlen) Call Write_rtl8019as(tbcr0 , Hulp1) Hulp1 = High(txlen) Call Write_rtl8019as(tbcr1 , Hulp1) Call Write_rtl8019as(cr , &H24) 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 Sub Assemble_ack Client_seqnum0 = Tcp_seqnum0 Client_seqnum1 = Tcp_seqnum1 Client_seqnum2 = Tcp_seqnum2 Client_seqnum3 = Tcp_seqnum3 Client_seqnum = Client_seqnum + Tcpdatalen_in Tcp_acknum0 = Client_seqnum0 Tcp_acknum1 = Client_seqnum1 Tcp_acknum2 = Client_seqnum2 Tcp_acknum3 = Client_seqnum3 End Sub Sub Tcpseqtomyseq Tcp_seqnum0 = My_seqnum0 Tcp_seqnum1 = My_seqnum1 Tcp_seqnum2 = My_seqnum2 Tcp_seqnum3 = My_seqnum3 End Sub ' Routine to switch on relay X and update status ' Sub Relayon(x) Decr X Relaystatus.x = 1 Call Status End Sub ' Routine to switch off relay X and update status ' Sub Relayoff(x) X = X - 5 Relaystatus.x = 0 Call Status End Sub ' Routine to switch on/off relais and get the status ' Sub Status Databus_ddr = &HFF Databus = Relaystatus Set Latch Reset Latch 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.10" Print Print "Source written by Ben Zijlstra june 2004" 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 ' htmlcode ' Htmlcode: Data "HTTP/1.0 200" , &H0D , &H0A , &H0D , &H0A Data "" Data "" Data "Ethernet I/O board" Data "" Data "" Data "get-info" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "" Data "
Input 1Input 2Input 3Input 4Relay 1Relay 2Relay 3Relay 4
" Data "

Ethernet I/O board" Data "

" Data "
onononon
offoffoffoff
" , &H0D , &H0A Data "endblock"