/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... use the ethernet device in loopback mode
 *      (DAC channel 0 is tied to ADC channel 0).
 */

#include <stdio.h>
#include <string.h>
#include <target.h>
#include "net.h"
#include "../delay.h"

#define SN	(255L<<24|255L<<16|255L<<8|192)	// choose subnet  mask
#define GW	(194L<<24| 64L<<16|159L<<8| 65)	//        gateway addr
#define IP	(194L<<24| 64L<<16|159L<<8| 79)	//        IP      addr
#define PN	80				//        port  number (http)

/*
 * The ethernet device channel 0 is initialized in TCP server mode.
 *
 * On connect, form data gets updated if present, and the html page
 * gets built and sent. After sending data, the channel gets closed
 * until the next connection is made.
 *
 * Connect the DAC0 output to ADC0. DAC0 and ADC0 values should not
 * differ significantly. Note, that DAC0 is the pin labelled ADC12.
 */
int
main(void)
{
	/*
	 * Reference voltage
	 *
	 * Setting refcon to 1 activates the internal
	 * reference and connects it to the Vref pin.
	 *
	 * Note: A 0.47uF capacitor is required (from
	 * Vref to GND) for proper operation!
	 */
	Intern_refcon = 1;

	Intern_dac0con = 0x12;			// DAC range 0 to Vref
	Intern_adccon  = 0xa4;			// ADC continuous conversion

	/*
	 * Initialize bus interface.
	 */
	Intern_gp0con = 0x00000220;
	Intern_gp1con = 0x02222211;
	Intern_gp2con = 0x22222220;
	Intern_gp3con = 0x22222222;
	Intern_gp4con = 0x22222222;
	Intern_xmcfg  = 1;
	Intern_xm0con = 3;
	Intern_xm1con = 3;
	Intern_xm2con = 3;
	Intern_xm3con = 1;
	Intern_xm0par = 0x722;
	Intern_xm1par = 0x722;
	Intern_xm2par = 0x722;
	Intern_xm3par = 0x722;
	puts("Bus interface initialized.");

	net_init(SN, GW, IP);			// initialize NET device

	printf("\n"
	       "NET7026 TCP server\n"
	       "==================\n\n"
	       "     Subnet mask : %3d.%3d.%3d.%3d\n"
	       " Gateway address : %3d.%3d.%3d.%3d\n"
	       "      IP address : %3d.%3d.%3d.%3d\n",
		net_rh(NET_SUBR), net_rb(NET_SUBR), net_rh(NET_SUBR+2), net_rb(NET_SUBR+2),
		net_rh(NET_GAR ), net_rb(NET_GAR ), net_rh(NET_GAR +2), net_rb(NET_GAR +2),
		net_rh(NET_SIPR), net_rb(NET_SIPR), net_rh(NET_SIPR+2), net_rb(NET_SIPR+2)
	);

	while (1) {
		static char pbuf[1000];		// html page buffer
		static char req	[100];		//   request buffer

		unsigned long dac;		// DAC data

		net_open(PN, 0);		// initialize socket (listen)

		printf("\nDisconnected, waiting for connection (port #%d)...\n", net_rw(NET_S0_PORTR));

		while (net_rb(NET_S0_SSR) != NET_SE) ;	// wait for sock_established

		printf("Connected (%3d.%3d.%3d.%3d), ",
			net_rh(NET_S0_DIPR  ), net_rb(NET_S0_DIPR  ),
			net_rh(NET_S0_DIPR+2), net_rb(NET_S0_DIPR+2)
		);

		/*
		 * Check for form data update.
		 * Invalid DAC data is zeroed.
		 */
		memset(req, 0, sizeof(req));
		net_read(req, sizeof(req)-1);
		if (strstr(req, "GET /?")) {
			char *p;

			if ((p = strstr(req, "HTTP/"))) *p = 0;
			fputs("updating, ", stdout);
			if ((p = strstr(req, "dac="))) {
				if (sscanf(p+4, "%lu", &dac) != 1 || dac > 4095) dac = 0;
				Intern_dac0dat = dac<<16, delay(1);
			}
		}

		while (!Intern_adcsta) ;	// wait for ADC result ready

		/*
		 * Build the html page to be sent.
		 */
		sprintf(pbuf,
			"HTTP/1.1 200 OK\n\n"	// GET response header
			"<html>"
			"<head>"
			"<title>NET7026 Loopback</title>"
			"</head>"
			"<body bgcolor=lightblue>"
			"<h1>NET7026 Loopback</h1>"
			"<h3>DAC0 -> ADC0</h3>"
			"<form>"
			"DAC0: <input name=dac value=%ld> (0... 4095)<br>"
			"<p>ADC0: %ld</p>"
			"<input type=submit value=Update>"
			"</form>"
			"<p><a href=http://www.mct.de  target=_blank>mct.de </a><br>"
			"   <a href=http://www.mct.net target=_blank>mct.net</a></p>"
			"</body>"
			"</html>",
			dac,
			(Intern_adcdat>>16)&0xfff
		);
		puts("sending page...");
		net_write(pbuf, strlen(pbuf));
		net_close();
	}
}

