
/*+-----------------------------------------------------------------------+  */
/*| (C) ADDI-DATA GmbH Dieselstra?e 3 D-77833 Ottersweier                 |  */
/*+-----------------------------------------------------------------------+  */
/*| Tel : +49 (0) 7223/9493-0     | email : info@addi-data.com            |  */
/*| Fax : +49 (0) 7223/9493-92    | Internet : http:$/$/www.addi-data.com   |*/
/*+-------------------------------+---------------------------------------+  */
/*| Project : APCI-3600           | Compiler : Microsoft Visual C++       |  */
/*| Module name : ANA_OUT.C       |  Version : 6.0                        |  */
/*+-------------------------------+---------------------------------------+  */
/*| Author : Guinot Catherine       Date : 05/08/2004                     |  */
/*+-----------------------------------------------------------------------+  */
/*| Description : Analog Output API Functions of the APCI-3600            |  */
/*+-----------------------------------------------------------------------+  */
/*|                             UPDATES                                   |  */
/*+----------+-----------+------------------------------------------------+  */
/*| Date     | Author    | Description of updates                         |  */
/*+----------+-----------+------------------------------------------------+  */
/*|          |           |                                                |  */
/*+----------+-----------+------------------------------------------------+  */
#include "apci3600-private.h"


#ifdef ANA_OUT_DEBUG
   #define AO_DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
#else
   #define AO_DPRINTK(fmt, args...)
#endif


EXPORT_SYMBOL(i_PCI3600_InitAnalogOutChannel );
EXPORT_SYMBOL(i_PCI3600_ReleaseAnalogOutChannel );
EXPORT_SYMBOL(i_PCI3600_GetAnalogOutReadyBitStatus );
EXPORT_SYMBOL(i_PCI3600_WriteAnalogOutValue );
EXPORT_SYMBOL(i_PCI3600_Set1AnalogOutChannel );
EXPORT_SYMBOL(i_PCI3600_ReserveAnalogOutSignalGeneratorComputerBuffer );
EXPORT_SYMBOL(i_PCI3600_FreeAnalogOutSignalGeneratorComputerBuffer );
EXPORT_SYMBOL(i_PCI3600_WriteAnalogOutSignalGeneratorComputerRAM );
EXPORT_SYMBOL(i_PCI3600_InitAnalogOutSignalGenerator );
EXPORT_SYMBOL(i_PCI3600_StartAnalogOutSignalGenerator );
EXPORT_SYMBOL(i_PCI3600_GetAnalogOutSignalGeneratorStatus );
EXPORT_SYMBOL(i_PCI3600_StopAnalogOutSignalGenerator );
EXPORT_SYMBOL(i_PCI3600_ReleaseAnalogOutSignalGenerator );
EXPORT_SYMBOL(i_PCI3600_AnalogOut_EnableDisableDigitalInputExternalTrigger );
EXPORT_SYMBOL(i_PCI3600_AnalogOut_EnableDisableMasterTrigger );
EXPORT_SYMBOL(i_PCI3600_QueryAnalogInputCyclicAcquisitionBufferSize );

