/***************************************************************************
	enet_ad.c
  	Z-World, 2002

	This program is used with controllers such as BL2000, BL2100, or
	Smart Star series controllers containing Analog Inputs and Outputs.
	
	Description
	===========
	This program demonstrates ethernet communication between
   two controllers.  The program sends an A/D voltage value to
   the second controller via ethernet for display.

   Use enet_menu.c to program a second controller 
   
	(Adapted from bl2000_enet.c)
	
   Hardware Connections
   ====================
   1. Connect a wire from DAC0 to AD3.
   2. Connect an crossover ethernet cable directly to the 
      second controller or a straight thru ethernet cable
      to the second controller via a hub.

	Instructions
	============
   1. Compile and run this program.
   2. Observe display on second controller.
   
***************************************************************************/
#class auto

#define DAC_CHANNEL  0		//choose DAC0 or DAC1
#define ADC_CHANNEL	3		//choose ADC channel

/***********************************
 * Configuration                   *
 * -------------                   *
 * All fields in this section must *
 * be altered to match your local  *
 * network settings.               *
 ***********************************/

/*
 * Pick the predefined TCP/IP configuration for this sample.  See
 * LIB\TCPIP\TCP_CONFIG.LIB for instructions on how to set the
 * configuration.
 */
#define TCPCONFIG 1

#memmap xmem
#use "dcrtcp.lib"

#define PORT1 8888    // Standard Telnet port 
#define PORT2 8889

/*
 * TCP/IP modification - reduce TCP socket buffer
 * size, to allow more connections. This can be increased,
 * with increased performance, if the number of sockets
 * are reduced.  Note that this buffer size is split in
 * two for TCP sockets--1024 bytes for send and 1024 bytes
 * for receive.
 */
#undef  SOCK_BUF_SIZE 
#define SOCK_BUF_SIZE 	2048

/*
 * We're only going to use to 2 sockets
 * Note: The default setting is 4 sockets
 */

#undef  MAX_SOCKETS
#define MAX_SOCKETS 		2

#define LEDOFF				0
#define TOGGLE				1
#define INCREMENT			2
#define OPERATE			3

char buffer1[4096];
static tcp_Socket Socket_1;	

//------------------------------------------------------------------------
// LED control function 
//------------------------------------------------------------------------
void leds( int mode )
{
	static int toggle, increment;
	auto int led, mask;
	
	#GLOBAL_INIT {toggle=0;}
	#GLOBAL_INIT {increment=0;}

	mask = 0x01;
	increment++;
	for(led = 1; led <= 4; led++)
	{
		
		if(increment & mask)
			ledOut(led, 1);
		else
			ledOut(led, 0);
		mask = mask << 1;
	}
}

int socket_closed(tcp_Socket *socket)
{
	if(sock_rbused(socket) > 0 || sock_tbused(socket) > 0)
	{
		if(sock_rbused(socket) > 0) 
			sock_fastread(socket,buffer1,sizeof(buffer1));

		if(sock_tbused(socket) > 0)
			sock_flush(socket);
		return(FALSE);
	}
	if(tcp_tick(socket) == 0)
		return(TRUE);
	else
		return(FALSE);
}


/**********************************************************************/
/* Listen for a connection from the OP6800 controller                 */
/**********************************************************************/
void basic_tcp(void) {
  
	char wr_buffer[128];
	int tcp_status;
	unsigned int len;
	float voltage;
	static int connected;
	
	#GLOBAL_INIT {connected = FALSE;}

	costate
	{
	   // Need to do continuously to handle the TCP processing on all sockets.
	 	tcp_tick(NULL);
	}

	costate
	{
		// Setup the controller to listen on PORT1
		tcp_listen(&Socket_1,PORT1,0,0,NULL,0);
		sock_mode(&Socket_1,TCP_MODE_BINARY);
				
		/*
		 * Use sock_dataready() in-conjunction with sock_established() to handle the case of
		 * a socket being opened, written to, and closed between two sock_established checks.
		 */
		waitfor(sock_established(&Socket_1));
		connected = TRUE;
		while (connected)
		{
			// Using tcp_tick() because to detect when the socket is closed.
			waitfor((tcp_status = tcp_tick(&Socket_1)) == 0 ||  sock_dataready(&Socket_1) > 0);
				
			// Check if the socket is closed, if not get the data
			if (tcp_status)
			{
				len = sock_fastread(&Socket_1,buffer1,sizeof(buffer1));
				buffer1[len] = '\0';
				
				voltage = anaInVolts(ADC_CHANNEL);
				voltage = voltage*2.5034;
				//voltage = 10.00 - voltage;
				sprintf(wr_buffer, "%f", voltage);
				sock_fastwrite(&Socket_1, wr_buffer, strlen(wr_buffer));
				leds(INCREMENT);
			}
			else
			{
			   // Close the socket
			   sock_flush(&Socket_1);
				sock_close(&Socket_1);
			
				// Wait for the socket to completely close down
				waitfor(socket_closed(&Socket_1));
				connected = FALSE;
				abort;
			}
		}
	}
}


/*********************************/
/* Main Program loop starts here */
/*********************************/
void main()
{
	float outvoltage;
	
	brdInit();
	
   sock_init();
   tcp_reserveport(PORT1);
   
	outvoltage = 0.5;
	
 	while (1)
 	{
   	costate
   	{
			if (outvoltage <= 3.8)
				anaOutVolts(DAC_CHANNEL, outvoltage+=0.2);
			else
				outvoltage = 0.5;
			waitfor(DelayMs(400));
		}
		
   	costate
   	{
			// Go do TCP/IP part of the application program  
         basic_tcp();
      }
      
  	}
}






