الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

نظام تشغيل عربى للانظمة المدمجة

رائج
مشاركة: واتساب X فيسبوك تيليجرام
#26

معذرة ثمه شئ لم أفهمه بعد

كيف كتبت العناوين(uri)

هل كانت مدمجة فى البرنامج الخاص بالميكرو

ثانيا

التعامل مع الواى فاى كيف نت تستقبل منه البيانات و تعرضها على الشاشة

يعنى أنا رأيت صورة لجوجل على الشاشة , هل هذه كانت صورة أم كان الموقع مفتوح بالفعل على الشاشة ,أريد توضيح لهذه النقطة بالذات

و إن كان الأمر أن الموقع مفتوح فكيف إستطعت أن تعرضة بهذه الصورة على هذه الشاشة بهذا التنسيق

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#27
نور (محمد نور) كتب:
معذرة ثمه شئ لم أفهمه بعد

كيف كتبت العناوين(uri)

هل كانت مدمجة فى البرنامج الخاص بالميكرو

ثانيا

التعامل مع الواى فاى كيف نت تستقبل منه البيانات و تعرضها على الشاشة

يعنى أنا رأيت صورة لجوجل على الشاشة , هل هذه كانت صورة أم كان الموقع مفتوح بالفعل على الشاشة ,أريد توضيح لهذه النقطة بالذات

و إن كان الأمر أن الموقع مفتوح فكيف إستطعت أن تعرضة بهذه الصورة على هذه الشاشة بهذا التنسيق

نعم قمت بطلب العنوان من داخل الكود

لم اقم بتصميم لوحة مفاتيح

بالنسبة للوايفاى ترسل له العنوان والبورت هو يقوم بارسال الطلب ومن ثم استقبال البيانات بالنسق الطلوب

انا اعتقد انك تقصد كيف يمكننى عرض ملف HTTP على شاشة صغيرة

فعلا هو امر صعب وكما تلاحظ ان فى الموقع الاول هنلك عدم تنسيق

لكن بالنسبة لموقع قوقل فان السيرفر له المقدرة على التحقق من الاى بى وعندما يعرف انه نظام مدمج يقوم بعمل اعادة توجية الى صفحة اخرة مخصصة للتصفح عن طريق الموبايل

هنلك اشياء اخرى كشدة الاشارة SS فان المديول له خرج انلوج يتدرج من 1 الى 2 فولت :)

-----------------------------------------------------------------------------------------

ملحوظة عن شراء المديول ياتى معه قرص يحتوى على الكود الداخلى للمديول وايضا على الدائرة الالكتروينة ودليل استخدام

مثال على ذلك

post-174126-1237922466_thumb.jpg

//////////////////////////////////////////////////////////////////////
// Ethernet MINI DRIVER
// Author: Fred Eady
// Version: 1.0
// Date: 05/06/07
// Description: ARP, PING, ECHO, TCP, UDP, DHCP
//
// THESE ARE BASIC DRIVER ROUTINES AND ARE NOT INTENDED TO BE USED IN
// A PRODUCTION ENVIRONMENT. EDTP OFFERS THESE DRIVER ROUTINES AS-IS
// AND IS NOT RESPONSIBLE FOR ANY MISUSE OR MISAPPLICATION OF THIS 
// CODE.
//////////////////////////////////////////////////////////////////////

#include <pic18.h>
#include <string.h>
#include <stdio.h>
#include "pic18f67j60_driver.h"

//******************************************************************
//*	Debugging variables
//* You can incorporate these back into their routines as locals if 
//* you wish.. I have put them here so you can see them using the
//* WATCH window of MPLAB.
//******************************************************************
char const *msgpointer;
char dhcpmsgchar;
char *packetptr;
//unsigned int tx_end,tx_cnt;
//char debugc, debuggc[400];
char incoming;
//unsigned int phstat_1,phstat_2,erxwrpt_l,erxwrpt_h,erxrdpt_l,erxrdpt_h;
//unsigned int debugi,debuggi[1];
//char econ_1,econ_2,eir_1,estat_1,eie_1;
unsigned int packet_cnt,new_rdptr,udpcnt,msecs_timer,clock_timer;
unsigned int offsetval, chksum_lo,chksum_hi,tx_end;
char lastsec,dhcpreturncode,msgtype,msglen;
unsigned long leasetime,lease_timer;
//******************************************************************
//*	Configuration Fuse Setings
//******************************************************************
// 18F67J60 FUSES
__CONFIG(1,XINSTDIS & WDTDIS & DEBUGDIS);
__CONFIG(2,HSPLL & IESODIS);

#define esc 0x1B

#define LED0	LATF1
//******************************************************************
//*	MACROS
//******************************************************************
#define rd_sram()	(EDATA)
#define wr_sram(a)	EDATA = a
//******************************************************************
//*	ETHERNET BUFFER DEFINITIONS 
//******************************************************************
#define MAXFRAME 		1518
#define TX_BUFFER_SIZE  1518
#define TXSTART			(8192 - (TX_BUFFER_SIZE + 8))
//#define TXEND			(TX_BUFFER_SIZE + 8)
#define RXSTART			0x0000
#define	RXSTOP			((TXSTART - 2) | 0x0001)
#define RXSIZE			(RXSTOP-(RXSTART+1))
//******************************************************************
//*	Flags
//******************************************************************
char flags;
#define synflag 	0x01  
#define	finflag		0x02  
#define entryflag 	0x04
#define arpflag		0x08
#define hexflag		0x10
#define bsynflag   	(flags & synflag)
#define bfinflag	(flags & finflag)
#define bentryflag	(flags & entryflag)
#define barpflag	(flags & arpflag)
#define bhexflag	(flags & hexflag)

#define clr_synflag flags &= ~synflag
#define set_synflag flags |= synflag
#define clr_finflag flags &= ~finflag
#define set_finflag flags |= finflag
#define clr_entryflag flags &= ~entryflag
#define set_entryflag flags |= entryflag
#define clr_arpflag flags &= ~arpflag
#define set_arpflag flags |= arpflag
#define clr_hexflag flags &= ~hexflag
#define set_hexflag flags |= hexflag

char dhcpflags;
#define bound 		0x01  
#define	offerrec	0x02  
#define done		0x04
#define trashit		0x08
#define newdhcppkt	0x10
#define bbound		(dhcpflags & bound)
#define bofferrec	(dhcpflags & offerrec)
#define bdone		(dhcpflags & done)
#define btrashit	(dhcpflags & trashit)
#define bnewdhcppkt	(dhcpflags & newdhcppkt)

#define clr_bound 		dhcpflags &= ~bound
#define set_bound 		dhcpflags |= bound
#define clr_offerrec 	dhcpflags &= ~offerrec
#define set_offerrec 	dhcpflags |= offerrec
#define clr_done		dhcpflags &= ~done
#define set_done 		dhcpflags |= done
#define clr_trashit		dhcpflags &= ~trashit
#define set_trashit		dhcpflags |= trashit
#define clr_newdhcppkt	dhcpflags &= ~newdhcppkt
#define set_newdhcppkt	dhcpflags |= newdhcppkt
//******************************************************************
//*	TELNET SERVER BANNER STATEMENT CONSTANT
//******************************************************************
char const telnet_banner[] = "\r\nEDTP 67J60 Driver>";
char const dhcpmacmsg[] = "\r\nMY MAC ADDRESS = 00-00-46-54-49-49";
char const dhcpipmsg[] = "\r\nNEW IP ADDRESS = ";
char const dhcpgwaymsg[] = "\r\nNEW GATEWAY IP ADDRESS = ";
char const dhcpsubnetmaskmsg[] = "\r\nNEW SUBNET MASK = ";
//******************************************************************
//*	Port Definitions
//*   This address is used by TCP and the Telnet function.
//*   This can be changed to any valid port number as long as
//*   you modify your code to recognize the new port number.
//******************************************************************
#define  MY_PORT_ADDRESS	  0x1F98  // 8088 DECIMAL
#define	 MCHP_UDP_PORT_ADDRESS	0x765F //30303 DECIMAL
//******************************************************************
//*	IP ADDRESS DEFINITION
//*   These are the default Ethernet Module IP addresses.
//*   You may change these to any valid address.
//******************************************************************
char ipaddrascii[3];
char ipaddrc[4] = { 192,168,1,150 };
char tempipaddrc[4];
char remoteipaddrc[4] = {192,168,1,100};
char svridc[4];
char gwayipaddrc[4];
char tempgwayipaddrc[4];
char subnetmaskc[4];
char tempsubnetmaskc[4];
char tempsvridc[4];
char templeasetimec[4];
char broadcastipaddrc[4] = {192,168,1,255};
//******************************************************************
//*	HARDWARE (MAC) ADDRESS DEFINITION
//*   This is the default Ethernet Module hardware address.
//*   You may change this to any valid address.
//******************************************************************
char macaddrc[6] = { 0,0,'E','D','T','P'};
char remotemacaddrc[6]; 
char svrmacaddrc[6];
//******************************************************************
//*	Function Declarations
//******************************************************************
//void read_xmit_buffer(void);
void init_EUSART(void);
unsigned char CharInQueue(void);
void putch(unsigned char c);
int recvchar(void);
int sendchar(int data);
void init_67J60(void);
void arp_reply(void);
void tcp(void);
void icmp(void);
void udp(void);
void setipaddrs(void);
void cksum(void);
void send_tcp_packet(void);
void assemble_ack(void);
void send_udp_datagram(void);
void arp_request(void);
void get_frame(void);
void application_code(void);
void dhcp_state_engine(void);
void init_DHCP(void);
void send_dhcp(char dhcpmsg_type);
char receive_dhcp(void);
void send_dhcp_bound_datagram(void);
void binary_to_ascii(unsigned int binarynumber);

//******************************************************************
//*	SRAM Definitions
//******************************************************************
char aux_data[16];			//received data area
char *addr;
char byte_read,data_H,data_L,cntr,byteout;
char high_nibble, low_nibble, high_char, low_char,resend;
unsigned int txlen,rxlen,chksum16,hdrlen,tcplen,tcpdatalen_in;
unsigned int tcpdatalen_out,ISN,portaddr,ip_packet_len;
unsigned long hdr_chksum,my_seqnum,client_seqnum,incoming_ack,expected_ack;
char tx_status[6];
char hours, mins, secs;
char secs_timer;
char chr_count,bytein;
char eeaddr;
unsigned int cntri;
unsigned int parameters[11];
#define local_ipaddr				0x00
#define	local_ipaddr3				0x00
#define	local_ipaddr2				0x01
#define	local_ipaddr1				0x02
#define	local_ipaddr0				0x03
#define host_ipaddr					0x04
#define	host_ipaddr3				0x04
#define	host_ipaddr2				0x05
#define	host_ipaddr1				0x06
#define	host_ipaddr0				0x07
#define loopsecs					0x08
unsigned long udpaddrs[2];
#define local_udpaddr				0x00
#define remote_udpaddr				0x01
//******************************************************************
//*	DHCP Definitions
//******************************************************************
#define DHCP_CLIENT_PORT					0x44//(68u)
#define DHCP_SERVER_PORT					0x43//(67u)

#define BOOT_REQUEST						0x01//(1u)
#define BOOT_REPLY						  0x02//(2u)
#define HW_TYPE						 	0x01//(1u)
#define HW_TYPE_LEN							  0x06//(6u)

#define DHCP_MESSAGE_TYPE			   	0x35//(53u)
#define DHCP_MESSAGE_TYPE_LEN		   	0x01//(1u)

#define DHCP_UNKNOWN_MESSAGE				0x00//(0u)

#define DHCP_DISCOVER_MESSAGE		   	0x01//(1u)
#define DHCP_OFFER_MESSAGE				  0x02//(2u)
#define DHCP_REQUEST_MESSAGE				0x03//(3u)
#define DHCP_DECLINE_MESSAGE				0x04//(4u)
#define DHCP_ACK_MESSAGE					0x05//(5u)
#define DHCP_NAK_MESSAGE					0x06//(6u)
#define DHCP_RELEASE_MESSAGE				0x07//(7u)

#define DHCP_SERVER_IDENTIFIER			  0x36//(54u)
#define DHCP_SERVER_IDENTIFIER_LEN		  0x04//(4u)

#define DHCP_PARAM_REQUEST_LIST		 	0x37//(55u)
#define DHCP_PARAM_REQUEST_LIST_LEN	 	0x02//(2u)
#define DHCP_PARAM_REQUEST_IP_ADDRESS	   0x32//(50u)
#define DHCP_PARAM_REQUEST_IP_ADDRESS_LEN   0x04//(4u)
#define DHCP_SUBNET_MASK					0x01//(1u)
#define DHCP_ROUTER					 	0x03//(3u)
#define DHCP_IP_LEASE_TIME				  0x33//(51u)
#define DHCP_END_OPTION				 	0xFF//(255u)

typedef enum _DHCP_STATES
{
	DHCP_ENTRY,					
	DHCP_INIT,						
	DHCP_WAIT,
	DHCP_BROADCAST,
	DHCP_DISCOVER,
	DHCP_REQUEST,
	DHCP_BIND,
	DHCP_BOUND,
	DHCP_DISABLED
}DHCP_STATE_LIST;

DHCP_STATE_LIST DHCPSTATE;

//******************************************************************
//*	Receive Ring Buffer Header Layout
//*   This is the 4-byte header that resides infront of the
//*   data packet in the receive buffer.
//******************************************************************
#define tx_control_byte	   0x0E
char  packetheader[6];
#define  nextpacket_low	0x00
#define  nextpacket_high   0x01
#define	rec_bytecnt_low	0x02
#define	rec_bytecnt_high   0x03
#define	rec_status_low 	   0x04
#define	rec_status_high	   0x05
//******************************************************************
//*	Ethernet Header Layout
//******************************************************************
char  udp_packet[100];				   
char  packet[1118];				
#define	enetpacketDest0	   0x00  //destination mac address
#define	enetpacketDest1	   0x01
#define	enetpacketDest2	   0x02
#define	enetpacketDest3	   0x03
#define	enetpacketDest4	   0x04
#define	enetpacketDest5	   0x05
#define	enetpacketSrc0	   0x06  //source mac address
#define	enetpacketSrc1	   0x07
#define	enetpacketSrc2	   0x08
#define	enetpacketSrc3	   0x09
#define	enetpacketSrc4	   0x0A
#define	enetpacketSrc5	   0x0B
#define	enetpacketType0	   0x0C  //type/length field
#define	enetpacketType1	   0x0D
#define enetpacketData	 0x0E  //IP data area begins here
//******************************************************************
//*	ARP Layout
//******************************************************************
#define	arp_hwtype		   0x0E
#define	arp_prtype		   0x10
#define	arp_hwlen		   0x12
#define	arp_prlen		   0x13
#define	arp_op			   0x14
#define	arp_shaddr		   0x16   //arp source mac address
#define	arp_sipaddr		   0x1C   //arp source ip address
#define	arp_thaddr		   0x20   //arp target mac address
#define	arp_tipaddr		   0x26   //arp target ip address
//******************************************************************
//*	IP Header Layout
//******************************************************************
#define	ip_vers_len		   0x0E	//IP version and header length 1a19
#define	ip_tos			   0x0F	//IP type of service
#define	ip_pktlen		   0x10	//packet length
#define	ip_id			   0x12	//datagram id
#define	ip_frag_offset	   0x14	//fragment offset
#define	ip_ttl			   0x16	//time to live
#define	ip_proto		   0x17	//protocol (ICMP=1, TCP=6, UDP=11)
#define	ip_hdr_cksum	   0x18	//header checksum 1a23
#define	ip_srcaddr		   0x1A	//IP address of source
#define	ip_destaddr		   0x1E	//IP addess of destination
#define	ip_data			   0x22	//IP data area
//******************************************************************
//*	TCP Header Layout
//******************************************************************
#define	TCP_srcport		   0x22	//TCP source port
#define	TCP_destport   	   0x24	//TCP destination port
#define	TCP_seqnum		 0x26	//sequence number
#define	TCP_acknum		   0x2A	//acknowledgement number
#define	TCP_hdrflags	   0x2E	//4-bit header len and flags
#define	TCP_window		   0x30	//window size
#define	TCP_cksum		   0x32	//TCP checksum
#define	TCP_urgentptr	  0x34	//urgent pointer
#define TCP_data		   0x36 //option/data
//******************************************************************
//*	TCP Flags
//*   IN flags represent incoming bits
//*   OUT flags represent outgoing bits
//******************************************************************
#define  FIN_IN			   (packet[TCP_hdrflags+1] & 0x01)
#define  SYN_IN			   (packet[TCP_hdrflags+1] & 0x02)
#define  RST_IN			   (packet[TCP_hdrflags+1] & 0x04)
#define  PSH_IN			   (packet[TCP_hdrflags+1] & 0x08)
#define  ACK_IN			   (packet[TCP_hdrflags+1] & 0x10)
#define  URG_IN			   (packet[TCP_hdrflags+1] & 0x20)
#define  FIN_OUT			  packet[TCP_hdrflags+1] |= 0x01 //0000 0001 
#define  SYN_OUT			  packet[TCP_hdrflags+1] |= 0x02 //0000 0010 
#define  RST_OUT			  packet[TCP_hdrflags+1] |= 0x04 //0000 0100 
#define  PSH_OUT			  packet[TCP_hdrflags+1] |= 0x08 //0000 1000 
#define  ACK_OUT			  packet[TCP_hdrflags+1] |= 0x10 //0001 0000 
#define  URG_OUT			  packet[TCP_hdrflags+1] |= 0x20 //0010 0000 
//******************************************************************
//*	IP Protocol Types
//******************************************************************
#define	PROT_ICMP			   0x01
#define	PROT_TCP			   0x06
#define	PROT_UDP			   0x11
//******************************************************************
//*	ICMP Header
//******************************************************************
#define	ICMP_type			   ip_data
#define	ICMP_code			   ICMP_type+1
#define	ICMP_cksum			   ICMP_code+1
#define	ICMP_id				   ICMP_cksum+2
#define	ICMP_seqnum			   ICMP_id+2
#define ICMP_data			  ICMP_seqnum+2
//******************************************************************
//*	UDP Header
//******************************************************************
#define	UDP_srcport			   ip_data
#define	UDP_destport		   UDP_srcport+2
#define	UDP_len				   UDP_destport+2
#define	UDP_cksum			   UDP_len+2
#define	UDP_data			   UDP_cksum+2
//******************************************************************
//*	DHCP Message
//******************************************************************
#define	DHCP_op					UDP_data
#define	DHCP_htype				DHCP_op+1
#define DHCP_hlen				DHCP_htype+1
#define DHCP_hops				DHCP_hlen+1
#define DHCP_xid				DHCP_hops+1
#define DHCP_secs				DHCP_xid+4
#define DHCP_flags				DHCP_secs+2
#define DHCP_ciaddr				DHCP_flags+2
#define DHCP_yiaddr				DHCP_ciaddr+4
#define DHCP_siaddr				DHCP_yiaddr+4
#define DHCP_giaddr				DHCP_siaddr+4
#define DHCP_chaddr				DHCP_giaddr+4
#define DHCP_sname				DHCP_chaddr+16
#define DHCP_file				DHCP_sname+64
#define DHCP_options			DHCP_file+128
#define DHCP_message_end		DHCP_options+312
//******************************************************************
//*	Macros
//******************************************************************
#define bitset(var, bitno) ((var) |= 1 << (bitno))
#define bitclr(var, bitno) ((var) &= ~(1 << (bitno)))
#define make8(var,offset)	((unsigned int)var >> (offset * 8)) & 0x00FF
#define	make16(varhigh,varlow)	(((unsigned int)varhigh & 0xFF)* 0x100) + ((unsigned int)varlow & 0x00FF)
#define make32(var1,var2,var3,var4) \
		((unsigned long)var1<<24)+((unsigned long)var2<<16)+ \
		((unsigned long)var3<<8)+((unsigned long)var4)		
#define make32i(var1,var2) ((unsigned long)var1<<16)+((unsigned long)var2)

#define  set_packet32(d,s) packet[d]   = (s & 0xFF000000) >> 24; \
						   packet[d+1] = (s & 0x00FF0000) >> 16; \
						   packet[d+2] = (s & 0x0000FF00) >> 8;  \
						   packet[d+3] = (s & 0x000000FF);
//******************************************************************
//*	USART Definitions
//******************************************************************
#define BAUD	57600		//desired baud rate
#define FOSC	41666667	//oscillator frequency
#define DIVIDER ((unsigned int)(FOSC/(16 * BAUD) -1))
//1,2,4,8,16,32,64,128 or 256 bytes 
#define USART_RX_BUFFER_SIZE  256	  
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
// 1,2,4,8,16,32,64,128 or 256 bytes 
#define USART_TX_BUFFER_SIZE  256	  
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )

