/* Application - HPDI32 - Any OS */
/* $Workfile: tx.c $ */
/* $Revision: 3 $ */
/* $Date: 10/27/07 4:39p $ */
/* $Log: /NEW SOURCESAFE DATABASE/SDK/PLX/gsc/hpdi32/tx/tx.c $
 * 
 * 3     10/27/07 4:39p Dnewbold
 * Linux porting changes.
 * 
 * 2     10/17/06 11:09a Dnewbold
 * Modularized the transmit test function.
 * 
 * 1     8/22/05 4:16p Dnewbold
*/

#include <stdio.h>
#include <string.h>

#include "main.h"
#include "util_label.h"
#include "util_sleep.h"



/* variables	*************************************************************/

static	U32	buffer[256L * 1024];	// 1MB of data.

							
							
/*****************************************************************************
*
*	Function:	_init
*
*	Purpose:
*
*		Initialize things in preparation for the test.
*
*	Arguments:
*
*		handle	The handle of the board to access.
*
*	Returned:
*
*		>= 0	The number of errors seen.
*
*****************************************************************************/

static int _init(void* handle)
{
	int	errs	= 0;
	U32	status;

	label_text("Initializing");
	memset(buffer, 0, sizeof(buffer));
	status	= hpdi32_init(handle);

	if (status != GSC_SUCCESS)
		errs	+= label_fail_func(1, "hpdi32_init", status);
	else
		printf("PASS\n");

	return(errs);
}



/*****************************************************************************
*
*	Function:	_config
*
*	Purpose:
*
*		Configure things in preparation for the test.
*
*	Arguments:
*
*		handle	The handle of the board to access.
*
*		fifos	Tell the caller if FIFOs are present.
*
*	Returned:
*
*		>= 0	The number of errors seen.
*
*****************************************************************************/

static int _config(void* handle, int* fifos)
{
	int				errs	= 0;
	unsigned long	feature	= 0;
	unsigned long	size	= 0;
	U32				status;

	label_text("Configuring");

	status	= HPDI32_MISC_TX_RX_TRI_STATE__YES(handle);

	if (status != GSC_SUCCESS)
		errs	+= label_fail_func(1, "HPDI32_MISC_TX_RX_TRI_STATE__YES", status);

	if (status == GSC_SUCCESS)
	{
		status	= HPDI32_FIFO_SIZE__TX_GET(handle, &size);

		if (status != GSC_SUCCESS)
			errs	+= label_fail_func(1, "HPDI32_FIFO_SIZE__TX_GET", status);
	}

	if (status == GSC_SUCCESS)
	{
		status	= HPDI32_MISC_FEATURES__FIFO_SIZE(handle, &feature);

		if (status != GSC_SUCCESS)
		{
			errs	+= label_fail_func(1, "HPDI32_MISC_FEATURES__FIFO_SIZE", status);
		}
		else if ((feature == HPDI32_MISC_FEATURES_PRESENT) && (size == 0))
		{
			fifos[0]	= 0;
			printf("  No FIFOs installed.\n");
		}
	}

	if (status == GSC_SUCCESS)
	{
		status	= HPDI32_IO_MODE__TX_PIO(handle);

		if (status != GSC_SUCCESS)
		{
			errs	+= label_fail_func(1, "HPDI32_IO_MODE__TX_PIO", status);
		}
	}

	if ((status == GSC_SUCCESS) && (fifos[0]))
	{
		status	= HPDI32_TX_ENABLE__YES(handle);

		if (status != GSC_SUCCESS)
			errs	+= label_fail_func(1, "HPDI32_TX_ENABLE__YES", status);
	}

	if (errs == 0)
		printf("PASS\n");

	return(errs);
}



/*****************************************************************************
*
*	Function:	_wait_for_tx_empty
*
*	Purpose:
*
*		Wait for the transmitted data to exit the Tx FIFO.
*
*	Arguments:
*
*		device		The handle used to access the device under test.
*
*	Returned:
*
*		GSC_SUCCESS	All went well.
*		else		An appropriate error status.
*
*****************************************************************************/

static U32 _wait_for_tx_empty(void* device)
{
	unsigned long	fifo;
	U32				status;

	printf("Waiting for Tx: ");
	fflush(stdout);
	sleep_ms(5);

	for (;;)
	{
		status	= HPDI32_FIFO_STATUS__TX_GET(device, &fifo);

		if (status != GSC_SUCCESS)
		{
			printf("FAIL <--- (HPDI32_FIFO_STATUS__TX_GET)\n");
			break;
		}

		if (fifo == HPDI32_FIFO_STATUS_EMPTY)
		{
			// Allow time for the last few items.
			sleep_ms(5);
			break;
		}
	}

	if (status == GSC_SUCCESS)
		printf("Done  (Data sent out cable interface.)\n");

	return(status);
}



/*****************************************************************************
*
*	Function:	_tx
*
*	Purpose:
*
*		Transmit the data.
*
*	Arguments:
*
*		handle	The handle of the board to access.
*
*		fifos	Are FIFOs present.
*
*		errs	Were any errors reported.
*
*	Returned:
*
*		>= 0	The number of errors seen.
*
*****************************************************************************/

static int _tx(void* handle, int fifos, int errs)
{
	char	buf[128];
	size_t	bytes	= sizeof(buffer);
	U32		sent	= 0;
	U32		status;

	for (;;)
	{
		sprintf(buf, "Writing %lu Bytes", (long) bytes);
		label_text(buf);

		if (fifos == 0)
		{
			errs	= 0;
			printf("ABORTED <--   (no FIFOS)\n");
			break;
		}

		if (errs)
		{
			errs	= 0;
			printf("ABORTED <--   (setup errors)\n");
			break;
		}

		status	= hpdi32_write(handle, buffer, sizeof(buffer), &sent);

		if (status != GSC_SUCCESS)
			errs	+= label_fail_func(1, "hpdi32_write", status);
		else
			printf("PASS\n");

		status	= _wait_for_tx_empty(handle);
		errs	+= (status == GSC_SUCCESS) ? 0 : 1;
		break;
	}

	return(errs);
}



/*****************************************************************************
*
*	Function:	tx_data
*
*	Purpose:
*
*		Perform a simple data transmit operation.
*
*	Arguments:
*
*		handle	The handle of the board to access.
*
*	Returned:
*
*		>= 0	The number of errors seen.
*
*****************************************************************************/

int	tx_data(void* handle)
{
	int				errs		= 0;
	int				fifos		= 1;

	label_text("Transmitting Data");
	printf("\n");
	label_level_inc();

	errs	+= _init(handle);
	errs	+= _config(handle, &fifos);
	errs	+= _tx(handle, fifos, errs);

	label_level_dec();
	return(errs);
}


