PIC18F97J60EthernetDriver
SwordfishUser.PIC18F97J60EthernetDriver History
Show minor edits - Show changes to output
Changed lines 217-226 from:
End ASM
Repeat
Until MISTAT.0 = 0
// BSR = 0
ASM
movlb 0
End ASM
to:
FSR2 = AddressOf(MISTAT)
While INDF2.0 <> 0 Wend
While INDF2.0 <> 0 Wend
Changed lines 238-243 from:
End ASM
//
ECON2.5 = 1
While ESTAT.0 <> 1 Nop
to:
FSR2 = AddressOf(ECON2)
INDF2.5 = 1
FSR2 = AddressOf(ESTAT)
While INDF2.0 <> 1 Wend
INDF2.5 = 1
FSR2 = AddressOf(ESTAT)
While INDF2.0 <> 1 Wend
Changed lines 244-245 from:
to:
FSR2 = AddressOf(ETXSTL)
POSTINC2 = $00 Nop
INDF2 = $19
POSTINC2 = $00 Nop
INDF2 = $19
Changed lines 248-249 from:
to:
FSR2 = AddressOf(ERXSTL)
POSTINC2 = $00 Nop
INDF2 = $00
POSTINC2 = $00 Nop
INDF2 = $00
Changed lines 252-253 from:
to:
FSR2 = AddressOf(ERXNDL)
POSTINC2 = $FF Nop
INDF2 = $18
POSTINC2 = $FF Nop
INDF2 = $18
Changed lines 256-258 from:
to:
FSR2 = AddressOf(ERXRDPTL)
POSTINC2 = $00 Nop
INDF2 = $00
FSR2 = AddressOf(ERXFCON)
INDF2 = %00100000 // Receiver Filter
POSTINC2 = $00 Nop
INDF2 = $00
FSR2 = AddressOf(ERXFCON)
INDF2 = %00100000 // Receiver Filter
Changed lines 263-264 from:
to:
FSR2 = AddressOf(MACON1)
INDF2 = %00001101 // TXPAUS, RXPAUS, MARXEN
INDF2 = %00001101 // TXPAUS, RXPAUS, MARXEN
Changed lines 266-267 from:
to:
FSR2 = AddressOf(MACON3)
POSTINC2 = %00110011 Nop // PADCFG0, TXCRCEN, FRMLNEN
INDF2 = %00000000
POSTINC2 = %00110011 Nop // PADCFG0, TXCRCEN, FRMLNEN
INDF2 = %00000000
Changed lines 270-280 from:
MABBIPG =
MAMXFLH =
//
to:
FSR2 = AddressOf(MAIPGL)
POSTINC2 = $12 Nop
INDF2 = $0C
FSR2 = AddressOf(MABBIPG)
INDF2 = $15
FSR2 = AddressOf(MAMXFLL)
POSTINC2 = $EE Nop // max_packet bytes
INDF2 = $05 Nop
MAADR1 = eth_mac(5) // Set up your MAC address
POSTINC2 = $12 Nop
INDF2 = $0C
FSR2 = AddressOf(MABBIPG)
INDF2 = $15
FSR2 = AddressOf(MAMXFLL)
POSTINC2 = $EE Nop // max_packet bytes
INDF2 = $05 Nop
MAADR1 = eth_mac(5) // Set up your MAC address
Changed line 287 from:
ECON1.2 = 1 // Enable packet reception
to:
ECON1.2 = 1 // Enable packet reception
Changed lines 298-307 from:
End ASM
//
ECON2
ESTAT.0 = 0
ASM
movlb 0
End ASM
// BSR
to:
FSR2 = AddressOf(ECON2)
INDF2.5 = 0
FSR2 = AddressOf(ESTAT)
INDF2.0 = 0
INDF2.5 = 0
FSR2 = AddressOf(ESTAT)
INDF2.0 = 0
Changed lines 310-311 from:
ERDPTL =(AddrPacket).Byte0 // Set the lower write pointer
ERDPTH =(AddrPacket).Byte1 // Set the upper write pointer
ERDPTH =
to:
ERDPTL =(AddrPacket).Byte0 // Set the lower write pointer
ERDPTH = (AddrPacket).Byte1 // Set the upper write pointer
ERDPTH = (AddrPacket).Byte1 // Set the upper write pointer
Changed lines 315-325 from:
ERXRDPTL = (next_address).Byte0 // Set the lower write pointer
ERXRDPTH = (next_address).Byte1 // Set the upper write pointer
ASM
movlb 14
End ASM
// BSR = 14
ECON2.6 = 1 // Decrement the number of packets
ASM
movlb 0
End ASM
// BSR = 0
ASM
//
ASM
movlb 0
End ASM
// BSR = 0
to:
ERXRDPTL = (next_address).Byte0 // Set the lower write pointer
ERXRDPTH = (next_address).Byte1 // Set the upper write pointer
FSR2 = AddressOf(ECON2)
INDF2.6 = 1 // Decrement the number of packets
ERXRDPTH = (next_address).Byte1 // Set the upper write pointer
FSR2 = AddressOf(ECON2)
INDF2.6 = 1 // Decrement the number of packets
Changed lines 320-321 from:
ERDPTL = (next_address).Byte0 // Set the lower write pointer
ERDPTH =(next_address).Byte1 // Set the upper write pointer
ERDPTH =
to:
ERDPTL = (next_address).Byte0 // Set the lower write pointer
ERDPTH = (next_address).Byte1 // Set the upper write pointer
ERDPTH = (next_address).Byte1 // Set the upper write pointer
Changed lines 329-341 from:
//
ETXSTL = $00
EWRPTH = $19
End ASM
//
EDATA_reg = $0E
to:
FSR2 = AddressOf(ETXSTL)
POSTINC2 = $00 Nop // Set the lower start of packet
INDF2 = $19 // Set the upper start of packet
FSR2 = AddressOf(EWRPTL)
POSTINC2 = $00 Nop // Set the lower write pointer
INDF2 = $19 // Set the upper write pointer
EDATA_reg = $0E // Start Byte (MUST START WITH THIS)
POSTINC2 = $00 Nop // Set the lower start of packet
INDF2 = $19 // Set the upper start of packet
FSR2 = AddressOf(EWRPTL)
POSTINC2 = $00 Nop // Set the lower write pointer
INDF2 = $19 // Set the upper write pointer
EDATA_reg = $0E // Start Byte (MUST START WITH THIS)
Changed line 340 from:
While ECON1.3 <> 0 Nop Wend
to:
While ECON1.3 <> 0 Wend
Changed line 809 from:
While ECON1.5 <> 0 Nop Wend
to:
While ECON1.5 <> 0 Wend
Changed line 878 from:
While ECON1.5 <> 0 Nop Wend
to:
While ECON1.5 <> 0 Wend
Changed line 1100 from:
"<title>LV18FJ Web Example</title>"+
to:
"<title>Web Example</title>"+
Added lines 30-35:
Public Sub Firewall(ICMP, TCP, UDP as boolean)
{Default all false, allow all type of packets}
{If ICMP = true, ignore ICMP request. Ex. Firewall(true, false, false)}
{If TCP = true, ignore TCP packets. Ex. Firewall(false, true, false)}
{If UDP = true, ignore UDP packets. Ex. Firewall(false, false, true)}
{Default all false, allow all type of packets}
{If ICMP = true, ignore ICMP request. Ex. Firewall(true, false, false)}
{If TCP = true, ignore TCP packets. Ex. Firewall(false, true, false)}
{If UDP = true, ignore UDP packets. Ex. Firewall(false, false, true)}
Added lines 61-66:
Public Sub CopyEthMemToRam_Inv(start_eth_address, dest_ram_address, length_w as word)
{Ex. CopyEthMemToRam(AddrPacket+6,AddressOf(data_dWord),4)}
Public Sub CopyRamToEthMem_Inv(start_ram_address, dest_eth_address, length_w as word)
{Ex. CopyRamToEthMem(AddressOf(data_dWord),TXSTART+22,4)}
{Ex. CopyEthMemToRam(AddrPacket+6,AddressOf(data_dWord),4)}
Public Sub CopyRamToEthMem_Inv(start_ram_address, dest_eth_address, length_w as word)
{Ex. CopyRamToEthMem(AddressOf(data_dWord),TXSTART+22,4)}
Added lines 1-1184:
Ethernet Module (driver) for PIC18F97J60 family .
This module support ICMP, ARP, UDP, TCP protocols and have Mini Web Server example.
No TCP/IP stack and fragmentation available now.
Default Ip address is 192.168.1.253
'''Available functions'''
=code [=
Public Sub Eth_SetParameters
{Set your IP, Mac, Mask ... etc... here}
Public Sub Eth_Init
{Init MCU Ethernet}
Public Sub Eth_Reset
{Reset MCU Ethernet}
Public Sub Eth_DoPacket
{Process incoming packets}
Public Function Eth_UserTCP(byref dest_ip_addr_T(4) as byte, byref source_port_T, dest_port_T, len_T as word) as word
{This Sub Function is called by library. Put your TCP response for WEB server parameters here. See example}
Public Function Eth_UserUDP(byref dest_ip_addr_U(4) as byte, byref dest_port_U, source_port_U, len_U as word) as word
{This Sub Function is called by library. Put your UDP response here. See example. ( ECHO example )}
Public Sub Eth_PutByte(value as byte)
{Put one byte in ETH memory}
Public Function Eth_GetByte as byte
{Get one byte from ETH memory}
Public Function CopyFlashToEthMem_CP(start_Flash_address as longword) as word
{Copy Const from flash to Eth Memory and return length of Const data}
{Const data must be defined as STRING. (and must be zero terminated)}
{Ex. len = CopyFlashToEthMem_CP(AddressOf(httpHeader))}
Public Function CopyRamToEthMem_CP(s as String) as word
{Copy ram data to Eth Memory and return length of data}
{ram data must be defined as String. (and must be zero terminated)}
{Ex. len = CopyRamToEthMem_CP(data)}
Public Sub CopyEthMemToRam(start_eth_address, dest_ram_address, length_w as word)
{Ex. CopyEthMemToRam(AddrPacket+6,AddressOf(dest_mac_addr),6)}
Public Sub CopyRamToEthMem(start_ram_address, dest_eth_address, length_w as word)
{Ex. CopyRamToEthMem(AddressOf(eth_mac),TXSTART+22,6)}
Public Sub CopyFlashToEthMem(start_Flash_address as longword, dest_eth_address, length_w as word)
{Ex. CopyFlashToEthMem(AddressOf(httpHeader),TXSTART+54,30)}
Public Sub CopyEthMemToEthMem(start_eth_address, dest_eth_address, length_w as word, where as byte)
{where = 0 copy from Eth RxBuf to Eth TxBuf}
{where = 1 copy from Eth TxBuf to Eth TxBuf}
{Ex. CopyEthMemToEthMem(AddrPacket+38,TXSTART+28,4,0)}
Public Sub WriteToEthMem(dest_eth_address as word, value as byte)
{Ex. WriteToEthMem(TXSTART+12,$08)}
Public Function ReadFromEthMem(start_eth_address as word) as byte
{Ex. data = ReadFromEthMem(AddrPacket+38)}
Public Function EthMemCompareWithRam(start_eth_address, start_ram_address, length_w as word) as boolean
{Ex. bol = EthMemCompareWithRam(AddrPacket+30,AddressOf(eth_ip_addr),4)}
Public Function EthMemCompareWithFlash(start_eth_address as word, start_Flash_address as longword, length_w as word) as boolean
{Ex. bol = EthMemCompareWithFlash(AddrPacket+54, AddressOf(httpHeader), 30)}
Public Function Eth_Cksum(start_eth_address, length_w as word) as word
{Ex. cksum_ip = Eth_Cksum(TXSTART+14,20)}
Public Sub Eth_WritePHYReg(register_address as byte, data as word)
{Write to PHY registers}
Public Sub Eth_SetLedConfig(NewConfig as word)
{Set Eth Led configuration. See datasheet for more detail}
Public Function Eth_ReadPacket as word
{Read packet and return TYPE OF SERVICE}
Public Sub Eth_Send(length_w as word)
{Send packet from Tx buffer}
=]
You can download source code from : [[http://www.microelemente.ro/Swordfish/Mini_WEB_Server.zip]]
!!!Example Code
=code [=
{
****************************************************************
* Name : MiniWebServer.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : MCU PIC18F97J60 family *
* : *
****************************************************************
}
Device = 18F67J60
Clock = 41.666667
Config FOSC = HSPLL
Config FOSC2 = ON
Config WDTPS = 1024
#option WDT = true
Include "lib_18F97J60_V3_3"
Include "lib1_18F97J60_V3_3"
Include "system"
Sub Init()
OSCTUNE = %01000000
DelayMS(100)
ClrWDT
WDTCON = 1
CMCON = $07
ADCON1 = %00001111 // All digital
ADCON2 = %10000111 // RC Clock
INTCON2 = %01111111 // PORTB Pull Up
TRISE = $0F
PORTE = $F0
End Sub
Sub Eth_SetParameters() // set your parameters here
eth_ip_addr(0) = 192
eth_ip_addr(1) = 168
eth_ip_addr(2) = 1
eth_ip_addr(3) = 253
eth_mac(0) = $00
eth_mac(1) = $04
eth_mac(2) = $A3
eth_mac(3) = $00
eth_mac(4) = $80
eth_mac(5) = $85
eth_port = 10001
dest_port = 10001
Uptime = 0
End Sub
Init
Eth_Reset
Eth_SetParameters
Eth_Init
Firewall(false,false,false)
While true
Eth_DoPacket // process incoming packets
Wend
End.
=]
!!!Module Code
=code [=
{
****************************************************************
* Name : lib_18F97J60_V3_3.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : *
* : *
****************************************************************
}
Module lib_18F97J60_V3_3
Include "lib1_18F97J60_V3_3"
Include "lib_user"
Include "system"
Const
ETH_ARP As Word = $0806,
ETH_ARP_REQ As Byte = $01,
ETH_ARP_RES As Byte = $02,
ETH_IP As Word = $0800,
ETH_IP_TCP As Byte = $06,
ETH_IP_UDP As Byte = $11,
ETH_IP_ICMP As Byte = $01,
ETH_IP_ICMP_ECHO As Byte = $08,
ETH_IP_ICMP_REPLY As Byte = $00,
URG As Byte = 5,
ACK As Byte = 4,
PSH As Byte = 3,
RST As Byte = 2,
SYN As Byte = 1,
FIN As Byte = 0,
PHLCON As Word = $0014,
PHCON1 As Word = $0000,
PHSTAT1 As Word = $0001,
PHCON2 As Word = $0010,
PHSTAT2 As Word = $0011
Sub Eth_WritePHYReg(register_address As Byte, data As Word)
MIREGADR = register_address // Address to MIREGADR
MIWRL = data.Byte0 // Lo byte to MIWRL
MIWRH = data.Byte1 // Hi byte to MIWRH
// Wait until the PHY register has been written
// BSR = 14
ASM
movlb 14
End ASM
Repeat
Until MISTAT.0 = 0
// BSR = 0
ASM
movlb 0
End ASM
End Sub
Sub Eth_SetLedConfig(NewConfig As Word)
Eth_WritePHYReg(PHLCON, NewConfig)
End Sub
Public Sub Firewall(F_ICMP, F_TCP, F_UDP As Boolean)
FICMP = F_ICMP
FTCP = F_TCP
FUDP = F_UDP
End Sub
Public Sub Eth_Init()
NextPacket = RXSTART
AddrPacket = RXSTART
LATA.0 = 0
LATA.1 = 0
TRISA.0 = 0
TRISA.1 = 0
ASM
movlb 14
End ASM
// BSR = 14
ECON2.5 = 1
While ESTAT.0 <> 1 Nop Wend
DelayMS(1)
//*** INIT **************************************//
ETXSTL = $00
ETXSTH = $19
// Start of RX buffer NOTE as ERXWRPT WILL TAKE ON SAME VALUES
ERXSTL = $00
ERXSTH = $00
// End of RX buffer
ERXNDL = $FF
ERXNDH = $18
// Pointer of RX buffer
ERXRDPTL = $00
ERXRDPTH = $00
ERXFCON = %00100000 // Receiver Filter
//*** MAC INIT *********************************//
// Enable MAC to RX
MACON1 = %00001101 // TXPAUS, RXPAUS, MARXEN
// Paded to 60 bytes and CRC and check length
MACON3 = %00110011 Nop // PADCFG0, TXCRCEN, FRMLNEN
MACON4 = %00000000
// Non Back to Back shit
MAIPGL = $12
MAIPGH = $0C
MABBIPG = $15
MAMXFLL = $EE // max_packet bytes
MAMXFLH = $05
ASM
movlb 0
End ASM
// BSR = 0
// Set up your MAC address
MAADR1 = eth_mac(5)
MAADR2 = eth_mac(4)
MAADR3 = eth_mac(3)
MAADR4 = eth_mac(2)
MAADR5 = eth_mac(1)
MAADR6 = eth_mac(0)
Eth_WritePHYReg(PHCON1, $0100) // PHCON1 full duplex
Eth_WritePHYReg(PHCON2, $0110) // PHCON2 Disable half duplex loopback in PHY
Eth_SetLedConfig($0472)
ECON1.2 = 1 // Enable packet reception
udp_counter = 1000 // start UDP counter with this value
tcp_counter = 1000
ACK_No = 0
SEQ_No = $42844A80
DelayMS(1000)
ClrWDT
Firewall(false, false, false)
End Sub
Public Sub Eth_Reset()
ASM
movlb 14
End ASM
// BSR = 14
ECON2.5 = 0
ESTAT.0 = 0
ASM
movlb 0
End ASM
// BSR = 0
TRISA = $FF
DelayMS(1)
ClrWDT
End Sub
Function Eth_ReadPacket() As Word
Dim next_address As Word
AddrPacket = NextPacket
ERDPTL =(AddrPacket).Byte0 // Set the lower write pointer
ERDPTH = (AddrPacket).Byte1 // Set the upper write pointer
NextPacket.Byte0 = EDATA_reg
NextPacket.Byte1 = EDATA_reg
next_address = NextPacket - 1
ERXRDPTL = (next_address).Byte0 // Set the lower write pointer
ERXRDPTH = (next_address).Byte1 // Set the upper write pointer
ASM
movlb 14
End ASM
// BSR = 14
ECON2.6 = 1 // Decrement the number of packets
ASM
movlb 0
End ASM
// BSR = 0
next_address = Check_FIFO(AddrPacket + 18)
ERDPTL = (next_address).Byte0 // Set the lower write pointer
ERDPTH = (next_address).Byte1 // Set the upper write pointer
Result.Byte1 = EDATA_reg
Result.Byte0 = EDATA_reg
AddrPacket = Check_FIFO(AddrPacket + 6)
End Function
Sub Eth_Send(length_w As Word)
Dim address As Word
ASM
movlb 14
End ASM
// BSR = 14
ETXSTL = $00 // Set the lower start of packet
ETXSTH = $19 // Set the upper start of packet
EWRPTL = $00 // Set the lower write pointer
EWRPTH = $19 // Set the upper write pointer
ASM
movlb 0
End ASM
// BSR = 0
EDATA_reg = $0E // Start Byte (MUST START WITH THIS)
address = (TXSTART - 1) + length_w
ETXNDL = (address).Byte0
ETXNDH = (address).Byte1
ECON1.3 = 1
While ECON1.3 <> 0 Nop Wend
End Sub
Sub Eth_MacSwap()
CopyEthMemToEthMem(AddrPacket+6,TXSTART,6,0)
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+6,6)
End Sub
Sub Eth_IpSwap()
CopyRamToEthMem(AddressOf(eth_ip_addr),TXSTART+26,4)
CopyEthMemToEthMem(AddrPacket+26,TXSTART+30,4,0)
End Sub
Sub Eth_MacSwap_User()
CopyRamToEthMem(AddressOf(dest_mac),TXSTART,6)
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+6,6)
End Sub
Sub Eth_IpSwap_User()
CopyRamToEthMem(AddressOf(eth_ip_addr),TXSTART+26,4)
CopyRamToEthMem(AddressOf(dest_ip_addr),TXSTART+30,4)
End Sub
Sub Eth_ARPResponse()
Eth_MacSwap
WriteToEthMem(TXSTART+12,$08)
EDATA_reg = $06 Nop
EDATA_reg = $00
EDATA_reg = $01
EDATA_reg = $08 Nop
EDATA_reg = $00
EDATA_reg = $06
EDATA_reg = $04 Nop
EDATA_reg = $00
EDATA_reg = $02
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+22,6)
CopyEthMemToEthMem(AddrPacket+28,TXSTART+38,4,0)
CopyEthMemToEthMem(AddrPacket+38,TXSTART+28,4,0)
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+32,6)
Eth_Send(42)
End Sub
Sub Eth_PingResponse()
Dim cksum,PacketSize As Word
PacketSize.Byte1 = ReadFromEthMem(AddrPacket+16)
PacketSize.Byte0 = EDATA_reg
PacketSize = PacketSize + 14
Eth_MacSwap
CopyEthMemToEthMem(AddrPacket+12,TXSTART+12,14,0)
Eth_IpSwap
WriteToEthMem(TXSTART+34,$00)
EDATA_reg = $00 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
CopyEthMemToEthMem(AddrPacket+38,TXSTART+38,PacketSize-38,0)
cksum = Eth_Cksum(TXSTART+34,PacketSize-34)
WriteToEthMem(TXSTART+36,(cksum).Byte1)
EDATA_reg = (cksum).Byte0
Eth_Send(PacketSize)
End Sub
Sub Eth_SendUDP(dest_portA, source_portA, PacketLenA As Word)
Dim TotalLen,cksum_ip,cksum_udp As Word,
Align As Byte
WriteToEthMem(TXSTART+12,$08)
EDATA_reg = $00
EDATA_reg = $45 Nop
EDATA_reg = $00
Inc(udp_counter)
TotalLen = PacketLenA + 28
EDATA_reg = (TotalLen).Byte1 Nop
EDATA_reg = (TotalLen).Byte0 Nop
EDATA_reg = (udp_counter).Byte1 Nop
EDATA_reg = (udp_counter).Byte0 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
EDATA_reg = $80
EDATA_reg = $11 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
cksum_ip = Eth_Cksum(TXSTART+14,20)
WriteToEthMem(TXSTART+24,(cksum_ip).Byte1)
EDATA_reg = (cksum_ip).Byte0
WriteToEthMem(TXSTART+34,(source_portA).Byte1)
EDATA_reg = (source_portA).Byte0
EDATA_reg = (dest_portA).Byte1
EDATA_reg = (dest_portA).Byte0
TotalLen = PacketLenA + 8
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
EDATA_reg = $00 Nop
EDATA_reg = $00
Align = TotalLen And $01
WriteToEthMem(TXSTART+PacketLenA+42,$00)
EDATA_reg = $00
CopyEthMemToEthMem(TXSTART+26,TXSTART+PacketLenA+Align+42,8,1)
WriteToEthMem(TXSTART+PacketLenA+Align+42+8,$00)
EDATA_reg = $11
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
cksum_udp = Eth_Cksum(TXSTART+34,TotalLen + Align + 12)
If cksum_udp = 0 Then cksum_udp = $FFFF End If
WriteToEthMem(TXSTART+40,(cksum_udp).Byte1)
EDATA_reg = (cksum_udp).Byte0
TotalLen = PacketLenA + 42
Eth_Send(TotalLen)
End Sub
Sub SendUDP(dest_port_S, source_port_S, len_data As Word, ByRef data_udp() As Byte)
Dim i As Word
Eth_MacSwap_User
Eth_IpSwap_User
Put_UDPPointer
i = 0
While i < len_data
Eth_PutByte(data_udp(i))
Inc(i)
Wend
Eth_SendUDP(dest_port_S, source_port_S, i)
End Sub
Sub Eth_ProcessUDP()
Dim PacketLen,source_port1,dest_port1,len,cksum_ip,cksum_udp As Word,
Align As Byte
cksum_ip.Byte1 = ReadFromEthMem(AddrPacket+24)
cksum_ip.Byte0 = EDATA_reg
cksum_udp.Byte1 = ReadFromEthMem(AddrPacket+40)
cksum_udp.Byte0 = EDATA_reg
len.Byte1 = ReadFromEthMem(AddrPacket+16)
len.Byte0 = EDATA_reg
CopyEthMemToEthMem(AddrPacket,TXSTART,len+14,0)
WriteToEthMem(TXSTART+24,$00)
EDATA_reg = $00
If cksum_ip <> Eth_Cksum(TXSTART+14,20) Then Exit End If
If len <= 28 Then Exit End If
Align = len And $01
WriteToEthMem(TXSTART+40,$00)
EDATA_reg = $00
WriteToEthMem(TXSTART+len+14,$00)
EDATA_reg = $00
CopyEthMemToEthMem(TXSTART+26,TXSTART+len+Align+14,8,1)
WriteToEthMem(TXSTART+len+Align+14+8,$00)
EDATA_reg = $11
len = len - 20
EDATA_reg = (len).Byte1
EDATA_reg = (len).Byte0
If cksum_udp <> Eth_Cksum(TXSTART+34,len + Align + 12) Then Exit End If
len = len - 8
source_port1.Byte1 = ReadFromEthMem(AddrPacket+36)
source_port1.Byte0 = EDATA_reg
dest_port1.Byte1 = ReadFromEthMem(AddrPacket+34)
dest_port1.Byte0 = EDATA_reg
CopyEthMemToRam(AddrPacket + 26,AddressOf(dest_ip_addr1),4)
WriteToEthMem(TXSTART+41,$00) // put tx pointer
Align = ReadFromEthMem(AddrPacket + 41) // put rx pointer to start of UDP data.
PacketLen = Eth_UserUDP(dest_ip_addr1, dest_port1, source_port1, len)
If PacketLen = 0 Then Exit End If
Eth_MacSwap
Eth_IpSwap
Eth_SendUDP(dest_port1, source_port1, PacketLen)
End Sub
Sub Eth_SendTCP(source_portT, dest_portT, PacketLenT As Word, ByRef SEQ_NoT,ACK_NoT As LongWord, TCP_FlagT As Byte)
Dim TotalLen,cksum_ip,cksum_tcp As Word,
Align As Byte
WriteToEthMem(TXSTART+12,$08)
EDATA_reg = $00
EDATA_reg = $45 Nop
EDATA_reg = $00
TotalLen =40 + PacketLenT
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
EDATA_reg = (tcp_counter).Byte1
EDATA_reg = (tcp_counter).Byte0
EDATA_reg = $40 Nop
EDATA_reg = $00
EDATA_reg = $80
EDATA_reg = $06 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
cksum_ip = Eth_Cksum(TXSTART+14,20)
WriteToEthMem(TXSTART+24,(cksum_ip).Byte1)
EDATA_reg = (cksum_ip).Byte0
WriteToEthMem(TXSTART+34,(source_portT).Byte1)
EDATA_reg = (source_portT).Byte0
EDATA_reg = (dest_portT).Byte1
EDATA_reg = (dest_portT).Byte0
CopyRamToEthMem_Inv(AddressOf(SEQ_NoT),TXSTART+38,4)
CopyRamToEthMem_Inv(AddressOf(ACK_NoT),TXSTART+42,4)
If TCP_FlagT = $12 Then WriteToEthMem(TXSTART+46,$70)
Else WriteToEthMem(TXSTART+46,$50) End If
WriteToEthMem(TXSTART+47,TCP_FlagT)
EDATA_reg = (Window).Byte1
EDATA_reg = (Window).Byte0
WriteToEthMem(TXSTART+50,$00)
EDATA_reg = $00
WriteToEthMem(TXSTART+14+TotalLen,$00)
EDATA_reg = $00
Align = TotalLen And $01
CopyEthMemToEthMem(TXSTART+26,TXSTART+14+TotalLen+Align,8,1)
WriteToEthMem(TXSTART+22+TotalLen+Align,$00)
EDATA_reg = $06 Nop
TotalLen =TotalLen - 20
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
cksum_tcp = Eth_Cksum(TXSTART+34,12+TotalLen+Align)
WriteToEthMem(TXSTART+50,(cksum_tcp).Byte1)
EDATA_reg = (cksum_tcp).Byte0
Eth_Send(34+TotalLen)
End Sub
Sub Eth_ProcessTCP()
Dim PacketLen,PacketLenUser,source_port2,dest_port2,len,cksum_ip,cksum_tcp As Word,
Align As Byte
cksum_ip.Byte1 = ReadFromEthMem(AddrPacket+24)
cksum_ip.Byte0 = EDATA_reg
cksum_tcp.Byte1 = ReadFromEthMem(AddrPacket+50)
cksum_tcp.Byte0 = EDATA_reg
len.Byte1 = ReadFromEthMem(AddrPacket+16)
len.Byte0 = EDATA_reg
PacketLen = len - 40
CopyEthMemToEthMem(AddrPacket,TXSTART,len+14,0)
WriteToEthMem(TXSTART+24,$00)
EDATA_reg = $00
If cksum_ip <> Eth_Cksum(TXSTART+14,20) Then Exit End If
Align = len And $01
WriteToEthMem(TXSTART+50,$00)
EDATA_reg = $00
WriteToEthMem(TXSTART+len+14,$00)
EDATA_reg = $00
CopyEthMemToEthMem(TXSTART+26,TXSTART+len+Align+14,8,1)
WriteToEthMem(TXSTART+len+Align+22,$00)
EDATA_reg = $06
len = len - 20
EDATA_reg = (len).Byte1
EDATA_reg = (len).Byte0
If cksum_tcp <> Eth_Cksum(TXSTART+34,len + Align + 12) Then Exit End If
source_port2.Byte1 = ReadFromEthMem(AddrPacket+36)
source_port2.Byte0 = EDATA_reg
dest_port2.Byte1 = ReadFromEthMem(AddrPacket+34)
dest_port2.Byte0 = EDATA_reg
tcp_counter.Byte1 = ReadFromEthMem(AddrPacket+18)
tcp_counter.Byte0 = EDATA_reg
TCP_FlagR = ReadFromEthMem(AddrPacket + 47)
CopyEthMemToRam_Inv(AddrPacket + 38,AddressOf(SEQ_NoR),4)
CopyEthMemToRam_Inv(AddrPacket + 42,AddressOf(ACK_NoR),4)
Window.Byte1 = ReadFromEthMem(AddrPacket+48)
Window.Byte0 = EDATA_reg
If TCP_FlagR.Bits(SYN) = 1 Then
ACK_No = SEQ_NoR + 1
TCP_Flag = $12
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 8, SEQ_No, ACK_No, TCP_Flag)
Exit
End If
If TCP_FlagR.Bits(FIN) = 1 Then
SEQ_No = ACK_NoR
ACK_No = SEQ_NoR + 1
TCP_Flag = $10
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 0, SEQ_No, ACK_No, TCP_Flag)
Exit
End If
If TCP_FlagR.Bits(PSH) = 1 Then
SEQ_No = ACK_NoR
ACK_No = SEQ_NoR + PacketLen
TCP_Flag = $10
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 0, SEQ_No, ACK_No, TCP_Flag)
CopyEthMemToRam(AddrPacket + 26,AddressOf(dest_ip_addr2),4)
WriteToEthMem(TXSTART+53,$00) // put tx pointer
Align = ReadFromEthMem(AddrPacket + 53) // put rx pointer to start of TCP data.
PacketLenUser = Eth_UserTCP(dest_ip_addr2, source_port2, dest_port2, PacketLen)
TCP_Flag = $10
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, PacketLenUser, SEQ_No, ACK_No, TCP_Flag)
SEQ_No = SEQ_No + PacketLenUser
TCP_Flag = $11
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 0, SEQ_No, ACK_No, TCP_Flag)
Exit
End If
End Sub
Public Sub Eth_DoPacket()
ClrWDT
If EIR.6 = 1 Then
Select Eth_ReadPacket
Case ETH_ARP
If EthMemCompareWithRam(AddrPacket+38,AddressOf(eth_ip_addr),4) = True Then
Select ReadFromEthMem(AddrPacket+21)
Case ETH_ARP_REQ Eth_ARPResponse
Case ETH_ARP_RES Nop
End Select
End If
Case ETH_IP
If EthMemCompareWithRam(AddrPacket+30,AddressOf(eth_ip_addr),4) = true Then
Select ReadFromEthMem(AddrPacket+23)
Case ETH_IP_ICMP
Select ReadFromEthMem(AddrPacket+34)
Case ETH_IP_ICMP_ECHO If FICMP = false Then Eth_PingResponse End If
Case ETH_IP_ICMP_REPLY Nop
End Select
Case ETH_IP_UDP If FUDP = false Then Eth_ProcessUDP End If
Case ETH_IP_TCP If FTCP = false Then Eth_ProcessTCP End If
End Select
End If
End Select
End If
End Sub
=]
=code [=
{
****************************************************************
* Name : lib1_18F97J60_V3_3.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : *
* : *
****************************************************************
}
Module lib1_18F97J60_V3_3
Include "system"
Public Const
RXSTART As Word = $0000,
RXEND As Word = $18FF,
TXSTART As Word = $1901
Public Dim
eth_ip_addr(4), dest_ip_addr(4),TCP_Flag,TCP_FlagR As Byte,
eth_mac(6), dest_mac(6), dest_ip_addr1(4), dest_ip_addr2(4) As Byte,
eth_port,dest_port, udp_counter, AddrPacket, NextPacket As Word,
SEQ_No, ACK_No, SEQ_NoR, ACK_NoR As LongWord,
Window,tcp_counter As Word,
FICMP,FTCP,FUDP As Boolean,
Uptime As Word
Public Dim EDATA_reg As Byte Absolute $0F61
Public Function Check_FIFO(address_s As Word) As Word
If address_s > RXEND Then result = address_s - (RXEND + RXSTART + 1)
Else result = address_s End If
End Function
Public Sub CopyEthMemToRam(start_eth_address, dest_ram_address, length_w As Word)
Dim i As Word
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
FSR2 = dest_ram_address
i = 0
While i < length_w
POSTINC2 = EDATA_reg
Inc(i)
Wend
End Sub
Public Sub CopyRamToEthMem(start_ram_address, dest_eth_address, length_w As Word)
Dim i As Word
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
FSR2 = start_ram_address
i = 0
While i < length_w
EDATA_reg = POSTINC2
Inc(i)
Wend
End Sub
Public Sub CopyEthMemToRam_Inv(start_eth_address, dest_ram_address, length_w As Word)
Dim i As Word
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
FSR2 = dest_ram_address + length_w - 1
i = 0
While i < length_w
POSTDEC2 = EDATA_reg
Inc(i)
Wend
End Sub
Public Sub CopyRamToEthMem_Inv(start_ram_address, dest_eth_address, length_w As Word)
Dim i As Word
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
FSR2 = start_ram_address + length_w - 1
i = 0
While i < length_w
EDATA_reg = POSTDEC2
Inc(i)
Wend
End Sub
Public Sub CopyFlashToEthMem(start_Flash_address As LongWord, dest_eth_address, length_w As Word)
Dim i As Word
i = 0
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
TBLPTRL = start_Flash_address.Byte0
TBLPTRH = start_Flash_address.Byte1
TBLPTRU = start_Flash_address.Byte2
While i < length_w
ASM
TBLRD*+
End ASM
EDATA_reg = TABLAT
Inc(i)
Wend
End Sub
Public Function CopyRamToEthMem_CP(ByRef s As String) As Word
result = 0
FSR2 = AddressOf(s)
While INDF2 <> 0
EDATA_reg = POSTINC2
Inc(result)
Wend
End Function
Public Function CopyFlashToEthMem_CP(start_Flash_address As LongWord) As Word
result = 0
TBLPTRL = start_Flash_address.Byte0
TBLPTRH = start_Flash_address.Byte1
TBLPTRU = start_Flash_address.Byte2
ASM
TBLRD*+
End ASM
While TABLAT <> 0
EDATA_reg = TABLAT
Inc(result)
ASM
TBLRD*+
End ASM
Wend
End Function
Public Sub CopyEthMemToEthMem(start_eth_address, dest_eth_address, length_w As Word, where As Byte)
Dim i As Word
If where = 0 Then
i = Check_FIFO(start_eth_address)
EDMASTL = i.Byte0
EDMASTH = i.Byte1
i = Check_FIFO(start_eth_address + length_w - 1)
EDMANDL = i.Byte0
EDMANDH = i.Byte1
Else
i = start_eth_address
EDMASTL = i.Byte0
EDMASTH = i.Byte1
i = start_eth_address + length_w - 1
EDMANDL = i.Byte0
EDMANDH = i.Byte1
End If
EDMADSTL = dest_eth_address.Byte0
EDMADSTH = dest_eth_address.Byte1
ECON1.4 = 0
ECON1.5 = 1
While ECON1.5 <> 0 Nop Wend
End Sub
Public Sub WriteToEthMem(dest_eth_address As Word, value As Byte)
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
EDATA_reg = value
End Sub
Public Function ReadFromEthMem(start_eth_address As Word) As Byte
Dim i As Word
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
result = EDATA_reg
End Function
Public Sub Eth_PutByte(value As Byte)
EDATA_reg = value
End Sub
Public Function Eth_GetByte() As Byte
result = EDATA_reg
End Function
Public Function EthMemCompareWithRam(start_eth_address, start_ram_address, length_w As Word) As Boolean
Dim i As Word
result = false
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
FSR2 = start_ram_address
i = 0
While i < length_w
If POSTINC2 <> EDATA_reg Then Exit End If
Inc(i)
Wend
result = true
End Function
Public Function EthMemCompareWithFlash(start_eth_address As Word, start_Flash_address As LongInt, length_w As Word) As Boolean
Dim i As Word
result = false
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
TBLPTRL = start_Flash_address.Byte0
TBLPTRH = start_Flash_address.Byte1
TBLPTRU = start_Flash_address.Byte2
i = 0
While i < length_w
ASM
TBLRD*+
End ASM
If EDATA_reg <> TABLAT Then Exit End If
Inc(i)
Wend
result = true
End Function
Public Function Eth_Cksum(start_eth_address, length_w As Word) As Word
Dim i As Word
EDMASTL = start_eth_address.Byte0
EDMASTH = start_eth_address.Byte1
i = start_eth_address + length_w - 1
EDMANDL = i.Byte0
EDMANDH = i.Byte1
ECON1.4 = 1
ECON1.5 = 1
While ECON1.5 <> 0 Nop Wend
result.Byte0 = EDMACSL
result.Byte1 = EDMACSH
End Function
Public Sub Put_UDPPointer()
WriteToEthMem(TXSTART+41,$00)
End Sub
Public Function MemCmp(addr1, addr2, len As Word) As Integer
Dim i, S_FSR1, S_FSR2 As Word
S_FSR1 = FSR1
S_FSR2 = FSR2
FSR1 = addr1
FSR2 =addr2
i = 0
While i < len
result = POSTINC1 - POSTINC2
If result <> 0 Then Break End If
Inc(i)
Wend
FSR1 = S_FSR1
FSR2 = S_FSR2
End Function
=]
=code [=
{
****************************************************************
* Name : lib_user.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : User library *
* : *
****************************************************************}
Module lib_user
Include "lib1_18F97J60_V3_3"
Include "index_page"
Include "Convert.bas"
Dim UpH,UpM As Word
Public Function Eth_UserTCP(ByRef dest_ip_addr_T() As Byte, ByRef source_port_T, dest_port_T, len_T As Word) As Word
Dim len_tcp_resp As Word, ' my reply len_tcp_response
i As Word,
getRequest As String(16),
txt15 As String(16),
mask As Byte
len_tcp_resp = 0
result = 0
If (source_port_T <> 80) Then
result = 0
Exit
End If
If (len_T = 0) Then
result = 0
Exit
End If
i = 0
While i < 15 ' get 15 first bytes only of the request
getRequest(i) = Eth_GetByte
Inc(i)
Wend
getRequest(i) = 0
i = 0
txt15 = httpMethod
While i < 5 ' only GET method is supported here
If txt15(i) <> getRequest(i) Then
result = 0
Exit
End If
Inc(i)
Wend
txt15 = "java1"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeScript) ' with Script MIME type
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@java1)
result = len_tcp_resp
Exit
End If
txt15 = "fonts"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeCSS) ' with HTML MIME type
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@fonts)
result = len_tcp_resp
Exit
End If
txt15 = "value"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeScript) ' with text MIME type
txt15 = "var PORTE = "
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(PORTE)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = " ;"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
UpH = Uptime / 100
UpM = Uptime - (UpH * 100)
txt15 = "var uph = "
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(UpH)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = " ;"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = "var upm = "
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(UpM)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = " ;"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
result = len_tcp_resp
Exit
End If
If getRequest(5) = "t" Then
Mask = 0
If ((getRequest(6) >= "0") And (getRequest(6) <= "7")) Then
Mask = Byte(getRequest(6)) - 48 ' convert ASCII to byte
Mask = 1 << Mask ' create bit mask
PORTE = PORTE Xor Mask ' toggle PORTD with xor operator
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeScript) ' with text MIME type
txt15 = "var PORTE ="
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(PORTE)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = "; setTimeout("+#34
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = "timer()"+#34+",100);"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
result = len_tcp_resp
Exit
End If
End If
txt15 = "reset"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
ASM
reset
End ASM
End If
If len_tcp_resp = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeHTML) ' with HTML MIME type
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@page1) ' HTML page first part
result = len_tcp_resp
Exit
End If
End Function
Public Function Eth_UserUDP(ByRef dest_ip_addr_U() As Byte, ByRef dest_port_U, source_port_U, len_U As Word) As Word
//Dim i As Word
result = 0
If source_port_U <> eth_port Then Exit End If
CopyEthMemToEthMem(AddrPacket+42, TXSTART+42, len_U, 0)
{ i = 0
While i < len_U
Eth_PutByte(Eth_GetByte) // echo (max. 1472 bytes)
Inc(i)
Wend }
result = len_U
End Function
=]
=code [=
{
****************************************************************
* Name : index_page.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : User library *
* : *
****************************************************************}
Module index_page
Public Const httpHeader = "HTTP/1.1 200 OK" + #10 + "Content-type: " ' HTTP header
Public Const httpMimeTypeHTML = "text/html" + #10 + #10 ' HTML MIME type
Public Const httpMimeTypeScript = "text/plain" + #10 + #10 ' TEXT MIME type
Public Const httpMimeTypeCSS = "text/css" + #10 + #10 ' CSS MIME type
Public Const httpMethod = "GET /"
Public Const page1 =
"<html><head>"+
"<title>LV18FJ Web Example</title>"+
"<link rel="+#34+"stylesheet"+#34+" type="+#34+
"text/css"+#34+" media="+#34+"screen"+#34+" href="+#34+
"fonts.css"+#34+" /></head><body>"+
"<dif id="+#34+"w"+#34+"><div id="+#34+"c"+#34+
"><div id="+#34+"t"+#34+">Mini Web Server Example</div>"+
"<form name="+#34+"f"+#34+"><h2>Commands</h2>"+
"<fieldset>"+
"<legend>Digital IN/OUT</legend>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Inputs : PORTE(0-3)</div>"+
"In 1:<span id="+#34+"t0"+#34+"></span> "+
"In 2:<span id="+#34+"t1"+#34+"></span> "+
"In 3:<span id="+#34+"t2"+#34+"></span> "+
"In 4:<span id="+#34+"t3"+#34+"></span>"+
"</div>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Outputs : PORTE(4-7)</div>"+
"Out 5:<input type=checkbox name=t4 onClick="+#34+"javascript:b(4);"+#34+"> "+
"Out 6:<input type=checkbox name=t5 onClick="+#34+"javascript:b(5);"+#34+"> "+
"Out 7:<input type=checkbox name=t6 onClick="+#34+"javascript:b(6);"+#34+"> "+
"Out 8:<input type=checkbox name=t7 onClick="+#34+"javascript:b(7);"+#34+"> "+
"</div></fieldset><br>"+
"<h2>Information</h2>"+
"<fieldset>"+
"<legend>CONTROLERS</legend>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">PIC18F67J60</div>Home made Ip-Watcher board</div>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">OS Version:</div>V 3.3</div>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Uptime:</div><span id="+#34+"uph"+#34+"></span> h <span id="+#34+
"upm"+#34+"></span> m"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Author Program :</div>Florin Andrei Medrea - YO2LIO -</div>"+
"</fieldset></form></div></div>"+
"<script type="+#34+"text/javascript"+#34+" src="+#34+"value.js"+#34+"></script>"+
"<script type="+#34+"text/javascript"+#34+" src="+#34+"java1.js"+#34+"></script>"+
"</body></html>"
Public Const java1 =
"function timer() {"+
"var jsel = document.createElement("+#34+"SCRIPT"+#34+");"+
"jsel.type = "+#34+"text/javascript"+#34+
";jsel.src = "+#34+"value.js"+#34+
";document.body.appendChild (jsel);"+
"div = document.getElementById("+#34+"uph"+#34+");"+
"div.innerHTML = uph;"+
"div = document.getElementById("+#34+"upm"+#34+");"+
"div.innerHTML = upm;"+
"var PORT = PORTE;"+
"var bit = "+#34+"OFF"+#34+
";for(i=0;i<4;i++){"+
"if(PORT&(1<<i)) {bit = "+#34+"ON"+#34+";}"+
"else {bit = "+#34+"OFF"+#34+";}"+
"div = document.getElementById("+#34+"t"+#34+"+i);"+
"div.innerHTML = bit;};"+
"PORT = PORTE;"+
"bit = false; "+
"for(i=4;i<8;i++){"+
"if(PORT&(1<<i)) {bit = true;}"+
"else {bit = false;}"+
"box = eval("+#34+"document.f.t"+#34+" + i); "+
"box.checked = bit;}; }"+
"function b(bit) {"+
"var jsel = document.createElement("+#34+"SCRIPT"+#34+");"+
"jsel.type = "+#34+"text/javascript"+#34+
";jsel.src = "+#34+"t"+#34+"+bit;"+
"document.body.appendChild (jsel);"+
"var bit = false; "+
"for(i=4;i<8;i++){"+
"if(PORTE&(1<<i)) {bit = true;}"+
"else {bit = false;}"+
"box = eval("+#34+"document.f.t"+#34+" + i); "+
"box.checked = bit;};}"+
"timer();"+
"setInterval("+#34+"timer()"+#34+",5000);"
Public Const fonts =
"* {font-family:Tahoma, Arial, Helvetica, sans-serif;"+
"font-size:1em;} body {text-align:center;"+
"background:#111;margin:0;font-size:0.8em;}"+
"#w {position:relative;text-align:left;}"+
"#c {padding: 5px;background:#FFF;width:700px;"+
"margin:0 auto;text-align:left;}"+
"#t {font-weight:bold;font-size: 2em;"+
"margin-bottom: 0.5em;}h2, h3 {"+
"margin:0 0 .906em 0;background:#099;"+
"padding:.181em .725em;color:#000;"+
"letter-spacing:.09em;}.s {position:relative;"+
"margin-bottom:.453em;line-height:1.993em;"+
"width:100%;}.s .l {float:left;width:18.931em;}"+
"fieldset {border:solid .09em #ccc;padding:.725em;"+
"margin:0;}fieldset legend {"+
"font-weight:bold;margin-left:-.362em;"+
"padding:0 .272em;background:#fff;color:#099;}"
=]
This module support ICMP, ARP, UDP, TCP protocols and have Mini Web Server example.
No TCP/IP stack and fragmentation available now.
Default Ip address is 192.168.1.253
'''Available functions'''
=code [=
Public Sub Eth_SetParameters
{Set your IP, Mac, Mask ... etc... here}
Public Sub Eth_Init
{Init MCU Ethernet}
Public Sub Eth_Reset
{Reset MCU Ethernet}
Public Sub Eth_DoPacket
{Process incoming packets}
Public Function Eth_UserTCP(byref dest_ip_addr_T(4) as byte, byref source_port_T, dest_port_T, len_T as word) as word
{This Sub Function is called by library. Put your TCP response for WEB server parameters here. See example}
Public Function Eth_UserUDP(byref dest_ip_addr_U(4) as byte, byref dest_port_U, source_port_U, len_U as word) as word
{This Sub Function is called by library. Put your UDP response here. See example. ( ECHO example )}
Public Sub Eth_PutByte(value as byte)
{Put one byte in ETH memory}
Public Function Eth_GetByte as byte
{Get one byte from ETH memory}
Public Function CopyFlashToEthMem_CP(start_Flash_address as longword) as word
{Copy Const from flash to Eth Memory and return length of Const data}
{Const data must be defined as STRING. (and must be zero terminated)}
{Ex. len = CopyFlashToEthMem_CP(AddressOf(httpHeader))}
Public Function CopyRamToEthMem_CP(s as String) as word
{Copy ram data to Eth Memory and return length of data}
{ram data must be defined as String. (and must be zero terminated)}
{Ex. len = CopyRamToEthMem_CP(data)}
Public Sub CopyEthMemToRam(start_eth_address, dest_ram_address, length_w as word)
{Ex. CopyEthMemToRam(AddrPacket+6,AddressOf(dest_mac_addr),6)}
Public Sub CopyRamToEthMem(start_ram_address, dest_eth_address, length_w as word)
{Ex. CopyRamToEthMem(AddressOf(eth_mac),TXSTART+22,6)}
Public Sub CopyFlashToEthMem(start_Flash_address as longword, dest_eth_address, length_w as word)
{Ex. CopyFlashToEthMem(AddressOf(httpHeader),TXSTART+54,30)}
Public Sub CopyEthMemToEthMem(start_eth_address, dest_eth_address, length_w as word, where as byte)
{where = 0 copy from Eth RxBuf to Eth TxBuf}
{where = 1 copy from Eth TxBuf to Eth TxBuf}
{Ex. CopyEthMemToEthMem(AddrPacket+38,TXSTART+28,4,0)}
Public Sub WriteToEthMem(dest_eth_address as word, value as byte)
{Ex. WriteToEthMem(TXSTART+12,$08)}
Public Function ReadFromEthMem(start_eth_address as word) as byte
{Ex. data = ReadFromEthMem(AddrPacket+38)}
Public Function EthMemCompareWithRam(start_eth_address, start_ram_address, length_w as word) as boolean
{Ex. bol = EthMemCompareWithRam(AddrPacket+30,AddressOf(eth_ip_addr),4)}
Public Function EthMemCompareWithFlash(start_eth_address as word, start_Flash_address as longword, length_w as word) as boolean
{Ex. bol = EthMemCompareWithFlash(AddrPacket+54, AddressOf(httpHeader), 30)}
Public Function Eth_Cksum(start_eth_address, length_w as word) as word
{Ex. cksum_ip = Eth_Cksum(TXSTART+14,20)}
Public Sub Eth_WritePHYReg(register_address as byte, data as word)
{Write to PHY registers}
Public Sub Eth_SetLedConfig(NewConfig as word)
{Set Eth Led configuration. See datasheet for more detail}
Public Function Eth_ReadPacket as word
{Read packet and return TYPE OF SERVICE}
Public Sub Eth_Send(length_w as word)
{Send packet from Tx buffer}
=]
You can download source code from : [[http://www.microelemente.ro/Swordfish/Mini_WEB_Server.zip]]
!!!Example Code
=code [=
{
****************************************************************
* Name : MiniWebServer.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : MCU PIC18F97J60 family *
* : *
****************************************************************
}
Device = 18F67J60
Clock = 41.666667
Config FOSC = HSPLL
Config FOSC2 = ON
Config WDTPS = 1024
#option WDT = true
Include "lib_18F97J60_V3_3"
Include "lib1_18F97J60_V3_3"
Include "system"
Sub Init()
OSCTUNE = %01000000
DelayMS(100)
ClrWDT
WDTCON = 1
CMCON = $07
ADCON1 = %00001111 // All digital
ADCON2 = %10000111 // RC Clock
INTCON2 = %01111111 // PORTB Pull Up
TRISE = $0F
PORTE = $F0
End Sub
Sub Eth_SetParameters() // set your parameters here
eth_ip_addr(0) = 192
eth_ip_addr(1) = 168
eth_ip_addr(2) = 1
eth_ip_addr(3) = 253
eth_mac(0) = $00
eth_mac(1) = $04
eth_mac(2) = $A3
eth_mac(3) = $00
eth_mac(4) = $80
eth_mac(5) = $85
eth_port = 10001
dest_port = 10001
Uptime = 0
End Sub
Init
Eth_Reset
Eth_SetParameters
Eth_Init
Firewall(false,false,false)
While true
Eth_DoPacket // process incoming packets
Wend
End.
=]
!!!Module Code
=code [=
{
****************************************************************
* Name : lib_18F97J60_V3_3.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : *
* : *
****************************************************************
}
Module lib_18F97J60_V3_3
Include "lib1_18F97J60_V3_3"
Include "lib_user"
Include "system"
Const
ETH_ARP As Word = $0806,
ETH_ARP_REQ As Byte = $01,
ETH_ARP_RES As Byte = $02,
ETH_IP As Word = $0800,
ETH_IP_TCP As Byte = $06,
ETH_IP_UDP As Byte = $11,
ETH_IP_ICMP As Byte = $01,
ETH_IP_ICMP_ECHO As Byte = $08,
ETH_IP_ICMP_REPLY As Byte = $00,
URG As Byte = 5,
ACK As Byte = 4,
PSH As Byte = 3,
RST As Byte = 2,
SYN As Byte = 1,
FIN As Byte = 0,
PHLCON As Word = $0014,
PHCON1 As Word = $0000,
PHSTAT1 As Word = $0001,
PHCON2 As Word = $0010,
PHSTAT2 As Word = $0011
Sub Eth_WritePHYReg(register_address As Byte, data As Word)
MIREGADR = register_address // Address to MIREGADR
MIWRL = data.Byte0 // Lo byte to MIWRL
MIWRH = data.Byte1 // Hi byte to MIWRH
// Wait until the PHY register has been written
// BSR = 14
ASM
movlb 14
End ASM
Repeat
Until MISTAT.0 = 0
// BSR = 0
ASM
movlb 0
End ASM
End Sub
Sub Eth_SetLedConfig(NewConfig As Word)
Eth_WritePHYReg(PHLCON, NewConfig)
End Sub
Public Sub Firewall(F_ICMP, F_TCP, F_UDP As Boolean)
FICMP = F_ICMP
FTCP = F_TCP
FUDP = F_UDP
End Sub
Public Sub Eth_Init()
NextPacket = RXSTART
AddrPacket = RXSTART
LATA.0 = 0
LATA.1 = 0
TRISA.0 = 0
TRISA.1 = 0
ASM
movlb 14
End ASM
// BSR = 14
ECON2.5 = 1
While ESTAT.0 <> 1 Nop Wend
DelayMS(1)
//*** INIT **************************************//
ETXSTL = $00
ETXSTH = $19
// Start of RX buffer NOTE as ERXWRPT WILL TAKE ON SAME VALUES
ERXSTL = $00
ERXSTH = $00
// End of RX buffer
ERXNDL = $FF
ERXNDH = $18
// Pointer of RX buffer
ERXRDPTL = $00
ERXRDPTH = $00
ERXFCON = %00100000 // Receiver Filter
//*** MAC INIT *********************************//
// Enable MAC to RX
MACON1 = %00001101 // TXPAUS, RXPAUS, MARXEN
// Paded to 60 bytes and CRC and check length
MACON3 = %00110011 Nop // PADCFG0, TXCRCEN, FRMLNEN
MACON4 = %00000000
// Non Back to Back shit
MAIPGL = $12
MAIPGH = $0C
MABBIPG = $15
MAMXFLL = $EE // max_packet bytes
MAMXFLH = $05
ASM
movlb 0
End ASM
// BSR = 0
// Set up your MAC address
MAADR1 = eth_mac(5)
MAADR2 = eth_mac(4)
MAADR3 = eth_mac(3)
MAADR4 = eth_mac(2)
MAADR5 = eth_mac(1)
MAADR6 = eth_mac(0)
Eth_WritePHYReg(PHCON1, $0100) // PHCON1 full duplex
Eth_WritePHYReg(PHCON2, $0110) // PHCON2 Disable half duplex loopback in PHY
Eth_SetLedConfig($0472)
ECON1.2 = 1 // Enable packet reception
udp_counter = 1000 // start UDP counter with this value
tcp_counter = 1000
ACK_No = 0
SEQ_No = $42844A80
DelayMS(1000)
ClrWDT
Firewall(false, false, false)
End Sub
Public Sub Eth_Reset()
ASM
movlb 14
End ASM
// BSR = 14
ECON2.5 = 0
ESTAT.0 = 0
ASM
movlb 0
End ASM
// BSR = 0
TRISA = $FF
DelayMS(1)
ClrWDT
End Sub
Function Eth_ReadPacket() As Word
Dim next_address As Word
AddrPacket = NextPacket
ERDPTL =(AddrPacket).Byte0 // Set the lower write pointer
ERDPTH = (AddrPacket).Byte1 // Set the upper write pointer
NextPacket.Byte0 = EDATA_reg
NextPacket.Byte1 = EDATA_reg
next_address = NextPacket - 1
ERXRDPTL = (next_address).Byte0 // Set the lower write pointer
ERXRDPTH = (next_address).Byte1 // Set the upper write pointer
ASM
movlb 14
End ASM
// BSR = 14
ECON2.6 = 1 // Decrement the number of packets
ASM
movlb 0
End ASM
// BSR = 0
next_address = Check_FIFO(AddrPacket + 18)
ERDPTL = (next_address).Byte0 // Set the lower write pointer
ERDPTH = (next_address).Byte1 // Set the upper write pointer
Result.Byte1 = EDATA_reg
Result.Byte0 = EDATA_reg
AddrPacket = Check_FIFO(AddrPacket + 6)
End Function
Sub Eth_Send(length_w As Word)
Dim address As Word
ASM
movlb 14
End ASM
// BSR = 14
ETXSTL = $00 // Set the lower start of packet
ETXSTH = $19 // Set the upper start of packet
EWRPTL = $00 // Set the lower write pointer
EWRPTH = $19 // Set the upper write pointer
ASM
movlb 0
End ASM
// BSR = 0
EDATA_reg = $0E // Start Byte (MUST START WITH THIS)
address = (TXSTART - 1) + length_w
ETXNDL = (address).Byte0
ETXNDH = (address).Byte1
ECON1.3 = 1
While ECON1.3 <> 0 Nop Wend
End Sub
Sub Eth_MacSwap()
CopyEthMemToEthMem(AddrPacket+6,TXSTART,6,0)
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+6,6)
End Sub
Sub Eth_IpSwap()
CopyRamToEthMem(AddressOf(eth_ip_addr),TXSTART+26,4)
CopyEthMemToEthMem(AddrPacket+26,TXSTART+30,4,0)
End Sub
Sub Eth_MacSwap_User()
CopyRamToEthMem(AddressOf(dest_mac),TXSTART,6)
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+6,6)
End Sub
Sub Eth_IpSwap_User()
CopyRamToEthMem(AddressOf(eth_ip_addr),TXSTART+26,4)
CopyRamToEthMem(AddressOf(dest_ip_addr),TXSTART+30,4)
End Sub
Sub Eth_ARPResponse()
Eth_MacSwap
WriteToEthMem(TXSTART+12,$08)
EDATA_reg = $06 Nop
EDATA_reg = $00
EDATA_reg = $01
EDATA_reg = $08 Nop
EDATA_reg = $00
EDATA_reg = $06
EDATA_reg = $04 Nop
EDATA_reg = $00
EDATA_reg = $02
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+22,6)
CopyEthMemToEthMem(AddrPacket+28,TXSTART+38,4,0)
CopyEthMemToEthMem(AddrPacket+38,TXSTART+28,4,0)
CopyRamToEthMem(AddressOf(eth_mac),TXSTART+32,6)
Eth_Send(42)
End Sub
Sub Eth_PingResponse()
Dim cksum,PacketSize As Word
PacketSize.Byte1 = ReadFromEthMem(AddrPacket+16)
PacketSize.Byte0 = EDATA_reg
PacketSize = PacketSize + 14
Eth_MacSwap
CopyEthMemToEthMem(AddrPacket+12,TXSTART+12,14,0)
Eth_IpSwap
WriteToEthMem(TXSTART+34,$00)
EDATA_reg = $00 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
CopyEthMemToEthMem(AddrPacket+38,TXSTART+38,PacketSize-38,0)
cksum = Eth_Cksum(TXSTART+34,PacketSize-34)
WriteToEthMem(TXSTART+36,(cksum).Byte1)
EDATA_reg = (cksum).Byte0
Eth_Send(PacketSize)
End Sub
Sub Eth_SendUDP(dest_portA, source_portA, PacketLenA As Word)
Dim TotalLen,cksum_ip,cksum_udp As Word,
Align As Byte
WriteToEthMem(TXSTART+12,$08)
EDATA_reg = $00
EDATA_reg = $45 Nop
EDATA_reg = $00
Inc(udp_counter)
TotalLen = PacketLenA + 28
EDATA_reg = (TotalLen).Byte1 Nop
EDATA_reg = (TotalLen).Byte0 Nop
EDATA_reg = (udp_counter).Byte1 Nop
EDATA_reg = (udp_counter).Byte0 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
EDATA_reg = $80
EDATA_reg = $11 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
cksum_ip = Eth_Cksum(TXSTART+14,20)
WriteToEthMem(TXSTART+24,(cksum_ip).Byte1)
EDATA_reg = (cksum_ip).Byte0
WriteToEthMem(TXSTART+34,(source_portA).Byte1)
EDATA_reg = (source_portA).Byte0
EDATA_reg = (dest_portA).Byte1
EDATA_reg = (dest_portA).Byte0
TotalLen = PacketLenA + 8
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
EDATA_reg = $00 Nop
EDATA_reg = $00
Align = TotalLen And $01
WriteToEthMem(TXSTART+PacketLenA+42,$00)
EDATA_reg = $00
CopyEthMemToEthMem(TXSTART+26,TXSTART+PacketLenA+Align+42,8,1)
WriteToEthMem(TXSTART+PacketLenA+Align+42+8,$00)
EDATA_reg = $11
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
cksum_udp = Eth_Cksum(TXSTART+34,TotalLen + Align + 12)
If cksum_udp = 0 Then cksum_udp = $FFFF End If
WriteToEthMem(TXSTART+40,(cksum_udp).Byte1)
EDATA_reg = (cksum_udp).Byte0
TotalLen = PacketLenA + 42
Eth_Send(TotalLen)
End Sub
Sub SendUDP(dest_port_S, source_port_S, len_data As Word, ByRef data_udp() As Byte)
Dim i As Word
Eth_MacSwap_User
Eth_IpSwap_User
Put_UDPPointer
i = 0
While i < len_data
Eth_PutByte(data_udp(i))
Inc(i)
Wend
Eth_SendUDP(dest_port_S, source_port_S, i)
End Sub
Sub Eth_ProcessUDP()
Dim PacketLen,source_port1,dest_port1,len,cksum_ip,cksum_udp As Word,
Align As Byte
cksum_ip.Byte1 = ReadFromEthMem(AddrPacket+24)
cksum_ip.Byte0 = EDATA_reg
cksum_udp.Byte1 = ReadFromEthMem(AddrPacket+40)
cksum_udp.Byte0 = EDATA_reg
len.Byte1 = ReadFromEthMem(AddrPacket+16)
len.Byte0 = EDATA_reg
CopyEthMemToEthMem(AddrPacket,TXSTART,len+14,0)
WriteToEthMem(TXSTART+24,$00)
EDATA_reg = $00
If cksum_ip <> Eth_Cksum(TXSTART+14,20) Then Exit End If
If len <= 28 Then Exit End If
Align = len And $01
WriteToEthMem(TXSTART+40,$00)
EDATA_reg = $00
WriteToEthMem(TXSTART+len+14,$00)
EDATA_reg = $00
CopyEthMemToEthMem(TXSTART+26,TXSTART+len+Align+14,8,1)
WriteToEthMem(TXSTART+len+Align+14+8,$00)
EDATA_reg = $11
len = len - 20
EDATA_reg = (len).Byte1
EDATA_reg = (len).Byte0
If cksum_udp <> Eth_Cksum(TXSTART+34,len + Align + 12) Then Exit End If
len = len - 8
source_port1.Byte1 = ReadFromEthMem(AddrPacket+36)
source_port1.Byte0 = EDATA_reg
dest_port1.Byte1 = ReadFromEthMem(AddrPacket+34)
dest_port1.Byte0 = EDATA_reg
CopyEthMemToRam(AddrPacket + 26,AddressOf(dest_ip_addr1),4)
WriteToEthMem(TXSTART+41,$00) // put tx pointer
Align = ReadFromEthMem(AddrPacket + 41) // put rx pointer to start of UDP data.
PacketLen = Eth_UserUDP(dest_ip_addr1, dest_port1, source_port1, len)
If PacketLen = 0 Then Exit End If
Eth_MacSwap
Eth_IpSwap
Eth_SendUDP(dest_port1, source_port1, PacketLen)
End Sub
Sub Eth_SendTCP(source_portT, dest_portT, PacketLenT As Word, ByRef SEQ_NoT,ACK_NoT As LongWord, TCP_FlagT As Byte)
Dim TotalLen,cksum_ip,cksum_tcp As Word,
Align As Byte
WriteToEthMem(TXSTART+12,$08)
EDATA_reg = $00
EDATA_reg = $45 Nop
EDATA_reg = $00
TotalLen =40 + PacketLenT
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
EDATA_reg = (tcp_counter).Byte1
EDATA_reg = (tcp_counter).Byte0
EDATA_reg = $40 Nop
EDATA_reg = $00
EDATA_reg = $80
EDATA_reg = $06 Nop
EDATA_reg = $00 Nop
EDATA_reg = $00
cksum_ip = Eth_Cksum(TXSTART+14,20)
WriteToEthMem(TXSTART+24,(cksum_ip).Byte1)
EDATA_reg = (cksum_ip).Byte0
WriteToEthMem(TXSTART+34,(source_portT).Byte1)
EDATA_reg = (source_portT).Byte0
EDATA_reg = (dest_portT).Byte1
EDATA_reg = (dest_portT).Byte0
CopyRamToEthMem_Inv(AddressOf(SEQ_NoT),TXSTART+38,4)
CopyRamToEthMem_Inv(AddressOf(ACK_NoT),TXSTART+42,4)
If TCP_FlagT = $12 Then WriteToEthMem(TXSTART+46,$70)
Else WriteToEthMem(TXSTART+46,$50) End If
WriteToEthMem(TXSTART+47,TCP_FlagT)
EDATA_reg = (Window).Byte1
EDATA_reg = (Window).Byte0
WriteToEthMem(TXSTART+50,$00)
EDATA_reg = $00
WriteToEthMem(TXSTART+14+TotalLen,$00)
EDATA_reg = $00
Align = TotalLen And $01
CopyEthMemToEthMem(TXSTART+26,TXSTART+14+TotalLen+Align,8,1)
WriteToEthMem(TXSTART+22+TotalLen+Align,$00)
EDATA_reg = $06 Nop
TotalLen =TotalLen - 20
EDATA_reg = (TotalLen).Byte1
EDATA_reg = (TotalLen).Byte0
cksum_tcp = Eth_Cksum(TXSTART+34,12+TotalLen+Align)
WriteToEthMem(TXSTART+50,(cksum_tcp).Byte1)
EDATA_reg = (cksum_tcp).Byte0
Eth_Send(34+TotalLen)
End Sub
Sub Eth_ProcessTCP()
Dim PacketLen,PacketLenUser,source_port2,dest_port2,len,cksum_ip,cksum_tcp As Word,
Align As Byte
cksum_ip.Byte1 = ReadFromEthMem(AddrPacket+24)
cksum_ip.Byte0 = EDATA_reg
cksum_tcp.Byte1 = ReadFromEthMem(AddrPacket+50)
cksum_tcp.Byte0 = EDATA_reg
len.Byte1 = ReadFromEthMem(AddrPacket+16)
len.Byte0 = EDATA_reg
PacketLen = len - 40
CopyEthMemToEthMem(AddrPacket,TXSTART,len+14,0)
WriteToEthMem(TXSTART+24,$00)
EDATA_reg = $00
If cksum_ip <> Eth_Cksum(TXSTART+14,20) Then Exit End If
Align = len And $01
WriteToEthMem(TXSTART+50,$00)
EDATA_reg = $00
WriteToEthMem(TXSTART+len+14,$00)
EDATA_reg = $00
CopyEthMemToEthMem(TXSTART+26,TXSTART+len+Align+14,8,1)
WriteToEthMem(TXSTART+len+Align+22,$00)
EDATA_reg = $06
len = len - 20
EDATA_reg = (len).Byte1
EDATA_reg = (len).Byte0
If cksum_tcp <> Eth_Cksum(TXSTART+34,len + Align + 12) Then Exit End If
source_port2.Byte1 = ReadFromEthMem(AddrPacket+36)
source_port2.Byte0 = EDATA_reg
dest_port2.Byte1 = ReadFromEthMem(AddrPacket+34)
dest_port2.Byte0 = EDATA_reg
tcp_counter.Byte1 = ReadFromEthMem(AddrPacket+18)
tcp_counter.Byte0 = EDATA_reg
TCP_FlagR = ReadFromEthMem(AddrPacket + 47)
CopyEthMemToRam_Inv(AddrPacket + 38,AddressOf(SEQ_NoR),4)
CopyEthMemToRam_Inv(AddrPacket + 42,AddressOf(ACK_NoR),4)
Window.Byte1 = ReadFromEthMem(AddrPacket+48)
Window.Byte0 = EDATA_reg
If TCP_FlagR.Bits(SYN) = 1 Then
ACK_No = SEQ_NoR + 1
TCP_Flag = $12
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 8, SEQ_No, ACK_No, TCP_Flag)
Exit
End If
If TCP_FlagR.Bits(FIN) = 1 Then
SEQ_No = ACK_NoR
ACK_No = SEQ_NoR + 1
TCP_Flag = $10
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 0, SEQ_No, ACK_No, TCP_Flag)
Exit
End If
If TCP_FlagR.Bits(PSH) = 1 Then
SEQ_No = ACK_NoR
ACK_No = SEQ_NoR + PacketLen
TCP_Flag = $10
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 0, SEQ_No, ACK_No, TCP_Flag)
CopyEthMemToRam(AddrPacket + 26,AddressOf(dest_ip_addr2),4)
WriteToEthMem(TXSTART+53,$00) // put tx pointer
Align = ReadFromEthMem(AddrPacket + 53) // put rx pointer to start of TCP data.
PacketLenUser = Eth_UserTCP(dest_ip_addr2, source_port2, dest_port2, PacketLen)
TCP_Flag = $10
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, PacketLenUser, SEQ_No, ACK_No, TCP_Flag)
SEQ_No = SEQ_No + PacketLenUser
TCP_Flag = $11
Eth_MacSwap
Eth_IpSwap
Eth_SendTCP(source_port2, dest_port2, 0, SEQ_No, ACK_No, TCP_Flag)
Exit
End If
End Sub
Public Sub Eth_DoPacket()
ClrWDT
If EIR.6 = 1 Then
Select Eth_ReadPacket
Case ETH_ARP
If EthMemCompareWithRam(AddrPacket+38,AddressOf(eth_ip_addr),4) = True Then
Select ReadFromEthMem(AddrPacket+21)
Case ETH_ARP_REQ Eth_ARPResponse
Case ETH_ARP_RES Nop
End Select
End If
Case ETH_IP
If EthMemCompareWithRam(AddrPacket+30,AddressOf(eth_ip_addr),4) = true Then
Select ReadFromEthMem(AddrPacket+23)
Case ETH_IP_ICMP
Select ReadFromEthMem(AddrPacket+34)
Case ETH_IP_ICMP_ECHO If FICMP = false Then Eth_PingResponse End If
Case ETH_IP_ICMP_REPLY Nop
End Select
Case ETH_IP_UDP If FUDP = false Then Eth_ProcessUDP End If
Case ETH_IP_TCP If FTCP = false Then Eth_ProcessTCP End If
End Select
End If
End Select
End If
End Sub
=]
=code [=
{
****************************************************************
* Name : lib1_18F97J60_V3_3.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : *
* : *
****************************************************************
}
Module lib1_18F97J60_V3_3
Include "system"
Public Const
RXSTART As Word = $0000,
RXEND As Word = $18FF,
TXSTART As Word = $1901
Public Dim
eth_ip_addr(4), dest_ip_addr(4),TCP_Flag,TCP_FlagR As Byte,
eth_mac(6), dest_mac(6), dest_ip_addr1(4), dest_ip_addr2(4) As Byte,
eth_port,dest_port, udp_counter, AddrPacket, NextPacket As Word,
SEQ_No, ACK_No, SEQ_NoR, ACK_NoR As LongWord,
Window,tcp_counter As Word,
FICMP,FTCP,FUDP As Boolean,
Uptime As Word
Public Dim EDATA_reg As Byte Absolute $0F61
Public Function Check_FIFO(address_s As Word) As Word
If address_s > RXEND Then result = address_s - (RXEND + RXSTART + 1)
Else result = address_s End If
End Function
Public Sub CopyEthMemToRam(start_eth_address, dest_ram_address, length_w As Word)
Dim i As Word
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
FSR2 = dest_ram_address
i = 0
While i < length_w
POSTINC2 = EDATA_reg
Inc(i)
Wend
End Sub
Public Sub CopyRamToEthMem(start_ram_address, dest_eth_address, length_w As Word)
Dim i As Word
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
FSR2 = start_ram_address
i = 0
While i < length_w
EDATA_reg = POSTINC2
Inc(i)
Wend
End Sub
Public Sub CopyEthMemToRam_Inv(start_eth_address, dest_ram_address, length_w As Word)
Dim i As Word
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
FSR2 = dest_ram_address + length_w - 1
i = 0
While i < length_w
POSTDEC2 = EDATA_reg
Inc(i)
Wend
End Sub
Public Sub CopyRamToEthMem_Inv(start_ram_address, dest_eth_address, length_w As Word)
Dim i As Word
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
FSR2 = start_ram_address + length_w - 1
i = 0
While i < length_w
EDATA_reg = POSTDEC2
Inc(i)
Wend
End Sub
Public Sub CopyFlashToEthMem(start_Flash_address As LongWord, dest_eth_address, length_w As Word)
Dim i As Word
i = 0
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
TBLPTRL = start_Flash_address.Byte0
TBLPTRH = start_Flash_address.Byte1
TBLPTRU = start_Flash_address.Byte2
While i < length_w
ASM
TBLRD*+
End ASM
EDATA_reg = TABLAT
Inc(i)
Wend
End Sub
Public Function CopyRamToEthMem_CP(ByRef s As String) As Word
result = 0
FSR2 = AddressOf(s)
While INDF2 <> 0
EDATA_reg = POSTINC2
Inc(result)
Wend
End Function
Public Function CopyFlashToEthMem_CP(start_Flash_address As LongWord) As Word
result = 0
TBLPTRL = start_Flash_address.Byte0
TBLPTRH = start_Flash_address.Byte1
TBLPTRU = start_Flash_address.Byte2
ASM
TBLRD*+
End ASM
While TABLAT <> 0
EDATA_reg = TABLAT
Inc(result)
ASM
TBLRD*+
End ASM
Wend
End Function
Public Sub CopyEthMemToEthMem(start_eth_address, dest_eth_address, length_w As Word, where As Byte)
Dim i As Word
If where = 0 Then
i = Check_FIFO(start_eth_address)
EDMASTL = i.Byte0
EDMASTH = i.Byte1
i = Check_FIFO(start_eth_address + length_w - 1)
EDMANDL = i.Byte0
EDMANDH = i.Byte1
Else
i = start_eth_address
EDMASTL = i.Byte0
EDMASTH = i.Byte1
i = start_eth_address + length_w - 1
EDMANDL = i.Byte0
EDMANDH = i.Byte1
End If
EDMADSTL = dest_eth_address.Byte0
EDMADSTH = dest_eth_address.Byte1
ECON1.4 = 0
ECON1.5 = 1
While ECON1.5 <> 0 Nop Wend
End Sub
Public Sub WriteToEthMem(dest_eth_address As Word, value As Byte)
EWRPTL = dest_eth_address.Byte0
EWRPTH = dest_eth_address.Byte1
EDATA_reg = value
End Sub
Public Function ReadFromEthMem(start_eth_address As Word) As Byte
Dim i As Word
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
result = EDATA_reg
End Function
Public Sub Eth_PutByte(value As Byte)
EDATA_reg = value
End Sub
Public Function Eth_GetByte() As Byte
result = EDATA_reg
End Function
Public Function EthMemCompareWithRam(start_eth_address, start_ram_address, length_w As Word) As Boolean
Dim i As Word
result = false
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
FSR2 = start_ram_address
i = 0
While i < length_w
If POSTINC2 <> EDATA_reg Then Exit End If
Inc(i)
Wend
result = true
End Function
Public Function EthMemCompareWithFlash(start_eth_address As Word, start_Flash_address As LongInt, length_w As Word) As Boolean
Dim i As Word
result = false
i = Check_FIFO(start_eth_address)
ERDPTL = i.byte0
ERDPTH = i.byte1
TBLPTRL = start_Flash_address.Byte0
TBLPTRH = start_Flash_address.Byte1
TBLPTRU = start_Flash_address.Byte2
i = 0
While i < length_w
ASM
TBLRD*+
End ASM
If EDATA_reg <> TABLAT Then Exit End If
Inc(i)
Wend
result = true
End Function
Public Function Eth_Cksum(start_eth_address, length_w As Word) As Word
Dim i As Word
EDMASTL = start_eth_address.Byte0
EDMASTH = start_eth_address.Byte1
i = start_eth_address + length_w - 1
EDMANDL = i.Byte0
EDMANDH = i.Byte1
ECON1.4 = 1
ECON1.5 = 1
While ECON1.5 <> 0 Nop Wend
result.Byte0 = EDMACSL
result.Byte1 = EDMACSH
End Function
Public Sub Put_UDPPointer()
WriteToEthMem(TXSTART+41,$00)
End Sub
Public Function MemCmp(addr1, addr2, len As Word) As Integer
Dim i, S_FSR1, S_FSR2 As Word
S_FSR1 = FSR1
S_FSR2 = FSR2
FSR1 = addr1
FSR2 =addr2
i = 0
While i < len
result = POSTINC1 - POSTINC2
If result <> 0 Then Break End If
Inc(i)
Wend
FSR1 = S_FSR1
FSR2 = S_FSR2
End Function
=]
=code [=
{
****************************************************************
* Name : lib_user.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : User library *
* : *
****************************************************************}
Module lib_user
Include "lib1_18F97J60_V3_3"
Include "index_page"
Include "Convert.bas"
Dim UpH,UpM As Word
Public Function Eth_UserTCP(ByRef dest_ip_addr_T() As Byte, ByRef source_port_T, dest_port_T, len_T As Word) As Word
Dim len_tcp_resp As Word, ' my reply len_tcp_response
i As Word,
getRequest As String(16),
txt15 As String(16),
mask As Byte
len_tcp_resp = 0
result = 0
If (source_port_T <> 80) Then
result = 0
Exit
End If
If (len_T = 0) Then
result = 0
Exit
End If
i = 0
While i < 15 ' get 15 first bytes only of the request
getRequest(i) = Eth_GetByte
Inc(i)
Wend
getRequest(i) = 0
i = 0
txt15 = httpMethod
While i < 5 ' only GET method is supported here
If txt15(i) <> getRequest(i) Then
result = 0
Exit
End If
Inc(i)
Wend
txt15 = "java1"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeScript) ' with Script MIME type
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@java1)
result = len_tcp_resp
Exit
End If
txt15 = "fonts"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeCSS) ' with HTML MIME type
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@fonts)
result = len_tcp_resp
Exit
End If
txt15 = "value"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeScript) ' with text MIME type
txt15 = "var PORTE = "
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(PORTE)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = " ;"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
UpH = Uptime / 100
UpM = Uptime - (UpH * 100)
txt15 = "var uph = "
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(UpH)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = " ;"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = "var upm = "
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(UpM)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = " ;"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
result = len_tcp_resp
Exit
End If
If getRequest(5) = "t" Then
Mask = 0
If ((getRequest(6) >= "0") And (getRequest(6) <= "7")) Then
Mask = Byte(getRequest(6)) - 48 ' convert ASCII to byte
Mask = 1 << Mask ' create bit mask
PORTE = PORTE Xor Mask ' toggle PORTD with xor operator
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeScript) ' with text MIME type
txt15 = "var PORTE ="
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = DecToStr(PORTE)
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = "; setTimeout("+#34
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
txt15 = "timer()"+#34+",100);"
len_tcp_resp = len_tcp_resp + CopyRamToEthMem_CP(txt15)
result = len_tcp_resp
Exit
End If
End If
txt15 = "reset"
If MemCmp(@getRequest(5), @txt15, 5) = 0 Then
ASM
reset
End ASM
End If
If len_tcp_resp = 0 Then
len_tcp_resp = CopyFlashToEthMem_CP(@httpHeader) ' HTTP header
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@httpMimeTypeHTML) ' with HTML MIME type
len_tcp_resp = len_tcp_resp + CopyFlashToEthMem_CP(@page1) ' HTML page first part
result = len_tcp_resp
Exit
End If
End Function
Public Function Eth_UserUDP(ByRef dest_ip_addr_U() As Byte, ByRef dest_port_U, source_port_U, len_U As Word) As Word
//Dim i As Word
result = 0
If source_port_U <> eth_port Then Exit End If
CopyEthMemToEthMem(AddrPacket+42, TXSTART+42, len_U, 0)
{ i = 0
While i < len_U
Eth_PutByte(Eth_GetByte) // echo (max. 1472 bytes)
Inc(i)
Wend }
result = len_U
End Function
=]
=code [=
{
****************************************************************
* Name : index_page.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 YO2LIO *
* : All Rights Reserved *
* Date : 10/11/2007 *
* Version : 3.3 *
* Notes : User library *
* : *
****************************************************************}
Module index_page
Public Const httpHeader = "HTTP/1.1 200 OK" + #10 + "Content-type: " ' HTTP header
Public Const httpMimeTypeHTML = "text/html" + #10 + #10 ' HTML MIME type
Public Const httpMimeTypeScript = "text/plain" + #10 + #10 ' TEXT MIME type
Public Const httpMimeTypeCSS = "text/css" + #10 + #10 ' CSS MIME type
Public Const httpMethod = "GET /"
Public Const page1 =
"<html><head>"+
"<title>LV18FJ Web Example</title>"+
"<link rel="+#34+"stylesheet"+#34+" type="+#34+
"text/css"+#34+" media="+#34+"screen"+#34+" href="+#34+
"fonts.css"+#34+" /></head><body>"+
"<dif id="+#34+"w"+#34+"><div id="+#34+"c"+#34+
"><div id="+#34+"t"+#34+">Mini Web Server Example</div>"+
"<form name="+#34+"f"+#34+"><h2>Commands</h2>"+
"<fieldset>"+
"<legend>Digital IN/OUT</legend>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Inputs : PORTE(0-3)</div>"+
"In 1:<span id="+#34+"t0"+#34+"></span> "+
"In 2:<span id="+#34+"t1"+#34+"></span> "+
"In 3:<span id="+#34+"t2"+#34+"></span> "+
"In 4:<span id="+#34+"t3"+#34+"></span>"+
"</div>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Outputs : PORTE(4-7)</div>"+
"Out 5:<input type=checkbox name=t4 onClick="+#34+"javascript:b(4);"+#34+"> "+
"Out 6:<input type=checkbox name=t5 onClick="+#34+"javascript:b(5);"+#34+"> "+
"Out 7:<input type=checkbox name=t6 onClick="+#34+"javascript:b(6);"+#34+"> "+
"Out 8:<input type=checkbox name=t7 onClick="+#34+"javascript:b(7);"+#34+"> "+
"</div></fieldset><br>"+
"<h2>Information</h2>"+
"<fieldset>"+
"<legend>CONTROLERS</legend>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">PIC18F67J60</div>Home made Ip-Watcher board</div>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">OS Version:</div>V 3.3</div>"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Uptime:</div><span id="+#34+"uph"+#34+"></span> h <span id="+#34+
"upm"+#34+"></span> m"+
"<div class="+#34+"s"+#34+"><div class="+#34+"l"+#34+
">Author Program :</div>Florin Andrei Medrea - YO2LIO -</div>"+
"</fieldset></form></div></div>"+
"<script type="+#34+"text/javascript"+#34+" src="+#34+"value.js"+#34+"></script>"+
"<script type="+#34+"text/javascript"+#34+" src="+#34+"java1.js"+#34+"></script>"+
"</body></html>"
Public Const java1 =
"function timer() {"+
"var jsel = document.createElement("+#34+"SCRIPT"+#34+");"+
"jsel.type = "+#34+"text/javascript"+#34+
";jsel.src = "+#34+"value.js"+#34+
";document.body.appendChild (jsel);"+
"div = document.getElementById("+#34+"uph"+#34+");"+
"div.innerHTML = uph;"+
"div = document.getElementById("+#34+"upm"+#34+");"+
"div.innerHTML = upm;"+
"var PORT = PORTE;"+
"var bit = "+#34+"OFF"+#34+
";for(i=0;i<4;i++){"+
"if(PORT&(1<<i)) {bit = "+#34+"ON"+#34+";}"+
"else {bit = "+#34+"OFF"+#34+";}"+
"div = document.getElementById("+#34+"t"+#34+"+i);"+
"div.innerHTML = bit;};"+
"PORT = PORTE;"+
"bit = false; "+
"for(i=4;i<8;i++){"+
"if(PORT&(1<<i)) {bit = true;}"+
"else {bit = false;}"+
"box = eval("+#34+"document.f.t"+#34+" + i); "+
"box.checked = bit;}; }"+
"function b(bit) {"+
"var jsel = document.createElement("+#34+"SCRIPT"+#34+");"+
"jsel.type = "+#34+"text/javascript"+#34+
";jsel.src = "+#34+"t"+#34+"+bit;"+
"document.body.appendChild (jsel);"+
"var bit = false; "+
"for(i=4;i<8;i++){"+
"if(PORTE&(1<<i)) {bit = true;}"+
"else {bit = false;}"+
"box = eval("+#34+"document.f.t"+#34+" + i); "+
"box.checked = bit;};}"+
"timer();"+
"setInterval("+#34+"timer()"+#34+",5000);"
Public Const fonts =
"* {font-family:Tahoma, Arial, Helvetica, sans-serif;"+
"font-size:1em;} body {text-align:center;"+
"background:#111;margin:0;font-size:0.8em;}"+
"#w {position:relative;text-align:left;}"+
"#c {padding: 5px;background:#FFF;width:700px;"+
"margin:0 auto;text-align:left;}"+
"#t {font-weight:bold;font-size: 2em;"+
"margin-bottom: 0.5em;}h2, h3 {"+
"margin:0 0 .906em 0;background:#099;"+
"padding:.181em .725em;color:#000;"+
"letter-spacing:.09em;}.s {position:relative;"+
"margin-bottom:.453em;line-height:1.993em;"+
"width:100%;}.s .l {float:left;width:18.931em;}"+
"fieldset {border:solid .09em #ccc;padding:.725em;"+
"margin:0;}fieldset legend {"+
"font-weight:bold;margin-left:-.362em;"+
"padding:0 .272em;background:#fff;color:#099;}"
=]