unsigned char USART_RxBuf[USART_RX_BUFFER_SIZE],USART_TxBuf[USART_TX_BUFFER_SIZE];
unsigned char USART_TxHead,USART_TxTail,USART_RxHead,USART_RxTail;
char remainder;
//******************************************************************
//*	BINARY TO ASCII CONVERSION
//******************************************************************
void binary_to_ascii(unsigned int binarynumber)
{
	char i;

	for(i=0;i<3;++i)
		ipaddrascii = 0x30;
	if(binarynumber > 255)
	return;
	if(binarynumber >= 100)
	{
	do{
			binarynumber-=100;
			ipaddrascii[0]+= 1;
	  }while(binarynumber >= 100);
	}
	if(binarynumber >= 10)
	{
	  do{
			binarynumber-=10;
			ipaddrascii[1]+= 1;
	  }while(binarynumber >= 10);
	}
	ipaddrascii[2]+= binarynumber;
}
//******************************************************************
//*	Read the transmit buffer
//*   This routine reads the contents of the transmit buffer
//*   Uncomment debuggc array definition to use
//******************************************************************
/*
void read_xmit_buffer(void)
{
	unsigned int i;
	//banksel(ERDPTL);
	ERDPTL= LOW_BYTE(TXSTART);
	ERDPTH= HIGH_BYTE(TXSTART);
	for(i=0;i<300;++i)	
		debuggc= rd_sram();
}
*/
//******************************************************************
//*	  SEND DHCP BOUND MESSAGE VIA BROADCAST UDP
//******************************************************************
void send_dhcp_bound_datagram()
{
	char *bufferptr,temp;
	unsigned int i,j;	
	char msg[];
	tx_end = 0;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

	i = 6;
	while(i--)   		//write destination MAC address	
	{
		EDATA = 0xFF;
		//i--;
	};	

	bufferptr = macaddrc;
	i = 6;
	while(i--)   			//write source MAC address	

	{
		EDATA = *bufferptr++;
	//	bufferptr++;
	//	i--;
	};	
	EDATA =  0x08;		//write 0800 type field
	EDATA =  0x00;
	tx_end += 15;

	//BEGIN IP HEADER
	EDATA =  0x45;		//write 4500 vers/len field
	EDATA =  0x00;
	EDATA =  0x00;		//write packet length 0x0114
	EDATA =  0x00;
	EDATA =  0x00;		//write id field
	EDATA =  0x01;
	EDATA =  0x00;		//write flags/frag offset
	EDATA =  0x00;
	EDATA =  0x64;		//write time to live
	EDATA =  0x11;		//write protocol type (UDP)
	EDATA =  0x00;		//write IP hdr checksum (0x0000)
	EDATA =  0x00;
	i = 4;
	bufferptr = ipaddrc;
	while(i--)   			//write source IP address	
	{
		EDATA =  *bufferptr++;
		//i--;
	};	
	i = 4;
	bufferptr = broadcastipaddrc;
	while(i--)   			//write destination IP address	
	{
		EDATA =  *bufferptr++;
		//i--;
	};	
	tx_end += 20;
	//END IP HEADER

	//START UPD HEADER
	EDATA =  HIGH_BYTE(MY_PORT_ADDRESS);		//write UDP source port (8088 decimal)
	EDATA =  LOW_BYTE(MY_PORT_ADDRESS);
	EDATA =  HIGH_BYTE(MCHP_UDP_PORT_ADDRESS);		//write UDP destination port (30303 decimal)
	EDATA =  LOW_BYTE(MCHP_UDP_PORT_ADDRESS);
	EDATA =  0x00;		//write UDP length 
	EDATA =  0x00;
	EDATA =  0x00;		//write UDP checksum (no checksum)
	EDATA =  0x00;
	tx_end += 8;
	//END UDP HEADER

	//START UDP DATA
	//write MAC address message
	i = 36;
	tx_end += i;
	msgpointer = dhcpmacmsg;
	while(i--)   			
		{
			EDATA =  *msgpointer++;
			//i--;
		};
	//write IP address message	
	i = 19;
	tx_end += i;
	msgpointer = dhcpipmsg;
	while(i--)   		
		{
			EDATA =  *msgpointer++;
		//	i--;
		};	
	for(i=0;i<4;++i)
		{
			binary_to_ascii(ipaddrc);
			bufferptr = ipaddrascii;	
			j = sizeof(ipaddrascii);
			tx_end += j;
			if(ipaddrascii[0] == 0x30)
			{
				tx_end--;
				j--;
				bufferptr++;
			}
			if(ipaddrascii[1] == 0x30  && ipaddrascii[0] == 0x30)
			{
				tx_end--;
				j--;
				bufferptr++;
			}	
			while(j--)   		//write FTII IP address 	
			{
				EDATA =  *bufferptr++;
				//j--;
			};
			if(i<3)
			{
				EDATA =  0x2E;	//write . period
				tx_end += 1;
			}
		}	
	//write gateway address message				
	 i = 27;
	 tx_end += i;
	 msgpointer = dhcpgwaymsg;
	 while(i--)		  //write gateway address message
	 {
		  EDATA =  *msgpointer++;
		//i--;
	 };	
	 for(i=0;i<4;++i)
	 {
		binary_to_ascii(gwayipaddrc);
		bufferptr = ipaddrascii;	
		j = sizeof(ipaddrascii);
		tx_end += j;
		if(ipaddrascii[0] == 0x30)
		{
		 	tx_end--;
			j--;
			bufferptr++;
		}
		if(ipaddrascii[1] == 0x30  && ipaddrascii[0] == 0x30)
		{
			tx_end--;
			j--;
			bufferptr++;
		}	
		while(j--)   		//write FTII gateway IP address 	
		{
			EDATA =  *bufferptr++;
			//j--;
		};
		if(i<3)
		{
			EDATA =  0x2E;	//write . period
			tx_end += 1;
		}
	   }
	//write subnet mask address message				
	 i = 20;
	 tx_end += i;
	 msgpointer = dhcpsubnetmaskmsg;
	 while(i--)   		//write gateway address message
	 {
		  EDATA =  *msgpointer++;
		//i--;
	 };	
	 for(i=0;i<4;++i)
	 {
		binary_to_ascii(subnetmaskc);
		bufferptr = ipaddrascii;	
		j = sizeof(ipaddrascii);
		tx_end += j;
		if(ipaddrascii[0] == 0x30)
		{
		 	tx_end--;
			j--;
			bufferptr++;
		}
		if(ipaddrascii[1] == 0x30  && ipaddrascii[0] == 0x30)
		{
			tx_end--;
			j--;
			bufferptr++;
		}	
		while(j--)   		//write subnet mask	
		{
			EDATA =  *bufferptr++;
			//j--;
		};
		if(i<3)
		{
			EDATA =  0x2E;	//write . period
			tx_end += 1;
		}
	   }
	//read_xmit_buffer();
	//++i;

	// write ip header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x11);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 15;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	// write udp header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x27);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 35;	
	EDATA =  HIGH_BYTE(i);   

	//compute ip header checksum
	hdrlen = (0x45 & 0x0F) * 4; //hdrlen = 20 bytes
	offsetval = TXSTART+15;		//beginning of IP header
	EDMASTL = LOW_BYTE(offsetval);
	EDMASTH = HIGH_BYTE(offsetval);
	offsetval += (hdrlen-1);
	EDMANDL = LOW_BYTE(offsetval);
	EDMANDH = HIGH_BYTE(offsetval);
	ECON1 |= (ECON1_CSUMEN | ECON1_DMAST);
   // while(ECON1 & ECON1_DMAST);
   	while(DMAST);
	chksum_lo =  EDMACSL;
	chksum_hi =  EDMACSH;

	//write ip checksum values to TX buffer
	offsetval = TXSTART+25;
	EWRPTL = LOW_BYTE(offsetval);
	EWRPTH = HIGH_BYTE(offsetval);
	EDATA =  chksum_hi;
	EDATA =  chksum_lo;
	tx_end += (TXSTART-1);
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	//temp =  EIR;
	//if((temp & EIR_TXERIF) == 1)
	if(TXERIF)
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//while(1 == (ECON1 & ECON1_TXRTS));
	while(TXRTS);
}
//******************************************************************
//*	INITIALIZE DHCP STATE MACHINE
//******************************************************************
void init_DHCP(void)
{
	if(DHCPSTATE == DHCP_DISABLED)
		return;

	DHCPSTATE = DHCP_ENTRY;
	dhcpflags = 0;
}
//******************************************************************
//*	DHCP STATE MACHINE
//******************************************************************
void dhcp_state_engine(void)
{
	unsigned int i;
	switch(DHCPSTATE)
	{
		case DHCP_ENTRY:
			printf("\r\nDHCP RESET..");
			for(i=0;i<4;++i)
				tempipaddrc = 0x00;
			DHCPSTATE = DHCP_INIT;
		case DHCP_INIT:
			printf("\r\nDHCP INIT..");	
			for(i=0;i<6;++i)
				svrmacaddrc = 0xFF;
			for(i=0;i<4;++i)
				svridc = 0xFF;
			msecs_timer = 0;
			DHCPSTATE = DHCP_WAIT;
		case DHCP_WAIT:
			if(msecs_timer >= 2000)
				DHCPSTATE = DHCP_BROADCAST;
		break;
		case DHCP_BROADCAST:
			leasetime = 60;
			if(bbound)
			{
				DHCPSTATE = DHCP_REQUEST;
			}
			else
			{
				send_dhcp(DHCP_DISCOVER_MESSAGE);
				msecs_timer = 0;
				DHCPSTATE = DHCP_DISCOVER;
				printf("\r\nSENT DISCOVER MESSAGE..");
			}
		break;
		case DHCP_DISCOVER:
			if(msecs_timer >= 2000)
			{
				DHCPSTATE = DHCP_BROADCAST;
				return;
			}
			if(bnewdhcppkt)
			{
				if(receive_dhcp() == DHCP_OFFER_MESSAGE)
				{
					DHCPSTATE = DHCP_REQUEST;
					printf("\r\nRECEIVED DHCP OFFER MESSAGE..");
				}
				clr_newdhcppkt;
			}
		break;
		case DHCP_REQUEST:
			send_dhcp(DHCP_REQUEST_MESSAGE);
			msecs_timer = 0;
			DHCPSTATE = DHCP_BIND;
			printf("\r\nSENT DHCP REQUEST MESSAGE..");
		break;
		case DHCP_BIND:
			if(bnewdhcppkt)
			{
				dhcpreturncode = receive_dhcp();
				clr_newdhcppkt;
			}
			if(dhcpreturncode == DHCP_NAK_MESSAGE)
			{	
				printf("\r\nRECEIVED DHCP NAK MESSAGE..");
				init_DHCP();
				return;
			}
			else if(dhcpreturncode == DHCP_ACK_MESSAGE)
			{
				printf("\r\nRECEIVED DHCP ACK MESSAGE..");
				lease_timer = 0;
				DHCPSTATE = DHCP_BOUND;
				for(i=0;i<4;++i)
				{
					ipaddrc = tempipaddrc;
					subnetmaskc = tempsubnetmaskc;
					gwayipaddrc = tempgwayipaddrc;
				}
				set_bound;
				printf("\r\nNEW IP ADDRESS IS %d.%d.%d.%d..",ipaddrc[0],ipaddrc[1],ipaddrc[2],ipaddrc[3]);
				printf("\r\nNEW GATEWAY ADDRESS IS %d.%d.%d.%d..",gwayipaddrc[0],gwayipaddrc[1],gwayipaddrc[2],gwayipaddrc[3]);
				printf("\r\nNEW SUBNET MASK IS %d.%d.%d.%d..",subnetmaskc[0],subnetmaskc[1],subnetmaskc[2],subnetmaskc[3]);
				send_dhcp_bound_datagram();
				return;
			}
			else if(msecs_timer >= 2000)
				DHCPSTATE = DHCP_BROADCAST;
		break;
		case DHCP_BOUND:
			if(lease_timer >= leasetime)
			{
				printf("\r\nDHCP LEASE TIME EXPIRED..");
				DHCPSTATE = DHCP_INIT;
			}
		break;
	}
}

//******************************************************************
//*	SEND A DHCP MESSAGE ROUTINE
//******************************************************************
void send_dhcp(char dhcpmsgtype)
{
	char *bufferptr,temp;
	unsigned int i;	

	tx_end = 0;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

	EDATA =  0x0E;   //write control byte
	i = 6;
	while(i)   		//write destination MAC address	
	{
		EDATA = 0xFF;
		i--;
	};	

	bufferptr = macaddrc;
	i = 6;
	while(i)   			//write source MAC address	

	{
		EDATA = *bufferptr;
		bufferptr++;
		i--;
	};	
	EDATA =  0x08;		//write 0800 type field
	EDATA =  0x00;
	tx_end += 15;

	//BEGIN IP HEADER
	EDATA =  0x45;		//write 4500 vers/len field
	EDATA =  0x00;
	EDATA =  0x00;		//write packet length 0x0114
	EDATA =  0x00;
	EDATA =  0x00;		//write id field
	EDATA =  0x01;
	EDATA =  0x00;		//write flags/frag offset
	EDATA =  0x00;
	EDATA =  0x64;		//write time to live
	EDATA =  0x11;		//write protocol type (UDP)
	EDATA =  0x00;		//write IP hdr checksum (0x0000)
	EDATA =  0x00;
	i = 4;
	while(i)   			//write source IP address	
	{
		EDATA =  0x00;
		i--;
	};	
	i = 4;
	while(i)   			//write destination IP address	
	{
		EDATA = 0xFF;
		i--;
	};	
	tx_end += 20;
	//END IP HEADER

	//START UDP HEADER
	EDATA =  0x00;		//write UDP source port (68)
	EDATA =  0x44;
	EDATA =  0x00;		//write UDP destination port (67)
	EDATA =  0x43;
	EDATA =  0x00;		//write UDP length 
	EDATA =  0x00;
	EDATA =  0x00;		//write UDP checksum (no checksum)
	EDATA =  0x00;
	tx_end += 8;
	//END UDP HEADER

	/*

   0				   1				   2				   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |	 op (1)	|   htype (1)   |   hlen (1)	|   hops (1)	|
   +---------------+---------------+---------------+---------------+
   |							xid (4)							|
   +-------------------------------+-------------------------------+
   |		   secs (2)			|		   flags (2)		   |
   +-------------------------------+-------------------------------+
   |						  ciaddr  (4)						  |
   +---------------------------------------------------------------+
   |						  yiaddr  (4)						  |
   +---------------------------------------------------------------+
   |						  siaddr  (4)						  |
   +---------------------------------------------------------------+
   |						  giaddr  (4)						  |
   +---------------------------------------------------------------+
   |															   |
   |						  chaddr  (16)						 |
   |															   |
   |															   |
   +---------------------------------------------------------------+
   |															   |
   |						  sname   (64)						 |
   +---------------------------------------------------------------+
   |															   |
   |						  file	(128)						|
   +---------------------------------------------------------------+
   |															   |
   |						  options (312)						|
   +---------------------------------------------------------------+

*/

	//BEGIN DHCP MESSAGE
	EDATA =  BOOT_REQUEST;		//write DHCP boot record type (request)
	EDATA =  HW_TYPE;		//write DHCP hw address type (10Mb Ethernet)
	EDATA =  HW_TYPE_LEN;		//write DHCP hw address length (6)
	EDATA =  0x00;		//write DHCP hops (0)
	EDATA =  0x01;		//write DHCP transaction id (01020304)
	EDATA =  0x02;		
	EDATA =  0x03;		
	EDATA =  0x04;		
	EDATA =  0x00;		//write DHCP elapsed boot time (0)
	EDATA =  0x00;		
	EDATA =  0x80;		//write DHCP flags (8000)
	EDATA =  0x00;		
	i = 16;
	while(i)   			//write ciaddr,yiaddr,siaddr,giaddr	
	{
		EDATA =  0x00;
		i--;
	};	
	bufferptr = macaddrc;
	i = 6;
	while(i)   			//write source MAC address to chaddr	

	{
		EDATA = *bufferptr;
		bufferptr++;
		i--;
	};	
	i = 202;
	while(i)   			//write remaining 10 bytes of 0x00 to chaddr	
						//write 64 bytes of 0x00 to sname
						//write 128 bytes of 0x00 to file
	{
		EDATA =  0x00;
		i--;
	};	
	tx_end += 236;  
	EDATA =  0x63;		//write DHCP magic cookie (63825363)
	EDATA =  0x82;		
	EDATA =  0x53;		
	EDATA =  0x63;		
	EDATA =  DHCP_MESSAGE_TYPE;		//write DHCP message type 
	EDATA =  DHCP_MESSAGE_TYPE_LEN;	 	
	EDATA =  dhcpmsgtype;		
	tx_end += 7;
	if(dhcpmsgtype == DHCP_DISCOVER_MESSAGE)
		clr_offerrec;
	if(dhcpmsgtype !=  DHCP_DISCOVER_MESSAGE &&
					   tempipaddrc[0] != 0x00 &&
					   tempipaddrc[1] != 0x00 &&
					   tempipaddrc[2] != 0x00 &&
					   tempipaddrc[3] != 0x00 )
		{
			EDATA =  DHCP_SERVER_IDENTIFIER;	   
			EDATA =  DHCP_SERVER_IDENTIFIER_LEN;		
			bufferptr = svridc;
			i = 4;
			while(i)   			//write server ip address (server id)
			{
				EDATA = *bufferptr;
				bufferptr++;
				i--;
			};
		tx_end += 6;
		}	
	EDATA =  DHCP_PARAM_REQUEST_LIST;		//write DHCP parameter list (2 entries)
	EDATA =  DHCP_PARAM_REQUEST_LIST_LEN;		
	EDATA =  DHCP_SUBNET_MASK;		//client's subnet mask
	EDATA =  DHCP_ROUTER;		//routers on the client's subnet	
	tx_end += 4;
	if(dhcpmsgtype == DHCP_REQUEST_MESSAGE)
	{
			EDATA =  DHCP_PARAM_REQUEST_IP_ADDRESS;	   
			EDATA =  DHCP_PARAM_REQUEST_IP_ADDRESS_LEN;		
			bufferptr = tempipaddrc;
			i = 4;
			while(i)   			//write requested ip address 
			{
				EDATA = *bufferptr;
				bufferptr++;
				i--;
			};
		tx_end += 6;
	}

	EDATA = 0xFF;		//end of options	
	tx_end += 1;
	//DHCP MESSAGE END

	// write ip header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x11);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 15;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	// write udp header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x27);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 35;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	//compute ip header checksum
	hdrlen = (0x45 & 0x0F) * 4; //hdrlen = 20 bytes
	offsetval = TXSTART+15;		//beginning of IP header
	EDMASTL = LOW_BYTE(offsetval);
	EDMASTH = HIGH_BYTE(offsetval);
	offsetval += (hdrlen-1);
	EDMANDL = LOW_BYTE(offsetval);
	EDMANDH = HIGH_BYTE(offsetval);
	ECON1 |= (ECON1_CSUMEN | ECON1_DMAST);
	while(ECON1 & ECON1_DMAST);
	chksum_lo =  EDMACSL;
	chksum_hi =  EDMACSH;

	//write ip checksum values to TX buffer
	offsetval = TXSTART+25;
	EWRPTL = LOW_BYTE(offsetval);
	EWRPTH = HIGH_BYTE(offsetval);
	EDATA =  chksum_hi;
	EDATA =  chksum_lo;
	tx_end += (TXSTART-1);
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	temp =  EIR;
	if((temp & EIR_TXERIF) == 1)
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
		//temp =  ECON1);
		//}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
//	++i;
}
//******************************************************************
//*	RECEIVE DHCP MESSAGE ROUTINE
//******************************************************************
char receive_dhcp(void)
{
	unsigned int i;
	//char *packetptr,dhcpmsgchar;
	msgtype = DHCP_UNKNOWN_MESSAGE;
	clr_done;
	if(packet[DHCP_op] == BOOT_REPLY)
	{
		if(bofferrec == 0)
		{
			for(i=0;i<4;++i)
				tempipaddrc = packet[DHCP_yiaddr+i];
		}
		if(  packet[DHCP_chaddr] == macaddrc[0] &&
			   packet[DHCP_chaddr+1] == macaddrc[1] &&
			   packet[DHCP_chaddr+2] == macaddrc[2] &&
			   packet[DHCP_chaddr+3] == macaddrc[3] &&
			   packet[DHCP_chaddr+4] == macaddrc[4] &&
			   packet[DHCP_chaddr+5] == macaddrc[5])
			   {
				   packetptr = &packet[DHCP_options+4];
				   do{
					   dhcpmsgchar = *packetptr++;
					   switch(dhcpmsgchar)
					   {
						   case DHCP_MESSAGE_TYPE:
					   		msglen = *packetptr++;
					   		if(msglen == 0x01)
					   		{
						   		msgtype = *packetptr++;
						   		if(bofferrec && (msgtype == DHCP_OFFER_MESSAGE))
						   		{
							   		set_trashit;
							   	}

							 }
							 else
							 	set_trashit;
							break; 

							case DHCP_SERVER_IDENTIFIER:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
								for(i=0;i<4;++i)
								{
									tempsvridc = *packetptr++;
								}
							 }
							 else
							 	set_trashit;
							break;

							case DHCP_SUBNET_MASK:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
								for(i=0;i<4;++i)
								{
									tempsubnetmaskc = *packetptr++;
								}
							 }
							 else
							 	set_trashit;
							break;

							case DHCP_IP_LEASE_TIME:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
						   		if(bofferrec)
						   		{	
							   		for(i=0;i<4;++i)
							   			*packetptr++;
							   	}
							   	else
							   	{
									for(i=0;i<4;++i)
									{
										templeasetimec = *packetptr++;
									}
								}
								leasetime = make32(templeasetimec[0],templeasetimec[1],templeasetimec[2],templeasetimec[3]);
								if(leasetime > 1800)
									leasetime -= 1800; //renew 30 minutes before the lease expires
								//uncomment line below to test DHCP RENEW	
								//leasetime = 60;
							 }
							 else
							 	set_trashit;
							break;

							case DHCP_ROUTER:
					   		msglen = *packetptr++;
					   		if(msglen >= 0x04) 
					   		{
						   		if(bofferrec)
						   		{	
							   		for(i=0;i<4;++i)
							   			*packetptr++;
							   	}
							   	else
							   	{
									for(i=0;i<4;++i)
									{
										tempgwayipaddrc = *packetptr++;
									}
								}
							 }
							 else
							 	set_trashit;
							 msglen -= 4;
							 while(msglen--)
							 	*packetptr++;
							break;

							case DHCP_END_OPTION:
								set_done;
							break;

							default:
					   		msglen = *packetptr++;
							 while(msglen--)
							 	*packetptr++;
							break;
						}

				   }while(bdone == 0);
			   }   
		}
		if(msgtype == DHCP_OFFER_MESSAGE)
		{
			for(i=0;i<4;++i)
				{
					svridc = tempsvridc;
				}
			set_offerrec;

		}
		else
		{
			if( svridc[0] != tempsvridc[0] ||
				svridc[1] != tempsvridc[1] ||
				svridc[2] != tempsvridc[2] ||
				svridc[3] != tempsvridc[3] )
				{
					msgtype = DHCP_UNKNOWN_MESSAGE;
				}

	}
	if(btrashit)
		clr_newdhcppkt;

	return msgtype;			   
}
//******************************************************************
//*	Perform ARP Request
//*   This routine uses a known remote IP address to get a remote
//*   Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_request(void)
{
	//char temp;
	unsigned int i,tx_end;	

	clr_arpflag;
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;
   //build destination MAC address	
	for(i=0;i<6;++i)
	{
   		wr_sram(0xFF);
		++tx_end;
	}
   //build source MAC address	
 	for(i=0;i<6;++i)
	{
		  wr_sram(macaddrc);
		++tx_end;
	}

	wr_sram(0x08);		//ARP packet type
	wr_sram(0x06);		
	tx_end +=2;
	wr_sram(0x00);		//hardware type = 10Mb Ethernet
	wr_sram(0x01);		
	tx_end +=2;
	wr_sram(0x08);		//IP protocol
	wr_sram(0x00);		
	tx_end +=2;
	wr_sram(0x06); 	 	//hardware addr len (06)
	wr_sram(0x04); 	 	//hardware protocol addr len(04)
	tx_end +=2;
	wr_sram(0x00);		//ARP request
	wr_sram(0x01);		
	tx_end += 2;
   //build source MAC address	
	for(i=0;i<6;++i)
	{
   		wr_sram(macaddrc);
		++tx_end;
	}
   //build source IP address	
	for(i=0;i<4;++i)
	{
   		wr_sram(ipaddrc);
		++tx_end;
	}
   //build unknown target MAC address area	
	for(i=0;i<6;++i)
	{
   		wr_sram(0x00);
		++tx_end;
	}
   //build target IP address	
	for(i=0;i<4;++i)
	{
   		wr_sram(remoteipaddrc);
		++tx_end;
	}
   //mark end of ARP request packet	
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);
   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	//do{
		//temp =  ECON1);
	while((ECON1 & ECON1_TXRTS) == 1);

	if(EIR & EIR_TXERIF == 1)
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	//TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	//++tx_end;
	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);

	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if((temp & ESTAT_TXABRT) == 1)
	   //printf("\r\nARP Request Transmission Aborted..");
	//else
	   //printf("\r\nARP Request Sent..");
 }

