app5

Dependencies:   TFTv2 nihh-utils xpl

main.cpp

Committer:
richnash
Date:
2018-10-28
Revision:
3:f96822b3edb5
Parent:
2:1335510cfb92
Child:
4:ed0665b5d253

File content as of revision 3:f96822b3edb5:


// ##################################################################################
// XPL with TFT Screen Application
// ##################################################################################

// if defined this will echo all debug txt going to the TFT onto the serial port
//#define TFT_ECHO
int _TFT_ECHO = 0;

// turn OFF dependency on being connected to ethernet
//#define ETH_OFF


// MBED Headers
#include "mbed.h"
#include "EthernetInterface.h"
#include "Watchdog.h"
#include "rtos.h"

// -----------------------------------------------------------
// Graphics Headers
#include "ILI9341.h"
#include "SPI_STMPE610.h"
#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "Arial43x48_numb.h"

// -----------------------------------------------------------
// My Headers
#include "Watchdog.h"
#include "xPL.h"
#include "nihh_utils.h"

// -----------------------------------------------------------
// XPL defines
#define UDP_PORT            3865
#define UDP_BUFFER_SIZE     500

#define XPL_NAME            "NUCLEO1"

// -----------------------------------------------------------
// global variables
Watchdog wd;
xPL xpl;

DigitalOut led1(LED1);  // green = normal startup
DigitalOut led2(LED2);  // blue = ethernet data received
DigitalOut led3(LED3);  // red = watchdog startup

Serial logger(SERIAL_TX, SERIAL_RX);

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

EthernetInterface   gEth;
UDPSocket     		gEth_socket;
char                gEth_socket_in_buffer[UDP_BUFFER_SIZE];

//char                in_buffer[UDP_BUFFER_SIZE+1];
int 				iRXBytes;
int					GLOBAL_NET_STATUS = 0;

SocketAddress       _sAddr;


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


#define PIN_RESET_TFT   PC_13 /* place holder */

#define PIN_MOSI        D11
#define PIN_MISO        D12
#define PIN_SCLK        D13
#define PIN_CS_TFT      D5
#define PIN_DC_TFT      D6
#define PIN_BL_TFT      D7
#define PIN_CS_SD       D4

#define PIN_XP          A2
#define PIN_XM          A0
#define PIN_YP          A3
#define PIN_YM          A1

struct point {
    int x;
    int y;
};

void calibrate(void);
bool getPixel(point& p);
point toPixel(point p);

typedef enum { YES, MAYBE, NO } TOUCH;

TOUCH getTouch(point& p);

int readTouch(PinName p, PinName m, PinName a, PinName i);

int x_off = 22071;
int y_off = 18707;
int pp_tx = 373;
int pp_ty = 297;

DigitalOut backlight(PIN_BL_TFT) ;

ILI9341 TFT(SPI_8, 10000000, PIN_MOSI, PIN_MISO, PIN_SCLK, PIN_CS_TFT, PIN_RESET_TFT, PIN_DC_TFT, "Seeed2.8") ;

// which screen page are we on
int page = 0 ;   // 0 is the special debug screen


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

Mutex mutex_TFT;

void TFT_Debug_XY_F ( int, int, char *, ... );

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


// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void terminal_error_state( void )
{
    led1=0;
    led2=0;
    led3=0;

    logger.printf("\r\n\r\nJUST TO BE CLEAR - THIS IS BAD BAD NEWS !!! \r\n");
    while( 1 )
        {
        led1 = !led1;
        led2 = !led2;
        led3 = !led3;
        wait(0.5);
        
		// Just waiting for the watchdog to kill us
        }
}


// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++   TFT SCREEN FUNCTIONS
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

int readTouch(PinName p, PinName m, PinName a, PinName i)
{
    DigitalOut _p(p);
    _p = 1;
    DigitalOut _m(m);
    _m = 0;
    AnalogIn   _a(a);
    AnalogIn   _i(i); // this pin has to be high Z (DigitalIn may also work)
    wait_us(10);
    return _a.read_u16();
}

