/********************************************************************************
 * File Name: GPIB2.c				 											*
 * Creation: 02/03/2003 JCG														*
 * Purpose: This sample demonstrates using Origin C code to enumerate the 		*
 * listeners on the GPIB board.													*
 * Copyright (c) OriginLab Corp.	2002, 2003, 2004, 2005, 2006, 2007			*
 * All Rights Reserved															*
 ********************************************************************************/

#include <origin.h>  // Origin C general header file
#include <NI488-2.h> // Prototypes for the National Instrument NI488.2 GPIB routines and constants.

//////////////////////////////////////////////////////////////////////////////////////////////
// There are two functions in this Origin C demo code 
// void Find() 
// void GpibError(char *msg);  
// See function discription below.
//
// After compliling, your can type the "Find" command in 
// command pane of code builder to execute this program.  
////////////////////////////////////////////////////////////////////////////////////////////// 

// Define a macro to print out the error message.
#define CHECK_ERROR	if (user_ibsta & ERR) { GpibError("ibwrt or ibrd Error"); return; }

// Prototype for function GpibError
void GpibError(char *msg);       				 /* Error function declaration             */

//////////////////////////////////////////////////////////////////////////////////////////////
// Function: void Find()
// Purpose: to enumerate the listeners on the GPIB.
//
// Argument(s): none.
// Return: void
//
// For HP34401A, the testing result is:
//
//	1> Find
//	Finding all listeners on the bus...
//
//	Number of instruments found = 1
//	The instrument at address 8 is a HEWLETT-PA
//	The instrument HEWLETT-PA was found
//////////////////////////////////////////////////////////////////////////////////////////////


#define MAX_INSTRUMENTS	30
void Find() 
{
	int nBoardIndex = 0;           				  /* Interface Index (GPIB0=0,GPIB1=1,etc.) */

	char  buffer[101];              			  /* name identification received from instrument  */
 	int nlisteners,    			   				  /* Number of listeners on GPIB             */
 
 	int        	nLoop,             				  /* FOR loop counter and array index        */

	Addr4882_t	SRQasserted;       				  /* Set to indicate if SRQ is asserted      */
	Addr4882_t	statusByte;        				  /* Serial Poll Response Byte               */
	Addr4882_t	pad;   			  				  /* Primary address of listener on GPIB     */
	Addr4882_t  result[MAX_INSTRUMENTS+1];        /* Array of listen addresses               */
	Addr4882_t  instruments[MAX_INSTRUMENTS+2];   /* Array of primary addresses              */

	/* Create an array containing all valid GPIB primary addresses.  The GPIB
	interface board is at address 0 by default.  This array (INSTRUMENTS)
	will be given to the function FindLstn to find all listeners. */
	
	for (int nLoop = 0; nLoop < MAX_INSTRUMENTS + 1; nLoop++)
		instruments[nLoop] = nLoop;
	
	instruments[31] = NOADDR;

	/* Print message to tell user that the program is searching for all active
	listeners.  Find all of the listeners on the bus. Store the listen
	addresses in the array RESULT. */
	printf("Finding all listeners on the bus...\n");
	printf("\n");

	ibrsc(nBoardIndex, 1);
	
	SendIFC(nBoardIndex);
	
	FindLstn(nBoardIndex, &instruments[1], result, 31);
	CHECK_ERROR;

	/* Assign the value of IBCNT to the variable NUM_LISTENERS.
	Print the number of listeners found. */
	nlisteners = (short)user_ibcntl;
	
	printf("Number of instruments found = %d\n", nlisteners);

	/* Send the *IDN? command to each device that was found.
    Establish a FOR loop to reand all listeners, the variable
    nLoop will serve as a counter for the FOR loop and
	as the index to the array RESULT. */

	for (nLoop = 0; nLoop < nlisteners + 1; nLoop++) 
	{

		/* Send the identification query to each listen address in the
		array RESULT.  The constant NLend instructs the function Send to
		append a linefeed character with EOI asserted to the end of the
		message. */
		
		Send(nBoardIndex, result[nLoop], "*IDN?", 5L, NLend);	
		CHECK_ERROR;

		/* Read the name identification response returned from each device.
		Store the response in the array BUFFER.  The constant STOPend
		instructs the function Receive to terminate the read when END
		is detected. */

		Receive(nBoardIndex, result[nLoop], buffer, 10L, STOPend);
		CHECK_ERROR;

		/* The low byte of the listen address is the primary address.
		Assign the variable PAD the primary address of the device.
		The macro GetPAD returns the low byte of the listen address. */

		pad = GetPAD(result[nLoop]);

		/* Use the null character to mark the end of the data received
		in the array BUFFER.  Print the primary address and the name
		identification of the device. */

		buffer[(short)user_ibcntl] = '\0';
		printf("The instrument at address %d is a %s\n", pad, buffer);

		/* print the the name identification*/
		printf("The instrument %s was found\n" ,buffer);

	}   /*  End of FOR loop */

	/* Call the ibonl function to disable the hardware and software. */
    ibonl(nBoardIndex, 0);
}