//******************************************************************
//*	Perform ARP Response
//*   This routine supplies a requesting computer with the
//*   Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_reply(void)
{
	unsigned int tx_end,i;	
	char temp;

	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

   //write destination MAC address
   for(i=0;i<6;++i)
   {	
	  wr_sram(packet[enetpacketSrc0+i]);
	  ++tx_end;
	}

   //write source MAC address
   for(i=0;i<6;++i)
	{
	  wr_sram(macaddrc);
	  ++tx_end;
	}

   //write typelen hwtype prtype hwlen prlen op:
   addr = &packet[enetpacketType0];
   packet[arp_op+1] = 0x02;
   for(i=0;i<10;++i)
	{
	  wr_sram(*addr++);
	  ++tx_end;
	}
   //write ethernet module MAC address
   for(i=0;i<6;++i)
	{
	  wr_sram(macaddrc);
	  ++tx_end;
	}
   //write ethernet module IP address
	  for(i=0;i<4;++i)
	   {
		   wr_sram(ipaddrc);
		 ++tx_end;
		}

   //write remote MAC address
   for(i=0;i<6;++i)
	{
	  wr_sram(packet[enetpacketSrc0+i]);
	  ++tx_end;
	}

   //write remote IP address
   for(i=0;i<4;++i)
	{
	  wr_sram(packet[arp_sipaddr+i]);
	  ++tx_end;
	}
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	//temp =  EIR;
	//if((temp & EIR_TXERIF) == 1)
	if(TXERIF)
	{
	 TXERIF = 0;
	 TXRST = 1;
   	 TXRST = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
		//temp =  ECON1);
		//}while((temp & ECON1_TXRTS) == 1);
//	while(1 == (ECON1 & ECON1_TXRTS));
	while(TXRTS);
	++tx_end;
	//banksel(ERDPTL);
	ERDPTL= LOW_BYTE(tx_end);
	ERDPTH= HIGH_BYTE(tx_end);

	//banksel(ERDPTL);
	//ERDPTL= 0x00;
	//ERDPTH= 0x00;
	for(i=0;i<7;++i)	
		tx_status= rd_sram();
	//temp =  ESTAT;
	//if((temp & ESTAT_TXABRT) == 1)
	if(TXABRT)
	   printf("\r\nARP Reply Transmission Aborted..");
	//else
	   //printf("\r\nARP Reply Sent..");

 }
//******************************************************************
//*	Application Code
//*   Your application code goes here.
//******************************************************************
void application_code()
{
   char i,j;

   if (aux_data[0] == 0x0D)
	  {
		 j = sizeof(telnet_banner);
		 for(i=0;i<j;++i)
		  packet[TCP_data+i] = telnet_banner;
		 tcpdatalen_out = j;
	  }

   else
	  tcpdatalen_out = tcpdatalen_in;
}

//******************************************************************
//*	TCP Function
//*   This function uses TCP protocol to act as a Telnet server on
//*   port 8088 decimal.  The application function is called with
//*   every incoming character.
//******************************************************************
void tcp()
{
	char *bufferptr,temp,i,j;
	unsigned int buffer_addr,tx_end,tx_cnt;

   //assemble the destination port address from the incoming packet
   portaddr = make16(packet[TCP_destport],packet[TCP_destport+1]);

   //calculate the length of the data coming in with the packet
   //tcpdatalen_in = incoming packet length - incoming ip header length - incoming tcp header length
   tcpdatalen_in = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4) - (((packet[TCP_hdrflags] & 0xF0) >> 4) * 4);

   //If an ACK is recieved and the destination port address is valid and no data is in the packet
   if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in == 0x00)
   {
	  //assemble the acknowledgment number from the incoming packet
	  incoming_ack = make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);

	  //if the incoming packet is a result of session establishment
	  if(bsynflag)
	  {
		 //clear the SYN flag
		 //the incoming acknowledgment is my new sequence number
		 clr_synflag;

		 my_seqnum = incoming_ack;

		 //send the Telnet server banner
		 //limit the character count to 40 decimal
				j = sizeof(telnet_banner);
				for(i=0;i<j;++i)
 				  packet[TCP_data+i] = telnet_banner;
		 //length of the banner message
		 	   tcpdatalen_out = j;

		 //expect to get an acknowledgment of the banner message
		 expected_ack = my_seqnum +tcpdatalen_out;

		 //send the TCP/IP packet
		 send_tcp_packet();
	  }
   }

   //if an ack is received and the port address is valid and there is data in the incoming packet
   if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in)
   {
	  for(i=0;i<tcpdatalen_in;++i)
	  {
		 //receive the data and put it into the incoming data buffer
		 aux_data = packet[TCP_data+i];

		 //run the TCP application
		 application_code();
	  }

	  //assemble the acknowledgment number from the incoming packet
	  incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);

	  //check for the number of bytes acknowledged
	  //determine how many bytes are outstanding and adjust the outgoing sequence number accordingly
	  if(incoming_ack <= expected_ack)
		 my_seqnum = expected_ack - (expected_ack - incoming_ack);

	  //my expected acknowledgement number
	  expected_ack = my_seqnum +tcpdatalen_out;


	  send_tcp_packet();
   }

   //this code segment processes the incoming SYN from the Telnet client
   //and sends back the initial sequence number (ISN) and acknowledges
   //the incoming SYN packet
   if(SYN_IN && portaddr == MY_PORT_ADDRESS)
   {
	  tcpdatalen_in = 0x01;
	  set_synflag;

	  setipaddrs();

	  temp = packet[TCP_srcport];
	  packet[TCP_srcport] = packet[TCP_destport];
	  packet[TCP_destport] = temp;

	  temp = packet[TCP_srcport+1];
	  packet[TCP_srcport+1] = packet[TCP_destport+1];
	  packet[TCP_destport+1] = temp;

	  assemble_ack();

	  if(++ISN == 0x0000 || ++ISN == 0xFFFF)
		 ISN = 0x1234;
	  my_seqnum = make32i(ISN,0xFFFF);

	  set_packet32(TCP_seqnum,my_seqnum);

	  packet[TCP_hdrflags+1] = 0x00;
	  SYN_OUT;
	  ACK_OUT;

	  packet[TCP_cksum] = 0x00;
	  packet[TCP_cksum+1] = 0x00;

	  hdr_chksum =0;
	  hdrlen = 0x08;
	  addr = &packet[ip_srcaddr];
	  cksum();
	  hdr_chksum = hdr_chksum + packet[ip_proto];
	  tcplen = make16(packet[ip_pktlen],packet[ip_pktlen+1]) - ((packet[ip_vers_len] & 0x0F) * 4);
	  hdr_chksum = hdr_chksum + tcplen;
	  hdrlen = tcplen;
	  addr = &packet[TCP_srcport];
	  cksum();
	  chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
	  packet[TCP_cksum] = make8(chksum16,1);
	  packet[TCP_cksum+1] = make8(chksum16,0);

	  tx_end = TXSTART;
	  //load beginning page for transmit buffer
	  //banksel(EWRPTL);
	  EWRPTL = LOW_BYTE(TXSTART);
	  EWRPTH = HIGH_BYTE(TXSTART);

	 //write control byte
	  wr_sram(tx_control_byte);
	  ++tx_end;

	tx_end = tx_end + rxlen;
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

	tx_cnt = tx_end - TXSTART;

   //for(buffer_addr=0;buffer_addr<tx_cnt;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_cnt)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_cnt--;
	};	

   //send the contents of the transmit buffer onto the network
	//temp =  EIR;
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
	   TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	while(1 ==(ECON1 & ECON1_TXRTS));	
	//++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if(1 ==( ESTAT) & ESTAT_TXABRT))
	   printf("\r\nTCP Transmission Aborted..");
	//else
	   //printf("\r\nTCP Message Sent..");
   }

   //this code segment processes a FIN from the Telnet client
   //and acknowledges the FIN and any incoming data.
   if(FIN_IN && portaddr == MY_PORT_ADDRESS)
   {
	  if(tcpdatalen_in)
	  {
		 for(i=0;i<tcpdatalen_in;++i)
		 {
			aux_data = packet[TCP_data+i];
			application_code();
		 }
	  }

	  set_finflag;

	  ++tcpdatalen_in;

	  incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
	  if(incoming_ack <= expected_ack)
		 my_seqnum = expected_ack - (expected_ack - incoming_ack);

	  expected_ack = my_seqnum +tcpdatalen_out;
	  send_tcp_packet();

   }
}
//******************************************************************
//*	Assemble the Acknowledgment
//*   This function assembles the acknowledgment to send to
//*   to the client by adding the received data count to the
//*   client's incoming sequence number.
//******************************************************************
void assemble_ack()
{
   client_seqnum=make32(packet[TCP_seqnum],packet[TCP_seqnum+1],packet[TCP_seqnum+2],packet[TCP_seqnum+3]);
   client_seqnum = client_seqnum + tcpdatalen_in;
   set_packet32(TCP_acknum,client_seqnum);
}
//******************************************************************
//*	Send TCP Packet
//*   This routine assembles and sends a complete TCP/IP packet.
//*   40 bytes of IP and TCP header data is assumed.
//******************************************************************
void send_tcp_packet()
{
	char temp,i,*bufferptr;
	unsigned int buffer_addr,tx_end,tx_cnt;

   //count IP and TCP header bytes.. Total = 40 bytes
   ip_packet_len = 40 + tcpdatalen_out;
   packet[ip_pktlen] = make8(ip_packet_len,1);
   packet[ip_pktlen+1] = make8(ip_packet_len,0);
   setipaddrs();

   temp = packet[TCP_srcport];
   packet[TCP_srcport] = packet[TCP_destport];
   packet[TCP_destport] = temp;
   temp = packet[TCP_srcport+1];
   packet[TCP_srcport+1] = packet[TCP_destport+1];
   packet[TCP_destport+1] = temp;

   assemble_ack();
   set_packet32(TCP_seqnum,my_seqnum);


   packet[TCP_hdrflags+1] = 0x00;
   ACK_OUT;
   if(bfinflag)
   {
	  FIN_OUT;
	  clr_finflag;
   }

   packet[TCP_cksum] = 0x00;
   packet[TCP_cksum+1] = 0x00;

   hdr_chksum =0;
   hdrlen = 0x08;
   addr = &packet[ip_srcaddr];
   cksum();
   hdr_chksum = hdr_chksum + packet[ip_proto];
   tcplen = ip_packet_len - ((packet[ip_vers_len] & 0x0F) * 4);
   hdr_chksum = hdr_chksum + tcplen;
   hdrlen = tcplen;
   addr = &packet[TCP_srcport];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[TCP_cksum] = make8(chksum16,1);
   packet[TCP_cksum+1] = make8(chksum16,0);

   txlen = ip_packet_len + 14;
   if(txlen < 60)
	  txlen = 60;
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

	tx_end = tx_end + txlen;
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

	tx_cnt = tx_end - TXSTART;

   //for(buffer_addr=0;buffer_addr<tx_cnt;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_cnt)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_cnt--;
	};	

   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while(1 == temp & ECON1_TXRTS));
	while(1 == (ECON1 & ECON1_TXRTS));
	//++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if(1 == ( ESTAT) & ESTAT_TXABRT))
	   //printf("\r\nTransmission Aborted..");
	//else
	   //printf("\r\nTCP Message Sent..");
}

//******************************************************************
//*	init_udp Function
//*   This function sends UDP packet
//******************************************************************
void send_udp_datagram()
{
	char *bufferptr,temp;
	unsigned int buffer_addr,i,tx_end,tx_cnt;	

	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write ENC28J60 control byte
	wr_sram(tx_control_byte);
	++tx_end;
   //build destination MAC address	
   	udp_packet[enetpacketDest0]=remotemacaddrc[0];
   	udp_packet[enetpacketDest1]=remotemacaddrc[1];
   	udp_packet[enetpacketDest2]=remotemacaddrc[2];
   	udp_packet[enetpacketDest3]=remotemacaddrc[3];
   	udp_packet[enetpacketDest4]=remotemacaddrc[4];
   	udp_packet[enetpacketDest5]=remotemacaddrc[5];
	tx_end += 6;
   //build source MAC address	
   	udp_packet[enetpacketSrc0]=macaddrc[0];
   	udp_packet[enetpacketSrc1]=macaddrc[1];
   	udp_packet[enetpacketSrc2]=macaddrc[2];
   	udp_packet[enetpacketSrc3]=macaddrc[3];
   	udp_packet[enetpacketSrc4]=macaddrc[4];
   	udp_packet[enetpacketSrc5]=macaddrc[5];
	tx_end += 6;
   //build packet type (IP)	
	udp_packet[enetpacketType0] = 0x08;
	udp_packet[enetpacketType1] = 0x00;
	tx_end += 2;
   //build version, length,tos,packet length
	udp_packet[ip_vers_len] = 0x45;
	udp_packet[ip_tos] = 0x00;
	udp_packet[ip_pktlen] = 0x00;
	udp_packet[ip_pktlen+1] = 0x24;
	tx_end += 4;
   //build packet ID	
	++cntri;
	udp_packet[ip_id] = make8(cntri,0);
	udp_packet[ip_id+1] = make8(cntri,1);
	tx_end += 2;
   //build fragment offset	
	udp_packet[ip_frag_offset] = 0x00;
	udp_packet[ip_frag_offset+1] = 0x00;
	tx_end += 2;
   //build time to live, UDP protocol ID	
	udp_packet[ip_ttl] = 0x80;
	udp_packet[ip_proto] = 0x11;
   //build IP source and destination addresses
	for(i=0;i<4;++i)
	{
   		udp_packet[ip_srcaddr+i]=ipaddrc;
   		udp_packet[ip_destaddr+i]=remoteipaddrc;
		tx_end += 2;
	}
   	//calculate the IP header checksum
   	udp_packet[ip_hdr_cksum]=0x00;
   	udp_packet[ip_hdr_cksum+1]=0x00;
   	hdr_chksum =0;
   	hdrlen = (udp_packet[ip_vers_len] & 0x0F) * 4;
   	addr = &udp_packet[ip_vers_len];
   	cksum();
   	chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   	udp_packet[ip_hdr_cksum] = make8(chksum16,1);
   	udp_packet[ip_hdr_cksum+1] = make8(chksum16,0);
	tx_end += 4;
   //build UDP source port address
   	udp_packet[UDP_srcport] = 0x13;
   	udp_packet[UDP_srcport+1] = 0x88;
	tx_end += 2;
   //build UDP destination port address
   	udp_packet[UDP_destport] = 0x00;
   	udp_packet[UDP_destport+1] = 0x07;
	tx_end += 2;
   //build UDP packet length
	udp_packet[UDP_len] = 0x00;
	udp_packet[UDP_len+1] = 0x10;
	tx_end += 2;
	//udp_packet[UDP_cksum] goes here
	tx_end += 2;
   //UDP data goes here
	for(i=0;i<8;++i)
	 udp_packet[UDP_data+i] = 0x30 + i;
	tx_end += 8;
	 //calculate the UDP checksum
	 udp_packet[UDP_cksum] = 0x00;
	 udp_packet[UDP_cksum+1] = 0x00;
	 hdr_chksum =0;
	 hdrlen = 0x08;
	 addr = &udp_packet[ip_srcaddr];
	 cksum();
	 hdr_chksum = hdr_chksum + udp_packet[ip_proto];
	 hdrlen = 0x02;
	 addr = &udp_packet[UDP_len];
	 cksum();
	 hdrlen = make16(udp_packet[UDP_len],udp_packet[UDP_len+1]);
	 addr = &udp_packet[UDP_srcport];
	 cksum();
	 chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
	 udp_packet[UDP_cksum] = make8(chksum16,1);
	 udp_packet[UDP_cksum+1] = make8(chksum16,0);
   //mark end of UDP datagram
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);
	tx_cnt = tx_end - TXSTART;
   //write UDP datagram to ENC28J60 Transmit Buffer
   //for(buffer_addr=0;buffer_addr<tx_cnt+1;++buffer_addr)
	  //wr_sram(udp_packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_cnt)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_cnt--;
	};	

   //send the contents of the transmit buffer onto the network
//	temp =  EIR);
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
	++tx_end;

	//banksel(ERDPTL);
	ERDPTL= LOW_BYTE(tx_end);
	ERDPTH= HIGH_BYTE(tx_end);
	for(i=0;i<7;++i)	
		tx_status= rd_sram();
	//temp =  ESTAT);
	if(1 == (ESTAT & ESTAT_TXABRT))
	   printf("\r\nUDP Datagram Transmission Aborted..");
	else
	   //printf("\r\nUDP Message Sent..");
	   ++udpcnt;
}
//******************************************************************
//*	UDP Function
//*   This function uses a Visual Basic UDP program to echo the
//*   data back to the VB program .
//******************************************************************
void udp()
{
	unsigned int buffer_addr,i,tx_end;	
	char *bufferptr,temp;

   //port 7 is the well-known echo port
   if(packet[UDP_destport] == 0x00 && packet[UDP_destport+1] ==0x07)
   {
	  //build the IP header
	  setipaddrs();

	  //swap the UDP source and destination ports
	  temp = packet[UDP_srcport];
	  packet[UDP_srcport] = packet[UDP_destport];
	  packet[UDP_destport] = temp;

	  temp = packet[UDP_srcport+1];
	  packet[UDP_srcport+1] = packet[UDP_destport+1];
	  packet[UDP_destport+1] = temp;

	  //calculate the UDP checksum
	  packet[UDP_cksum] = 0x00;
	  packet[UDP_cksum+1] = 0x00;

	  hdr_chksum =0;
	  hdrlen = 0x08;
	  addr = &packet[ip_srcaddr];
	  cksum();
	  hdr_chksum = hdr_chksum + packet[ip_proto];
	  hdrlen = 0x02;
	  addr = &packet[UDP_len];
	  cksum();
	  hdrlen = make16(packet[UDP_len],packet[UDP_len+1]);
	  addr = &packet[UDP_srcport];
	  cksum();
	  chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
	  packet[UDP_cksum] = make8(chksum16,1);
	  packet[UDP_cksum+1] = make8(chksum16,0);

	  //echo the incoming data back to the VB program
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

	tx_end = tx_end + make16(packetheader[rec_bytecnt_high],packetheader[rec_bytecnt_low] - 4);
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //for(buffer_addr=0;buffer_addr<tx_end;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_end)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_end--;
	};	

   //send the contents of the transmit buffer onto the network
	temp =  EIR;
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
	//++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if(1 == ( ESTAT) & ESTAT_TXABRT))
	   //printf("\r\nUDP Echo Transmission Aborted..");
	//else
	   //printf("\r\nUDP Message Sent..");
}
	//else
		//LATD6 = 1;

}
//******************************************************************
//*	Perform ICMP Function
//*   This routine responds to a ping.
//******************************************************************
void icmp(void)
{ 
	unsigned int buffer_addr,i,tx_end;	
	char temp,*bufferptr;
   //set echo reply
   packet[ICMP_type]=0x00;
   packet[ICMP_code]=0x00;

   //clear the ICMP checksum
   packet[ICMP_cksum]=0x00;
   packet[ICMP_cksum+1]=0x00;

   //setup the IP header
   setipaddrs();

   //calculate the ICMP checksum
   hdr_chksum =0;
   hdrlen = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4);
   addr = &packet[ICMP_type];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[ICMP_cksum] = make8(chksum16,1);
   packet[ICMP_cksum+1] = make8(chksum16,0);
  /* 
   //calculate the ICMP checksum
   hdrlen = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4);
   addr = &packet[ICMP_type];
   //banksel(EDMASTL);
   EDMASTL = LOW_BYTE((unsigned int) addr));
   EDMASTH = HIGH_BYTE((unsigned int) addr));
   //debuggc[1] =  EDMASTL);
   //debuggc [0]=  EDMASTH);
   buffer_addr = ((unsigned int) addr + hdrlen)-1;
   EDMANDL = LOW_BYTE(buffer_addr));
   EDMANDH = HIGH_BYTE(buffer_addr));
   //debuggc[3] =  EDMANDL);
   //debuggc[2] =  EDMANDH);
   ECON1 |= 0x30);
   while(ECON1 & 0x20);
   packet[ICMP_cksum] =  EDMACSH);
   packet[ICMP_cksum+1] =  EDMACSL);
  */	
   //send the ICMP packet along on its way
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

	tx_end = (tx_end) + make16(packetheader[rec_bytecnt_high],packetheader[rec_bytecnt_low] - 4);//4 is checksum of incoming packet
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

	bufferptr = packet;
	while(tx_end--)
	{
		EDATA = *bufferptr++;
		//bufferptr++;
	//	tx_end--;
	};	

   //for(buffer_addr=0;buffer_addr<tx_end;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	//if(1 == (EIR & EIR_TXERIF))
	if(TXERIF)
	{
	 TXERIF = 0;
	 TXRST = 1;
   	 TXRST = 0;
	}
	  TXRTS = 1;
//	++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if((temp & ESTAT_TXABRT) == 1)
	 //  printf("\r\nICMP Transmission Aborted..");
	//else
	 //  printf("\r\nICMP Message Sent..");
}

//******************************************************************
//*	SETIPADDRS
//*   This function builds the IP header.
//******************************************************************
void setipaddrs()
{
   //move IP source address to destination address
   packet[ip_destaddr]=packet[ip_srcaddr];
   packet[ip_destaddr+1]=packet[ip_srcaddr+1];
   packet[ip_destaddr+2]=packet[ip_srcaddr+2];
   packet[ip_destaddr+3]=packet[ip_srcaddr+3];
   //make ethernet module IP address source address
   packet[ip_srcaddr]=ipaddrc[0];
   packet[ip_srcaddr+1]=ipaddrc[1];
   packet[ip_srcaddr+2]=ipaddrc[2];
   packet[ip_srcaddr+3]=ipaddrc[3];
   //move hardware source address to destinatin address
   packet[enetpacketDest0]=packet[enetpacketSrc0];
   packet[enetpacketDest1]=packet[enetpacketSrc1];
   packet[enetpacketDest2]=packet[enetpacketSrc2];
   packet[enetpacketDest3]=packet[enetpacketSrc3];
   packet[enetpacketDest4]=packet[enetpacketSrc4];
   packet[enetpacketDest5]=packet[enetpacketSrc5];
   //make ethernet module mac address the source address
   packet[enetpacketSrc0]=macaddrc[0];
   packet[enetpacketSrc1]=macaddrc[1];
   packet[enetpacketSrc2]=macaddrc[2];
   packet[enetpacketSrc3]=macaddrc[3];
   packet[enetpacketSrc4]=macaddrc[4];
   packet[enetpacketSrc5]=macaddrc[5];

   //calculate the IP header checksum
   packet[ip_hdr_cksum]=0x00;
   packet[ip_hdr_cksum+1]=0x00;

   hdr_chksum =0;
   hdrlen = (packet[ip_vers_len] & 0x0F) * 4;
   addr = &packet[ip_vers_len];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[ip_hdr_cksum] = make8(chksum16,1);
   packet[ip_hdr_cksum+1] = make8(chksum16,0);
 }