TOUCH getTouch(point& p)
{
    int y2 = readTouch(PIN_XP,PIN_XM,PIN_YP,PIN_YM);
    int x2 = readTouch(PIN_YP,PIN_YM,PIN_XP,PIN_XM);
    int y1 = readTouch(PIN_XP,PIN_XM,PIN_YP,PIN_YM);
    int x1 = readTouch(PIN_YP,PIN_YM,PIN_XP,PIN_XM);
    int xd = x1 - x2;
    int yd = y1 - y2;
    xd = (xd > 0) ? xd : -xd;
    yd = (yd > 0) ? xd : -xd;
    p.x = x1 + x2;
    p.y = y1 + y2;
    
    const int th = 8000;
    const int df =  100;
    TOUCH touch;
    if (x1 < th || x2 < th ||
            y1 < th || y2 < th) {
        p.x = 0;
        p.y = 0;
        touch = NO;
    } else if (xd > df || yd > df) {
        touch = MAYBE;
    } else {
        touch = YES;
    }
    //TFT.locate(0,50);
    //TFT.printf("x: %6i y: %6i",p.x,p.y);
    return touch;
}

point toPixel(point p)
{
    p.x -= x_off;
    p.x /= pp_tx;
    int w = TFT.width();
    if (p.x > w) p.x = w;
    if (p.x < 0) p.x = 0;
    p.y -= y_off;
    p.y /= pp_ty;
    int h = TFT.height();
    if (p.y > h) p.y = h;
    if (p.y < 0) p.y = 0;
    return (p);
}

bool getPixel(point& p)
{
    TOUCH touch = getTouch(p);
    p = toPixel(p);
    return touch == YES;
}

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void initTFT(void)
{
    //Configure the display driver
    //TFT.BusEnable(true) ;
    TFT.FastWindow(true) ;
    TFT.background(Black);
    TFT.foreground(White);
    wait(0.01) ;
    TFT.cls();
    //TFT.BusEnable(false) ;
}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


void screen1(void) // Welcome Screen
{
	page = 1;
	
    //TFT.BusEnable(true) ;
    backlight = 0 ;
    TFT.background(White) ;
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.foreground(Red) ;
    TFT.locate(20, 40) ;
    TFT.printf("NASHLAND") ;
    TFT.foreground(Blue);
    TFT.locate(20, 80) ;
    TFT.printf("EMBEDDED") ; 
    TFT.locate(20, 120) ;
    TFT.printf("CONTROLLER") ;
    
    TFT.foreground(Black);
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.foreground(Blue) ;
    TFT.locate(30, 180) ;
    TFT.printf("This program is running on a") ;
    TFT.locate(30, 200) ;
    TFT.printf("ST Nucleo 144 Controller") ;
    TFT.locate(30, 220) ;
    TFT.printf("running mbed.os") ;
    
    //TFT.BusEnable(false) ;
    backlight = 1 ;
}

void screen_Debug(void)
{
    int y = Terminal6x8[2] + 2;
    
    mutex_TFT.lock();
    
    page = 0;
    
    TFT.set_font((unsigned char*) Terminal6x8);
    
    //Draw some text
    backlight = 0 ;
    
    TFT.background(Black);
    TFT.foreground(White);
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    TFT.cls() ;
	
    backlight = 1 ;
    
        {
        // Output the network information
        const char *ip = gEth.get_ip_address();
        const char *netmask = gEth.get_netmask();
        const char *gateway = gEth.get_gateway();
        TFT.locate(0, 1*y);
        TFT.printf("IP address: %s\r\n", ip ? ip : "None");
        TFT.locate(0, 2*y);
        TFT.printf("Netmask: %s\r\n", netmask ? netmask : "None");
        TFT.locate(0, 3*y);
        TFT.printf("Gateway: %s\r\n", gateway ? gateway : "None");
        }
    
	mutex_TFT.unlock();
}


