/*******************************************************************************
        Samples/RCM2200/pingled.c
        Z-World, 2001

        ICMP demonstration, by pinging a remote host.

        This sample program is an adaptation of samples/tcpip/ping.c.  It
        has been modified for the RCM2200 to flash LEDs on the prototyping
        board.  It flashes DS2 when it sends a ping and flashes DS3 when
        it receives a ping response.  The MASTER core controls the LEDs.

        To use this program modify the MY_IP_ADDRESS, MY_NETMASK, MY_GATEWAY,
        and MY_NAMESERVER to the appropriate settings for the network.  Then
        change PING_WHO to the host you want to ping.  The MY_NAMESERVER
        define is only necessary when you are specifing PING_WHO by name
        instead of by IP address.

        You can modify the PING_DELAY define to change the amount of time
        in milliseconds between the outgoing pings.

        If you would like to see the incoming ping replies, uncomment the
        VERBOSE define.
*******************************************************************************/

#define MY_IP_ADDRESS 	"10.10.6.100"
#define MY_NETMASK		"255.255.255.0"
#define MY_GATEWAY		"10.10.6.1"
#define MY_NAMESERVER	"10.10.6.1"

/** Define causes printf() when response arrives **/
//#define VERBOSE

/** Remote interfaace to send PING to (passed to resolve()): **/
#define PING_WHO			"10.10.6.1"

/** How often to send PING's (in milliseconds): **/
#define PING_DELAY		2000

#memmap xmem
#use "dcrtcp.lib"

/*******************************************************************************
		Routines to change the LEDs.  The DS2 and DS3 LEDs are on two bits of
		the E register, PE1 and PE7.  The pingleds_setup() routine turns off
		DS2 and DS3.  The pingoutled() routine turns DS2 on when what is
		nonzero and off when it is zero.  Similarly, the pinginled() routine
		toggles DS3.
*******************************************************************************/

#define LEDON	1
#define LEDOFF	0


void pingoutled(int what)
{
	/*  Control DS2.  Output 0 to turn LED on. */
	WrPortI(PEB1R, NULL, (what != LEDOFF) ? 0 : (1<<1));
}

void pinginled(int what)
{
	/*  Control DS3.  Output 0 to turn LED on. */
	WrPortI(PEB7R, NULL, (what != LEDOFF) ? 0 : (1<<7));
}

void pingleds_setup()
{
	/*  Convert the I/O ports.  Disable slave port which make
	 *  Port A an output, and PORT E not have SCS signal.
	 *  Read shadow and set PE1 and PE7 as normal I/O.
	 *  LED's are connted to PE1 and PE7, make them outputs.
	 */
	WrPortI(SPCR, & SPCRShadow, 0x84);
	WrPortI(PEFR,  & PEFRShadow,  ~((1<<7)|(1<<1)) & PEFRShadow);
	WrPortI(PEDDR, & PEDDRShadow, (1<<7)|(1<<1));

	pingoutled(LEDOFF);
	pinginled(LEDOFF);
}


int main()
{
	longword seq,ping_who,tmp_seq,time_out;

	seq=0;

	pingleds_setup();
	
	sock_init();
	
	/*
	 *		Get the binary ip address for the target of our 
	 *		pinging.
	 */
	
	ping_who=resolve(PING_WHO);
	if(ping_who==0) {
		printf("unable to resolve %s\n",PING_WHO);
		return 1;
	}
	
	for(;;) {
		/*
		 *		It is important to call tcp_tick() here because
		 *		ping packets will not get processed otherwise.
		 *
		 */

		tcp_tick(NULL);
		
		/*
		 *		Send one ping every PING_DELAY ms.
		 */
		
		costate {
			waitfor(DelayMs(PING_DELAY));
			_ping(ping_who,seq++);
			pingoutled(LEDON);					// flash the DS3 LED
			waitfor(DelayMs(50));
			pingoutled(LEDOFF);
		}
		
		/*
		 *		Has a ping come in?  time_out!=0xfffffff->yes.
		 */

		costate {
			time_out=_chk_ping(ping_who,&tmp_seq);
			if(time_out!=0xffffffff) {

#ifdef VERBOSE			
				printf("received ping:  %ld\n", tmp_seq);
#endif

				pinginled(LEDON);					// flash the DS4 LED
				waitfor(DelayMs(50));
				pinginled(LEDOFF);
			}
		}
	}   /* end for-ever... */
}