/*i_PCI3600_InitAnalogOutChannel*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_InitAnalogOutChannel ()                       |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : Wrong clock selection                                           */
/*         -4 : Wrong Speed mode parameter                                      */
/*         -5 : The board is not initialised                                    */
/*         -6 : Speed mode not available                                        */
/*         -7 : The channel is already initialised by another process           */
/*         -8 : Initialisation Error                                            */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_InitAnalogOutChannel (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t b_SamplingClockSelection,
		uint8_t b_SpeedMode)
{
	int   i_ReturnValue     = 0;

	if (!pdev)
		return -1;

	/*********************************/
	/* Test the selected channel nbr */
	/*********************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/****************************/
		/* Test the clock selection */
		/****************************/
		if ((b_SamplingClockSelection == PCI3600_SAMPLING_CLOCK1) ||
				(b_SamplingClockSelection == PCI3600_SAMPLING_CLOCK2)) {
			/***************************************/
			/* Test the Speed mode parameter value */
			/***************************************/
			if ((b_SpeedMode == PCI3600_SINGLE_SPEED) ||
					(b_SpeedMode == PCI3600_DOUBLE_SPEED) ||
					(b_SpeedMode == PCI3600_QUAD_SPEED)) {
				/************************************/
				/* Test if the board is initialised */
				/************************************/
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_BoardInfos.
						b_BoardInitialised == 1) {
					/*********************************/
					/* Test the speed mode parameter */
					/*********************************/
					if (i_PCI3600_Intern_TestSpeedModeParameter (&APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation,
							b_SamplingClockSelection,
							b_SpeedMode) != 0) {
						/****************************/
						/* Speed mode not available */
						/****************************/
						i_ReturnValue = -6;

					}
				} else {
					/********************************/
					/* The board is not initialised */
					/********************************/
					i_ReturnValue = -5;

				}
			} else {
				/******************************/
				/* Wrong Speed mode parameter */
				/******************************/
				i_ReturnValue = -4;

			}
		} else {
			/*************************/
			/* Wrong clock selection */
			/*************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	if (i_ReturnValue == 0)
	{
		/**************************************************/
		/* Test if the channel is not already initialised */
		/**************************************************/
		if ((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitStatus == 0) ||
				((APCI3600_PRIVDATA(pdev)->
				  s_PCI3600_BoardInformation.
				  s_AnalogOutInfos[b_Channel].
				  b_ChannelInitStatus == 1) &&
				 (APCI3600_PRIVDATA(pdev)->
				  s_PCI3600_BoardInformation.
				  s_AnalogOutInfos[b_Channel].
				  b_ChannelInitProcessIndex == 0))) {

			if (i_PCI3600_Primary_InitAnalogOutChannel (GET_MEM_BAR3(pdev) +
					PCI3600_ANALOG_OUTPUT_OFFSET,
					b_Channel,
					b_SamplingClockSelection,
					b_SpeedMode) != 0) {
				/************************/
				/* Initialisation Error */
				/************************/
				i_ReturnValue = -8;

			} else {
				/************************************************/
				/* Set the analog output channel as initialised */
				/************************************************/
				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitStatus = 1;

				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitProcessIndex = 0;

			}

		} else {
			/*********************************************************/
			/* The channel is already initialised by another process */
			/*********************************************************/
			i_ReturnValue = -7;

		}
	}
	return (i_ReturnValue);

}
/*i_PCI3600_ReleaseAnalogOutChannel*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_ReleaseAnalogOutChannel ()                    |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The channel is not initialised or initialised by another        */
/*              process                                                         */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_ReleaseAnalogOutChannel (struct pci_dev *pdev,
		uint8_t b_Channel)
{
	int   i_ReturnValue     = 0;

	if (!pdev)
		return -1;

	/*********************************/
	/* Test the selected channel nbr */
	/*********************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/**************************************/
		/* Test if the channel is initialised */
		/**************************************/
		if (((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitStatus == 1) &&
				(APCI3600_PRIVDATA(pdev)->
				 s_PCI3600_BoardInformation.
				 s_AnalogOutInfos[b_Channel].
				 b_ChannelInitProcessIndex == 0))) {

			/****************************************************/
			/* Set the analog output channel as not initialised */
			/****************************************************/
			APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			s_AnalogOutInfos[b_Channel].
			b_ChannelInitStatus = 0;


		} else {
			/********************************************************************/
			/* The channel is not initialised or initialised by another process */
			/********************************************************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	return (i_ReturnValue);

}
/*i_PCI3600_GetAnalogOutReadyBitStatus*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_GetAnalogOutReadyBitStatus ()                 |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The channel is not initialised                                  */
/*         -4 : The channel is initialised for the signal generator mode        */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_GetAnalogOutReadyBitStatus (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t* pb_ReadyBitStatus)
{
	int   i_ReturnValue     = 0;
	int   i_Return          = 0;


	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/**************************************/
		/* Test if the channel is initialised */
		/**************************************/
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitStatus == 1) {

			/***************************************************************/
			/* Test if the channel is not initialised for Signal generator */
			/***************************************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelSignalGeneratorInitStatus == 0) {
				i_Return = i_PCI3600_Primary_ReadAnalogOutReadyBit (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
						   b_Channel,
						   pb_ReadyBitStatus);

			} else {
				/************************************************************/
				/* The channel is initialised for the signal generator mode */
				/************************************************************/
				i_ReturnValue = -4;

			}

		} else {
			/**********************************/
			/* The channel is not initialised */
			/**********************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	return (i_ReturnValue);

}
/*i_PCI3600_WriteAnalogOutValue*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_WriteAnalogOutValue ()                        |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The channel is not initialised                                  */
/*         -4 : This function cannot work if the digital external trigger is    */
/*              enabled                                                         */
/*         -5 : The channel is initialised for the signal generator mode        */
/*         -6 : The channel is not ready to receive a new value                 */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_WriteAnalogOutValue (struct pci_dev *pdev,
										uint8_t b_Channel,
										uint16_t w_Value)
{
	int   i_ReturnValue     = 0;
	int   i_Return          = 0;
	uint8_t  b_ReadyBitStatus  = 0;


	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/**************************************/
		/* Test if the channel is initialised */
		/**************************************/
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitStatus == 1) {
			/*******************************************************/
			/* Test if the digital external trigger is not enabled */
			/*******************************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelDigExtTriggerEnable == 0) {

				/***************************************************************/
				/* Test if the channel is not initialised for Signal generator */
				/***************************************************************/
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						b_ChannelSignalGeneratorInitStatus == 0) {
					/*****************************/
					/* Test the ready bit Status */
					/*****************************/
					i_Return = i_PCI3600_Primary_ReadAnalogOutReadyBit (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
							   b_Channel,
							   &b_ReadyBitStatus);

					if (b_ReadyBitStatus == 1) {
						/***********************/
						/* Write the new value */
						/***********************/
						i_Return = i_PCI3600_Primary_WriteAnalogOutValue (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
								   GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,
								   b_Channel,
								   w_Value);

					} else {
						/***************************************************/
						/* The channel is not ready to receive a new value */
						/***************************************************/
						i_ReturnValue = -6;

					}
				} else {
					/************************************************************/
					/* The channel is initialised for the signal generator mode */
					/************************************************************/
					i_ReturnValue = -5;

				}

			} else {
				/************************************************************************/
				/* This function cannot work if the digital external trigger is enabled */
				/************************************************************************/
				i_ReturnValue = -4;

			}
		} else {
			/**********************************/
			/* The channel is not initialised */
			/**********************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	return (i_ReturnValue);

}
/*i_PCI3600_Set1AnalogOutChannel*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_Set1AnalogOutChannel ()                       |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The channel is not initialised                                  */
/*         -4 : This function cannot work if the digital external trigger is    */
/*              enabled                                                         */
/*         -5 : The channel is initialised for the signal generator mode        */
/*         -6 : Time function error                                             */
/*         -7 : Time out occur                                                  */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_Set1AnalogOutChannel (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint16_t w_Value)
{
	int   i_ReturnValue     = 0;
	int   i_Return      = 0;
	int   i_TimeReturn      = 0;
	uint8_t  b_ReadyBitStatus  = 0;
	uint8_t  b_TimeOutStatus   = 0;
	ADDI_TIMEVAL dw64_SystemTimeBegin;


	if (!pdev)
		return -1;


	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/**************************************/
		/* Test if the channel is initialised */
		/**************************************/
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelInitStatus == 1) {
			/*******************************************************/
			/* Test if the digital external trigger is not enabled */
			/*******************************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelDigExtTriggerEnable == 0) {

				/***************************************************************/
				/* Test if the channel is not initialised for Signal generator */
				/***************************************************************/
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						b_ChannelSignalGeneratorInitStatus == 0) {
					i_TimeReturn = i_ADDIUTILS_GetSystemTime    (&dw64_SystemTimeBegin);

					if (i_TimeReturn == 0) {
						do {
							/*****************************/
							/* Test the ready bit Status */
							/*****************************/
							i_Return = i_PCI3600_Primary_ReadAnalogOutReadyBit (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
									   b_Channel,
									   &b_ReadyBitStatus);

							i_TimeReturn = i_ADDIUTILS_CheckSystemTime (dw64_SystemTimeBegin,
										   PCI3600_ANALOG_OUTPUT_READY_BIT_TIMEOUT,
										   &b_TimeOutStatus );

							if (i_TimeReturn != 0) {
								/***********************/
								/* Time function error */
								/***********************/
								i_ReturnValue = -6;

							}
						} while ((b_ReadyBitStatus == 0) && (i_Return == 0) && (i_TimeReturn == 0) && (b_TimeOutStatus == 0));
						if ((i_Return == 0) && (b_TimeOutStatus == 0) && (i_TimeReturn == 0) && (b_ReadyBitStatus == 1)) {
							/***********************/
							/* Write the new value */
							/***********************/
							i_Return = i_PCI3600_Primary_WriteAnalogOutValue (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
									   GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,
									   b_Channel,
									   w_Value);

						}
						/**************************/
						/* Test if time out occur */
						/**************************/
						if (b_TimeOutStatus == 1) {
							/******************/
							/* Time out occur */
							/******************/
							i_ReturnValue = -7;

						}
					} else {
						/***********************/
						/* Time function error */
						/***********************/
						i_ReturnValue = -6;

					}
				} else {
					/************************************************************/
					/* The channel is initialised for the signal generator mode */
					/************************************************************/
					i_ReturnValue = -5;

				}

			} else {
				/************************************************************************/
				/* This function cannot work if the digital external trigger is enabled */
				/************************************************************************/
				i_ReturnValue = -4;

			}
		} else {
			/**********************************/
			/* The channel is not initialised */
			/**********************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	return (i_ReturnValue);

}
/*i_PCI3600_ReserveAnalogOutSignalGeneratorComputerBuffer*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_ReserveAnalogOutSignalGeneratorComputerBuffer |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : Buffer Size error                                               */
/*         -4 : The buffer is already reserved by another process               */
/*         -5 : The PC DMA Buffer is in use                                     */
/*         -6 : The channel is initialised in signal generator mode             */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_ReserveAnalogOutSignalGeneratorComputerBuffer (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint32_t dw_BufferSize)
{
	int   i_ReturnValue     = 0;
	uint8_t  b_CyclicAcquisitionInUse = 0;
	uint8_t  b_Cpt = 0;
	uint32_t dw_Offset = 0;

	if (!pdev)
		return -1;


	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/************************/
		/* Test the buffer size */
		/************************/
		if (((dw_BufferSize * 4) < (APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_BoardInfos.
									s_PCAllocatedMemoryBuffer.
									ul_BufferSize - ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER)))) && (dw_BufferSize != 0)) {
			/******************************************************************/
			/* Test if the buffer are not already reserved by another process */
			/******************************************************************/
			if ((APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelBufferReserved == 0) ||
					((APCI3600_PRIVDATA(pdev)->
					  s_PCI3600_BoardInformation.
					  s_AnalogOutInfos[b_Channel].
					  b_ChannelBufferReserved == 1) && (APCI3600_PRIVDATA(pdev)->
														s_PCI3600_BoardInformation.
														s_AnalogOutInfos[b_Channel].
														b_ChannelBufferProcessIndex == 0))) {
				/******************************************************************************************/
				/* Test if the analog input or the chronometer are initialised in cyclic acquisition mode */
				/******************************************************************************************/
				for (b_Cpt = 0; b_Cpt < APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						b_AnalogInModuleNumber; b_Cpt ++) {
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogInModuleInfos[b_Cpt].
							b_ModuleCyclicAcquisitionInitStatus == 1) {
						b_CyclicAcquisitionInUse = 1;

						b_Cpt = APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								b_AnalogInModuleNumber;

					}
				}
				for (b_Cpt = 0; b_Cpt < APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						b_ChronometerNumber; b_Cpt ++) {
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_ChronometerInfos[b_Cpt].
							b_ChronometerCyclicAcquisitionInitStatus == 1) {
						b_CyclicAcquisitionInUse = 1;

						b_Cpt = APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								b_ChronometerNumber;

					}
				}
				/******************************************************************************************/
				/* Test if the analog input or the chronometer are initialised in cyclic acquisition mode */
				/******************************************************************************************/
				if (b_CyclicAcquisitionInUse == 0) {
					/***********************************************************/
					/* Test if the channel is in use for signal generator mode */
					/***********************************************************/
					if (APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[b_Channel].
							b_ChannelSignalGeneratorInitStatus == 1) {
						/*******************************************************/
						/* The channel is initialised in signal generator mode */
						/*******************************************************/
						i_ReturnValue = -6;

					}
				} else {
					/*******************************/
					/* The PC DMA Buffer is in use */
					/*******************************/
					i_ReturnValue = -5;

				}
			} else {
				/*************************************************************/
				/* The buffer is not reserved or reserved by another process */
				/*************************************************************/
				i_ReturnValue = -4;

			}
		} else {
			/*********************/
			/* Buffer Size error */
			/*********************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	if (i_ReturnValue == 0)
	{

		/**************************************************************/
		/* Test if the other analog output channel buffer is reserved */
		/**************************************************************/
		/**************************************************************/
		/* Test if the other analog output channel buffer is reserved */
		/**************************************************************/
		if (b_Channel == 0) {
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[1].
					b_ChannelBufferReserved == 1) {
				dw_Offset = APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[1].
							s_AnalogOutPCDMABufferInfos.
							dw_BufferSize;

			} else {
				dw_Offset = 0;

			}
		} else {
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[0].
					b_ChannelBufferReserved == 1) {
				dw_Offset = APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[0].
							s_AnalogOutPCDMABufferInfos.
							dw_BufferSize;

			} else {
				dw_Offset = 0;

			}
		}
		/*************************************************/
		/* Save the information from the reserved buffer */
		/*************************************************/
		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		pdw_DMABuffer[1] = (uint32_t)(uintptr_t)APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   s_BoardInfos.
						   s_PCAllocatedMemoryBuffer.
						   pv_DMABufferRing0[0] + dw_Offset + ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		pdw_DMABuffer[0] = (uint32_t)(uintptr_t)APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   s_BoardInfos.
						   s_PCAllocatedMemoryBuffer.
						   pv_DMABufferRing0[0] + dw_Offset + ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		dw_PhysicalAddress = APCI3600_PRIVDATA(pdev)->
							 s_PCI3600_BoardInformation.
							 s_BoardInfos.
							 s_PCAllocatedMemoryBuffer.
							 ul_PhysicalAddress [0] + dw_Offset + ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		dw_BufferSize = (dw_BufferSize * 4);

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		b_Empty = 1;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		b_Full = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		dw_ReadPointer = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		s_AnalogOutPCDMABufferInfos.
		dw_WritePointer = 0;

		/*********************************************************************/
		/* Update the Analog Input / Chronometer Computer Buffer information */
		/*********************************************************************/

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		pdw_DMABuffer[0] = (uint32_t)(uintptr_t)APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   s_BoardInfos.
						   s_PCAllocatedMemoryBuffer.
						   pv_DMABufferRing0  [0] + dw_Offset + (dw_BufferSize * 4) + ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		pdw_DMABuffer[1] = (uint32_t)(uintptr_t)APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   s_BoardInfos.
						   s_PCAllocatedMemoryBuffer.
						   pv_DMABufferRing0  [0] + dw_Offset + (dw_BufferSize * 4) + ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		dw_PhysicalAddress = APCI3600_PRIVDATA(pdev)->
							 s_PCI3600_BoardInformation.
							 s_BoardInfos.
							 s_PCAllocatedMemoryBuffer.
							 ul_PhysicalAddress [0] + dw_Offset + (dw_BufferSize * 4) + ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		dw_BufferSize = APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_BoardInfos.
						s_PCAllocatedMemoryBuffer.
						ul_BufferSize - (dw_Offset + (dw_BufferSize * 4)) - ((sizeof(str_PCI9054DMADescriptor) * PCI3600_MAX_NUMBER_OF_DESCRIPTOR + 0x10) * (PCI3600_NBR_OF_ANALOG_OUTPUT_CHANNEL + PCI3600_NBR_OF_ANALOG_INPUT_MODULE + PCI3600_NBR_OF_CHRONOMETER));

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		b_Empty = 1;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		b_Full = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		dw_ReadPointer = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnaInpChronomPCDMABufferInfos.
		dw_WritePointer = 0;


		/******************************/
		/* Set the buffer as reserved */
		/******************************/
		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelBufferReserved = 1;

		/************************************************/
		/* Save the process who has reserved the buffer */
		/************************************************/
		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelBufferProcessIndex = 0;


	}
	return (i_ReturnValue);

}
/*i_PCI3600_FreeAnalogOutSignalGeneratorComputerBuffer*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_FreeAnalogOutSignalGeneratorComputerBuffer () |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The buffer is not reserved or reserved by another process       */
/*         -4 : The channel is initialised in signal generator mode             */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_FreeAnalogOutSignalGeneratorComputerBuffer (struct pci_dev *pdev,
		uint8_t b_Channel)
{
	int   i_ReturnValue     = 0;

	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/***************************************************/
		/* Test if the buffer are reserved by this process */
		/***************************************************/
		if ((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelBufferReserved == 1) && (APCI3600_PRIVDATA(pdev)->
												  s_PCI3600_BoardInformation.
												  s_AnalogOutInfos[b_Channel].
												  b_ChannelBufferProcessIndex == 0)) {
			/***********************************************************/
			/* Test if the channel is in use for signal generator mode */
			/***********************************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelSignalGeneratorInitStatus == 1) {
				/*******************************************************/
				/* The channel is initialised in signal generator mode */
				/*******************************************************/
				i_ReturnValue = -4;

			}
		} else {
			/*************************************************************/
			/* The buffer is not reserved or reserved by another process */
			/*************************************************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	if (i_ReturnValue == 0)
	{

		/********************************/
		/* Clear the buffer information */
		/********************************/
		memset (&APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				s_AnalogOutPCDMABufferInfos,0, sizeof (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						s_AnalogOutPCDMABufferInfos));

		/**********************************/
		/* Set the buffer as not reserved */
		/**********************************/
		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelBufferReserved = 0;


	}
	return (i_ReturnValue);

}
/*i_PCI3600_WriteAnalogOutSignalGeneratorComputerRAM*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name :                                                            |*/
/*        i_PCI3600_WriteAnalogOutSignalGeneratorComputerRAM        */
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The buffer is not reserved                                      */
/*         -4 : The buffer is full                                              */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_WriteAnalogOutSignalGeneratorComputerRAM (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint32_t dw_NbrOfValue,
		uint16_t* pw_ValueArray,
		uint32_t* pdw_NbrOfWrittenValues,
		uint32_t* pdw_NbrOfFreeValues)
{
	int   i_ReturnValue     = 0;
	uint32_t dw_FreeSize       = 0;
	uint32_t dw_Cpt            = 0;
	uint32_t* pdw_BufferPointer = NULL;
	uint32_t dw_TempWritePointer = 0;

	if (!pdev)
		return -1;


	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/**********************************/
		/* Test if the buffer is reserved */
		/**********************************/
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelBufferReserved == 1) {
			/**********************************/
			/* Test if the buffer is full     */
			/**********************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					b_Full == 1) {
				/**********************/
				/* The buffer is full */
				/**********************/
				i_ReturnValue = -4;

			}
		} else {
			/******************************/
			/* The buffer is not reserved */
			/******************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	if (i_ReturnValue == 0)
	{

		/******************************************/
		/* Determine the free place in the buffer */
		/******************************************/
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				s_AnalogOutPCDMABufferInfos.
				b_Empty == 0) {
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					dw_ReadPointer > APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					dw_WritePointer  ) {
				dw_FreeSize = (APCI3600_PRIVDATA(pdev)->
							   s_PCI3600_BoardInformation.
							   s_AnalogOutInfos[b_Channel].
							   s_AnalogOutPCDMABufferInfos.
							   dw_ReadPointer - APCI3600_PRIVDATA(pdev)->
							   s_PCI3600_BoardInformation.
							   s_AnalogOutInfos[b_Channel].
							   s_AnalogOutPCDMABufferInfos.
							   dw_WritePointer) * 4; // *4 to convert in Byte

			} else {
				dw_FreeSize = (((APCI3600_PRIVDATA(pdev)->
								 s_PCI3600_BoardInformation.
								 s_AnalogOutInfos[b_Channel].
								 s_AnalogOutPCDMABufferInfos.
								 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnalogOutInfos[b_Channel].
								s_AnalogOutPCDMABufferInfos.
								dw_WritePointer) + APCI3600_PRIVDATA(pdev)->
							   s_PCI3600_BoardInformation.
							   s_AnalogOutInfos[b_Channel].
							   s_AnalogOutPCDMABufferInfos.
							   dw_ReadPointer ) * 4; // *4 to convert in Byte

			}
		} else {
			dw_FreeSize = APCI3600_PRIVDATA(pdev)->
						  s_PCI3600_BoardInformation.
						  s_AnalogOutInfos[b_Channel].
						  s_AnalogOutPCDMABufferInfos.
						  dw_BufferSize;

		}
		if (dw_NbrOfValue <= (dw_FreeSize / 4)) {
			*pdw_NbrOfWrittenValues = dw_NbrOfValue;

		} else {
			*pdw_NbrOfWrittenValues = (dw_FreeSize / 4);

		}
		pdw_BufferPointer = (uint32_t *)(uintptr_t)APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							s_AnalogOutInfos[b_Channel].
							s_AnalogOutPCDMABufferInfos.
							pdw_DMABuffer [1];

		dw_TempWritePointer = APCI3600_PRIVDATA(pdev)->
							  s_PCI3600_BoardInformation.
							  s_AnalogOutInfos[b_Channel].
							  s_AnalogOutPCDMABufferInfos.
							  dw_WritePointer;

		/*********************************************/
		/* Write the new values in the PC RAM Buffer */
		/*********************************************/
		for (dw_Cpt = 0; dw_Cpt < *pdw_NbrOfWrittenValues; dw_Cpt ++) {
			pdw_BufferPointer [dw_TempWritePointer] = (uint32_t)pw_ValueArray [dw_Cpt];

			dw_TempWritePointer = (dw_TempWritePointer + 1) % (APCI3600_PRIVDATA(pdev)->
								  s_PCI3600_BoardInformation.
								  s_AnalogOutInfos[b_Channel].
								  s_AnalogOutPCDMABufferInfos.
								  dw_BufferSize / 4);

		}

		//           v_PCI3600_Intern_CallCriticalFunction (PCI3600_CRITICAL_SECTION_SELECTION,
		//                                                  b_KRNL_Mode,
		//                                                  b_BoardIndex,
		//                                                  b_ProcessIndex,
		//                                                  ps_PCI3600_GlobalStruct,
		//                                                  PCI3600CRITICAL_IncrAnaOupBufferWritePointer,
		//                                                  2,
		//                                                  0,
		//                                                  b_Channel,
		//                                                  *pdw_NbrOfWrittenValues);

		i_PCI3600_Intern_IncrAnaOupBufferWritePointer(pdev,
				b_Channel,
				*pdw_NbrOfWrittenValues);


		*pdw_NbrOfFreeValues = (dw_FreeSize / 4) - *pdw_NbrOfWrittenValues;


	}
	return (i_ReturnValue);

}
/*i_PCI3600_InitAnalogOutSignalGenerator*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_InitAnalogOutSignalGenerator ()               |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : Wrong mode parameter                                            */
/*         -4 : The channel is not initialised                                  */
/*         -5 : The buffer is not reserved                                      */
/*         -6 : The compare value cannot be greater that the size of the on     */
/*              board buffer and cannot be null                                 */
/*         -7 : The Signal generator is already initialised by another process  */
/*         -8 : The signal generator is running                                 */
/*         -9 : Not enough place in the on board RAM                            */
/*        -10 : A cycle acquisition or a signal generator is running            */
/*        -11 : The compare value must be greater than the actual free place    */
/*              in the on board RAM                                             */
/*        -12 : The size of the PC RAM buffer must be the same as the           */
/*              On Board Buffer size and it must be full                        */
/*        -13 : The interrupt routine is not installed                          */
/*        -14 : Time function error                                             */
/*        -15 : Time out occur                                                  */
/*        -16 : Prepare DMA transfer Error                                      */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_InitAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t   b_Channel,
		uint8_t   b_Mode,
		uint32_t dw_OnBoardBufferSize,
		uint32_t dw_CompareValue)
{
	int   i_ReturnValue     = 0;
	uint8_t  b_CyclicAcquisitionInUse = 0;
	uint8_t  b_Cpt = 0;
	uint8_t  b_DMAStatus = 0;
	int   i_TimeReturn = 0;
	int   i_Return = 0;
	uint8_t  b_TimeOutStatus = 0;
	uint32_t dw_NbrOfData = 0;
	uint32_t dw_OnBoardBufferRealSize = 0;
	ADDI_TIMEVAL dw64_SystemTimeBegin;
	uint32_t dw_NbrOfDataToBeTransfered = 0;
	uint32_t dw_OnBoardFreePlace = 0;


	if (!pdev)
		return -1;



	dw_OnBoardBufferRealSize = (1024 * ((uint32_t)1 << dw_OnBoardBufferSize));

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/***************************/
		/* Test the mode parameter */
		/***************************/
		if ((b_Mode == PCI3600_FREE_RUN_MODE) || (b_Mode == PCI3600_RING_BUFFER_MODE)) {
			/**************************************/
			/* Test if the channel is initialised */
			/**************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelInitStatus == 1) {
				/**********************************/
				/* Test if the buffer is reserved */
				/**********************************/
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						b_ChannelBufferReserved == 1) {
					/**************************/
					/* Test the compare value */
					/**************************/
					if (((dw_CompareValue < (dw_OnBoardBufferRealSize / 4)) && (dw_CompareValue != 0)) || (b_Mode == PCI3600_FREE_RUN_MODE)) {
						/******************************************************************************/
						/* Test if the signal generator is not already initialised by another process */
						/******************************************************************************/
						if ((APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_AnalogOutInfos[b_Channel].
								b_ChannelSignalGeneratorInitStatus == 0) ||
								((APCI3600_PRIVDATA(pdev)->
								  s_PCI3600_BoardInformation.
								  s_AnalogOutInfos[b_Channel].
								  b_ChannelSignalGeneratorInitStatus == 1) &&
								 (APCI3600_PRIVDATA(pdev)->
								  s_PCI3600_BoardInformation.
								  s_AnalogOutInfos[b_Channel].
								  b_ChannelSignalGeneratorInitProcessIndex == 0))) {
							/***********************************************/
							/* Test if the signal generator is not running */
							/***********************************************/
							if (APCI3600_PRIVDATA(pdev)->
									s_PCI3600_BoardInformation.
									s_AnalogOutInfos[b_Channel].
									b_ChannelSignalGeneratorStartStatus == 0) {
								/*****************************************************/
								/* Test if there is enough place in the on board RAM */
								/*****************************************************/
								if (dw_OnBoardBufferRealSize < APCI3600_PRIVDATA(pdev)->
										s_PCI3600_BoardInformation.
										s_HardwareInformations.
										dw_OnBoardRAMSize) {
									/******************************************************************/
									/* Test if no other cycle acquisition or signal generator running */
									/******************************************************************/
									for (b_Cpt = 0; b_Cpt < APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											b_AnalogInModuleNumber; b_Cpt ++) {
										if (APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnalogInModuleInfos[b_Cpt].
												b_ModuleCyclicAcquisitionStartStatus == 1) {
											b_CyclicAcquisitionInUse = 1;

											b_Cpt = APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													b_AnalogInModuleNumber;

										}
									}
									for (b_Cpt = 0; b_Cpt < APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											b_ChronometerNumber; b_Cpt ++) {
										if (APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_ChronometerInfos[b_Cpt].
												b_ChronometerCyclicAcquisitionStartStatus == 1) {
											b_CyclicAcquisitionInUse = 1;

											b_Cpt = APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													b_ChronometerNumber;

										}
									}
									for (b_Cpt = 0; b_Cpt < APCI3600_PRIVDATA(pdev)->
											s_PCI3600_BoardInformation.
											b_AnalogOutChannelNumber; b_Cpt ++) {
										if ((APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnalogOutInfos[b_Cpt].
												b_ChannelSignalGeneratorStartStatus == 1) && (APCI3600_PRIVDATA(pdev)->
														s_PCI3600_BoardInformation.
														s_AnalogOutInfos[b_Cpt].
														b_ChannelSignalGeneratorRunMode == PCI3600_RING_BUFFER_MODE)) {
											b_CyclicAcquisitionInUse = 1;

											b_Cpt = APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													b_AnalogOutChannelNumber;

										}
									}
									/******************************************************************/
									/* Test if no other cycle acquisition or signal generator running */
									/******************************************************************/
									if (b_CyclicAcquisitionInUse != 1) {
										/*****************************************************/
										/* Determine the number of data in the PC RAM buffer */
										/*****************************************************/
										if (APCI3600_PRIVDATA(pdev)->
												s_PCI3600_BoardInformation.
												s_AnalogOutInfos[b_Channel].
												s_AnalogOutPCDMABufferInfos.
												b_Full == 0) {
											if (APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													s_AnalogOutInfos[b_Channel].
													s_AnalogOutPCDMABufferInfos.
													dw_ReadPointer > APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													s_AnalogOutInfos[b_Channel].
													s_AnalogOutPCDMABufferInfos.
													dw_WritePointer  ) {
												dw_NbrOfData = ((APCI3600_PRIVDATA(pdev)->
																 s_PCI3600_BoardInformation.
																 s_AnalogOutInfos[b_Channel].
																 s_AnalogOutPCDMABufferInfos.
																 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
																s_PCI3600_BoardInformation.
																s_AnalogOutInfos[b_Channel].
																s_AnalogOutPCDMABufferInfos.
																dw_ReadPointer) + APCI3600_PRIVDATA(pdev)->
															   s_PCI3600_BoardInformation.
															   s_AnalogOutInfos[b_Channel].
															   s_AnalogOutPCDMABufferInfos.
															   dw_WritePointer;

											} else {
												dw_NbrOfData = APCI3600_PRIVDATA(pdev)->
															   s_PCI3600_BoardInformation.
															   s_AnalogOutInfos[b_Channel].
															   s_AnalogOutPCDMABufferInfos.
															   dw_WritePointer - APCI3600_PRIVDATA(pdev)->
															   s_PCI3600_BoardInformation.
															   s_AnalogOutInfos[b_Channel].
															   s_AnalogOutPCDMABufferInfos.
															   dw_ReadPointer;

											}
										} else {
											dw_NbrOfData = (APCI3600_PRIVDATA(pdev)->
															s_PCI3600_BoardInformation.
															s_AnalogOutInfos[b_Channel].
															s_AnalogOutPCDMABufferInfos.
															dw_BufferSize / 4);

										}
										/*************************************************/
										/* Determine the free place in the PC RAM buffer */
										/*************************************************/
										if ((dw_OnBoardBufferRealSize / 4) > dw_NbrOfData) {
											dw_OnBoardFreePlace = (dw_OnBoardBufferRealSize / 4) - dw_NbrOfData;

										} else {
											dw_OnBoardFreePlace = 0;

										}
										/**************************************/
										/* Test the nbr of data in the PC RAM */
										/**************************************/
										if ((dw_OnBoardFreePlace < dw_CompareValue) || (b_Mode == PCI3600_FREE_RUN_MODE)) {
											/*************************************/
											/* Test the buffer size in Free mode */
											/*************************************/
											if (((APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													s_AnalogOutInfos[b_Channel].
													s_AnalogOutPCDMABufferInfos.
													dw_BufferSize == dw_OnBoardBufferRealSize) && (APCI3600_PRIVDATA(pdev)->
															s_PCI3600_BoardInformation.
															s_AnalogOutInfos[b_Channel].
															s_AnalogOutPCDMABufferInfos.
															b_Full == 1))

												|| (b_Mode == PCI3600_RING_BUFFER_MODE)) {}
											else {
												/****************************************************************************************************/
												/* The size of the PC RAM buffer must be the same that the On Board Buffer size and it must be full */
												/****************************************************************************************************/
												i_ReturnValue = -12;

											}
										} else {
											/************************************************************************************/
											/* The compare value must be greater than the actual free place in the on board RAM */
											/************************************************************************************/
											i_ReturnValue =-11;

										}
									} else {
										/********************************************************/
										/* A cycle acquisition or a signal generator is running */
										/********************************************************/
										i_ReturnValue = -10;

									}
								} else {
									/****************************************/
									/* Not enough place in the on board RAM */
									/****************************************/
									i_ReturnValue = -9;

								}
							} else {
								/***********************************/
								/* The signal generator is running */
								/***********************************/
								i_ReturnValue = -8;

							}
						} else {
							/******************************************************************/
							/* The Signal generator is already initialised by another process */
							/******************************************************************/
							i_ReturnValue = -7;

						}
					} else {
						/***********************************************************************************************/
						/* The compare value cannot be greater that the size of the on board buffer and cannot be null */
						/***********************************************************************************************/
						i_ReturnValue = -6;

					}
				} else {
					/******************************/
					/* The buffer is not reserved */
					/******************************/
					i_ReturnValue = -5;

				}
			} else {
				/**********************************/
				/* The channel is not initialised */
				/**********************************/
				i_ReturnValue = -4;

			}
		} else {
			/************************/
			/* Wrong mode parameter */
			/************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	if (i_ReturnValue == 0)
	{

		/***********************************/
		/* Reserve the on board RAM buffer */
		/***********************************/
		if (i_PCI3600_Intern_ReserveOnBoardRAMBuffer (&(APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation),
				b_Channel,
				dw_OnBoardBufferRealSize) != 0) {
			/*********************************************/
			/* Not enough free space in the on board RAM */
			/*********************************************/
			i_ReturnValue = -9;

		}

		if (i_ReturnValue == 0) {
			AO_DPRINTK ("before : i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor\n");
			/********************************/
			/* Complete the descriptor list */
			/********************************/
			i_Return = i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor (PCI3600_DMA_PC_TO_BOARD,
					   PCI3600_DISABLE,
					   0,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   s_AnalogOutInfos[b_Channel].
					   s_AnalogOutPCDMABufferInfos.
					   dw_PhysicalAddress,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   s_AnalogOutInfos[b_Channel].
					   s_AnalogOutPCDMABufferInfos.
					   dw_BufferSize,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   s_AnalogOutInfos[b_Channel].
					   s_AnalogOutPCDMABufferInfos.
					   dw_ReadPointer,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   s_AnalogOutInfos[b_Channel].
					   s_AnalogOutPCDMABufferInfos.
					   dw_WritePointer,
					   dw_NbrOfData,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_OnBoardRAMReservedBuffer[b_Channel].
					   dw_Address,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_OnBoardRAMReservedBuffer[b_Channel].
					   dw_BufferSize,
					   0,
					   0,
					   0,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_DescriptorsInfos[b_Channel].
					   dw_NbrOfDescriptorAllocated,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_DescriptorsInfos[b_Channel].
					   dw_DescriptorListPhysicalAddress,
					   APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_DescriptorsInfos[b_Channel].
					   ps_PCI9054DMADescriptor,
					   &APCI3600_PRIVDATA(pdev)->
					   s_PCI3600_BoardInformation.
					   ps_DescriptorsInfos[b_Channel].
					   dw_NbrOfDescriptorUsed,
					   &dw_NbrOfDataToBeTransfered);
			AO_DPRINTK ("after : i_PCI3600_Intern_PCI9054_CompleteScatterGatherDescriptor\n");

			/**************************/
			/* Test if no Error occur */
			/**************************/
			if (i_Return == 0) {
				AO_DPRINTK ("First Descriptor Physical Address (in Hex): %x\n",APCI3600_PRIVDATA(pdev)->
							s_PCI3600_BoardInformation.
							ps_DescriptorsInfos[b_Channel].
							dw_DescriptorListPhysicalAddress);
				AO_DPRINTK("1 Descriptor : dw_BufferPhysicalAddress : %x\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[0].
						   dw_BufferPhysicalAddress);

				AO_DPRINTK("1 Descriptor : dw_LocalBusPhysicalAddress : %x\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[0].
						   dw_LocalBusPhysicalAddress);

				AO_DPRINTK("1 Descriptor : dw_BufferSize : %u\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[0].
						   dw_BufferSize);

				AO_DPRINTK("1 Descriptor : dw_NextDescriptorAddress : %u\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[0].
						   dw_NextDescriptorAddress);


				AO_DPRINTK("2 Descriptor : dw_BufferPhysicalAddress : %x\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[1].
						   dw_BufferPhysicalAddress);

				AO_DPRINTK("2 Descriptor : dw_LocalBusPhysicalAddress : %x\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[1].
						   dw_LocalBusPhysicalAddress);

				AO_DPRINTK("2 Descriptor : dw_BufferSize : %u\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[1].
						   dw_BufferSize);

				AO_DPRINTK("2 Descriptor : dw_NextDescriptorAddress : %u\n",APCI3600_PRIVDATA(pdev)->
						   s_PCI3600_BoardInformation.
						   ps_DescriptorsInfos[b_Channel].
						   ps_PCI9054DMADescriptor[1].
						   dw_NextDescriptorAddress);

				/*****************************************/
				/* Transfer the Data to the on board RAM */
				/*****************************************/
				/*************************/
				/* Init the DMA transfer */
				/*************************/
				i_PCI3600_Primary_PCI9054InitDMAScatterGatherTransfer (GET_MEM_BAR0(pdev),
						PCI3600_DMA_CHANNEL_0,
						PCI3600_DISABLE,
						APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						ps_DescriptorsInfos[b_Channel].
						dw_DescriptorListPhysicalAddress);

				/**************************/
				/* Start the DMA transfer */
				/**************************/
				i_PCI3600_Primary_PCI9054StartDMATransfer (GET_MEM_BAR0(pdev),
						PCI3600_DMA_CHANNEL_0);

				AO_DPRINTK ("after : i_PCI3600_Primary_PCI9054StartDMATransfer\n");
				i_TimeReturn = i_ADDIUTILS_GetSystemTime    (&dw64_SystemTimeBegin);
				AO_DPRINTK ("after : i_ADDIUTILS_GetSystemTime\n");

				if (i_TimeReturn == 0) {
					do {
						i_PCI3600_Primary_PCI9054GetDMATransferStatus (GET_MEM_BAR0(pdev),
								PCI3600_DMA_CHANNEL_0,
								&b_DMAStatus);
						AO_DPRINTK ("after : i_PCI3600_Primary_PCI9054GetDMATransferStatus : b_DMAStatus : %hu\n",b_DMAStatus);

						i_TimeReturn = i_ADDIUTILS_CheckSystemTime (dw64_SystemTimeBegin,
									   PCI3600_DMA_TRANSFER_TIMEOUT,
									   &b_TimeOutStatus );
						AO_DPRINTK ("after : i_ADDIUTILS_CheckSystemTime : b_TimeOutStatus : %hu\n",b_TimeOutStatus);

						if (i_TimeReturn != 0) {
							/***********************/
							/* Time function error */
							/***********************/
							i_ReturnValue = -14;

						}
						/********************************/
						/* Wait the end of the transfer */
						/********************************/
					} while ((b_DMAStatus == 0) && (b_TimeOutStatus == 0));
					/**************************/
					/* Test if time out occur */
					/**************************/
					if (b_TimeOutStatus == 1) {
						AO_DPRINTK ("after : time out = 1\n");

						if ((APCI3600_PRIVDATA(pdev)->
								s_PCI3600_BoardInformation.
								s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
								b_InUse == 1) && (APCI3600_PRIVDATA(pdev)->
												  s_PCI3600_BoardInformation.
												  s_DMAControllersInfos [PCI3600_DMA_CHANNEL_0].
												  ps_DMATransferInfo[0].
												  b_ProcessIndex == 0)) {
							/**************************/
							/* Abort the DMA transfer */
							/**************************/
							i_PCI3600_Primary_PCI9054AbortDMATransfer (GET_MEM_BAR0(pdev),
									PCI3600_DMA_CHANNEL_0);

						}
						/******************/
						/* Time out occur */
						/******************/
						i_ReturnValue = -15;

					}
				} else {
					/***********************/
					/* Time function error */
					/***********************/
					i_ReturnValue = -14;

				}
			} else {
				/******************************/
				/* Prepare DMA transfer Error */
				/******************************/
				i_ReturnValue = -16;

			}
			if (i_ReturnValue == 0) {
				AO_DPRINTK ("before : i_PCI3600_Primary_InitAnalogOutSignalGenerator\n");

				/*********************************************/
				/* Init the cyclic mode of the analog output */
				/*********************************************/
				i_PCI3600_Primary_InitAnalogOutSignalGenerator (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
						GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
						b_Channel,
						b_Mode,
						(APCI3600_PRIVDATA(pdev)->
						 s_PCI3600_BoardInformation.
						 ps_OnBoardRAMReservedBuffer [b_Channel].
						 dw_Address - PCI3600_ON_BOARD_RAM_BASE_ADDRESS),
						dw_OnBoardBufferRealSize,
						dw_NbrOfDataToBeTransfered * 4,
						dw_CompareValue * 4);

				AO_DPRINTK ("after : i_PCI3600_Primary_InitAnalogOutSignalGenerator\n");

				/********************************************/
				/* Save the initialisation in the structure */
				/********************************************/
				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorInitStatus = 1;

				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorInitProcessIndex = 0;

				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorRunMode = b_Mode;

				/************************************/
				/* Update the PC RAM Buffer Pointer */
				/************************************/
				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				s_AnalogOutPCDMABufferInfos.
				dw_ReadPointer = (APCI3600_PRIVDATA(pdev)->
								  s_PCI3600_BoardInformation.
								  s_AnalogOutInfos[b_Channel].
								  s_AnalogOutPCDMABufferInfos.
								  dw_ReadPointer + dw_NbrOfDataToBeTransfered) % (APCI3600_PRIVDATA(pdev)->
										  s_PCI3600_BoardInformation.
										  s_AnalogOutInfos[b_Channel].
										  s_AnalogOutPCDMABufferInfos.
										  dw_BufferSize / 4);

				/************************/
				/* Update the full flag */
				/************************/
				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				s_AnalogOutPCDMABufferInfos.
				b_Full = 0;

				/*******************************/
				/* Test if the buffer is empty */
				/*******************************/
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						s_AnalogOutPCDMABufferInfos.
						dw_ReadPointer == APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						s_AnalogOutPCDMABufferInfos.
						dw_WritePointer) {
					/**********************/
					/* Set the empty flag */
					/**********************/
					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					b_Empty = 1;

				}
			} else {


				/****************************/
				/* Free the on board buffer */
				/****************************/
				i_PCI3600_Intern_FreeOnBoardRAMBuffer (&(APCI3600_PRIVDATA(pdev)->
													   s_PCI3600_BoardInformation),
													   b_Channel);


			}

		}
	}
	return (i_ReturnValue);

}
/*i_PCI3600_StartAnalogOutSignalGenerator*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_StartAnalogOutSignalGenerator ()              |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The signal generator is not initialised or not by this process  */
/*         -4 : The signal generator is already started                         */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_StartAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t b_Channel)
{
	int   i_ReturnValue     = 0;

	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/***********************************************/
		/* Test if the signal generator is initialised */
		/***********************************************/
		if ((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorInitStatus == 1) &&
				(APCI3600_PRIVDATA(pdev)->
				 s_PCI3600_BoardInformation.
				 s_AnalogOutInfos[b_Channel].
				 b_ChannelSignalGeneratorInitProcessIndex == 0)) {
			/***************************************************/
			/* Test if the signal generator is already started */
			/***************************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelSignalGeneratorStartStatus == 1) {
				/*******************************************/
				/* The signal generator is already started */
				/*******************************************/
				i_ReturnValue = -4;

			}
		} else {
			/******************************************************************/
			/* The signal generator is not initialised or not by this process */
			/******************************************************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	/**************************/
	/* Test if an error occur */
	/**************************/
	if (i_ReturnValue == 0)
	{

		i_PCI3600_Primary_StartAnalogOutSignalGenerator (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
				b_Channel);

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorStartStatus = 1;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorStartProcessIndex = 0;


	}
	return (i_ReturnValue);

}
/*i_PCI3600_GetAnalogOutSignalGeneratorStatus*/
/*+----------------------------------------------------------------------------+ */
/*| Function Name : i_PCI3600_GetAnalogOutSignalGeneratorStatus ()          | */
/*+----------------------------------------------------------------------------+ */
/*| Task :                                                                     | */
/*                                                                               */
/*+----------------------------------------------------------------------------+ */
/*| Input Parameters :                                                         | */
/*         uint32_t dw_BoardHandle     : Handle of the board                       */
/*                                                                               */
/*+----------------------------------------------------------------------------+ */
/*| Output Parameters :                                                        | */
/*                                                                               */
/*+----------------------------------------------------------------------------+ */
/*| Return Value :                                                             | */
/*         > 0 : Warning                                                         */
/*         0 : No Error                                                          */
/*         -1 : The handle parameter of the board is wrong                       */
/*         -2 : Wrong channel number                                             */
/*         -3 : The signal generator is not started or started by another process*/
/*+----------------------------------------------------------------------------+ */
int __needlock i_PCI3600_GetAnalogOutSignalGeneratorStatus (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t* pb_Status,
		uint32_t* pdw_NbrOfValueInOnBoardRAM,
		uint32_t* pdw_NbrOfValueInComputerRAM)
{
	int   i_ReturnValue     = 0;


	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/*****************************************************************************/
		/* Test if the signal generator is not started or started by another process */
		/*****************************************************************************/
		if ((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorStartStatus == 0) ||
				((APCI3600_PRIVDATA(pdev)->
				  s_PCI3600_BoardInformation.
				  s_AnalogOutInfos[b_Channel].
				  b_ChannelSignalGeneratorStartStatus == 1) && (APCI3600_PRIVDATA(pdev)->
						  s_PCI3600_BoardInformation.
						  s_AnalogOutInfos[b_Channel].
						  b_ChannelSignalGeneratorStartProcessIndex != 0))) {
			/*********************************************************************/
			/* The signal generator is not started or started by another process */
			/*********************************************************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	/**************************/
	/* Test if an error occur */
	/**************************/
	if (i_ReturnValue == 0)
	{

		/******************************************/
		/* Get the status of the signal generator */
		/******************************************/
		i_PCI3600_Primary_GetAnalogOutSignalGeneratorStatus (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,
				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelDigExtTriggerEnable,
				b_Channel,
				pb_Status);

		/****************************************************/
		/* Read the nbr of value in the on board RAM buffer */
		/****************************************************/
		INPDW_MEM (GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
				   204 + (b_Channel * 4),pdw_NbrOfValueInOnBoardRAM);

		/*****************************************************/
		/* Determine the number of data in the PC RAM buffer */
		/*****************************************************/
		if (APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				s_AnalogOutPCDMABufferInfos.
				b_Empty == 0) {
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					s_AnalogOutPCDMABufferInfos.
					b_Full == 0) {
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						s_AnalogOutPCDMABufferInfos.
						dw_ReadPointer > APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_AnalogOutInfos[b_Channel].
						s_AnalogOutPCDMABufferInfos.
						dw_WritePointer  ) {
					*pdw_NbrOfValueInComputerRAM = ((APCI3600_PRIVDATA(pdev)->
													 s_PCI3600_BoardInformation.
													 s_AnalogOutInfos[b_Channel].
													 s_AnalogOutPCDMABufferInfos.
													 dw_BufferSize / 4) - APCI3600_PRIVDATA(pdev)->
													s_PCI3600_BoardInformation.
													s_AnalogOutInfos[b_Channel].
													s_AnalogOutPCDMABufferInfos.
													dw_ReadPointer) + APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_AnalogOutInfos[b_Channel].
												   s_AnalogOutPCDMABufferInfos.
												   dw_WritePointer;

				} else {
					*pdw_NbrOfValueInComputerRAM = APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_AnalogOutInfos[b_Channel].
												   s_AnalogOutPCDMABufferInfos.
												   dw_ReadPointer - APCI3600_PRIVDATA(pdev)->
												   s_PCI3600_BoardInformation.
												   s_AnalogOutInfos[b_Channel].
												   s_AnalogOutPCDMABufferInfos.
												   dw_WritePointer;

				}
			} else {
				*pdw_NbrOfValueInComputerRAM = APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation.
											   s_AnalogOutInfos[b_Channel].
											   s_AnalogOutPCDMABufferInfos.
											   dw_BufferSize / 4;

			}
		} else {
			*pdw_NbrOfValueInComputerRAM = 0;

		}

	}
	return (i_ReturnValue);

}
/*i_PCI3600_StopAnalogOutSignalGenerator*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_StopAnalogOutSignalGenerator ()               |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The signal generator is not started or started by another       */
/*              process                                                         */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_StopAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t b_Channel)
{
	int   i_ReturnValue     = 0;


	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/*****************************************************************************/
		/* Test if the signal generator is not started or started by another process */
		/*****************************************************************************/
		if ((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorStartStatus == 0) ||
				((APCI3600_PRIVDATA(pdev)->
				  s_PCI3600_BoardInformation.
				  s_AnalogOutInfos[b_Channel].
				  b_ChannelSignalGeneratorStartStatus == 1) && (APCI3600_PRIVDATA(pdev)->
						  s_PCI3600_BoardInformation.
						  s_AnalogOutInfos[b_Channel].
						  b_ChannelSignalGeneratorStartProcessIndex != 0))) {
			/*********************************************************************/
			/* The signal generator is not started or started by another process */
			/*********************************************************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	/**************************/
	/* Test if an error occur */
	/**************************/
	if (i_ReturnValue == 0)
	{

		i_PCI3600_Primary_StopAnalogOutSignalGenerator (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
				b_Channel);

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorStartStatus = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorStartProcessIndex = 0;


	}
	return (i_ReturnValue);

}
/*i_PCI3600_ReleaseAnalogOutSignalGenerator*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name : i_PCI3600_ReleaseAnalogOutSignalGenerator ()            |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : The signal generator is not initialised or not initialised by   */
/*              this process                                                    */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_ReleaseAnalogOutSignalGenerator (struct pci_dev *pdev,
		uint8_t b_Channel)
{
	int   i_ReturnValue     = 0;


	if (!pdev)
		return -1;

	/************************/
	/* Test the channel nbr */
	/************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/***************************************************************/
		/* Test if the signal generator is initialised by this process */
		/***************************************************************/
		if ((APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelSignalGeneratorInitStatus == 0) ||
				((APCI3600_PRIVDATA(pdev)->
				  s_PCI3600_BoardInformation.
				  s_AnalogOutInfos[b_Channel].
				  b_ChannelSignalGeneratorInitStatus == 1) && (APCI3600_PRIVDATA(pdev)->
						  s_PCI3600_BoardInformation.
						  s_AnalogOutInfos[b_Channel].
						  b_ChannelSignalGeneratorInitProcessIndex != 0))) {
			/******************************************************************************/
			/* The signal generator is not initialised or not initialised by this process */
			/******************************************************************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	/**************************/
	/* Test if an error occur */
	/**************************/
	if (i_ReturnValue == 0)
	{

		i_PCI3600_Primary_StopAnalogOutSignalGenerator (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_CLOCK_BUS_GENERAL_OFFSET,
				GET_MEM_BAR3(pdev) + PCI3600_ON_BOARD_LOCAL_DMA_CONTROLLER_OFFSET,
				b_Channel);


		/********************************/
		/* Free the on board RAM buffer */
		/********************************/
		i_PCI3600_Intern_FreeOnBoardRAMBuffer (&(APCI3600_PRIVDATA(pdev)->
											   s_PCI3600_BoardInformation),
											   b_Channel);


		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorStartStatus = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorStartProcessIndex = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorInitStatus = 0;

		APCI3600_PRIVDATA(pdev)->
		s_PCI3600_BoardInformation.
		s_AnalogOutInfos[b_Channel].
		b_ChannelSignalGeneratorInitProcessIndex = 0;


	}
	return (i_ReturnValue);

}
/*i_PCI3600_AnalogOut_EnableDisableDigitalInputExternalTrigger*/
/*+----------------------------------------------------------------------------+*/
/*| Function Name :                                                             */
/*|   i_PCI3600_AnalogOut_EnableDisableDigitalInputExternalTrigger ()       |*/
/*+----------------------------------------------------------------------------+*/
/*| Task :                                                                     |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters :                                                         |*/
/*         uint32_t dw_BoardHandle     : Handle of the board                      */
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters :                                                        |*/
/*                                                                              */
/*+----------------------------------------------------------------------------+*/
/*| Return Value :                                                             |*/
/*         > 0 : Warning                                                        */
/*         0 : No Error                                                         */
/*         -1 : The handle parameter of the board is wrong                      */
/*         -2 : Wrong channel number                                            */
/*         -3 : Extern trigger flag is wrong                                    */
/*         -4 : The channel is not initialised                                  */
/*         -5 : The digital external trigger is not initialised                 */
/*+----------------------------------------------------------------------------+*/
int __needlock i_PCI3600_AnalogOut_EnableDisableDigitalInputExternalTrigger (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t b_ExternTriggerFlag)
{
	int   i_ReturnValue     = 0;
	int   i_Return          = 0;


	if (!pdev)
		return -1;

	/*********************************/
	/* Test the selected channel nbr */
	/*********************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/*************************/
		/* Test the Trigger Flag */
		/*************************/
		if ((b_ExternTriggerFlag == PCI3600_ENABLE) ||
				(b_ExternTriggerFlag == PCI3600_DISABLE)) {
			/**************************************/
			/* Test if the channel is initialised */
			/**************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelInitStatus == 1) {
				/*******************************************************/
				/* Test if the digital external trigger is initialised */
				/*******************************************************/
				if (APCI3600_PRIVDATA(pdev)->
						s_PCI3600_BoardInformation.
						s_DigExtTriggerInfos.
						b_InitStatus == 1) {

					i_Return = i_PCI3600_Primary_EnableDisableAnalogOutDigitalExternalTrigger (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
							   b_Channel,
							   b_ExternTriggerFlag);

					APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelDigExtTriggerEnable = b_ExternTriggerFlag;


				} else {
					/***************************************************/
					/* The digital external trigger is not initialised */
					/***************************************************/
					i_ReturnValue = -5;

				}
			} else {
				/**********************************/
				/* The channel is not initialised */
				/**********************************/
				i_ReturnValue = -4;

			}
		} else {
			/********************************/
			/* Extern trigger flag is wrong */
			/********************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	return (i_ReturnValue);

}
/*i_PCI3600_AnalogOut_EnableDisableMasterTrigger*/
/*+----------------------------------------------------------------------------+  */
/*| Function Name :                                                               */
/*|   i_PCI3600_AnalogOut_EnableDisableMasterTrigger ()                     |  */
/*+----------------------------------------------------------------------------+  */
/*| Task :                                                                     |  */
/*  Enabled/Disable the master trigger for the analog output channel b_Channel.   */
/*+----------------------------------------------------------------------------+  */
/*| Input Parameters :                                                         |  */
/*         uint32_t dw_BoardHandle     : Handle of the board                        */
/*         uint8_t  b_Channel           : Index of the analog output channel (0 to 1)*/
/*         uint8_t  b_MasterTriggerFlag : Enable/disable Flag for the master trigger */
/*                                     0 : Disable                                */
/*                                     1 : Enable                                 */
/*+----------------------------------------------------------------------------+  */
/*| Output Parameters :                                                        |  */
/*                                                                                */
/*+----------------------------------------------------------------------------+  */
/*| Return Value :                                                             |  */
/*         > 0 : Warning                                                          */
/*         0 : No Error                                                           */
/*         -1 : The handle parameter of the board is wrong                        */
/*         -2 : Wrong channel number                                              */
/*         -3 : Extern trigger flag is wrong                                      */
/*         -4 : The channel is not initialised                                    */
/*+----------------------------------------------------------------------------+  */
int __needlock i_PCI3600_AnalogOut_EnableDisableMasterTrigger (struct pci_dev *pdev,
		uint8_t b_Channel,
		uint8_t b_MasterTriggerFlag)
{
	int   i_ReturnValue     = 0;
	int   i_Return          = 0;


	if (!pdev)
		return -1;

	/*********************************/
	/* Test the selected channel nbr */
	/*********************************/
	if (b_Channel < APCI3600_PRIVDATA(pdev)->
			s_PCI3600_BoardInformation.
			b_AnalogOutChannelNumber)
	{
		/*************************/
		/* Test the Trigger Flag */
		/*************************/
		if ((b_MasterTriggerFlag == PCI3600_ENABLE) ||
				(b_MasterTriggerFlag == PCI3600_DISABLE)) {
			/**************************************/
			/* Test if the channel is initialised */
			/**************************************/
			if (APCI3600_PRIVDATA(pdev)->
					s_PCI3600_BoardInformation.
					s_AnalogOutInfos[b_Channel].
					b_ChannelInitStatus == 1) {

				i_Return = i_PCI3600_Primary_EnableDisableAnalogOutMasterTrigger (GET_MEM_BAR3(pdev) + PCI3600_ANALOG_OUTPUT_OFFSET,
						   b_Channel,
						   b_MasterTriggerFlag);

				APCI3600_PRIVDATA(pdev)->
				s_PCI3600_BoardInformation.
				s_AnalogOutInfos[b_Channel].
				b_ChannelMasterTriggerEnable = b_MasterTriggerFlag;


			} else {
				/**********************************/
				/* The channel is not initialised */
				/**********************************/
				i_ReturnValue = -4;

			}
		} else {
			/********************************/
			/* Extern trigger flag is wrong */
			/********************************/
			i_ReturnValue = -3;

		}
	} else
	{
		/************************/
		/* Wrong channel number */
		/************************/
		i_ReturnValue = -2;

	}
	return (i_ReturnValue);

}

/* returns the size of the allocated DMA buffer */
/*| Return Value :                                                             |  */
/*         0 : No Error                                                           */
/*         -1 : The handle parameter of the board is wrong                        */
int __needlock i_PCI3600_QueryAnalogInputCyclicAcquisitionBufferSize (struct pci_dev *pdev, uint32_t* pdw_BufferSize)
{
	if (!pdev)
		return -1;
	*pdw_BufferSize = APCI3600_PRIVDATA (pdev)->s_PCI3600_BoardInformation.s_AnaInpChronomPCDMABufferInfos.dw_BufferSize;
	return 0;
}