void calibrate(void)
{
    int i;
    int a = 0,b = 0,c = 0, d = 0;
    int pos_x = 0, pos_y = 0;
    point p;
    
    page = 99;
    
    backlight = 0 ;
    //TFT.BusEnable(true) ;
    
    TFT.background(Black);
    wait(0.1) ;
    TFT.foreground(White);
    wait(0.1) ;
    TFT.cls() ;
    wait(0.1) ;
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(90,0);
    TFT.printf("Graphics");
    
    TFT.line(0,3,6,3,White);
    TFT.line(3,0,3,6,White);
    
    backlight = 1 ;
    
    //if (font)
    //{
        // get the center of the screen
        pos_x = TFT.columns() / 2 - 3;
        pos_x = pos_x * Arial12x12[1];
        pos_y = (TFT.rows() / 2) - 1;
        pos_y = pos_y * Arial12x12[2];
        TFT.locate(pos_x,pos_y);
        TFT.printf("press cross    ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("to calibrate   ");
    //}
    
    for (i=0; i<5; i++) {
        while (getTouch(p) != YES)
            /*nothing*/;
        a += p.x;
        b += p.y;
    }
    a = a / 5;
    b = b / 5;
    //if (font)
    //{
        TFT.locate(pos_x,pos_y);
        TFT.printf("ok             ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("release touch  ");
    //}
    while (getTouch(p) != NO)
        /*nothing*/;
    
    TFT.cls();
    TFT.line(TFT.width() -5, TFT.height() - 8,TFT.width() - 5,TFT.height() -1,White);   // paint cross
    TFT.line(TFT.width() - 8,TFT.height() - 5,TFT.width() - 1,TFT.height() - 5,White);
    //if (font)
    //{
        TFT.locate(pos_x,pos_y);
        TFT.printf("press cross    ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("to calibrate   ");
    //}
    for (i=0; i<5; i++) {
        while (getTouch(p) != YES)
            /*nothing*/;
        c+= p.x;
        d+= p.y;
    }
    c = c / 5;
    d = d / 5;
    x_off = a;
    y_off = b;
    i = c-a;  // delta x
    pp_tx = i / (TFT.width() - 6);
    i = d-b;  // delta y
    pp_ty = i / (TFT.height() - 6);
    //if (font)
    //{
        TFT.locate(pos_x,pos_y);
        TFT.printf("Calibrated     ");
        TFT.locate(pos_x,pos_y + Arial12x12[2]);
        TFT.printf("x %6i %4i", x_off, pp_tx);
        TFT.locate(pos_x,pos_y + 2*Arial12x12[2]);
        TFT.printf("y %6i %4i", y_off, pp_ty);
    //}
    while (getTouch(p) != NO)
        /*nothing*/;
    TFT.cls();
    
    //TFT.BusEnable(false) ;
    
    printf("x_off:%6i pp_tx:%4i \n\r", x_off, pp_tx);
    printf("y_off:%6i pp_ty:%4i \n\r", y_off, pp_ty);
}


// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void TFT_Debug_XY2(int x, int y, const char * pszTxt)
{
	// is the TFT on the debug page?
	if( page == 0 ) 
		{
		int xFont = Terminal6x8[1];
		int yFont = Terminal6x8[2] + 2;
		
		mutex_TFT.lock();
			
			TFT.locate(x*xFont, y*yFont);
			TFT.printf(pszTxt);
			
		mutex_TFT.unlock();
		}
	
	// is serial echo on?
	if( _TFT_ECHO ) 
		{
		logger.printf("%s\r\n", pszTxt );
		}
}

void TFT_Debug_XY_F2( int x, int y, const char *fmt, ... )
{
	mutex_TFT.lock();
		{
		char szLogFormat [100];
		
		// sort out the args !
		va_list args;
		va_start(args, fmt);
		
		// Format the string
		vsnprintf( szLogFormat, 100, fmt, args);
		va_end(args);
		
		// output the string
		TFT_Debug_XY2( x, y, szLogFormat);
		}
	
	mutex_TFT.unlock();
}

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

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void status_callback(nsapi_event_t status, intptr_t param)
{
	//char szLogFormat [100];
	
	logger.printf("status_callback\r\n");
	
	//strcpy( szLogFormat, "ETH: Connection " );
	//TFT_Debug_XY2( 0, 0, szLogFormat);
	
	GLOBAL_NET_STATUS = param;
	
	switch(param) 
		{
		case NSAPI_STATUS_LOCAL_UP:
			{
			logger.printf("NSAPI_STATUS_LOCAL_UP\r\n");
//			strcpy( szLogFormat, "ETH: Connection - LOCAL_UP              ");
//			TFT_Debug_XY2( 0, 0, szLogFormat);
			break;
			}
		case NSAPI_STATUS_GLOBAL_UP:
			{
			logger.printf("NSAPI_STATUS_GLOBAL_UP\r\n");
			
/*
			strcpy( szLogFormat, "ETH: Connection - GLOBAL_UP              ");
			TFT_Debug_XY2( 0, 0, szLogFormat);
			
			// Output the network address
			const char *ip = gEth.get_ip_address();
			const char *netmask = gEth.get_netmask();
			const char *gateway = gEth.get_gateway();
			
			TFT_Debug_XY_F2(0, 1, "IP address: %s\r\n", ip ? ip : "None");
			TFT_Debug_XY_F2(0, 2, "Netmask: %s\r\n", netmask ? netmask : "None");
			TFT_Debug_XY_F2(0, 3, "Gateway: %s\r\n", gateway ? gateway : "None");
*/
			
			break;
			}
		case NSAPI_STATUS_DISCONNECTED:
			{
			logger.printf("NSAPI_STATUS_DISCONNECTED\r\n");
//			strcpy( szLogFormat, "ETH: Connection - DISCONNECTED              ");
//			TFT_Debug_XY2( 0, 0, szLogFormat);
			break;
			}
		case NSAPI_STATUS_CONNECTING:
			{
			logger.printf("NSAPI_STATUS_CONNECTING\r\n");
//			strcpy( szLogFormat, "ETH: Connection - CONNECTING              ");
//			TFT_Debug_XY2( 0, 0, szLogFormat);
			break;
			}
		default:
			{
			logger.printf("NSAPI - default ?\r\n");
//			strcpy( szLogFormat, "ETH: Connection - ????                  ");
//			TFT_Debug_XY2( 0, 0, szLogFormat);
			break;
			}
		}
}

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
static bool DeviceConnect()
{
    int retries = 10;
    int rc = 0;
    
    //logger.printf("DeviceConnect()\r\n");
    
    while (retries--) 
        {
        rc = gEth.connect();
        if (rc == 0) {
//			logger.printf("DeviceConnect: Waiting\r\n");
//			wait(2);
//			logger.printf("DeviceConnect: Done\r\n");
            return true;
            }
        else
            {
            logger.printf("Connecting... ERR %d\r\n", rc);
            }
        
        wd.Service();
        }
    
    logger.printf("Connecting... FAILED\r\n");
    return false;
}

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
static bool DeviceEthStartup()
{
	//logger.printf("DeviceEthStartup()\r\n");
	
	// get ethernet up !
	if( !DeviceConnect() ) terminal_error_state();
	
	// Output the network address
	//const char *ip = gEth.get_ip_address();
	//const char *netmask = gEth.get_netmask();
	//const char *gateway = gEth.get_gateway();
	
	//TFT_Debug_XY_F2(0, 1, "IP address: %s\r\n", ip ? ip : "None");
	//TFT_Debug_XY_F2(0, 2, "Netmask: %s\r\n", netmask ? netmask : "None");
	//TFT_Debug_XY_F2(0, 3, "Gateway: %s\r\n", gateway ? gateway : "None");
	
    return true;
}

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void SendUdPMessage(char *buffer)
{
	// send the UDP data as broadcast
	int rc = gEth_socket.sendto( "255.255.255.255", UDP_PORT, (const void *)buffer, strlen( buffer ) );
	//logger.printf("[SEND rc=%d] buffer[%d]\r\n%s\r\n", rc, strlen(buffer), buffer);
}

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void AfterParseAction(xPL_Message * message)
{
	char szLogFormat [100];
	
    // is this a message for me ?
    if (xpl.TargetIsMe(message))
		{
		logger.printf("XPL: MSG IS FOR ME !");
		logger.printf("%s\r\n", message->toString());

		// is this a control message?
		if (message->IsSchema("control", "basic"))
			{
			logger.printf("XPL: {control.basic}");
			}
		}
	
	// Put it on the screen
	sprintf( szLogFormat, "XPL: [%20s] %2d items    ", message->source.device_id, message->command_count );
	TFT_Debug_XY2( 1, 18, szLogFormat);
	
	//logger.printf("XPL: [%s]\r\n", message->source.device_id );
	//logger.printf("XPL: [%s] %d items\r\n", message->source.device_id, message->command_count );
	//TFT_Debug_XY_F( 0, 18, "XPL: [%s] %d items      ", message->source.device_id, message->command_count );
	//TFT_Debug_XY( 0, 19, "XPL:                          ");
	
	// do we have any data ???  maybe the parse failed....
	if( message->command_count == 0 )
		{
        // 
//        logger.printf("XPL: no data? [bytes: %d] \r\n%s\r\n", iRXBytes, gEth_socket_in_buffer );
        //TFT_Debug_XY( 0, 19, "XPL: ERROR - PARSE FAILED ??  ");
		sprintf( szLogFormat, "XPL: ERROR - PARSE FAILED ??  ");
		TFT_Debug_XY2( 1, 19, szLogFormat);
        }
    else
        {
        // output the message data  
        for (short i=0; i<message->command_count; i++)
            {
            // grab each item and do something with it
            //logger.printf("%s=%s\r\n", message->command[i].name, message->command[i].value);
            }
        //TFT_Debug_XY_F( 0, 19, "XPL: %d items processed        ", message->command_count );
		sprintf( szLogFormat, "XPL: %d items processed        ", message->command_count );
		TFT_Debug_XY2( 1, 19, szLogFormat);
        }
    
    // output the full msg!
    //logger.printf("%s\r\n", message->toString());
}

// -----------------------------------------------------------
// 
// -----------------------------------------------------------
void Receiver_Thread()
{
    SocketAddress   _sAddr;
    int             iNoDataCount = 0;
    int 			rc;
    int				iDataMsgCount = 0;

    // setup a listener
    gEth_socket.set_blocking(true);
    gEth_socket.set_timeout(3000);
    
    // open the socket
    rc = gEth_socket.open((NetworkInterface*)&gEth);
    if( rc != 0)
        {
        logger.printf("UDPSocket RECEIVER OPEN ERROR   (rc=%d)\r\n", rc);
        terminal_error_state();
        }
    
    // bind the port
    rc = gEth_socket.bind(UDP_PORT);
    logger.printf("Binding port %d\r\n", UDP_PORT);
    if( rc != 0)
        {
        logger.printf("UDPSocket BIND ERROR   (rc=%d)\r\n", rc);
        terminal_error_state();
        }
    
    // loop forever
    while(1)
        {
        // receive from the udp socket
        
		TFT_Debug_XY_F2(1, 15, "RX: Attempt (%2d)                ", iNoDataCount);
		
		iRXBytes = gEth_socket.recvfrom(&_sAddr, gEth_socket_in_buffer, UDP_BUFFER_SIZE);
		
		TFT_Debug_XY2(20, 15, "-DONE-");
		
		// see what weve got !
		if (iRXBytes == NSAPI_ERROR_WOULD_BLOCK)
			{
			led3 = 1; // error
			
			// timeout with no data...
			++iNoDataCount;
			TFT_Debug_XY2(1, 16, "RX: NoData (TIMEOUT)             ");
			
			//screen_Debug();
			}
		else if (iRXBytes < 0)
			{
			led3 = 1; // error
			
			// some other error
			++iNoDataCount;
			TFT_Debug_XY2(1, 16, "RX: NoData (ERR)                 ");
			}
		else if( iRXBytes > 0)
			{
			led3 = 0; // no error
			led2 = 1;
			
			// good data :)
			iNoDataCount = 0;
			gEth_socket_in_buffer[iRXBytes] = '\0';
			TFT_Debug_XY_F2(1, 16, "RX: [%d bytes] %s:%d    ", iRXBytes, _sAddr.get_ip_address(), _sAddr.get_port());
			
			// try and parse the msg
			xpl.ParseInputMessage(gEth_socket_in_buffer);
			
			TFT_Debug_XY_F2(1, 26, "RX: DATA(%d)", iDataMsgCount++);
			led2 = 0;
			}
		
		// have we stopped receiving data ?!?!?
		if( iNoDataCount > 60 ) // about 3 mins (60*3secs) of no data
			{
			// go for a reboot...
			terminal_error_state();
			}
        
        // stroke the WD
        wd.Service();  
        }
}


// -----------------------------------------------------------
// 
// -----------------------------------------------------------
Thread thread1(osPriorityAboveNormal, 8 * 1024); // OS_STACK_SIZE in theory 8k
int main() 
    {
	const char *ip;
	char xpl_ip[20];
	int prev_net_status=0;
	
	point p;
	
	bool waitTouch = false ;
	int iAppLoop=0;
	int iHBSentCount = 0;
	
	// FIRST THINGS FIRST!!!  set the WD timeout interval...
	// 100 seconds to get connected and receive an IP address
	wd.Configure(100000.0);
	
	// open pc serial
	logger.baud(115200);
	logger.printf("---- ETHERNET UDP Test ----\r\n");
	
	// turn all the LEDs off
	led1 = 0;   // green = normal startup
	led2 = 0;   // blue = ethernet data received
	led3 = 0;   // red = watchdog startup
	
    // WatchDog Startup Information
    logger.printf("\r\n------------------------------------------------------\r\n" );
    logger.printf("[SystemCoreClock] %d Hz\r\n", SystemCoreClock);
    logger.printf("[Reset reason] ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) logger.printf("Independant-Watchdog  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)) logger.printf("Window-Watchdog  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST)) logger.printf("Low-Power-Reset  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)) logger.printf("Software-Reset  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)) logger.printf("Power-On/Down-Reset  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST)) logger.printf("Reset-pin  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST)) logger.printf("Brownout  ");
    if (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY)) logger.printf("Low-speed-internal-clock-ready  ");
    __HAL_RCC_CLEAR_RESET_FLAGS();
    logger.printf("\r\n------------------------------------------------------\r\n");
    
    if (wd.WatchdogCausedReset())
        {
        logger.printf("<<Watchdog caused reset>>\r\n");
        led3 = 1;
        }
    else
        {
        logger.printf("<<Normal Startup>>\r\n");
        led1 = 1;
        led2 = 1;
        led3 = 0;
        }
    logger.printf("------------------------------------------------------\r\n\r\n");
    
	// Fireup the TFT Screen
	initTFT() ;
	//logger.printf("TFT Started {width = %d, height = %d}\n\r", TFT.width(), TFT.height()) ;
	//calibrate();
	//screen_Debug();
	screen1();
	
    // fire up the ethernet & the receive socket
    gEth.attach(&status_callback);
    DeviceEthStartup();
    
    // just wait for everything to settle
    logger.printf("Network.");
    while( GLOBAL_NET_STATUS != NSAPI_STATUS_GLOBAL_UP )
		{
		logger.printf(".");
		wait(1);
		}
	logger.printf("UP!\r\n");
    
    // stroke the wd - all ok so far !
    wd.Service();
	
	screen_Debug();
	
    // 10 second is enough to make sure everything is ok - UDP read is every 3 seconds
    wd.Configure(10000.0);
    
	// process the devices ip adress into the XPL instance ID
	ip = gEth.get_ip_address();
	strcpy( xpl_ip, ip );
	UTILS_strip_char_in_string( xpl_ip, '.' );
	
    // setup xpl
    xpl.SendExternal = &SendUdPMessage;         // pointer to the send callback
    xpl.AfterParseAction = &AfterParseAction;   // pointer to a post parsing action callback 
    xpl.SetSource( "NIHH", XPL_NAME, xpl_ip);   // parameters for hearbeat message
	
    // kick off the XPL receiver thread to run in the background
//    thread1.set_priority(osPriorityAboveNormal);	// osPriorityNormal osPriorityHigh osPriorityBelowNormal osPriorityAboveNormal
    thread1.start( Receiver_Thread );
	
	
	// calibrate the screen
	//calibrate();
	
	
	// start running the main processing stuff here
	while (true) 
		{
		//logger.printf(".\n\r") ;
		
		//TFT_Debug_XY2( 5, 10, "Hello world..." );
		
		// pause for a mo !
		//wait(5);
		
		
        do  {
			led1 = !led1;
			
			if( GLOBAL_NET_STATUS != prev_net_status )
				{
				TFT_Debug_XY_F2(0, 0, "NET: %d", GLOBAL_NET_STATUS);
				logger.printf("net..\n\r") ;
				
				prev_net_status = GLOBAL_NET_STATUS;
				}
			
			
            // allow xpl to do its thing...
            #ifndef CONNECTED_OFF
                xpl.Process();
            #endif
            
            if( getPixel(p) ) 
                {
                logger.printf("TFT Touch x = %d, y = %d\n\r", p.x, p.y) ;
                waitTouch = false ;
                wait(.2); // stop 
                
                backlight = !backlight;
                
                }
            
            // every X loops send a test XPL msg
            ++iAppLoop;
            if( iAppLoop >= 50 )
                {
                xPL_Message _message;
                
                /*
                _message.SetSchema( "clock", "update" );
                _message.SetTarget( "*" );
                _message.type = XPL_STAT;
                _message.hop = 1;
                _message.AddCommand("time", "20180730113315");
                xpl.SendMessage( (xPL_Message *)&_message, true );
                */
                
                _message.SetSchema( "sensor", "basic" );
                _message.SetTarget( "*" );
                _message.type = XPL_STAT;
                _message.hop = 1;
                _message.AddCommand("device", "test1");
                _message.AddCommand("type", "test");
                _message.AddCommand("current", "1");
                xpl.SendMessage( (xPL_Message *)&_message, true );
                
                logger.printf("<<<<<< Sample Message Sent >>>>>>\r\n");
                TFT_Debug_XY_F2(1, 27, "TX: HB(%d)", iHBSentCount++);
                
                // reset
                iAppLoop = 0;
                }
            
            // pause for a sec !
            ThisThread::sleep_for(100);
			
            } while(waitTouch != false) ;
		
		}
	
    }