PIC18F97J60EthernetDriver
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
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 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)} 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 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)} 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
{ **************************************************************** * 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
{ **************************************************************** * 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 FSR2 = AddressOf(MISTAT) While INDF2.0 <> 0 Wend 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 FSR2 = AddressOf(ECON2) INDF2.5 = 1 FSR2 = AddressOf(ESTAT) While INDF2.0 <> 1 Wend DelayMS(1) //*** INIT **************************************// FSR2 = AddressOf(ETXSTL) POSTINC2 = $00 Nop INDF2 = $19 // Start of RX buffer NOTE as ERXWRPT WILL TAKE ON SAME VALUES FSR2 = AddressOf(ERXSTL) POSTINC2 = $00 Nop INDF2 = $00 // End of RX buffer FSR2 = AddressOf(ERXNDL) POSTINC2 = $FF Nop INDF2 = $18 // Pointer of RX buffer FSR2 = AddressOf(ERXRDPTL) POSTINC2 = $00 Nop INDF2 = $00 FSR2 = AddressOf(ERXFCON) INDF2 = %00100000 // Receiver Filter //*** MAC INIT *********************************// // Enable MAC to RX FSR2 = AddressOf(MACON1) INDF2 = %00001101 // TXPAUS, RXPAUS, MARXEN // Paded to 60 bytes and CRC and check length FSR2 = AddressOf(MACON3) POSTINC2 = %00110011 Nop // PADCFG0, TXCRCEN, FRMLNEN INDF2 = %00000000 // Non Back to Back shit 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 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() FSR2 = AddressOf(ECON2) INDF2.5 = 0 FSR2 = AddressOf(ESTAT) INDF2.0 = 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 FSR2 = AddressOf(ECON2) INDF2.6 = 1 // Decrement the number of packets 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 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) address = (TXSTART - 1) + length_w ETXNDL = (address).Byte0 ETXNDH = (address).Byte1 ECON1.3 = 1 While ECON1.3 <> 0 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
{ **************************************************************** * 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 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 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
{ **************************************************************** * 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 Inc(Uptime) 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
{ **************************************************************** * 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>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;}"