//*************************************************************************
/*
Copyright (c) 2009. Pandora Products
*/
//*************************************************************************
/*
*  Module Name:         fire_net - Firing box network code
*
*  Description:         This code will be used to connect to the
*						firing box CSMA RS-485 network used between
*						firing boxes
*
*  Revision History:	25-Sep-2009 [fa981152d5] Real network support
*						11-Jan-2011	DTR is inverted wrt TX use
*						22-Jan-2011 [f2fa5910e4] Add delay for XMIT Enable/Disable
*                       23-Aug-2011 [0020ac449a] Add RS-232 debug flag
*						31-Dec-2011 The head end controller will do the tx/RX 
*									control [55fd308482]
*/
//************************************************************************

#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include "real_phy.h"

#ifdef BSD_VERSION
	#include "bsdserial.h"
#else
	#include "linserial.h"
#endif

#include "debug.h"

#if 0
	#pragma mark -
	#pragma mark -- Data --
#endif

#define FIRENET_BAUD	38400
#define FIRENET_DWELL	100
#define NET_TX_ON_DLY	10		// usec Found by experiment
#define NET_TX_OFF_DLY	5000		// usec Found by experiment


#if 0
	#pragma mark -
	#pragma mark -- External SIMULATION API --
#endif

//*************************************************************************
/*
*  void real_prep_phys( void )	- Initialize Phy layer
*
*	INPUT:	NONE
*
*	OUTPUT:	NONE
*
*	This is called by the startup code (before threading)
*	to init the PHY layer
*/
//************************************************************************

void real_prep_phys( void )
{
	// Nothing to do here....
}

#if 0
	#pragma mark -
	#pragma mark -- External API --
#endif

//*************************************************************************
/*
*  void *real_init_phy( char *port )	- Initialize Phy layer
*
*	INPUT:	port	- Serial port used (number in list)
*
*	OUTPUT:	Return port handle if opened, NULL if problem
*
*	This is called by each node to get the port used for I/O
*/
//************************************************************************

void  *real_init_phy( char *port )
{
	void *rtnval = NULL;
	int psn = strtol(port,NULL,0);
	PORT_LIST *plist;
	PORT_HANDLE *ph;
	
	// (1) Build the port list
	
	plist = ListPorts( 1 );
	if( plist != NULL )
	{
		// (2) Now open the serial port for this run
		
		ph = OpenPort( psn,
						plist,
						FIRENET_BAUD,
						SER_STOP_ONE,
						SER_PARITY_NONE);
		if( ph != NULL )
		{
#ifdef RS232_COM
            printf("\n** FIRENET RS-232 DEBUG MODE **\n");
#endif
			// (3) Turn off DTR and start runnning
			
			real_phy_tx(0,ph);
			rtnval = (void *)ph;
		}
		
		FreePorts( plist );
	}
						
	return( rtnval );
}

//*************************************************************************
/*
*  void real_close_phy( char *port )	- Close Phy layer
*
*	INPUT:	h	- Port handle
*
*	OUTPUT:	NONE
*/
//************************************************************************

void real_close_phy( void *h )
{
	PORT_HANDLE *ph = (PORT_HANDLE *)h;
	
	ClosePort( ph );
}

//*************************************************************************
/*
* int real_put_phy( unsigned char data )	- Put data into output buffer
*
*	INPUT:	data	- Character for output
*			h		- PHY handle (ignored here)
*
*	OUTPUT:	0	- Success, <> 0 failure to store
*
*/
//************************************************************************

int real_put_phy( unsigned char data,void *h )
{
	int rtnval = -1;
	PORT_HANDLE *ph = (PORT_HANDLE *)h;
	char buffer[4];
	
	buffer[0] = (char)data;
	rtnval = WritePort(buffer,1,ph);
	
	// Did we get something ?
	
	if( rtnval == 1 )
		rtnval = 0;
	
	// If echo eat it


	//if(real_stat_phy(ph) )
	//{
	//	ReadPort(buffer,1,ph);
	//}
	
	return( rtnval );
}

//*************************************************************************
/*
* int real_stat_phy( void *h )	- Is there data to read ?
*
*	INPUT:	psn	- This thread's read psn
*
*	OUTPUT:	1	- We have data, 0 no data (psn == buf_psn)
*
*/
//************************************************************************
	
int real_stat_phy( void *h )
{
	int rtnval = -1;
	PORT_HANDLE *ph = (PORT_HANDLE *)h;
	
	rtnval = StatPort( FIRENET_DWELL, ph );
			
	return( rtnval );
}

//*************************************************************************
/*
* int real_get_phy( void *h )	- Read data
*
*	INPUT:	h	- Port handle
*
*	OUTPUT:	Returned data, EOF if no data
*/
//************************************************************************

int real_get_phy( void *h )
{
	int rtnval = EOF;
	PORT_HANDLE *ph = (PORT_HANDLE *)h;
	char buffer[4];
	int val;
	
	val = ReadPort( buffer,1,ph );
	if( val >= 1 )
	{
		rtnval = (int)(0xff & buffer[0]);
	}
	
	return( rtnval );
}

//*************************************************************************
/*
* void real_phy_tx( int flag,void *h )	- Enable/Disable xmit
*
*	INPUT:	flag	- 1 Enable transmit,0 disable transmit
*			h		- Port handle
*
*	OUTPUT:	Returned data, EOF if no data
*
*	11-Jan-2011	Invert meaning of flag since DTR from USB board is
*				inverted.
*	22-Jan-2011	Add delays on TX on and TX off.  Delay after on and before OFF
*	31-Dec-2011 Delete this as hardware in the head end controller will do the
*				tx/RX control [55fd308482]
*/
//************************************************************************

void real_phy_tx( int flag,void *h )
{
	//PORT_HANDLE *ph = (PORT_HANDLE *)h;
	
	// Turn DTR on or OFF
	// NOTE: DTR FLAG = 1	=> XMIT ON -> DTR OFF
	//			 FLAG = 0	=> XMIT OFF -> DTR ON
    
#ifdef RS232_COM
    flag = 0;          // TURN DTR OFF ALWAYS
#endif
	
	if( flag )
	{
		//DTRPort(0,ph);
		//usleep(NET_TX_ON_DLY);		// Delay after ON
	}
	else
	{
		//usleep(NET_TX_OFF_DLY);		// Delay before OFF
		//DTRPort(1,ph);
	}
}