//******************************************************************
//*	CHECKSUM CALCULATION ROUTINE
//******************************************************************
void cksum()
{
	  while(hdrlen > 1)
	  {
		 data_H=*addr++;
		 data_L=*addr++;
		 chksum16=make16(data_H,data_L);
		 hdr_chksum = hdr_chksum + chksum16;
		 hdrlen -=2;
	  }
	  if(hdrlen > 0)
	  {
		 data_H=*addr;
		 data_L=0x00;
		 chksum16=make16(data_H,data_L);
		 hdr_chksum = hdr_chksum + chksum16;
	  }
}

void putch(unsigned char c)
{
   while(!TRMT) 	// TRMT1 is set when TSR is empty
	  continue;

  TXREG1 = c;		// load the register
}

//******************************************************************
//*	Init USART Function
//******************************************************************
void init_EUSART(void)
{
  //BRG16 = 0;
  BRGH = 1;
  SYNC = 0;

  SPBRG1 = DIVIDER;	//load baud rate divisor	
  TRISC7 = 1;			//receive pin
  TRISC6 = 1;			//transmit pin
  TXSTA1 = 0x04;		//high speed baud rate	
  RCSTA1 = 0x80;		//enable serial port and serial port pins


  USART_RxTail = 0x00;	//flush receive buffer 
  USART_RxHead = 0x00;
  USART_TxTail = 0x00;	//flush transmit buffer
  USART_TxHead = 0x00;
  RC1IP = 1;			//receive interrupt = high priority
  TX1IP = 1;			//transmit interrupt = high priority
  RC1IE = 1;			//enable receive interrupt
  PEIE = 1;				//enable all unmasked peripheral interrupts
  GIE = 1;				//enable all unmasked interrupts
  CREN = 1;			//enable USART1 receiver
  TX1IE = 0;			//disable USART1 transmit interrupt
  TXEN = 1;			//transmitter enabled
  SPEN = 1;
}

void interrupt USART(void)
{
  unsigned char data,tmphead,tmptail;
/*
//USE WITH 32KHz CLOCK ONLY
  if((TMR1IF) && (TMR1IE))
   {
		TMR1H = 0x80;
		TMR1IF = 0;
		if(60 == ++secs)
		 {
			secs = 0;
		 	++mins;
		 }
		if(60 == mins)
		 {
			mins = 0;
			++hours;
		 }
		if(24 == hours)
		 {
			hours = 0;
		 }
		 ++secs_timer;
		 ++lease_timer;
	}

*/
  if((TMR2IF) && (TMR2IE))
   {
		TMR2IF = 0;
		++msecs_timer;
	 	//LED0 ^= 1;
		if(1000 == ++clock_timer)
		 {
			clock_timer = 0;
			++secs;
			++secs_timer;
			++lease_timer;
		 }
		if(60 == secs)
		 {
			secs = 0;
		 	++mins;
		 }
		if(60 == mins)
		 {
			mins = 0;
			++hours;
		 }
		if(24 == hours)
		 {
			hours = 0;
		 }

   }

  if(RC1IF)
 {
   data = RCREG1;				   // read the received data 
								// calculate buffer index 
   tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;
   USART_RxHead = tmphead;		// store new index 

   if ( tmphead == USART_RxTail )
   {
	 // ERROR! Receive buffer overflow 
   }

   USART_RxBuf[tmphead] = data;   // store received data in buffer 
  }


  if(TRMT)
  {
								// check if all data is transmitted  
   if ( USART_TxHead != USART_TxTail )
   {
								// calculate buffer index  
	 tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
	 USART_TxTail = tmptail;	  // store new index  

	TXREG1 = USART_TxBuf[tmptail];  // start transmition  
   }
   else
   {
	 TX1IE = 0;		 // disable TX interrupt  
   }
  }
}

int recvchar(void)
{
  unsigned char tmptail;
								// wait for incomming data  
  while ( USART_RxHead == USART_RxTail );
								// calculate buffer index  
  tmptail = ( USART_RxTail + 1 ) & USART_RX_BUFFER_MASK;
  USART_RxTail = tmptail;		// store new index  

  return USART_RxBuf[tmptail];   // return data  
}

int sendchar(int data)
{
  unsigned char tmphead;
								// calculate buffer index 
  tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK;
								// wait for free space in buffer 
  while ( tmphead == USART_TxTail );
								// store data in buffer 
  USART_TxBuf[tmphead] = (unsigned char)data;
  USART_TxHead = tmphead;		// store new index 

  TX1IE = 1;			// enable TX interrupt 

  return data;
}

unsigned char CharInQueue(void)
{
  return(USART_RxHead != USART_RxTail);
}

unsigned int rd_phy(char reg)
{
	unsigned int rc;
	char low,high;
	// Set the right address and start the register read operation
	MIREGADR = reg;
	NOP();
	MICMD = MICMD_MIIRD;
	NOP();	
	// Loop to wait until the PHY register has been read through the MII
	while(BUSY);
	// Stop reading
	MICMD = 0x00;
	NOP();	
	// Obtain results and return
	low = MIRDL;
	high = MIRDH;
	rc = (high << 8) | low;
	return rc;
}

void wr_phy(char reg, unsigned int data)
{
	// Write the register address
	MIREGADR = reg;
	NOP();
	// Write the data
	// Order is important: write low byte first, high byte last
	MIWRL = LOW_BYTE(data);
	NOP();
	MIWRH = HIGH_BYTE(data);
	NOP();
	// Wait until the PHY register has been written
	while(BUSY);
}

void init_EEPROM(void)
{
	SSP1STAT = 0b01000000;
	SSP1CON1 = 0x21;
}