//////////////////////////////////////////////////////////////////////////////////////////////
// Function:void GpibError(char *msg); 
// Purpose:	This function will notify you that a NI-488 function failed by
// 			printing an error message.  The status variable user_ibsta will also be
// 			printed in hexadecimal along with the mnemonic meaning of the bit
// 			position. The status variable user_iberr will be printed in decimal
// 			along with the mnemonic meaning of the decimal value.  The status
// 			variable user_ibcntl will be printed in decimal.

// 			The NI-488 function IBONL is called to disable the hardware and
// 			software.
// Argumnent(s): msg the error message will be out put
// Return: void					
//////////////////////////////////////////////////////////////////////////////////////////////

void GpibError(char *msg) 
{
    printf ("%s\n", msg);

    printf ("ibsta = &H%x  <", user_ibsta);
    if (user_ibsta & ERR )  printf (" ERR");
    if (user_ibsta & TIMO)  printf (" TIMO");
    if (user_ibsta & END )  printf (" END");
    if (user_ibsta & SRQI)  printf (" SRQI");
    if (user_ibsta & RQS )  printf (" RQS");
    if (user_ibsta & CMPL)  printf (" CMPL");
    if (user_ibsta & LOK )  printf (" LOK");
    if (user_ibsta & REM )  printf (" REM");
    if (user_ibsta & CIC )  printf (" CIC");
    if (user_ibsta & ATN )  printf (" ATN");
    if (user_ibsta & TACS)  printf (" TACS");
    if (user_ibsta & LACS)  printf (" LACS");
    if (user_ibsta & DTAS)  printf (" DTAS");
    if (user_ibsta & DCAS)  printf (" DCAS");
    printf (" >\n");

    printf ("iberr = %d", user_iberr);
    if (user_iberr == EDVR) printf (" EDVR <DOS Error>\n");
    if (user_iberr == ECIC) printf (" ECIC <Not Controller-In-Charge>\n");
    if (user_iberr == ENOL) printf (" ENOL <No Listener>\n");
    if (user_iberr == EADR) printf (" EADR <Address error>\n");
    if (user_iberr == EARG) printf (" EARG <Invalid argument>\n");
    if (user_iberr == ESAC) printf (" ESAC <Not System Controller>\n");
    if (user_iberr == EABO) printf (" EABO <Operation aborted>\n");
    if (user_iberr == ENEB) printf (" ENEB <No GPIB board>\n");
    if (user_iberr == EOIP) printf (" EOIP <Async I/O in progress>\n");
    if (user_iberr == ECAP) printf (" ECAP <No capability>\n");
    if (user_iberr == EFSO) printf (" EFSO <File system error>\n");
    if (user_iberr == EBUS) printf (" EBUS <Command error>\n");
    if (user_iberr == ESTB) printf (" ESTB <Status byte lost>\n");
    if (user_iberr == ESRQ) printf (" ESRQ <SRQ stuck on>\n");
    if (user_iberr == ETAB) printf (" ETAB <Table Overflow>\n");

    printf ("ibcntl = %ld\n", user_ibcntl);
    printf ("\n");
    
    return;
}