void init_67J60(void)
{
	char x;

	TRISA = 0b11111100;
	TRISB = 0b11111111;
	TRISC = 0b01010111;
	TRISD = 0b11111011;
	TRISF = 0x00;
	LATF = 0xFF;
	//Enable Ethernet
	ETHEN = 1;

	while(!PHYRDY);

	msecs_timer = 0;
	clock_timer = 0;
	while(msecs_timer < 2);
	LATF = 0x00;

	RXEN = 0;
   	TXRTS = 0;

	packetheader[nextpacket_low] = LOW_BYTE(RXSTART);
	packetheader[nextpacket_high] = HIGH_BYTE(RXSTART);

	//ERDPTL =  LOW_BYTE(RXSTART);
	//ERDPTH = HIGH_BYTE(RXSTART);

	ERXSTL = LOW_BYTE(RXSTART);
	ERXSTH = HIGH_BYTE(RXSTART);
	ERXRDPTL = LOW_BYTE(RXSTOP);
	ERXRDPTH = HIGH_BYTE(RXSTOP);
	ERXNDL = LOW_BYTE(RXSTOP);
	ERXNDH = HIGH_BYTE(RXSTOP);
	ETXSTL =  LOW_BYTE(TXSTART);
	ETXSTH =  HIGH_BYTE(TXSTART);

	MACON1 =  MACON1_TXPAUS | MACON1_RXPAUS | MACON1_MARXEN;
	NOP();
	// Pad packets to 60 bytes, add CRC, and check Type/Length field
	MACON3 =  MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN;
	NOP();
	// Allow infinite deferals if the medium is continuously busy 
	// (do not time out a transmission if the half duplex medium is 
	// completely saturated with other people's data)
	MACON4 =  MACON4_DEFER;
	NOP();

	// Late collisions occur beyond 63 bytes (default for 802.3 spec)
	MACLCON2 =  63;
	NOP();

	MAIPGL =  0x12;
	NOP();
	MAIPGH =  0x0C;
	NOP();
	MAMXFLL =  LOW_BYTE(MAXFRAME);	
	NOP();
	MAMXFLH =  HIGH_BYTE(MAXFRAME);
	NOP();

	MAADR1 =  macaddrc[0];
	NOP();
	MAADR2 =  macaddrc[1];
	NOP();
	MAADR3 =  macaddrc[2];
	NOP();
	MAADR4 =  macaddrc[3];
	NOP();
	MAADR5 =  macaddrc[4];
	NOP();
	MAADR6 =  macaddrc[5];
	NOP();

	wr_phy(PHCON2, 0x0110);
	wr_phy(PHCON1,0x0000);

	wr_phy(PHLCON, 0x0472);	

	// Set the back-to-back inter-packet gap time to IEEE specified 
	// requirements.  The meaning of the MABBIPG value changes with the duplex
	// state, so it must be updated in this function.
	// In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex

	MABBIPG = 0x12;	

	// Enable packet reception
	RXEN =1;
	EIE = 0x00;
	/*
	debugi = rd_phy(PHCON2);
	NOP();
	debugi = rd_phy(PHCON1);
	NOP();
	debugi = rd_phy(PHLCON);
   */
	printf("\r\n67J60 Initialized\r\n");
}
//******************************************************************
//*	Get A Frame From the Buffer
//*   This routine removes an Ethernet frame from the receive buffer
//*   ring.
//******************************************************************
void get_frame()
{
	unsigned int i;
	char *bufferptr;

	//banksel(ERDPTL);
	ERDPTL = packetheader[nextpacket_low];
	ERDPTH = packetheader[nextpacket_high];

	bufferptr = packetheader;
	bufferptr--;
	i = 0;
	while(i<6)
	{
		bufferptr++;
		i++;
		*bufferptr = EDATA;
	};

	rxlen = make16(packetheader[rec_bytecnt_high],packetheader[rec_bytecnt_low]);

	bufferptr = packet;
	bufferptr--;
	i = rxlen;
	while(i)
	{
		bufferptr++;
		i--;
		*bufferptr = EDATA;
	};

	new_rdptr = (make16(packetheader[nextpacket_high],packetheader[nextpacket_low]));
	--new_rdptr;
//	if((new_rdptr < RXSTART) || (new_rdptr > RXSTOP))
	if((new_rdptr > 8191) || (new_rdptr > RXSTOP))
		new_rdptr = RXSTOP;

	ECON2 |= ECON2_PKTDEC;

	//banksel(ERXRDPTL);
	ERXRDPTL = LOW_BYTE(new_rdptr);
	ERXRDPTH = HIGH_BYTE(new_rdptr);

   	//process an incoming ARP request packet
   	if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x06)
   	  {
	   if(packet[arp_hwtype+1] == 0x01 &&
	   packet[arp_prtype] == 0x08 && 
	   packet[arp_prtype+1] == 0x00 &&
	   packet[arp_hwlen] == 0x06 && 
	   packet[arp_prlen] == 0x04 &&
	   //packet[arp_op+1] == 0x01 &&
	   packet[arp_tipaddr]   == ipaddrc[0] &&
	   packet[arp_tipaddr+1] == ipaddrc[1] &&
	   packet[arp_tipaddr+2] == ipaddrc[2] &&
	   packet[arp_tipaddr+3] == ipaddrc[3])
	  {
		switch(packet[arp_op+1])
		{
			case 0x01:
				arp_reply();
				break;
			case 0x02:
	   			for(i=0;i<6;i++)
		 		 remotemacaddrc = packet[arp_shaddr+i];
				set_arpflag;
				break;
		}		
	  }	
	 }

   	//process an IP packet
   	else if(packet[enetpacketType0] == 0x08	&& 
		  packet[enetpacketType1] == 0x00 	   &&
		  packet[ip_destaddr]   == ipaddrc[0]  &&
		  packet[ip_destaddr+1] == ipaddrc[1]  &&
		  packet[ip_destaddr+2] == ipaddrc[2]  &&
		  packet[ip_destaddr+3] == ipaddrc[3])
	{
	  switch(packet[ip_proto])
	  {
		  case PROT_ICMP:
			  icmp();
		  break;
		  case PROT_UDP:
			  if(packet[UDP_srcport] == DHCP_SERVER_PORT)
			   dhcp_state_engine();
			  else
			   udp();
		  break;
		  case PROT_TCP:
			   tcp();
		  break;
		  default:
		 	LED0 = 1;
		  break;
		 }
		}
   	//process a DHCP message
   	else if(packet[enetpacketType0] == 0x08	&& 
		  packet[enetpacketType1] == 0x00 	   &&
		  packet[ip_destaddr]   == 0xFF  &&
		  packet[ip_destaddr+1] == 0xFF  &&
		  packet[ip_destaddr+2] == 0xFF  &&
		  packet[ip_destaddr+3] == 0xFF	 &&
		  packet[ip_proto] == PROT_UDP)
	{
			 set_newdhcppkt;
			   dhcp_state_engine();
	}

}
//char revid;
void main(void)
{
	char old_secs;

	OSCTUNE = 0x40;

//******************************************************************
//*	CONFIGURE AND START TIMER1
//* SET TO OVERFLOW EVERY 1S
//* USE WITH 32KHz CLOCK ONLY
//******************************************************************
	TMR1ON = 0;
	//TMR1H = 0x80;
	//TMR1L = 0x00;
	//T1CON = 0b00001110;
	//TMR1IE = 1;
	//TMR1ON = 1;
//******************************************************************
//*	CONFIGURE AND START TIMER2
//* SET TO OVERFLOW EVERY 1mS
//******************************************************************
	T2CON = 0x7A;		
	PR2 = 0x29;	
	TMR2ON = 1;
	TMR2IE = 1;

	hours = 0x00;
	mins = 0x00;
	secs = 0x00;

	init_EUSART();
	init_67J60();
	init_DHCP();
	//udpcnt = 0;
while(1)
	{
	 if(EPKTCNT != 0)
		get_frame();

	 dhcp_state_engine();
	 if(old_secs != secs)
	 {
		 old_secs = secs;
	 	LED0 ^= 1;
	 }

	 //printf("%c[12;25H %02d:%02d:%02d",esc,hours, mins, secs);
//////////////////////////////////////////////////////////////////////
// Ethernet MINI DRIVER
// Author: Fred Eady
// Version: 1.0
// Date: 05/06/07
// Description: ARP, PING, ECHO, TCP, UDP, DHCP
//
// THESE ARE BASIC DRIVER ROUTINES AND ARE NOT INTENDED TO BE USED IN
// A PRODUCTION ENVIRONMENT. EDTP OFFERS THESE DRIVER ROUTINES AS-IS
// AND IS NOT RESPONSIBLE FOR ANY MISUSE OR MISAPPLICATION OF THIS 
// CODE.
//////////////////////////////////////////////////////////////////////

#include <pic18.h>
#include <string.h>
#include <stdio.h>
#include "pic18f67j60_driver.h"

//******************************************************************
//*	Debugging variables
//* You can incorporate these back into their routines as locals if 
//* you wish.. I have put them here so you can see them using the
//* WATCH window of MPLAB.
//******************************************************************
char const *msgpointer;
char dhcpmsgchar;
char *packetptr;
//unsigned int tx_end,tx_cnt;
//char debugc, debuggc[400];
char incoming;
//unsigned int phstat_1,phstat_2,erxwrpt_l,erxwrpt_h,erxrdpt_l,erxrdpt_h;
//unsigned int debugi,debuggi[1];
//char econ_1,econ_2,eir_1,estat_1,eie_1;
unsigned int packet_cnt,new_rdptr,udpcnt,msecs_timer,clock_timer;
unsigned int offsetval, chksum_lo,chksum_hi,tx_end;
char lastsec,dhcpreturncode,msgtype,msglen;
unsigned long leasetime,lease_timer;
//******************************************************************
//*	Configuration Fuse Setings
//******************************************************************
// 18F67J60 FUSES
__CONFIG(1,XINSTDIS & WDTDIS & DEBUGDIS);
__CONFIG(2,HSPLL & IESODIS);

#define esc 0x1B

#define LED0	LATF1
//******************************************************************
//*	MACROS
//******************************************************************
#define rd_sram()	(EDATA)
#define wr_sram(a)	EDATA = a
//******************************************************************
//*	ETHERNET BUFFER DEFINITIONS 
//******************************************************************
#define MAXFRAME 		1518
#define TX_BUFFER_SIZE  1518
#define TXSTART			(8192 - (TX_BUFFER_SIZE + 8))
//#define TXEND			(TX_BUFFER_SIZE + 8)
#define RXSTART			0x0000
#define	RXSTOP			((TXSTART - 2) | 0x0001)
#define RXSIZE			(RXSTOP-(RXSTART+1))
//******************************************************************
//*	Flags
//******************************************************************
char flags;
#define synflag 	0x01  
#define	finflag		0x02  
#define entryflag 	0x04
#define arpflag		0x08
#define hexflag		0x10
#define bsynflag   	(flags & synflag)
#define bfinflag	(flags & finflag)
#define bentryflag	(flags & entryflag)
#define barpflag	(flags & arpflag)
#define bhexflag	(flags & hexflag)

#define clr_synflag flags &= ~synflag
#define set_synflag flags |= synflag
#define clr_finflag flags &= ~finflag
#define set_finflag flags |= finflag
#define clr_entryflag flags &= ~entryflag
#define set_entryflag flags |= entryflag
#define clr_arpflag flags &= ~arpflag
#define set_arpflag flags |= arpflag
#define clr_hexflag flags &= ~hexflag
#define set_hexflag flags |= hexflag

char dhcpflags;
#define bound 		0x01  
#define	offerrec	0x02  
#define done		0x04
#define trashit		0x08
#define newdhcppkt	0x10
#define bbound		(dhcpflags & bound)
#define bofferrec	(dhcpflags & offerrec)
#define bdone		(dhcpflags & done)
#define btrashit	(dhcpflags & trashit)
#define bnewdhcppkt	(dhcpflags & newdhcppkt)

#define clr_bound 		dhcpflags &= ~bound
#define set_bound 		dhcpflags |= bound
#define clr_offerrec 	dhcpflags &= ~offerrec
#define set_offerrec 	dhcpflags |= offerrec
#define clr_done		dhcpflags &= ~done
#define set_done 		dhcpflags |= done
#define clr_trashit		dhcpflags &= ~trashit
#define set_trashit		dhcpflags |= trashit
#define clr_newdhcppkt	dhcpflags &= ~newdhcppkt
#define set_newdhcppkt	dhcpflags |= newdhcppkt
//******************************************************************
//*	TELNET SERVER BANNER STATEMENT CONSTANT
//******************************************************************
char const telnet_banner[] = "\r\nEDTP 67J60 Driver>";
char const dhcpmacmsg[] = "\r\nMY MAC ADDRESS = 00-00-46-54-49-49";
char const dhcpipmsg[] = "\r\nNEW IP ADDRESS = ";
char const dhcpgwaymsg[] = "\r\nNEW GATEWAY IP ADDRESS = ";
char const dhcpsubnetmaskmsg[] = "\r\nNEW SUBNET MASK = ";
//******************************************************************
//*	Port Definitions
//*   This address is used by TCP and the Telnet function.
//*   This can be changed to any valid port number as long as
//*   you modify your code to recognize the new port number.
//******************************************************************
#define  MY_PORT_ADDRESS	  0x1F98  // 8088 DECIMAL
#define	 MCHP_UDP_PORT_ADDRESS	0x765F //30303 DECIMAL
//******************************************************************
//*	IP ADDRESS DEFINITION
//*   These are the default Ethernet Module IP addresses.
//*   You may change these to any valid address.
//******************************************************************
char ipaddrascii[3];
char ipaddrc[4] = { 192,168,1,150 };
char tempipaddrc[4];
char remoteipaddrc[4] = {192,168,1,100};
char svridc[4];
char gwayipaddrc[4];
char tempgwayipaddrc[4];
char subnetmaskc[4];
char tempsubnetmaskc[4];
char tempsvridc[4];
char templeasetimec[4];
char broadcastipaddrc[4] = {192,168,1,255};
//******************************************************************
//*	HARDWARE (MAC) ADDRESS DEFINITION
//*   This is the default Ethernet Module hardware address.
//*   You may change this to any valid address.
//******************************************************************
char macaddrc[6] = { 0,0,'E','D','T','P'};
char remotemacaddrc[6]; 
char svrmacaddrc[6];
//******************************************************************
//*	Function Declarations
//******************************************************************
//void read_xmit_buffer(void);
void init_EUSART(void);
unsigned char CharInQueue(void);
void putch(unsigned char c);
int recvchar(void);
int sendchar(int data);
void init_67J60(void);
void arp_reply(void);
void tcp(void);
void icmp(void);
void udp(void);
void setipaddrs(void);
void cksum(void);
void send_tcp_packet(void);
void assemble_ack(void);
void send_udp_datagram(void);
void arp_request(void);
void get_frame(void);
void application_code(void);
void dhcp_state_engine(void);
void init_DHCP(void);
void send_dhcp(char dhcpmsg_type);
char receive_dhcp(void);
void send_dhcp_bound_datagram(void);
void binary_to_ascii(unsigned int binarynumber);

//******************************************************************
//*	SRAM Definitions
//******************************************************************
char aux_data[16];			//received data area
char *addr;
char byte_read,data_H,data_L,cntr,byteout;
char high_nibble, low_nibble, high_char, low_char,resend;
unsigned int txlen,rxlen,chksum16,hdrlen,tcplen,tcpdatalen_in;
unsigned int tcpdatalen_out,ISN,portaddr,ip_packet_len;
unsigned long hdr_chksum,my_seqnum,client_seqnum,incoming_ack,expected_ack;
char tx_status[6];
char hours, mins, secs;
char secs_timer;
char chr_count,bytein;
char eeaddr;
unsigned int cntri;
unsigned int parameters[11];
#define local_ipaddr				0x00
#define	local_ipaddr3				0x00
#define	local_ipaddr2				0x01
#define	local_ipaddr1				0x02
#define	local_ipaddr0				0x03
#define host_ipaddr					0x04
#define	host_ipaddr3				0x04
#define	host_ipaddr2				0x05
#define	host_ipaddr1				0x06
#define	host_ipaddr0				0x07
#define loopsecs					0x08
unsigned long udpaddrs[2];
#define local_udpaddr				0x00
#define remote_udpaddr				0x01
//******************************************************************
//*	DHCP Definitions
//******************************************************************
#define DHCP_CLIENT_PORT					0x44//(68u)
#define DHCP_SERVER_PORT					0x43//(67u)

#define BOOT_REQUEST						0x01//(1u)
#define BOOT_REPLY						  0x02//(2u)
#define HW_TYPE						 	0x01//(1u)
#define HW_TYPE_LEN							  0x06//(6u)

#define DHCP_MESSAGE_TYPE			   	0x35//(53u)
#define DHCP_MESSAGE_TYPE_LEN		   	0x01//(1u)

#define DHCP_UNKNOWN_MESSAGE				0x00//(0u)

#define DHCP_DISCOVER_MESSAGE		   	0x01//(1u)
#define DHCP_OFFER_MESSAGE				  0x02//(2u)
#define DHCP_REQUEST_MESSAGE				0x03//(3u)
#define DHCP_DECLINE_MESSAGE				0x04//(4u)
#define DHCP_ACK_MESSAGE					0x05//(5u)
#define DHCP_NAK_MESSAGE					0x06//(6u)
#define DHCP_RELEASE_MESSAGE				0x07//(7u)

#define DHCP_SERVER_IDENTIFIER			  0x36//(54u)
#define DHCP_SERVER_IDENTIFIER_LEN		  0x04//(4u)

#define DHCP_PARAM_REQUEST_LIST		 	0x37//(55u)
#define DHCP_PARAM_REQUEST_LIST_LEN	 	0x02//(2u)
#define DHCP_PARAM_REQUEST_IP_ADDRESS	   0x32//(50u)
#define DHCP_PARAM_REQUEST_IP_ADDRESS_LEN   0x04//(4u)
#define DHCP_SUBNET_MASK					0x01//(1u)
#define DHCP_ROUTER					 	0x03//(3u)
#define DHCP_IP_LEASE_TIME				  0x33//(51u)
#define DHCP_END_OPTION				 	0xFF//(255u)

typedef enum _DHCP_STATES
{
	DHCP_ENTRY,					
	DHCP_INIT,						
	DHCP_WAIT,
	DHCP_BROADCAST,
	DHCP_DISCOVER,
	DHCP_REQUEST,
	DHCP_BIND,
	DHCP_BOUND,
	DHCP_DISABLED
}DHCP_STATE_LIST;

DHCP_STATE_LIST DHCPSTATE;

//******************************************************************
//*	Receive Ring Buffer Header Layout
//*   This is the 4-byte header that resides infront of the
//*   data packet in the receive buffer.
//******************************************************************
#define tx_control_byte	   0x0E
char  packetheader[6];
#define  nextpacket_low	0x00
#define  nextpacket_high   0x01
#define	rec_bytecnt_low	0x02
#define	rec_bytecnt_high   0x03
#define	rec_status_low 	   0x04
#define	rec_status_high	   0x05
//******************************************************************
//*	Ethernet Header Layout
//******************************************************************
char  udp_packet[100];				   
char  packet[1118];				
#define	enetpacketDest0	   0x00  //destination mac address
#define	enetpacketDest1	   0x01
#define	enetpacketDest2	   0x02
#define	enetpacketDest3	   0x03
#define	enetpacketDest4	   0x04
#define	enetpacketDest5	   0x05
#define	enetpacketSrc0	   0x06  //source mac address
#define	enetpacketSrc1	   0x07
#define	enetpacketSrc2	   0x08
#define	enetpacketSrc3	   0x09
#define	enetpacketSrc4	   0x0A
#define	enetpacketSrc5	   0x0B
#define	enetpacketType0	   0x0C  //type/length field
#define	enetpacketType1	   0x0D
#define enetpacketData	 0x0E  //IP data area begins here
//******************************************************************
//*	ARP Layout
//******************************************************************
#define	arp_hwtype		   0x0E
#define	arp_prtype		   0x10
#define	arp_hwlen		   0x12
#define	arp_prlen		   0x13
#define	arp_op			   0x14
#define	arp_shaddr		   0x16   //arp source mac address
#define	arp_sipaddr		   0x1C   //arp source ip address
#define	arp_thaddr		   0x20   //arp target mac address
#define	arp_tipaddr		   0x26   //arp target ip address
//******************************************************************
//*	IP Header Layout
//******************************************************************
#define	ip_vers_len		   0x0E	//IP version and header length 1a19
#define	ip_tos			   0x0F	//IP type of service
#define	ip_pktlen		   0x10	//packet length
#define	ip_id			   0x12	//datagram id
#define	ip_frag_offset	   0x14	//fragment offset
#define	ip_ttl			   0x16	//time to live
#define	ip_proto		   0x17	//protocol (ICMP=1, TCP=6, UDP=11)
#define	ip_hdr_cksum	   0x18	//header checksum 1a23
#define	ip_srcaddr		   0x1A	//IP address of source
#define	ip_destaddr		   0x1E	//IP addess of destination
#define	ip_data			   0x22	//IP data area
//******************************************************************
//*	TCP Header Layout
//******************************************************************
#define	TCP_srcport		   0x22	//TCP source port
#define	TCP_destport   	   0x24	//TCP destination port
#define	TCP_seqnum		 0x26	//sequence number
#define	TCP_acknum		   0x2A	//acknowledgement number
#define	TCP_hdrflags	   0x2E	//4-bit header len and flags
#define	TCP_window		   0x30	//window size
#define	TCP_cksum		   0x32	//TCP checksum
#define	TCP_urgentptr	  0x34	//urgent pointer
#define TCP_data		   0x36 //option/data
//******************************************************************
//*	TCP Flags
//*   IN flags represent incoming bits
//*   OUT flags represent outgoing bits
//******************************************************************
#define  FIN_IN			   (packet[TCP_hdrflags+1] & 0x01)
#define  SYN_IN			   (packet[TCP_hdrflags+1] & 0x02)
#define  RST_IN			   (packet[TCP_hdrflags+1] & 0x04)
#define  PSH_IN			   (packet[TCP_hdrflags+1] & 0x08)
#define  ACK_IN			   (packet[TCP_hdrflags+1] & 0x10)
#define  URG_IN			   (packet[TCP_hdrflags+1] & 0x20)
#define  FIN_OUT			  packet[TCP_hdrflags+1] |= 0x01 //0000 0001 
#define  SYN_OUT			  packet[TCP_hdrflags+1] |= 0x02 //0000 0010 
#define  RST_OUT			  packet[TCP_hdrflags+1] |= 0x04 //0000 0100 
#define  PSH_OUT			  packet[TCP_hdrflags+1] |= 0x08 //0000 1000 
#define  ACK_OUT			  packet[TCP_hdrflags+1] |= 0x10 //0001 0000 
#define  URG_OUT			  packet[TCP_hdrflags+1] |= 0x20 //0010 0000 
//******************************************************************
//*	IP Protocol Types
//******************************************************************
#define	PROT_ICMP			   0x01
#define	PROT_TCP			   0x06
#define	PROT_UDP			   0x11
//******************************************************************
//*	ICMP Header
//******************************************************************
#define	ICMP_type			   ip_data
#define	ICMP_code			   ICMP_type+1
#define	ICMP_cksum			   ICMP_code+1
#define	ICMP_id				   ICMP_cksum+2
#define	ICMP_seqnum			   ICMP_id+2
#define ICMP_data			  ICMP_seqnum+2
//******************************************************************
//*	UDP Header
//******************************************************************
#define	UDP_srcport			   ip_data
#define	UDP_destport		   UDP_srcport+2
#define	UDP_len				   UDP_destport+2
#define	UDP_cksum			   UDP_len+2
#define	UDP_data			   UDP_cksum+2
//******************************************************************
//*	DHCP Message
//******************************************************************
#define	DHCP_op					UDP_data
#define	DHCP_htype				DHCP_op+1
#define DHCP_hlen				DHCP_htype+1
#define DHCP_hops				DHCP_hlen+1
#define DHCP_xid				DHCP_hops+1
#define DHCP_secs				DHCP_xid+4
#define DHCP_flags				DHCP_secs+2
#define DHCP_ciaddr				DHCP_flags+2
#define DHCP_yiaddr				DHCP_ciaddr+4
#define DHCP_siaddr				DHCP_yiaddr+4
#define DHCP_giaddr				DHCP_siaddr+4
#define DHCP_chaddr				DHCP_giaddr+4
#define DHCP_sname				DHCP_chaddr+16
#define DHCP_file				DHCP_sname+64
#define DHCP_options			DHCP_file+128
#define DHCP_message_end		DHCP_options+312
//******************************************************************
//*	Macros
//******************************************************************
#define bitset(var, bitno) ((var) |= 1 << (bitno))
#define bitclr(var, bitno) ((var) &= ~(1 << (bitno)))
#define make8(var,offset)	((unsigned int)var >> (offset * 8)) & 0x00FF
#define	make16(varhigh,varlow)	(((unsigned int)varhigh & 0xFF)* 0x100) + ((unsigned int)varlow & 0x00FF)
#define make32(var1,var2,var3,var4) \
		((unsigned long)var1<<24)+((unsigned long)var2<<16)+ \
		((unsigned long)var3<<8)+((unsigned long)var4)		
#define make32i(var1,var2) ((unsigned long)var1<<16)+((unsigned long)var2)

#define  set_packet32(d,s) packet[d]   = (s & 0xFF000000) >> 24; \
						   packet[d+1] = (s & 0x00FF0000) >> 16; \
						   packet[d+2] = (s & 0x0000FF00) >> 8;  \
						   packet[d+3] = (s & 0x000000FF);
//******************************************************************
//*	USART Definitions
//******************************************************************
#define BAUD	57600		//desired baud rate
#define FOSC	41666667	//oscillator frequency
#define DIVIDER ((unsigned int)(FOSC/(16 * BAUD) -1))
//1,2,4,8,16,32,64,128 or 256 bytes 
#define USART_RX_BUFFER_SIZE  256	  
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
// 1,2,4,8,16,32,64,128 or 256 bytes 
#define USART_TX_BUFFER_SIZE  256	  
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )

unsigned char USART_RxBuf[USART_RX_BUFFER_SIZE],USART_TxBuf[USART_TX_BUFFER_SIZE];
unsigned char USART_TxHead,USART_TxTail,USART_RxHead,USART_RxTail;
char remainder;
//******************************************************************
//*	BINARY TO ASCII CONVERSION
//******************************************************************
void binary_to_ascii(unsigned int binarynumber)
{
	char i;

	for(i=0;i<3;++i)
		ipaddrascii = 0x30;
	if(binarynumber > 255)
	return;
	if(binarynumber >= 100)
	{
	do{
			binarynumber-=100;
			ipaddrascii[0]+= 1;
	  }while(binarynumber >= 100);
	}
	if(binarynumber >= 10)
	{
	  do{
			binarynumber-=10;
			ipaddrascii[1]+= 1;
	  }while(binarynumber >= 10);
	}
	ipaddrascii[2]+= binarynumber;
}
//******************************************************************
//*	Read the transmit buffer
//*   This routine reads the contents of the transmit buffer
//*   Uncomment debuggc array definition to use
//******************************************************************
/*
void read_xmit_buffer(void)
{
	unsigned int i;
	//banksel(ERDPTL);
	ERDPTL= LOW_BYTE(TXSTART);
	ERDPTH= HIGH_BYTE(TXSTART);
	for(i=0;i<300;++i)	
		debuggc= rd_sram();
}
*/
//******************************************************************
//*	  SEND DHCP BOUND MESSAGE VIA BROADCAST UDP
//******************************************************************
void send_dhcp_bound_datagram()
{
	char *bufferptr,temp;
	unsigned int i,j;	
	char msg[];
	tx_end = 0;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

	i = 6;
	while(i--)   		//write destination MAC address	
	{
		EDATA = 0xFF;
		//i--;
	};	

	bufferptr = macaddrc;
	i = 6;
	while(i--)   			//write source MAC address	

	{
		EDATA = *bufferptr++;
	//	bufferptr++;
	//	i--;
	};	
	EDATA =  0x08;		//write 0800 type field
	EDATA =  0x00;
	tx_end += 15;

	//BEGIN IP HEADER
	EDATA =  0x45;		//write 4500 vers/len field
	EDATA =  0x00;
	EDATA =  0x00;		//write packet length 0x0114
	EDATA =  0x00;
	EDATA =  0x00;		//write id field
	EDATA =  0x01;
	EDATA =  0x00;		//write flags/frag offset
	EDATA =  0x00;
	EDATA =  0x64;		//write time to live
	EDATA =  0x11;		//write protocol type (UDP)
	EDATA =  0x00;		//write IP hdr checksum (0x0000)
	EDATA =  0x00;
	i = 4;
	bufferptr = ipaddrc;
	while(i--)   			//write source IP address	
	{
		EDATA =  *bufferptr++;
		//i--;
	};	
	i = 4;
	bufferptr = broadcastipaddrc;
	while(i--)   			//write destination IP address	
	{
		EDATA =  *bufferptr++;
		//i--;
	};	
	tx_end += 20;
	//END IP HEADER

	//START UPD HEADER
	EDATA =  HIGH_BYTE(MY_PORT_ADDRESS);		//write UDP source port (8088 decimal)
	EDATA =  LOW_BYTE(MY_PORT_ADDRESS);
	EDATA =  HIGH_BYTE(MCHP_UDP_PORT_ADDRESS);		//write UDP destination port (30303 decimal)
	EDATA =  LOW_BYTE(MCHP_UDP_PORT_ADDRESS);
	EDATA =  0x00;		//write UDP length 
	EDATA =  0x00;
	EDATA =  0x00;		//write UDP checksum (no checksum)
	EDATA =  0x00;
	tx_end += 8;
	//END UDP HEADER

	//START UDP DATA
	//write MAC address message
	i = 36;
	tx_end += i;
	msgpointer = dhcpmacmsg;
	while(i--)   			
		{
			EDATA =  *msgpointer++;
			//i--;
		};
	//write IP address message	
	i = 19;
	tx_end += i;
	msgpointer = dhcpipmsg;
	while(i--)   		
		{
			EDATA =  *msgpointer++;
		//	i--;
		};	
	for(i=0;i<4;++i)
		{
			binary_to_ascii(ipaddrc);
			bufferptr = ipaddrascii;	
			j = sizeof(ipaddrascii);
			tx_end += j;
			if(ipaddrascii[0] == 0x30)
			{
				tx_end--;
				j--;
				bufferptr++;
			}
			if(ipaddrascii[1] == 0x30  && ipaddrascii[0] == 0x30)
			{
				tx_end--;
				j--;
				bufferptr++;
			}	
			while(j--)   		//write FTII IP address 	
			{
				EDATA =  *bufferptr++;
				//j--;
			};
			if(i<3)
			{
				EDATA =  0x2E;	//write . period
				tx_end += 1;
			}
		}	
	//write gateway address message				
	 i = 27;
	 tx_end += i;
	 msgpointer = dhcpgwaymsg;
	 while(i--)		  //write gateway address message
	 {
		  EDATA =  *msgpointer++;
		//i--;
	 };	
	 for(i=0;i<4;++i)
	 {
		binary_to_ascii(gwayipaddrc);
		bufferptr = ipaddrascii;	
		j = sizeof(ipaddrascii);
		tx_end += j;
		if(ipaddrascii[0] == 0x30)
		{
		 	tx_end--;
			j--;
			bufferptr++;
		}
		if(ipaddrascii[1] == 0x30  && ipaddrascii[0] == 0x30)
		{
			tx_end--;
			j--;
			bufferptr++;
		}	
		while(j--)   		//write FTII gateway IP address 	
		{
			EDATA =  *bufferptr++;
			//j--;
		};
		if(i<3)
		{
			EDATA =  0x2E;	//write . period
			tx_end += 1;
		}
	   }
	//write subnet mask address message				
	 i = 20;
	 tx_end += i;
	 msgpointer = dhcpsubnetmaskmsg;
	 while(i--)   		//write gateway address message
	 {
		  EDATA =  *msgpointer++;
		//i--;
	 };	
	 for(i=0;i<4;++i)
	 {
		binary_to_ascii(subnetmaskc);
		bufferptr = ipaddrascii;	
		j = sizeof(ipaddrascii);
		tx_end += j;
		if(ipaddrascii[0] == 0x30)
		{
		 	tx_end--;
			j--;
			bufferptr++;
		}
		if(ipaddrascii[1] == 0x30  && ipaddrascii[0] == 0x30)
		{
			tx_end--;
			j--;
			bufferptr++;
		}	
		while(j--)   		//write subnet mask	
		{
			EDATA =  *bufferptr++;
			//j--;
		};
		if(i<3)
		{
			EDATA =  0x2E;	//write . period
			tx_end += 1;
		}
	   }
	//read_xmit_buffer();
	//++i;

	// write ip header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x11);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 15;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	// write udp header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x27);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 35;	
	EDATA =  HIGH_BYTE(i);   

	//compute ip header checksum
	hdrlen = (0x45 & 0x0F) * 4; //hdrlen = 20 bytes
	offsetval = TXSTART+15;		//beginning of IP header
	EDMASTL = LOW_BYTE(offsetval);
	EDMASTH = HIGH_BYTE(offsetval);
	offsetval += (hdrlen-1);
	EDMANDL = LOW_BYTE(offsetval);
	EDMANDH = HIGH_BYTE(offsetval);
	ECON1 |= (ECON1_CSUMEN | ECON1_DMAST);
   // while(ECON1 & ECON1_DMAST);
   	while(DMAST);
	chksum_lo =  EDMACSL;
	chksum_hi =  EDMACSH;

	//write ip checksum values to TX buffer
	offsetval = TXSTART+25;
	EWRPTL = LOW_BYTE(offsetval);
	EWRPTH = HIGH_BYTE(offsetval);
	EDATA =  chksum_hi;
	EDATA =  chksum_lo;
	tx_end += (TXSTART-1);
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	//temp =  EIR;
	//if((temp & EIR_TXERIF) == 1)
	if(TXERIF)
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//while(1 == (ECON1 & ECON1_TXRTS));
	while(TXRTS);
}
//******************************************************************
//*	INITIALIZE DHCP STATE MACHINE
//******************************************************************
void init_DHCP(void)
{
	if(DHCPSTATE == DHCP_DISABLED)
		return;

	DHCPSTATE = DHCP_ENTRY;
	dhcpflags = 0;
}
//******************************************************************
//*	DHCP STATE MACHINE
//******************************************************************
void dhcp_state_engine(void)
{
	unsigned int i;
	switch(DHCPSTATE)
	{
		case DHCP_ENTRY:
			printf("\r\nDHCP RESET..");
			for(i=0;i<4;++i)
				tempipaddrc = 0x00;
			DHCPSTATE = DHCP_INIT;
		case DHCP_INIT:
			printf("\r\nDHCP INIT..");	
			for(i=0;i<6;++i)
				svrmacaddrc = 0xFF;
			for(i=0;i<4;++i)
				svridc = 0xFF;
			msecs_timer = 0;
			DHCPSTATE = DHCP_WAIT;
		case DHCP_WAIT:
			if(msecs_timer >= 2000)
				DHCPSTATE = DHCP_BROADCAST;
		break;
		case DHCP_BROADCAST:
			leasetime = 60;
			if(bbound)
			{
				DHCPSTATE = DHCP_REQUEST;
			}
			else
			{
				send_dhcp(DHCP_DISCOVER_MESSAGE);
				msecs_timer = 0;
				DHCPSTATE = DHCP_DISCOVER;
				printf("\r\nSENT DISCOVER MESSAGE..");
			}
		break;
		case DHCP_DISCOVER:
			if(msecs_timer >= 2000)
			{
				DHCPSTATE = DHCP_BROADCAST;
				return;
			}
			if(bnewdhcppkt)
			{
				if(receive_dhcp() == DHCP_OFFER_MESSAGE)
				{
					DHCPSTATE = DHCP_REQUEST;
					printf("\r\nRECEIVED DHCP OFFER MESSAGE..");
				}
				clr_newdhcppkt;
			}
		break;
		case DHCP_REQUEST:
			send_dhcp(DHCP_REQUEST_MESSAGE);
			msecs_timer = 0;
			DHCPSTATE = DHCP_BIND;
			printf("\r\nSENT DHCP REQUEST MESSAGE..");
		break;
		case DHCP_BIND:
			if(bnewdhcppkt)
			{
				dhcpreturncode = receive_dhcp();
				clr_newdhcppkt;
			}
			if(dhcpreturncode == DHCP_NAK_MESSAGE)
			{	
				printf("\r\nRECEIVED DHCP NAK MESSAGE..");
				init_DHCP();
				return;
			}
			else if(dhcpreturncode == DHCP_ACK_MESSAGE)
			{
				printf("\r\nRECEIVED DHCP ACK MESSAGE..");
				lease_timer = 0;
				DHCPSTATE = DHCP_BOUND;
				for(i=0;i<4;++i)
				{
					ipaddrc = tempipaddrc;
					subnetmaskc = tempsubnetmaskc;
					gwayipaddrc = tempgwayipaddrc;
				}
				set_bound;
				printf("\r\nNEW IP ADDRESS IS %d.%d.%d.%d..",ipaddrc[0],ipaddrc[1],ipaddrc[2],ipaddrc[3]);
				printf("\r\nNEW GATEWAY ADDRESS IS %d.%d.%d.%d..",gwayipaddrc[0],gwayipaddrc[1],gwayipaddrc[2],gwayipaddrc[3]);
				printf("\r\nNEW SUBNET MASK IS %d.%d.%d.%d..",subnetmaskc[0],subnetmaskc[1],subnetmaskc[2],subnetmaskc[3]);
				send_dhcp_bound_datagram();
				return;
			}
			else if(msecs_timer >= 2000)
				DHCPSTATE = DHCP_BROADCAST;
		break;
		case DHCP_BOUND:
			if(lease_timer >= leasetime)
			{
				printf("\r\nDHCP LEASE TIME EXPIRED..");
				DHCPSTATE = DHCP_INIT;
			}
		break;
	}
}

//******************************************************************
//*	SEND A DHCP MESSAGE ROUTINE
//******************************************************************
void send_dhcp(char dhcpmsgtype)
{
	char *bufferptr,temp;
	unsigned int i;	

	tx_end = 0;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

	EDATA =  0x0E;   //write control byte
	i = 6;
	while(i)   		//write destination MAC address	
	{
		EDATA = 0xFF;
		i--;
	};	

	bufferptr = macaddrc;
	i = 6;
	while(i)   			//write source MAC address	

	{
		EDATA = *bufferptr;
		bufferptr++;
		i--;
	};	
	EDATA =  0x08;		//write 0800 type field
	EDATA =  0x00;
	tx_end += 15;

	//BEGIN IP HEADER
	EDATA =  0x45;		//write 4500 vers/len field
	EDATA =  0x00;
	EDATA =  0x00;		//write packet length 0x0114
	EDATA =  0x00;
	EDATA =  0x00;		//write id field
	EDATA =  0x01;
	EDATA =  0x00;		//write flags/frag offset
	EDATA =  0x00;
	EDATA =  0x64;		//write time to live
	EDATA =  0x11;		//write protocol type (UDP)
	EDATA =  0x00;		//write IP hdr checksum (0x0000)
	EDATA =  0x00;
	i = 4;
	while(i)   			//write source IP address	
	{
		EDATA =  0x00;
		i--;
	};	
	i = 4;
	while(i)   			//write destination IP address	
	{
		EDATA = 0xFF;
		i--;
	};	
	tx_end += 20;
	//END IP HEADER

	//START UDP HEADER
	EDATA =  0x00;		//write UDP source port (68)
	EDATA =  0x44;
	EDATA =  0x00;		//write UDP destination port (67)
	EDATA =  0x43;
	EDATA =  0x00;		//write UDP length 
	EDATA =  0x00;
	EDATA =  0x00;		//write UDP checksum (no checksum)
	EDATA =  0x00;
	tx_end += 8;
	//END UDP HEADER

	/*

   0				   1				   2				   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |	 op (1)	|   htype (1)   |   hlen (1)	|   hops (1)	|
   +---------------+---------------+---------------+---------------+
   |							xid (4)							|
   +-------------------------------+-------------------------------+
   |		   secs (2)			|		   flags (2)		   |
   +-------------------------------+-------------------------------+
   |						  ciaddr  (4)						  |
   +---------------------------------------------------------------+
   |						  yiaddr  (4)						  |
   +---------------------------------------------------------------+
   |						  siaddr  (4)						  |
   +---------------------------------------------------------------+
   |						  giaddr  (4)						  |
   +---------------------------------------------------------------+
   |															   |
   |						  chaddr  (16)						 |
   |															   |
   |															   |
   +---------------------------------------------------------------+
   |															   |
   |						  sname   (64)						 |
   +---------------------------------------------------------------+
   |															   |
   |						  file	(128)						|
   +---------------------------------------------------------------+
   |															   |
   |						  options (312)						|
   +---------------------------------------------------------------+

*/

	//BEGIN DHCP MESSAGE
	EDATA =  BOOT_REQUEST;		//write DHCP boot record type (request)
	EDATA =  HW_TYPE;		//write DHCP hw address type (10Mb Ethernet)
	EDATA =  HW_TYPE_LEN;		//write DHCP hw address length (6)
	EDATA =  0x00;		//write DHCP hops (0)
	EDATA =  0x01;		//write DHCP transaction id (01020304)
	EDATA =  0x02;		
	EDATA =  0x03;		
	EDATA =  0x04;		
	EDATA =  0x00;		//write DHCP elapsed boot time (0)
	EDATA =  0x00;		
	EDATA =  0x80;		//write DHCP flags (8000)
	EDATA =  0x00;		
	i = 16;
	while(i)   			//write ciaddr,yiaddr,siaddr,giaddr	
	{
		EDATA =  0x00;
		i--;
	};	
	bufferptr = macaddrc;
	i = 6;
	while(i)   			//write source MAC address to chaddr	

	{
		EDATA = *bufferptr;
		bufferptr++;
		i--;
	};	
	i = 202;
	while(i)   			//write remaining 10 bytes of 0x00 to chaddr	
						//write 64 bytes of 0x00 to sname
						//write 128 bytes of 0x00 to file
	{
		EDATA =  0x00;
		i--;
	};	
	tx_end += 236;  
	EDATA =  0x63;		//write DHCP magic cookie (63825363)
	EDATA =  0x82;		
	EDATA =  0x53;		
	EDATA =  0x63;		
	EDATA =  DHCP_MESSAGE_TYPE;		//write DHCP message type 
	EDATA =  DHCP_MESSAGE_TYPE_LEN;	 	
	EDATA =  dhcpmsgtype;		
	tx_end += 7;
	if(dhcpmsgtype == DHCP_DISCOVER_MESSAGE)
		clr_offerrec;
	if(dhcpmsgtype !=  DHCP_DISCOVER_MESSAGE &&
					   tempipaddrc[0] != 0x00 &&
					   tempipaddrc[1] != 0x00 &&
					   tempipaddrc[2] != 0x00 &&
					   tempipaddrc[3] != 0x00 )
		{
			EDATA =  DHCP_SERVER_IDENTIFIER;	   
			EDATA =  DHCP_SERVER_IDENTIFIER_LEN;		
			bufferptr = svridc;
			i = 4;
			while(i)   			//write server ip address (server id)
			{
				EDATA = *bufferptr;
				bufferptr++;
				i--;
			};
		tx_end += 6;
		}	
	EDATA =  DHCP_PARAM_REQUEST_LIST;		//write DHCP parameter list (2 entries)
	EDATA =  DHCP_PARAM_REQUEST_LIST_LEN;		
	EDATA =  DHCP_SUBNET_MASK;		//client's subnet mask
	EDATA =  DHCP_ROUTER;		//routers on the client's subnet	
	tx_end += 4;
	if(dhcpmsgtype == DHCP_REQUEST_MESSAGE)
	{
			EDATA =  DHCP_PARAM_REQUEST_IP_ADDRESS;	   
			EDATA =  DHCP_PARAM_REQUEST_IP_ADDRESS_LEN;		
			bufferptr = tempipaddrc;
			i = 4;
			while(i)   			//write requested ip address 
			{
				EDATA = *bufferptr;
				bufferptr++;
				i--;
			};
		tx_end += 6;
	}

	EDATA = 0xFF;		//end of options	
	tx_end += 1;
	//DHCP MESSAGE END

	// write ip header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x11);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 15;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	// write udp header total length
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART+0x27);
	EWRPTH = HIGH_BYTE(TXSTART+0x00);

	i = tx_end - 35;	
	EDATA =  HIGH_BYTE(i);   
	EDATA =  LOW_BYTE(i);   

	//compute ip header checksum
	hdrlen = (0x45 & 0x0F) * 4; //hdrlen = 20 bytes
	offsetval = TXSTART+15;		//beginning of IP header
	EDMASTL = LOW_BYTE(offsetval);
	EDMASTH = HIGH_BYTE(offsetval);
	offsetval += (hdrlen-1);
	EDMANDL = LOW_BYTE(offsetval);
	EDMANDH = HIGH_BYTE(offsetval);
	ECON1 |= (ECON1_CSUMEN | ECON1_DMAST);
	while(ECON1 & ECON1_DMAST);
	chksum_lo =  EDMACSL;
	chksum_hi =  EDMACSH;

	//write ip checksum values to TX buffer
	offsetval = TXSTART+25;
	EWRPTL = LOW_BYTE(offsetval);
	EWRPTH = HIGH_BYTE(offsetval);
	EDATA =  chksum_hi;
	EDATA =  chksum_lo;
	tx_end += (TXSTART-1);
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	temp =  EIR;
	if((temp & EIR_TXERIF) == 1)
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
		//temp =  ECON1);
		//}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
//	++i;
}
//******************************************************************
//*	RECEIVE DHCP MESSAGE ROUTINE
//******************************************************************
char receive_dhcp(void)
{
	unsigned int i;
	//char *packetptr,dhcpmsgchar;
	msgtype = DHCP_UNKNOWN_MESSAGE;
	clr_done;
	if(packet[DHCP_op] == BOOT_REPLY)
	{
		if(bofferrec == 0)
		{
			for(i=0;i<4;++i)
				tempipaddrc = packet[DHCP_yiaddr+i];
		}
		if(  packet[DHCP_chaddr] == macaddrc[0] &&
			   packet[DHCP_chaddr+1] == macaddrc[1] &&
			   packet[DHCP_chaddr+2] == macaddrc[2] &&
			   packet[DHCP_chaddr+3] == macaddrc[3] &&
			   packet[DHCP_chaddr+4] == macaddrc[4] &&
			   packet[DHCP_chaddr+5] == macaddrc[5])
			   {
				   packetptr = &packet[DHCP_options+4];
				   do{
					   dhcpmsgchar = *packetptr++;
					   switch(dhcpmsgchar)
					   {
						   case DHCP_MESSAGE_TYPE:
					   		msglen = *packetptr++;
					   		if(msglen == 0x01)
					   		{
						   		msgtype = *packetptr++;
						   		if(bofferrec && (msgtype == DHCP_OFFER_MESSAGE))
						   		{
							   		set_trashit;
							   	}

							 }
							 else
							 	set_trashit;
							break; 

							case DHCP_SERVER_IDENTIFIER:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
								for(i=0;i<4;++i)
								{
									tempsvridc = *packetptr++;
								}
							 }
							 else
							 	set_trashit;
							break;

							case DHCP_SUBNET_MASK:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
								for(i=0;i<4;++i)
								{
									tempsubnetmaskc = *packetptr++;
								}
							 }
							 else
							 	set_trashit;
							break;

							case DHCP_IP_LEASE_TIME:
					   		msglen = *packetptr++;
					   		if(msglen == 0x04)
					   		{
						   		if(bofferrec)
						   		{	
							   		for(i=0;i<4;++i)
							   			*packetptr++;
							   	}
							   	else
							   	{
									for(i=0;i<4;++i)
									{
										templeasetimec = *packetptr++;
									}
								}
								leasetime = make32(templeasetimec[0],templeasetimec[1],templeasetimec[2],templeasetimec[3]);
								if(leasetime > 1800)
									leasetime -= 1800; //renew 30 minutes before the lease expires
								//uncomment line below to test DHCP RENEW	
								//leasetime = 60;
							 }
							 else
							 	set_trashit;
							break;

							case DHCP_ROUTER:
					   		msglen = *packetptr++;
					   		if(msglen >= 0x04) 
					   		{
						   		if(bofferrec)
						   		{	
							   		for(i=0;i<4;++i)
							   			*packetptr++;
							   	}
							   	else
							   	{
									for(i=0;i<4;++i)
									{
										tempgwayipaddrc = *packetptr++;
									}
								}
							 }
							 else
							 	set_trashit;
							 msglen -= 4;
							 while(msglen--)
							 	*packetptr++;
							break;

							case DHCP_END_OPTION:
								set_done;
							break;

							default:
					   		msglen = *packetptr++;
							 while(msglen--)
							 	*packetptr++;
							break;
						}

				   }while(bdone == 0);
			   }   
		}
		if(msgtype == DHCP_OFFER_MESSAGE)
		{
			for(i=0;i<4;++i)
				{
					svridc = tempsvridc;
				}
			set_offerrec;

		}
		else
		{
			if( svridc[0] != tempsvridc[0] ||
				svridc[1] != tempsvridc[1] ||
				svridc[2] != tempsvridc[2] ||
				svridc[3] != tempsvridc[3] )
				{
					msgtype = DHCP_UNKNOWN_MESSAGE;
				}

	}
	if(btrashit)
		clr_newdhcppkt;

	return msgtype;			   
}
//******************************************************************
//*	Perform ARP Request
//*   This routine uses a known remote IP address to get a remote
//*   Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_request(void)
{
	//char temp;
	unsigned int i,tx_end;	

	clr_arpflag;
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;
   //build destination MAC address	
	for(i=0;i<6;++i)
	{
   		wr_sram(0xFF);
		++tx_end;
	}
   //build source MAC address	
 	for(i=0;i<6;++i)
	{
		  wr_sram(macaddrc);
		++tx_end;
	}

	wr_sram(0x08);		//ARP packet type
	wr_sram(0x06);		
	tx_end +=2;
	wr_sram(0x00);		//hardware type = 10Mb Ethernet
	wr_sram(0x01);		
	tx_end +=2;
	wr_sram(0x08);		//IP protocol
	wr_sram(0x00);		
	tx_end +=2;
	wr_sram(0x06); 	 	//hardware addr len (06)
	wr_sram(0x04); 	 	//hardware protocol addr len(04)
	tx_end +=2;
	wr_sram(0x00);		//ARP request
	wr_sram(0x01);		
	tx_end += 2;
   //build source MAC address	
	for(i=0;i<6;++i)
	{
   		wr_sram(macaddrc);
		++tx_end;
	}
   //build source IP address	
	for(i=0;i<4;++i)
	{
   		wr_sram(ipaddrc);
		++tx_end;
	}
   //build unknown target MAC address area	
	for(i=0;i<6;++i)
	{
   		wr_sram(0x00);
		++tx_end;
	}
   //build target IP address	
	for(i=0;i<4;++i)
	{
   		wr_sram(remoteipaddrc);
		++tx_end;
	}
   //mark end of ARP request packet	
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);
   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	//do{
		//temp =  ECON1);
	while((ECON1 & ECON1_TXRTS) == 1);

	if(EIR & EIR_TXERIF == 1)
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	//TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	//++tx_end;
	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);

	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if((temp & ESTAT_TXABRT) == 1)
	   //printf("\r\nARP Request Transmission Aborted..");
	//else
	   //printf("\r\nARP Request Sent..");
 }

//******************************************************************
//*	Perform ARP Response
//*   This routine supplies a requesting computer with the
//*   Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_reply(void)
{
	unsigned int tx_end,i;	
	char temp;

	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

   //write destination MAC address
   for(i=0;i<6;++i)
   {	
	  wr_sram(packet[enetpacketSrc0+i]);
	  ++tx_end;
	}

   //write source MAC address
   for(i=0;i<6;++i)
	{
	  wr_sram(macaddrc);
	  ++tx_end;
	}

   //write typelen hwtype prtype hwlen prlen op:
   addr = &packet[enetpacketType0];
   packet[arp_op+1] = 0x02;
   for(i=0;i<10;++i)
	{
	  wr_sram(*addr++);
	  ++tx_end;
	}
   //write ethernet module MAC address
   for(i=0;i<6;++i)
	{
	  wr_sram(macaddrc);
	  ++tx_end;
	}
   //write ethernet module IP address
	  for(i=0;i<4;++i)
	   {
		   wr_sram(ipaddrc);
		 ++tx_end;
		}

   //write remote MAC address
   for(i=0;i<6;++i)
	{
	  wr_sram(packet[enetpacketSrc0+i]);
	  ++tx_end;
	}

   //write remote IP address
   for(i=0;i<4;++i)
	{
	  wr_sram(packet[arp_sipaddr+i]);
	  ++tx_end;
	}
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //send the contents of the transmit buffer onto the network
	//temp =  EIR;
	//if((temp & EIR_TXERIF) == 1)
	if(TXERIF)
	{
	 TXERIF = 0;
	 TXRST = 1;
   	 TXRST = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
		//temp =  ECON1);
		//}while((temp & ECON1_TXRTS) == 1);
//	while(1 == (ECON1 & ECON1_TXRTS));
	while(TXRTS);
	++tx_end;
	//banksel(ERDPTL);
	ERDPTL= LOW_BYTE(tx_end);
	ERDPTH= HIGH_BYTE(tx_end);

	//banksel(ERDPTL);
	//ERDPTL= 0x00;
	//ERDPTH= 0x00;
	for(i=0;i<7;++i)	
		tx_status= rd_sram();
	//temp =  ESTAT;
	//if((temp & ESTAT_TXABRT) == 1)
	if(TXABRT)
	   printf("\r\nARP Reply Transmission Aborted..");
	//else
	   //printf("\r\nARP Reply Sent..");

 }
//******************************************************************
//*	Application Code
//*   Your application code goes here.
//******************************************************************
void application_code()
{
   char i,j;

   if (aux_data[0] == 0x0D)
	  {
		 j = sizeof(telnet_banner);
		 for(i=0;i<j;++i)
		  packet[TCP_data+i] = telnet_banner;
		 tcpdatalen_out = j;
	  }

   else
	  tcpdatalen_out = tcpdatalen_in;
}

//******************************************************************
//*	TCP Function
//*   This function uses TCP protocol to act as a Telnet server on
//*   port 8088 decimal.  The application function is called with
//*   every incoming character.
//******************************************************************
void tcp()
{
	char *bufferptr,temp,i,j;
	unsigned int buffer_addr,tx_end,tx_cnt;

   //assemble the destination port address from the incoming packet
   portaddr = make16(packet[TCP_destport],packet[TCP_destport+1]);

   //calculate the length of the data coming in with the packet
   //tcpdatalen_in = incoming packet length - incoming ip header length - incoming tcp header length
   tcpdatalen_in = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4) - (((packet[TCP_hdrflags] & 0xF0) >> 4) * 4);

   //If an ACK is recieved and the destination port address is valid and no data is in the packet
   if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in == 0x00)
   {
	  //assemble the acknowledgment number from the incoming packet
	  incoming_ack = make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);

	  //if the incoming packet is a result of session establishment
	  if(bsynflag)
	  {
		 //clear the SYN flag
		 //the incoming acknowledgment is my new sequence number
		 clr_synflag;

		 my_seqnum = incoming_ack;

		 //send the Telnet server banner
		 //limit the character count to 40 decimal
				j = sizeof(telnet_banner);
				for(i=0;i<j;++i)
 				  packet[TCP_data+i] = telnet_banner;
		 //length of the banner message
		 	   tcpdatalen_out = j;

		 //expect to get an acknowledgment of the banner message
		 expected_ack = my_seqnum +tcpdatalen_out;

		 //send the TCP/IP packet
		 send_tcp_packet();
	  }
   }

   //if an ack is received and the port address is valid and there is data in the incoming packet
   if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in)
   {
	  for(i=0;i<tcpdatalen_in;++i)
	  {
		 //receive the data and put it into the incoming data buffer
		 aux_data = packet[TCP_data+i];

		 //run the TCP application
		 application_code();
	  }

	  //assemble the acknowledgment number from the incoming packet
	  incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);

	  //check for the number of bytes acknowledged
	  //determine how many bytes are outstanding and adjust the outgoing sequence number accordingly
	  if(incoming_ack <= expected_ack)
		 my_seqnum = expected_ack - (expected_ack - incoming_ack);

	  //my expected acknowledgement number
	  expected_ack = my_seqnum +tcpdatalen_out;


	  send_tcp_packet();
   }

   //this code segment processes the incoming SYN from the Telnet client
   //and sends back the initial sequence number (ISN) and acknowledges
   //the incoming SYN packet
   if(SYN_IN && portaddr == MY_PORT_ADDRESS)
   {
	  tcpdatalen_in = 0x01;
	  set_synflag;

	  setipaddrs();

	  temp = packet[TCP_srcport];
	  packet[TCP_srcport] = packet[TCP_destport];
	  packet[TCP_destport] = temp;

	  temp = packet[TCP_srcport+1];
	  packet[TCP_srcport+1] = packet[TCP_destport+1];
	  packet[TCP_destport+1] = temp;

	  assemble_ack();

	  if(++ISN == 0x0000 || ++ISN == 0xFFFF)
		 ISN = 0x1234;
	  my_seqnum = make32i(ISN,0xFFFF);

	  set_packet32(TCP_seqnum,my_seqnum);

	  packet[TCP_hdrflags+1] = 0x00;
	  SYN_OUT;
	  ACK_OUT;

	  packet[TCP_cksum] = 0x00;
	  packet[TCP_cksum+1] = 0x00;

	  hdr_chksum =0;
	  hdrlen = 0x08;
	  addr = &packet[ip_srcaddr];
	  cksum();
	  hdr_chksum = hdr_chksum + packet[ip_proto];
	  tcplen = make16(packet[ip_pktlen],packet[ip_pktlen+1]) - ((packet[ip_vers_len] & 0x0F) * 4);
	  hdr_chksum = hdr_chksum + tcplen;
	  hdrlen = tcplen;
	  addr = &packet[TCP_srcport];
	  cksum();
	  chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
	  packet[TCP_cksum] = make8(chksum16,1);
	  packet[TCP_cksum+1] = make8(chksum16,0);

	  tx_end = TXSTART;
	  //load beginning page for transmit buffer
	  //banksel(EWRPTL);
	  EWRPTL = LOW_BYTE(TXSTART);
	  EWRPTH = HIGH_BYTE(TXSTART);

	 //write control byte
	  wr_sram(tx_control_byte);
	  ++tx_end;

	tx_end = tx_end + rxlen;
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

	tx_cnt = tx_end - TXSTART;

   //for(buffer_addr=0;buffer_addr<tx_cnt;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_cnt)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_cnt--;
	};	

   //send the contents of the transmit buffer onto the network
	//temp =  EIR;
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
	   TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	while(1 ==(ECON1 & ECON1_TXRTS));	
	//++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if(1 ==( ESTAT) & ESTAT_TXABRT))
	   printf("\r\nTCP Transmission Aborted..");
	//else
	   //printf("\r\nTCP Message Sent..");
   }

   //this code segment processes a FIN from the Telnet client
   //and acknowledges the FIN and any incoming data.
   if(FIN_IN && portaddr == MY_PORT_ADDRESS)
   {
	  if(tcpdatalen_in)
	  {
		 for(i=0;i<tcpdatalen_in;++i)
		 {
			aux_data = packet[TCP_data+i];
			application_code();
		 }
	  }

	  set_finflag;

	  ++tcpdatalen_in;

	  incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
	  if(incoming_ack <= expected_ack)
		 my_seqnum = expected_ack - (expected_ack - incoming_ack);

	  expected_ack = my_seqnum +tcpdatalen_out;
	  send_tcp_packet();

   }
}
//******************************************************************
//*	Assemble the Acknowledgment
//*   This function assembles the acknowledgment to send to
//*   to the client by adding the received data count to the
//*   client's incoming sequence number.
//******************************************************************
void assemble_ack()
{
   client_seqnum=make32(packet[TCP_seqnum],packet[TCP_seqnum+1],packet[TCP_seqnum+2],packet[TCP_seqnum+3]);
   client_seqnum = client_seqnum + tcpdatalen_in;
   set_packet32(TCP_acknum,client_seqnum);
}
//******************************************************************
//*	Send TCP Packet
//*   This routine assembles and sends a complete TCP/IP packet.
//*   40 bytes of IP and TCP header data is assumed.
//******************************************************************
void send_tcp_packet()
{
	char temp,i,*bufferptr;
	unsigned int buffer_addr,tx_end,tx_cnt;

   //count IP and TCP header bytes.. Total = 40 bytes
   ip_packet_len = 40 + tcpdatalen_out;
   packet[ip_pktlen] = make8(ip_packet_len,1);
   packet[ip_pktlen+1] = make8(ip_packet_len,0);
   setipaddrs();

   temp = packet[TCP_srcport];
   packet[TCP_srcport] = packet[TCP_destport];
   packet[TCP_destport] = temp;
   temp = packet[TCP_srcport+1];
   packet[TCP_srcport+1] = packet[TCP_destport+1];
   packet[TCP_destport+1] = temp;

   assemble_ack();
   set_packet32(TCP_seqnum,my_seqnum);


   packet[TCP_hdrflags+1] = 0x00;
   ACK_OUT;
   if(bfinflag)
   {
	  FIN_OUT;
	  clr_finflag;
   }

   packet[TCP_cksum] = 0x00;
   packet[TCP_cksum+1] = 0x00;

   hdr_chksum =0;
   hdrlen = 0x08;
   addr = &packet[ip_srcaddr];
   cksum();
   hdr_chksum = hdr_chksum + packet[ip_proto];
   tcplen = ip_packet_len - ((packet[ip_vers_len] & 0x0F) * 4);
   hdr_chksum = hdr_chksum + tcplen;
   hdrlen = tcplen;
   addr = &packet[TCP_srcport];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[TCP_cksum] = make8(chksum16,1);
   packet[TCP_cksum+1] = make8(chksum16,0);

   txlen = ip_packet_len + 14;
   if(txlen < 60)
	  txlen = 60;
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

	tx_end = tx_end + txlen;
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

	tx_cnt = tx_end - TXSTART;

   //for(buffer_addr=0;buffer_addr<tx_cnt;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_cnt)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_cnt--;
	};	

   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while(1 == temp & ECON1_TXRTS));
	while(1 == (ECON1 & ECON1_TXRTS));
	//++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if(1 == ( ESTAT) & ESTAT_TXABRT))
	   //printf("\r\nTransmission Aborted..");
	//else
	   //printf("\r\nTCP Message Sent..");
}

//******************************************************************
//*	init_udp Function
//*   This function sends UDP packet
//******************************************************************
void send_udp_datagram()
{
	char *bufferptr,temp;
	unsigned int buffer_addr,i,tx_end,tx_cnt;	

	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write ENC28J60 control byte
	wr_sram(tx_control_byte);
	++tx_end;
   //build destination MAC address	
   	udp_packet[enetpacketDest0]=remotemacaddrc[0];
   	udp_packet[enetpacketDest1]=remotemacaddrc[1];
   	udp_packet[enetpacketDest2]=remotemacaddrc[2];
   	udp_packet[enetpacketDest3]=remotemacaddrc[3];
   	udp_packet[enetpacketDest4]=remotemacaddrc[4];
   	udp_packet[enetpacketDest5]=remotemacaddrc[5];
	tx_end += 6;
   //build source MAC address	
   	udp_packet[enetpacketSrc0]=macaddrc[0];
   	udp_packet[enetpacketSrc1]=macaddrc[1];
   	udp_packet[enetpacketSrc2]=macaddrc[2];
   	udp_packet[enetpacketSrc3]=macaddrc[3];
   	udp_packet[enetpacketSrc4]=macaddrc[4];
   	udp_packet[enetpacketSrc5]=macaddrc[5];
	tx_end += 6;
   //build packet type (IP)	
	udp_packet[enetpacketType0] = 0x08;
	udp_packet[enetpacketType1] = 0x00;
	tx_end += 2;
   //build version, length,tos,packet length
	udp_packet[ip_vers_len] = 0x45;
	udp_packet[ip_tos] = 0x00;
	udp_packet[ip_pktlen] = 0x00;
	udp_packet[ip_pktlen+1] = 0x24;
	tx_end += 4;
   //build packet ID	
	++cntri;
	udp_packet[ip_id] = make8(cntri,0);
	udp_packet[ip_id+1] = make8(cntri,1);
	tx_end += 2;
   //build fragment offset	
	udp_packet[ip_frag_offset] = 0x00;
	udp_packet[ip_frag_offset+1] = 0x00;
	tx_end += 2;
   //build time to live, UDP protocol ID	
	udp_packet[ip_ttl] = 0x80;
	udp_packet[ip_proto] = 0x11;
   //build IP source and destination addresses
	for(i=0;i<4;++i)
	{
   		udp_packet[ip_srcaddr+i]=ipaddrc;
   		udp_packet[ip_destaddr+i]=remoteipaddrc;
		tx_end += 2;
	}
   	//calculate the IP header checksum
   	udp_packet[ip_hdr_cksum]=0x00;
   	udp_packet[ip_hdr_cksum+1]=0x00;
   	hdr_chksum =0;
   	hdrlen = (udp_packet[ip_vers_len] & 0x0F) * 4;
   	addr = &udp_packet[ip_vers_len];
   	cksum();
   	chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   	udp_packet[ip_hdr_cksum] = make8(chksum16,1);
   	udp_packet[ip_hdr_cksum+1] = make8(chksum16,0);
	tx_end += 4;
   //build UDP source port address
   	udp_packet[UDP_srcport] = 0x13;
   	udp_packet[UDP_srcport+1] = 0x88;
	tx_end += 2;
   //build UDP destination port address
   	udp_packet[UDP_destport] = 0x00;
   	udp_packet[UDP_destport+1] = 0x07;
	tx_end += 2;
   //build UDP packet length
	udp_packet[UDP_len] = 0x00;
	udp_packet[UDP_len+1] = 0x10;
	tx_end += 2;
	//udp_packet[UDP_cksum] goes here
	tx_end += 2;
   //UDP data goes here
	for(i=0;i<8;++i)
	 udp_packet[UDP_data+i] = 0x30 + i;
	tx_end += 8;
	 //calculate the UDP checksum
	 udp_packet[UDP_cksum] = 0x00;
	 udp_packet[UDP_cksum+1] = 0x00;
	 hdr_chksum =0;
	 hdrlen = 0x08;
	 addr = &udp_packet[ip_srcaddr];
	 cksum();
	 hdr_chksum = hdr_chksum + udp_packet[ip_proto];
	 hdrlen = 0x02;
	 addr = &udp_packet[UDP_len];
	 cksum();
	 hdrlen = make16(udp_packet[UDP_len],udp_packet[UDP_len+1]);
	 addr = &udp_packet[UDP_srcport];
	 cksum();
	 chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
	 udp_packet[UDP_cksum] = make8(chksum16,1);
	 udp_packet[UDP_cksum+1] = make8(chksum16,0);
   //mark end of UDP datagram
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);
	tx_cnt = tx_end - TXSTART;
   //write UDP datagram to ENC28J60 Transmit Buffer
   //for(buffer_addr=0;buffer_addr<tx_cnt+1;++buffer_addr)
	  //wr_sram(udp_packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_cnt)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_cnt--;
	};	

   //send the contents of the transmit buffer onto the network
//	temp =  EIR);
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
	++tx_end;

	//banksel(ERDPTL);
	ERDPTL= LOW_BYTE(tx_end);
	ERDPTH= HIGH_BYTE(tx_end);
	for(i=0;i<7;++i)	
		tx_status= rd_sram();
	//temp =  ESTAT);
	if(1 == (ESTAT & ESTAT_TXABRT))
	   printf("\r\nUDP Datagram Transmission Aborted..");
	else
	   //printf("\r\nUDP Message Sent..");
	   ++udpcnt;
}
//******************************************************************
//*	UDP Function
//*   This function uses a Visual Basic UDP program to echo the
//*   data back to the VB program .
//******************************************************************
void udp()
{
	unsigned int buffer_addr,i,tx_end;	
	char *bufferptr,temp;

   //port 7 is the well-known echo port
   if(packet[UDP_destport] == 0x00 && packet[UDP_destport+1] ==0x07)
   {
	  //build the IP header
	  setipaddrs();

	  //swap the UDP source and destination ports
	  temp = packet[UDP_srcport];
	  packet[UDP_srcport] = packet[UDP_destport];
	  packet[UDP_destport] = temp;

	  temp = packet[UDP_srcport+1];
	  packet[UDP_srcport+1] = packet[UDP_destport+1];
	  packet[UDP_destport+1] = temp;

	  //calculate the UDP checksum
	  packet[UDP_cksum] = 0x00;
	  packet[UDP_cksum+1] = 0x00;

	  hdr_chksum =0;
	  hdrlen = 0x08;
	  addr = &packet[ip_srcaddr];
	  cksum();
	  hdr_chksum = hdr_chksum + packet[ip_proto];
	  hdrlen = 0x02;
	  addr = &packet[UDP_len];
	  cksum();
	  hdrlen = make16(packet[UDP_len],packet[UDP_len+1]);
	  addr = &packet[UDP_srcport];
	  cksum();
	  chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
	  packet[UDP_cksum] = make8(chksum16,1);
	  packet[UDP_cksum+1] = make8(chksum16,0);

	  //echo the incoming data back to the VB program
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

	tx_end = tx_end + make16(packetheader[rec_bytecnt_high],packetheader[rec_bytecnt_low] - 4);
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

   //for(buffer_addr=0;buffer_addr<tx_end;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

	bufferptr = packet;
	while(tx_end)
	{
		EDATA = *bufferptr;
		bufferptr++;
		tx_end--;
	};	

   //send the contents of the transmit buffer onto the network
	temp =  EIR;
	if(1 == (EIR & EIR_TXERIF))
	{
	 TXERIF = 0;
	 TXRTS = 1;
   	 TXRTS = 0;
	}
	TXIF = 0;
   	TXRTS = 1;
	//do{
	//	temp =  ECON1);
	//	}while((temp & ECON1_TXRTS) == 1);
	while(1 == (ECON1 & ECON1_TXRTS));
	//++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if(1 == ( ESTAT) & ESTAT_TXABRT))
	   //printf("\r\nUDP Echo Transmission Aborted..");
	//else
	   //printf("\r\nUDP Message Sent..");
}
	//else
		//LATD6 = 1;

}
//******************************************************************
//*	Perform ICMP Function
//*   This routine responds to a ping.
//******************************************************************
void icmp(void)
{ 
	unsigned int buffer_addr,i,tx_end;	
	char temp,*bufferptr;
   //set echo reply
   packet[ICMP_type]=0x00;
   packet[ICMP_code]=0x00;

   //clear the ICMP checksum
   packet[ICMP_cksum]=0x00;
   packet[ICMP_cksum+1]=0x00;

   //setup the IP header
   setipaddrs();

   //calculate the ICMP checksum
   hdr_chksum =0;
   hdrlen = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4);
   addr = &packet[ICMP_type];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[ICMP_cksum] = make8(chksum16,1);
   packet[ICMP_cksum+1] = make8(chksum16,0);
  /* 
   //calculate the ICMP checksum
   hdrlen = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4);
   addr = &packet[ICMP_type];
   //banksel(EDMASTL);
   EDMASTL = LOW_BYTE((unsigned int) addr));
   EDMASTH = HIGH_BYTE((unsigned int) addr));
   //debuggc[1] =  EDMASTL);
   //debuggc [0]=  EDMASTH);
   buffer_addr = ((unsigned int) addr + hdrlen)-1;
   EDMANDL = LOW_BYTE(buffer_addr));
   EDMANDH = HIGH_BYTE(buffer_addr));
   //debuggc[3] =  EDMANDL);
   //debuggc[2] =  EDMANDH);
   ECON1 |= 0x30);
   while(ECON1 & 0x20);
   packet[ICMP_cksum] =  EDMACSH);
   packet[ICMP_cksum+1] =  EDMACSL);
  */	
   //send the ICMP packet along on its way
	tx_end = TXSTART;
   //load beginning page for transmit buffer
	//banksel(EWRPTL);
	EWRPTL = LOW_BYTE(TXSTART);
	EWRPTH = HIGH_BYTE(TXSTART);

   //write control byte
	wr_sram(tx_control_byte);
	++tx_end;

	tx_end = (tx_end) + make16(packetheader[rec_bytecnt_high],packetheader[rec_bytecnt_low] - 4);//4 is checksum of incoming packet
	//banksel(ETXNDL);
	ETXNDL = LOW_BYTE(tx_end);
	ETXNDH = HIGH_BYTE(tx_end);

	bufferptr = packet;
	while(tx_end--)
	{
		EDATA = *bufferptr++;
		//bufferptr++;
	//	tx_end--;
	};	

   //for(buffer_addr=0;buffer_addr<tx_end;++buffer_addr)
	  //wr_sram(packet[enetpacketDest0 + buffer_addr]);

   //send the contents of the transmit buffer onto the network
	//temp =  EIR);
	//if(1 == (EIR & EIR_TXERIF))
	if(TXERIF)
	{
	 TXERIF = 0;
	 TXRST = 1;
   	 TXRST = 0;
	}
	  TXRTS = 1;
//	++tx_end;

	////banksel(ERDPTL);
	//ERDPTL= LOW_BYTE(tx_end);
	//ERDPTH= HIGH_BYTE(tx_end);
	//for(i=0;i<7;++i)	
		//tx_status= rd_sram();
	//temp =  ESTAT);
	//if((temp & ESTAT_TXABRT) == 1)
	 //  printf("\r\nICMP Transmission Aborted..");
	//else
	 //  printf("\r\nICMP Message Sent..");
}

//******************************************************************
//*	SETIPADDRS
//*   This function builds the IP header.
//******************************************************************
void setipaddrs()
{
   //move IP source address to destination address
   packet[ip_destaddr]=packet[ip_srcaddr];
   packet[ip_destaddr+1]=packet[ip_srcaddr+1];
   packet[ip_destaddr+2]=packet[ip_srcaddr+2];
   packet[ip_destaddr+3]=packet[ip_srcaddr+3];
   //make ethernet module IP address source address
   packet[ip_srcaddr]=ipaddrc[0];
   packet[ip_srcaddr+1]=ipaddrc[1];
   packet[ip_srcaddr+2]=ipaddrc[2];
   packet[ip_srcaddr+3]=ipaddrc[3];
   //move hardware source address to destinatin address
   packet[enetpacketDest0]=packet[enetpacketSrc0];
   packet[enetpacketDest1]=packet[enetpacketSrc1];
   packet[enetpacketDest2]=packet[enetpacketSrc2];
   packet[enetpacketDest3]=packet[enetpacketSrc3];
   packet[enetpacketDest4]=packet[enetpacketSrc4];
   packet[enetpacketDest5]=packet[enetpacketSrc5];
   //make ethernet module mac address the source address
   packet[enetpacketSrc0]=macaddrc[0];
   packet[enetpacketSrc1]=macaddrc[1];
   packet[enetpacketSrc2]=macaddrc[2];
   packet[enetpacketSrc3]=macaddrc[3];
   packet[enetpacketSrc4]=macaddrc[4];
   packet[enetpacketSrc5]=macaddrc[5];

   //calculate the IP header checksum
   packet[ip_hdr_cksum]=0x00;
   packet[ip_hdr_cksum+1]=0x00;

   hdr_chksum =0;
   hdrlen = (packet[ip_vers_len] & 0x0F) * 4;
   addr = &packet[ip_vers_len];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[ip_hdr_cksum] = make8(chksum16,1);
   packet[ip_hdr_cksum+1] = make8(chksum16,0);
 }
//******************************************************************
//*	CHECKSUM CALCULATION ROUTINE
//******************************************************************
void cksum()
{
	  while(hdrlen > 1)
	  {
		 data_H=*addr++;
		 data_L=*addr++;
		 chksum16=make16(data_H,data_L);
		 hdr_chksum = hdr_chksum + chksum16;
		 hdrlen -=2;
	  }
	  if(hdrlen > 0)
	  {
		 data_H=*addr;
		 data_L=0x00;
		 chksum16=make16(data_H,data_L);
		 hdr_chksum = hdr_chksum + chksum16;
	  }
}

void putch(unsigned char c)
{
   while(!TRMT) 	// TRMT1 is set when TSR is empty
	  continue;

  TXREG1 = c;		// load the register
}

//******************************************************************
//*	Init USART Function
//******************************************************************
void init_EUSART(void)
{
  //BRG16 = 0;
  BRGH = 1;
  SYNC = 0;

  SPBRG1 = DIVIDER;	//load baud rate divisor	
  TRISC7 = 1;			//receive pin
  TRISC6 = 1;			//transmit pin
  TXSTA1 = 0x04;		//high speed baud rate	
  RCSTA1 = 0x80;		//enable serial port and serial port pins


  USART_RxTail = 0x00;	//flush receive buffer 
  USART_RxHead = 0x00;
  USART_TxTail = 0x00;	//flush transmit buffer
  USART_TxHead = 0x00;
  RC1IP = 1;			//receive interrupt = high priority
  TX1IP = 1;			//transmit interrupt = high priority
  RC1IE = 1;			//enable receive interrupt
  PEIE = 1;				//enable all unmasked peripheral interrupts
  GIE = 1;				//enable all unmasked interrupts
  CREN = 1;			//enable USART1 receiver
  TX1IE = 0;			//disable USART1 transmit interrupt
  TXEN = 1;			//transmitter enabled
  SPEN = 1;
}

void interrupt USART(void)
{
  unsigned char data,tmphead,tmptail;
/*
//USE WITH 32KHz CLOCK ONLY
  if((TMR1IF) && (TMR1IE))
   {
		TMR1H = 0x80;
		TMR1IF = 0;
		if(60 == ++secs)
		 {
			secs = 0;
		 	++mins;
		 }
		if(60 == mins)
		 {
			mins = 0;
			++hours;
		 }
		if(24 == hours)
		 {
			hours = 0;
		 }
		 ++secs_timer;
		 ++lease_timer;
	}

*/
  if((TMR2IF) && (TMR2IE))
   {
		TMR2IF = 0;
		++msecs_timer;
	 	//LED0 ^= 1;
		if(1000 == ++clock_timer)
		 {
			clock_timer = 0;
			++secs;
			++secs_timer;
			++lease_timer;
		 }
		if(60 == secs)
		 {
			secs = 0;
		 	++mins;
		 }
		if(60 == mins)
		 {
			mins = 0;
			++hours;
		 }
		if(24 == hours)
		 {
			hours = 0;
		 }

   }

  if(RC1IF)
 {
   data = RCREG1;				   // read the received data 
								// calculate buffer index 
   tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;
   USART_RxHead = tmphead;		// store new index 

   if ( tmphead == USART_RxTail )
   {
	 // ERROR! Receive buffer overflow 
   }

   USART_RxBuf[tmphead] = data;   // store received data in buffer 
  }


  if(TRMT)
  {
								// check if all data is transmitted  
   if ( USART_TxHead != USART_TxTail )
   {
								// calculate buffer index  
	 tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
	 USART_TxTail = tmptail;	  // store new index  

	TXREG1 = USART_TxBuf[tmptail];  // start transmition  
   }
   else
   {
	 TX1IE = 0;		 // disable TX interrupt  
   }
  }
}

int recvchar(void)
{
  unsigned char tmptail;
								// wait for incomming data  
  while ( USART_RxHead == USART_RxTail );
								// calculate buffer index  
  tmptail = ( USART_RxTail + 1 ) & USART_RX_BUFFER_MASK;
  USART_RxTail = tmptail;		// store new index  

  return USART_RxBuf[tmptail];   // return data  
}

int sendchar(int data)
{
  unsigned char tmphead;
								// calculate buffer index 
  tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK;
								// wait for free space in buffer 
  while ( tmphead == USART_TxTail );
								// store data in buffer 
  USART_TxBuf[tmphead] = (unsigned char)data;
  USART_TxHead = tmphead;		// store new index 

  TX1IE = 1;			// enable TX interrupt 

  return data;
}

unsigned char CharInQueue(void)
{
  return(USART_RxHead != USART_RxTail);
}

unsigned int rd_phy(char reg)
{
	unsigned int rc;
	char low,high;
	// Set the right address and start the register read operation
	MIREGADR = reg;
	NOP();
	MICMD = MICMD_MIIRD;
	NOP();	
	// Loop to wait until the PHY register has been read through the MII
	while(BUSY);
	// Stop reading
	MICMD = 0x00;
	NOP();	
	// Obtain results and return
	low = MIRDL;
	high = MIRDH;
	rc = (high << 8) | low;
	return rc;
}

void wr_phy(char reg, unsigned int data)
{
	// Write the register address
	MIREGADR = reg;
	NOP();
	// Write the data
	// Order is important: write low byte first, high byte last
	MIWRL = LOW_BYTE(data);
	NOP();
	MIWRH = HIGH_BYTE(data);
	NOP();
	// Wait until the PHY register has been written
	while(BUSY);
}

void init_EEPROM(void)
{
	SSP1STAT = 0b01000000;
	SSP1CON1 = 0x21;
}

void init_67J60(void)
{
	char x;

	TRISA = 0b11111100;
	TRISB = 0b11111111;
	TRISC = 0b01010111;
	TRISD = 0b11111011;
	TRISF = 0x00;
	LATF = 0xFF;
	//Enable Ethernet
	ETHEN = 1;

	while(!PHYRDY);

	msecs_timer = 0;
	clock_timer = 0;
	while(msecs_timer < 2);
	LATF = 0x00;

	RXEN = 0;
   	TXRTS = 0;

	packetheader[nextpacket_low] = LOW_BYTE(RXSTART);
	packetheader[nextpacket_high] = HIGH_BYTE(RXSTART);

	//ERDPTL =  LOW_BYTE(RXSTART);
	//ERDPTH = HIGH_BYTE(RXSTART);

	ERXSTL = LOW_BYTE(RXSTART);
	ERXSTH = HIGH_BYTE(RXSTART);
	ERXRDPTL = LOW_BYTE(RXSTOP);
	ERXRDPTH = HIGH_BYTE(RXSTOP);
	ERXNDL = LOW_BYTE(RXSTOP);
	ERXNDH = HIGH_BYTE(RXSTOP);
	ETXSTL =  LOW_BYTE(TXSTART);
	ETXSTH =  HIGH_BYTE(TXSTART);

	MACON1 =  MACON1_TXPAUS | MACON1_RXPAUS | MACON1_MARXEN;
	NOP();
	// Pad packets to 60 bytes, add CRC, and check Type/Length field
	MACON3 =  MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN;
	NOP();
	// Allow infinite deferals if the medium is continuously busy 
	// (do not time out a transmission if the half duplex medium is 
	// completely saturated with other people's data)
	MACON4 =  MACON4_DEFER;
	NOP();

	// Late collisions occur beyond 63 bytes (default for 802.3 spec)
	MACLCON2 =  63;
	NOP();

	MAIPGL =  0x12;
	NOP();
	MAIPGH =  0x0C;
	NOP();
	MAMXFLL =  LOW_BYTE(MAXFRAME);	
	NOP();
	MAMXFLH =  HIGH_BYTE(MAXFRAME);
	NOP();

	MAADR1 =  macaddrc[0];
	NOP();
	MAADR2 =  macaddrc[1];
	NOP();
	MAADR3 =  macaddrc[2];
	NOP();
	MAADR4 =  macaddrc[3];
	NOP();
	MAADR5 =  macaddrc[4];
	NOP();
	MAADR6 =  macaddrc[5];
	NOP();

	wr_phy(PHCON2, 0x0110);
	wr_phy(PHCON1,0x0000);

	wr_phy(PHLCON, 0x0472);	

	// Set the back-to-back inter-packet gap time to IEEE specified 
	// requirements.  The meaning of the MABBIPG value changes with the duplex
	// state, so it must be updated in this function.
	// In full duplex, 0x15 represents 9.6us; 0x12 is 9.6us in half duplex

	MABBIPG = 0x12;	

	// Enable packet reception
	RXEN =1;
	EIE = 0x00;
	/*
	debugi = rd_phy(PHCON2);
	NOP();
	debugi = rd_phy(PHCON1);
	NOP();
	debugi = rd_phy(PHLCON);
   */
	printf("\r\n67J60 Initialized\r\n");
}
//******************************************************************
//*	Get A Frame From the Buffer
//*   This routine removes an Ethernet frame from the receive buffer
//*   ring.
//******************************************************************
void get_frame()
{
	unsigned int i;
	char *bufferptr;

	//banksel(ERDPTL);
	ERDPTL = packetheader[nextpacket_low];
	ERDPTH = packetheader[nextpacket_high];

	bufferptr = packetheader;
	bufferptr--;
	i = 0;
	while(i<6)
	{
		bufferptr++;
		i++;
		*bufferptr = EDATA;
	};

	rxlen = make16(packetheader[rec_bytecnt_high],packetheader[rec_bytecnt_low]);

	bufferptr = packet;
	bufferptr--;
	i = rxlen;
	while(i)
	{
		bufferptr++;
		i--;
		*bufferptr = EDATA;
	};

	new_rdptr = (make16(packetheader[nextpacket_high],packetheader[nextpacket_low]));
	--new_rdptr;
//	if((new_rdptr < RXSTART) || (new_rdptr > RXSTOP))
	if((new_rdptr > 8191) || (new_rdptr > RXSTOP))
		new_rdptr = RXSTOP;

	ECON2 |= ECON2_PKTDEC;

	//banksel(ERXRDPTL);
	ERXRDPTL = LOW_BYTE(new_rdptr);
	ERXRDPTH = HIGH_BYTE(new_rdptr);

   	//process an incoming ARP request packet
   	if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x06)
   	  {
	   if(packet[arp_hwtype+1] == 0x01 &&
	   packet[arp_prtype] == 0x08 && 
	   packet[arp_prtype+1] == 0x00 &&
	   packet[arp_hwlen] == 0x06 && 
	   packet[arp_prlen] == 0x04 &&
	   //packet[arp_op+1] == 0x01 &&
	   packet[arp_tipaddr]   == ipaddrc[0] &&
	   packet[arp_tipaddr+1] == ipaddrc[1] &&
	   packet[arp_tipaddr+2] == ipaddrc[2] &&
	   packet[arp_tipaddr+3] == ipaddrc[3])
	  {
		switch(packet[arp_op+1])
		{
			case 0x01:
				arp_reply();
				break;
			case 0x02:
	   			for(i=0;i<6;i++)
		 		 remotemacaddrc = packet[arp_shaddr+i];
				set_arpflag;
				break;
		}		
	  }	
	 }

   	//process an IP packet
   	else if(packet[enetpacketType0] == 0x08	&& 
		  packet[enetpacketType1] == 0x00 	   &&
		  packet[ip_destaddr]   == ipaddrc[0]  &&
		  packet[ip_destaddr+1] == ipaddrc[1]  &&
		  packet[ip_destaddr+2] == ipaddrc[2]  &&
		  packet[ip_destaddr+3] == ipaddrc[3])
	{
	  switch(packet[ip_proto])
	  {
		  case PROT_ICMP:
			  icmp();
		  break;
		  case PROT_UDP:
			  if(packet[UDP_srcport] == DHCP_SERVER_PORT)
			   dhcp_state_engine();
			  else
			   udp();
		  break;
		  case PROT_TCP:
			   tcp();
		  break;
		  default:
		 	LED0 = 1;
		  break;
		 }
		}
   	//process a DHCP message
   	else if(packet[enetpacketType0] == 0x08	&& 
		  packet[enetpacketType1] == 0x00 	   &&
		  packet[ip_destaddr]   == 0xFF  &&
		  packet[ip_destaddr+1] == 0xFF  &&
		  packet[ip_destaddr+2] == 0xFF  &&
		  packet[ip_destaddr+3] == 0xFF	 &&
		  packet[ip_proto] == PROT_UDP)
	{
			 set_newdhcppkt;
			   dhcp_state_engine();
	}

}
//char revid;
void main(void)
{
	char old_secs;

	OSCTUNE = 0x40;

//******************************************************************
//*	CONFIGURE AND START TIMER1
//* SET TO OVERFLOW EVERY 1S
//* USE WITH 32KHz CLOCK ONLY
//******************************************************************
	TMR1ON = 0;
	//TMR1H = 0x80;
	//TMR1L = 0x00;
	//T1CON = 0b00001110;
	//TMR1IE = 1;
	//TMR1ON = 1;
//******************************************************************
//*	CONFIGURE AND START TIMER2
//* SET TO OVERFLOW EVERY 1mS
//******************************************************************
	T2CON = 0x7A;		
	PR2 = 0x29;	
	TMR2ON = 1;
	TMR2IE = 1;

	hours = 0x00;
	mins = 0x00;
	secs = 0x00;

	init_EUSART();
	init_67J60();
	init_DHCP();
	//udpcnt = 0;
while(1)
	{
	 if(EPKTCNT != 0)
		get_frame();

	 dhcp_state_engine();
	 if(old_secs != secs)
	 {
		 old_secs = secs;
	 	LED0 ^= 1;
	 }

	 //printf("%c[12;25H %02d:%02d:%02d",esc,hours, mins, secs);

	}
}

	}
}

ethernet_mini_package.zip

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#28
اقتباس
بالنسبة للوايفاى ترسل له العنوان والبورت هو يقوم بارسال الطلب ومن ثم استقبال البيانات بالنسق الطلوب

انا اعتقد انك تقصد كيف يمكننى عرض ملف HTTP على شاشة صغيرة

فعلا هو امر صعب وكما تلاحظ ان فى الموقع الاول هنلك عدم تنسيق

لكن بالنسبة لموقع قوقل فان السيرفر له المقدرة على التحقق من الاى بى وعندما يعرف انه نظام مدمج يقوم بعمل اعادة توجية الى صفحة اخرة مخصصة للتصفح عن طريق الموبايل

أخى بارك الله فيك الأمر ليس بهذه السهول التى ذكرتها

أنت لكى تقوم بعرض صفحة Html فى أى مكان و على أى نظام و بأى برنامج ,لابد و أن يتم عمل ما يسمى parsing للhtml

الذى يقوم بهذا parsing هو المتصفح

إذن لكى يتم عرض صفحة جوجل فى دارتك على شاشاتك, لابد أن يكون هناك يقوم بعمل parsing

أى يقوم بتحويل نسق الhtml إلى شئ يتم عرضه على الصفحة المتصفح

سؤالى هو هل قمت بعمل هذا الparser !!

أم ماذا فعلت لكى يتم عرض صفحة جوجل كما رأيتها فى الصور !؟

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#29
نور (محمد نور) كتب:
أخى بارك الله فيك الأمر ليس بهذه السهول التى ذكرتها

أنت لكى تقوم بعرض صفحة Html فى أى مكان و على أى نظام و بأى برنامج ,لابد و أن يتم عمل ما يسمى parsing للhtml

الذى يقوم بهذا parsing هو المتصفح

إذن لكى يتم عرض صفحة جوجل فى دارتك على شاشاتك, لابد أن يكون هناك يقوم بعمل parsing

أى يقوم بتحويل نسق الhtml إلى شئ يتم عرضه على الصفحة المتصفح

سؤالى هو هل قمت بعمل هذا الparser !!

أم ماذا فعلت لكى يتم عرض صفحة جوجل كما رأيتها فى الصور !؟

نعم كلامك صحيح تحتاج الى برنامج يكافي متصفحات الانترنت حتى تتمكن من عرضها

هذا البرنامج مدمج داخل بروسيسر

rabbit

الموجود داخل الواى فاى مديول

يقوم بتخذين الصفحة داخل

EEPROM

بنسق

BITMAP

فى حقيقة الامر ان البرنامج الموجود داخل هذا البروسيسر يقوم بكل الامور المعقدة

مثل التخاطب مع الطبقات السفلى

link ---> IP data ---> udb data / tcp / or etc ---> application

فقط ما احتاجة فى الارسال ارسال رقم البرتوكول

HTTP

وعمل تاخير زمنى حتى يتم تحميل البرنامج داخل الذاكرة الخارجية ومن ثم تحميل

ملف البيتماب وتحويله الى

RGB

---------------------------------------------------------

قد تحتاج الى عمل

html parser

اذا استخدمت القطعة

W315XX

هذا يعتمد على نوع التطبيق الذى تريد تصميمه

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#30

نعم أكيد

يعنى أفهم من هذا أن الذى كان على الشاشة صورة و ليست صفحة HTML

خسارة

حاول أن تأتى بتلك القطعة التى ذكرتها و أن تحاول ان تتعامل مع تلك المعطيات

لو أنك نجحت فى هذا الأمر فإن هذا سوف يعد بحق إنجاز رائع يستحق كل التقدير و طبعا بعض المال ;)

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#31

عمل المتصفح ليس بالمشكلة على لغة HLL انا عندى بعض الخبرة فى موضوع ال HTTP من برنامج الدونلود حتى لو لم يكن ما يقوم به هو عرض BITmap من على ذاركة الموديول يمكن ايضا تصميم متصفح لكن ستحتاد الى ميكرو اعلى فى السرعة والامكانيات

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#32

سؤال اخر لك اخى محمد

هل تعمل الكريستال معك جيدا على ال test bord ام انك تستخدم مذبذب اخر

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#33
حريف برمجة كتب:
عمل المتصفح ليس بالمشكلة على لغة HLL انا عندى بعض الخبرة فى موضوع ال HTTP من برنامج الدونلود حتى لو لم يكن ما يقوم به هو عرض BITmap من على ذاركة الموديول يمكن ايضا تصميم متصفح لكن ستحتاد الى ميكرو اعلى فى السرعة والامكانيات

انا اتفق مع تماما

تحويل صفحة الاتش تى ام ال الى بت ماب ليس بالامر الصعب

ولكن يحتاج الى وقت ومايكرو له زاكرة كبيره

عموما اى شى يظهر فى الشاشة هو عبارة عن صورة سواء ملف وورد او فديو او او او

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#34
حريف برمجة كتب:
سؤال اخر لك اخى محمد

هل تعمل الكريستال معك جيدا على ال test bord ام انك تستخدم مذبذب اخر

12 ميقا هيرتز

تعمل بصورة جيدة حتى اننى لم استخدم مكثفات باى باص او مكثف ريست

-------------------------------------------------

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#35
fadi-k كتب:
واعتقد ان تصميم متصفح انترنت صعوبته بقدر سهولته واعتقد ان تصميمه يكون اسهل باستخدام السي على الميكرو كنترولر ولكن بشكل

ليس بشكل مباشر يجب عمل مكتبات على السي .

كلامك صحيح هى مسالة وقت فقط لكن الفكرة واضحة

-------------------------------------------------

تم تعديل هذه المشاركة بواسطة محمد الامين في 25 مارس 2009 في 22:25

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#36
حريف برمجة كتب:
سؤال اخر لك اخى محمد

هل تعمل الكريستال معك جيدا على ال test bord ام انك تستخدم مذبذب اخر

12 ميقا هيرتز

تعمل بصورة جيدة حتى اننى لم استخدم مكثفات باى باص او مكثف ريست

-------------------------------------------------

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#37

السلام عليكم

تعقيبا على كلام الاخ محمد نور ان عمل متصفح الانترنت هو فك بروتوكول http وعرضه على شكل صورة وايضا حزم بروتوكول http وارساله الى المخدم المطلوب عند

عمل اي كليك على اي ايقونة في هذه الصفحة واعتقد ان تصميم متصفح انترنت صعوبته بقدر سهولته واعتقد ان تصميمه يكون اسهل باستخدام السي على الميكرو كنترولر ولكن بشكل

ليس بشكل مباشر يجب عمل مكتبات على السي .

بعد التعديل بروتوكول http اما HTMLفهي لغة برمجة للصفحات وايضا يمكن للمتصفح ان يعمل مستعرض ملفات FTTP.

تم تعديل هذه المشاركة بواسطة fadi-k في 26 مارس 2009 في 02:19

#38
اقتباس
12 ميقا هيرتز

مع انى مشغل 4 لكن فى مشاكل ولا تعمل الا اذا قربت يدى من المذبذب والذى يعنى مشكلة فى المكثفات

مع انها كانت تعمل فى الاول حتى انى اضطررت الى اخراجها على pcb لدائرة فلاشر بسيطة لتجربة هذا

هشوف فى النت يمكن الالقى مشكلة مشابهة

واليك الفيديو فى المرفقات

والبناسبة خذ البرنامج عندك وحاول تجربه ووصل اى ليد على PortB عشان انا شاكك فى السوفت وير ايضا

flasher.rar

program.rar

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#39
حريف برمجة كتب:
مع انى مشغل 4 لكن فى مشاكل ولا تعمل الا اذا قربت يدى من المذبذب والذى يعنى مشكلة فى المكثفات

مع انها كانت تعمل فى الاول حتى انى اضطررت الى اخراجها على pcb لدائرة فلاشر بسيطة لتجربة هذا

هشوف فى النت يمكن الالقى مشكلة مشابهة

واليك الفيديو فى المرفقات

والبناسبة خذ البرنامج عندك وحاول تجربه ووصل اى ليد على PortB عشان انا شاكك فى السوفت وير ايضا

ايوا

انا جربت الكود تبعك

واليك المشكلة

الخطوط الافقية بتمثل مكثفات فلما تعطيها بنضات فى بورت كامل بتردد عالى بتولد اشارات بتاثر على كل الاجسام المعدنية حول البورت ومن ضمنا تلك التى عليها الكرستالة

لما انت تقرب يدك للكرستالة بتكون عملت ارضى يمتص تلك الموجات الكهرومعنطيسية وبلتالى الكرستالة راح تشتغل معاك وبنفس الطريقة اذا وصلت مكثفات باى باص

عموما لوتحب تتاكد جرب اعمل لووب داخل البرنامج لعمل تاخير زمنى

ممكن تجرب البرنامج التالى وراح يشتغل معك

وهو فلاش بسيط

portb.0

الكوود

  LIST   P=PIC16F819
  #include p16f819.inc 

	clrf STATUS
	clrf PORTB
	movlw H'00'
	bsf STATUS , RP0
	movwf TRISB
	bcf STATUS , RP0
	blink:
	clrf PORTB 
   clrf H'0032'
	  reseto:

   clrf H'0030'
   clrf H'0031'


   delay:
   incf  H'0030' 
   movf H'0030'  , w

   btfss STATUS , Z 
   goto delay
   incf H'0031'
   movf H'0030'  , w
   btfss STATUS , Z 
   goto delay
   bcf PORTB ,0
   incf H'0032'


   btfss H'0032'  , 1
   goto reseto
   goto blink  

   END

amin_asm0.rar

تم تعديل هذه المشاركة بواسطة محمد الامين في 26 مارس 2009 في 12:28

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#40

انا حصلت معايا نفس المشكلة وكنت فاكر ان دة عطل هاردووير فى البيك من كتر الاستخدام لان البيك لية عدد مرات برمجة محددة

طب حل المشكلة دى اية من جهة الهاردويير ؟

#41

للاسف نفس الموال

هل البرنامج الذى بعثته لك عمل معك نفس المشكل

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#42
حريف برمجة كتب:
للاسف نفس الموال

هل البرنامج الذى بعثته لك عمل معك نفس المشكل

ايوا انا جربت برنامجك وما اشتغل وعللت ليك السبب

هل جربت البرنامج المرفق؟

هل قمت بوصل الليد على

port b pin 0

البرنامج التانى شغال انا جربته

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#43

لا اعتقد ان المشكلة فى السرعة فقد ابطأت سرعة التذبذب ومازال هناك نفس الشكلة وانا اشك فى ال IDE

بالنسبة لبرنامجك جربته على ال bread board ولم يعمل وجربتة على اللوحة المطبوعة لكن للاسف الليد موصلة بها على rb3 ولكن قست الجهد على B0 ولكنه لا يتغير

المهم البرنامج الجديد فى المرفقات حاول تجربته لعله يكون سوفت وير كما اتمنى

واذ امكن يمكن تعديل برنامجك ليعمل على RB3 اذا امكن

وشئ اخير اذا اردت ان انقل هذه المشاركات الى موضوع جديد لانها تشوه موضوعك قل لى ذلك

وشكرا

Pic_new_project.rar

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#44

اخى حريف بالنسبة لبرنامجك الاخير فمشكلته تختلف عن الاول

حيث انة لم يعمل لانه مجرد من الاعدادات :) بمجرد ان قمت بتحميلة على المبرمج اعطانى انذار بان الكود خالى من الاعدادات (اقصد ظبط نوع المتزبزب والسرعة ....الخ)

انت تستخدم MPLAB ?

عموما لا اعتقد انك لم تحل المشكلة حتى الان .

اذا لم تحل يمكننا ان نتواصل بالرسائل PM

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#45

اعتقد انى ضبطت الاعدادات لكن لا عليك

اقتباس
انت تستخدم MPLAB ?

نعم

اقتباس
عموما لا اعتقد انك لم تحل المشكلة حتى الان .

المشكلة اعتقد ان لها علاقة بالسوفت وير الموجود لدى

لكن حللت المشكلة بالهاردوير بان اوصلت دخل المذبذب على osc1 والاخر ثبته على vcc

لكنه لم يعطنى قيم زمنية دقيقة

كنت اريده استخدامه ك decoder فى دائرة rf

لكن على العموم صممت decoder لكنه ايضا لم يعطى قيم دقيقة ايضا فاستخدمت واحد تجارى

شكرا عل وقتك متاسسسسف لانى لا استطيع الاتصال لان النت عندى مقطوع

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#46

بالنسبة للmplab بمجرد عمل build يتم تكوين ملف الهيكس ديسيمال ولكن بدون اعدادات لذلك لايعمل عند تحميلة على المايكرو فى حين انة يعمل على السميوليتر

هذه هى الطريقة التى يتم حفظ الملف بها

اولا قم بعمل الاعدادات configuration

post-174126-1239966374_thumb.jpg

ثم بعد ذلك قم بعمل export واحفظ الملف وبعد ذلك قم بعملية البرمجة

post-174126-1239966437_thumb.jpg

اذا استخدمت كرستالة اكبراو تساوى 4 ميقا هيرتز اظبط الاعدادات على HS

---------------------------------------------------------------------------------------

عموما بما انك حللت المشكلة فالحمد لله ولاتنسى ان تتحفنا بصور لمشروعك بعد الانتهاء :blush:

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#47

ياباشا موضوع الاعدادات سليم واعرف موضوع المذبذب

ويتم حفظ الاعدادات حتى ان برنامج winpicيقرأ الاعدادات عند تحميل الملف عليه

اقتباس
عموما بما انك حللت المشكلة فالحمد لله ولاتنسى ان تتحفنا بصور لمشروعك بعد الانتهاء

يا عم بلاش احراج انا كنت عاوز اعمله ديكودر مش اكتر

موقع البرنامج

مبارك لشعب تونس photo-thumb-42837.png

#48

السلام عليكم

أستغرب الردود على هذا الموضوع

ولا واحد حاول مناقشة نظام التشغيل أو المشاركة في حل مشاكله

كل الأسئلة تقريباً خارج الموضوع

على أية حال

ألا ترى معي أن موضوع تحميل البرنامج من الذاكرة الخارجية أقل ما يقال عنه أنه سيئ

لأنه يضع عقبة أمام البرامج الأكبر من المساحة التي خصصتها للبرامج في برنامجك

لهذا أقترح عليك أن تقوم بعمل مؤشر pointer خاص بك

هذا المؤشر يعمل على أخذ التعليمات تعليمة تعليمة وتخزينها في مكان معين لديك في الذاكرة

هذا يضمن لك أمرين

الأمر الأول ستحل مشكلة call

الأمر الثاني ستستطيع تحميل أي برنامج من الذاكرة الخارجية بدون أي قيد يذكر

أتمنى أن توضح لي لو كان لدي مشكلة في الفهم لمشكلتك

أو لو كان لدي خطأ بما يتعلق بالمايكروكنتلور أو التعامل مع الذاكرة لأن خبرتي في الموضوع لا تتعدى قفل إلكتروني :lol:

مبدئياً يهيألي أن نظام التشغيل الخاص بك single Task?

أتمنى لك التوفيق

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#49
علاء الصالحي كتب:
ألا ترى معي أن موضوع تحميل البرنامج من الذاكرة الخارجية أقل ما يقال عنه أنه سيئ

لأنه يضع عقبة أمام البرامج الأكبر من المساحة التي خصصتها للبرامج في برنامجك

كلامك صحيح وهذه هى المشكلة التى يعانى منها النظام حالية

وللاسف لايمكن ان تتم معالجة الاوب كود مباشرة من الذاكرة الخارجية

يجب ان تنقل اولا الى الذاكرة الداخلية ومن ثم معالجتها

ما افعلة الان لمعالجة مشكلة الامر

call

تحميل قيمة البوينتر الى الرام

اضافة عنوان النداء الى البوينتر

تنفيز اوامر النداء

ومن ثم اعادة تحميل الموقع الحقيقى للبوينتر من الرام الى البوينتر

:wacko:

موضوع معقد وبطىء التنفيز

سوف احاول اعادة كتابة البرناممج لمايكرو كنترولر اكبر شوية :wink:

هذا هو البرنامج الحالى

اقتباس
//*************************************************************

//**************arabia embedded OS val 0.001 *****************

//********************for 14bits PIC MCU***********************

//**************Eng. Mohammed Elamin **************************

//*** eng.alamin@gmail.com*************************************

//this code is 100% written in MEDEAST*************************

//*************************************************************

#include "D:\Program Files\PICC\Projects\os\main.h"

#use fast_io(B)

void main()

{

//======== dont tuch ========================================================

int data , smrb[3], m , l , pos ;

int16 loader , i;

int1 booting ;

//===========================================================================

setup_adc_ports(NO_ANALOGS);

setup_adc(ADC_OFF);

setup_spi(SPI_SS_DISABLED);

setup_timer_1(T1_DISABLED);

setup_timer_2(T2_DISABLED,0,1);

init_ext_eeprom();

if(booting == 0)

{

printf("%s" ,"ARABIA OS loading..." );

// delay_ms(1000);

// output_high(pin_b0);

// output_high(pin_b1);

// output_high(pin_b7);

// delay_ms(1000);

#asm

bsf 0x3 , 5

bsf 0x3 , 6

bcf 0x018c , 4

#endasm

l = 0 ;

pos = 0;

for( m = 0 ; m<= 40 ; m ++)

{ output_high(pin_a2);

smrb[0] = read_ext_eeprom(m);

delay_ms(10);

smrb[1] = read_ext_eeprom(l++);

//smrb[0] = 0x1;

//smrb[1] = 0x86 ;

loader = (smrb[1] * 0x100) ;

loader = loader + smrb[0] ;

write_program_eeprom (0x403 + pos , loader);

pos ++ ;

m ++ ;

booting =1 ;

delay_ms(50);

}

}

#asm

clrf 0x3

clrf 0x5

movlw 0x00

bsf 0x3 , 5

movwf 0x5

bcf 0x3 , 5

movf Data , w

bsf 0x5 , 1

movlw 0xa

movwf 0x4

movlw 0x04

movwf 0x0

movlw 0x2

movwf 0x2

#endasm

}

اقتباس
مبدئياً يهيألي أن نظام التشغيل الخاص بك single Task?

نعم بالظبط كدا :wink:

اقتباس
أتمنى أن توضح لي لو كان لدي مشكلة في الفهم لمشكلتك

أو لو كان لدي خطأ بما يتعلق بالمايكروكنتلور أو التعامل مع الذاكرة لأن خبرتي في الموضوع لا تتعدى قفل إلكتروني :lol:

لا والله اخوى ماعندك مشكلة مداخلتك ذكية جدا ماشاء الله عليك :wub:

عن أبي هريرة رضي الله عنه عن النبي صلى الله عليه وسلم أنه قال: سيأتي على الناس زمان سنوات خداعات: يصدق فيها الكاذب ويكذب فيها الصادق، ويؤتمن فيها الخائن ويخون فيها الأمين، وينطق فيها الرويبضة. قيل يا رسول الله وما الرويبضة؟ قال: الرجل التافه ينطق في أمر العامة . رواه احمد والحاكم وصححه الالبانى من حديث ابى هريره.‏

#50

ما رأيك في التالي

يكون لديك مؤشر في الذاكرة الداخلية يعمل عمل المؤشر الخاص بتنفيذ الأوامر

تقوم بنقل تعليمة واحدة من البرنامج الموجود في الذاكرة الداخلية

أقصد عملية النقل تسير بمقدار تعليمة تعليمة

نستخدم باقي الذاكرة الداخلية كمكدس stack

عندما تواجه تعليمة call

تضع العنوان الحالي في stack

وتغير المؤشر الخاص الخاص بالذاكرة الخارجية إلى العنوان الجديد

على فكرة هذا هو النظام المتبع في أي لغة برمجة

لهذا تجد من يقول call method عملية مكلفة

ملاحظة:هذا الحل سيكون عقيم جداً لو كانت عملية القراءة من الذاكرة الخارجية بطيئة بشكل ملحوظ

بالنسبة لموضوع البرنامج الخاص بك

لو أمكن كلمنا عنه قليلاً

خصوصاً شيفرة الأسيمبلي لأني قد نسيت كل ما يتعلق بالأسيمبلي

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…