/** @file convert.c

This file is here as exemple to show how it is possible to conver analog values
into temperature values by using conversion files.

@par CREATION
@author Krauth Julien
@date   06.06.05

@par VERSION
@verbatim
$LastChangedRevision: 338 $
$LastChangedDate: 2006-11-02 11:54:22 +0100 (Thu, 02 Nov 2006) $
@endverbatim

@par COMPILER
@verbatim
Compiler	: gcc
Version	: gcc (GCC) 3.3.6 (Debian 1:3.3.6-5)
kernel	: 2.4.26
@endverbatim

@par UPDATES
@verbatim
Date			:
Author		:
Description	:
@endverbatim

@par LICENCE
@verbatim
Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.

ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

You shoud also find the complete GPL in the COPYING file
accompanying this source code.
@endverbatim
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <math.h>
#include <apci3200.h>
#include <errno.h>
#include <err.h>
#include "convert.h"

str_TemperatureBuffers s_TemperatureBuffers;

/** returns the directory where to find CSV
 * first search environment variable APCI3200_CSVDIR and return define ADDIDATA_CSVDIR as default
 */
static const char* getcsvdir(void)
{
	char* tmp = getenv("APCI3200_CSVDIR");
	if(tmp) return tmp;
	return ADDIDATA_CSVDIR;
}

/** Initialize the global variable s_TemperatureBuffers.
*/
void v_APCI3200_InitGlobalStruct (void)
{
	memset(&s_TemperatureBuffers,0,sizeof(s_TemperatureBuffers));
}

/** Free the allocated buffer.
*/
void v_APCI3200_FreeGlobalStruct (void)
{
	/* Free the RTD buffers */
	if (s_TemperatureBuffers.s_RTDBuffers.b_TypePTArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_RTDBuffers.s_TypePT_RTDStruct.pd_ResistanceValue);
		free(s_TemperatureBuffers.s_RTDBuffers.s_TypePT_RTDStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_RTDBuffers.b_TypePTArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_RTDBuffers.b_TypeNiArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_RTDBuffers.s_TypeNi_RTDStruct.pd_ResistanceValue);
		free(s_TemperatureBuffers.s_RTDBuffers.s_TypeNi_RTDStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_RTDBuffers.b_TypeNiArrayLoaded = 0;
	}

	/* Free the TH buffers */
	if (s_TemperatureBuffers.s_THBuffers.b_TypeBArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers. s_TypeB_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeB_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeBArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeEArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeE_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeE_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeEArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeJArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeJ_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeJ_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeJArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeKArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeK_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeK_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeKArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeNArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeN_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeN_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeNArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeRArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeR_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeR_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeRArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeSArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeS_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeS_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeSArrayLoaded = 0;
	}

	if (s_TemperatureBuffers.s_THBuffers.b_TypeTArrayLoaded == 1)
	{
		free(s_TemperatureBuffers.s_THBuffers.s_TypeT_THStruct.pd_VoltageValue);
		free(s_TemperatureBuffers.s_THBuffers. s_TypeT_THStruct.pd_TemperatureValue);
		s_TemperatureBuffers.s_THBuffers.b_TypeTArrayLoaded = 0;
	}
}

/** Search the string length.
*
* @param [in]	pc_ReadString		String to treat.
* @param [out]	pw_ReadStringLength	Sring size
*/
void v_SearchStringLength (char *pc_ReadString, unsigned int *pw_ReadStringLength)
{
	*pw_ReadStringLength = strlen (pc_ReadString);

	/* Test if the last char ist a "\n" char */
	if (pc_ReadString [strlen (pc_ReadString) - 1] == '\n')
	{
		/*Clear the "\n" char*/
		pc_ReadString [strlen (pc_ReadString) - 1] = 0;
		*pw_ReadStringLength = strlen (pc_ReadString);
	}
	else
	{
		*pw_ReadStringLength = strlen (pc_ReadString);
	}
}

/** Decompose the convert file String.
*
* @param [in]	pc_ReadString	String to decompose.
* @param [in]	w_NbrMaxOfValue	Max nubmer of value to found in the string.
* @param [in]	d_Step			Step of the voltage or the resitance value.
* @param [out]	d_Value			Voltage or resistance values.
* @param [out]	d_TempValue		Temperature values.
* @param [out]	pw_NbrOfValue	Number of value found in the string.
*
* @retval	0	No error.
* @retval	-1	The number of value is greater than the number max.
*/
int i_APCI3200_DecomposeConvertFileString (char *pc_ReadString,
		unsigned int w_NbrMaxOfValue,
		double d_Step,
		double *pd_Value,
		double *pd_TempValue,
		unsigned int *pw_NbrOfValue)
{
	int i_ReturnValue = 0;
	unsigned int w_StringSize = 0;
	unsigned int w_Cpt = 0;
	unsigned int w_CptOld = 0;
	unsigned int w_Value = 0;
	char pc_ValueString[300];

	if (pc_ReadString != NULL)
	{
		/* Search the size of the Read String */
		v_SearchStringLength (pc_ReadString,&w_StringSize);

		*pw_NbrOfValue = 0;

		/* Search the number of value in the string */
		for (w_Cpt = 0; w_Cpt < w_StringSize; w_Cpt ++)
		{
			if (pc_ReadString [w_Cpt] == ';')
			{
				*pw_NbrOfValue = *pw_NbrOfValue + 1;
			}
		}
		*pw_NbrOfValue = *pw_NbrOfValue - 1;

		/* Test if the number of value is not greater than the number max */
		if (*pw_NbrOfValue <= w_NbrMaxOfValue)
		{
			/* Search the first value */
			for (w_Cpt = 0; w_Cpt < w_StringSize; w_Cpt ++)
			{
				if (pc_ReadString [w_Cpt] == ';')
				{
					strncpy (pc_ValueString, pc_ReadString, w_Cpt);
					pc_ValueString [w_Cpt] = 0;

					/* Convert the value*/
					pd_TempValue[0] = atof (pc_ValueString);
					break;
				}
			}

			/* Search the temp value */
			for (w_Value = 0; w_Value < *pw_NbrOfValue ; w_Value++)
			{
				w_CptOld = w_Cpt + 1;

				for (w_Cpt = w_CptOld; w_Cpt < w_StringSize; w_Cpt ++)
				{
					if (pc_ReadString [w_Cpt] == ';')
					{
						strncpy (pc_ValueString, &pc_ReadString[w_CptOld], (w_Cpt - w_CptOld));
						pc_ValueString [(w_Cpt - w_CptOld)] = 0;

						/* Convert the value*/
						pd_Value[w_Value] = atof (pc_ValueString);

						if (w_Value > 0)
						{
							pd_TempValue[w_Value] = pd_TempValue[w_Value - 1] + d_Step;
						}
						break;
					}
				}
			}
		}
		else
		{
			i_ReturnValue = -1;
		}
	}
	else
	{
		*pw_NbrOfValue = 0;
	}

	if (i_ReturnValue != 0)
		printf ("%s: error = %d\n", __FUNCTION__,i_ReturnValue);
	return (i_ReturnValue);
}

/** Complete the RTD buffer passed at argument.
*
* @param [in]	b_RTDType		Type of RTD:<br>
* 								- ADDIDATA_RTD_TYPE_PT<br>
* 								- ADDIDATA_RTD_TYPE_Ni
*
* @param [out]	ps_RTDStruct	pointer to the RTD buffer<br>
* 								which will be filled with<br>
*								the values of the temperature convert file.
*
* @retval	0	No error occur.
* @retval	-1: Wrong RTD type.
* @retval	-2: Error while allocating memory.
* @retval	-3: Error with the temperature convert file.
*/
int i_APCI3200_CompleteRTDBuffer (unsigned char b_RTDType, pstr_APCI3200_RTDStruct ps_RTDStruct)
{
	int i_ErrorCode = 0;
	int i_ReturnValue = 0;
	FILE *pf_FileHandle = NULL;
	unsigned int w_Index = 0;
	unsigned int w_Cpt = 0;
	double *pd_ResistanceValue;	 /* Pointer to allocated buffer in the global structure */
	double *pd_TemperatureValue;  /* Pointer to allocated buffer in the global structure */
	double d_ResistanceValue[5];
	double d_TempValue[5];
	char c_FileName[300];
	char c_ReadString[3000];
	unsigned long dw_NbrMaxValue = 0;
	unsigned int w_NbrOfValue = 0;
	struct stat s_FileStat;

	if (b_RTDType == ADDIDATA_RTD_TYPE_PT)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_RTD_TYPE_PT_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_RTD_TYPE_PT_ARRAY_SIZE;
	}
	else if (b_RTDType == ADDIDATA_RTD_TYPE_Ni)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_RTD_TYPE_Ni_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_RTD_TYPE_Ni_ARRAY_SIZE;
	}
	else
		i_ReturnValue = -1;

	if (i_ReturnValue == 0)
	{
		/*
		 * Allocate memory to create the buffer with the values of the convert file
		 * and copy it to the structure passed in argument
		 */

		/* calloc(dw_NbrMaxValue+1,...) because we begin to write at index 1, 0 is not used */
		if (   ((pd_ResistanceValue = calloc(dw_NbrMaxValue+1,sizeof(double))) != NULL )
				&& ((pd_TemperatureValue = calloc(dw_NbrMaxValue+1,sizeof(double))) != NULL ) )
		{
			ps_RTDStruct -> pd_ResistanceValue  = pd_ResistanceValue;
			ps_RTDStruct -> pd_TemperatureValue = pd_TemperatureValue;

			/* Open the file */
			pf_FileHandle = fopen (c_FileName,"rt");

			if (pf_FileHandle != NULL)
			{
				/* Test the size of the file */
				if (stat(c_FileName,&s_FileStat) == 0)
				{
					// Remove the file size test because the size is depending of the filesystem type.
					//		  switch(b_RTDType)
					//		     {
					//		     case ADDIDATA_RTD_TYPE_PT:
					//		           if (s_FileStat.st_size != ADDIDATA_RTD_TYPE_PT_FILE_SIZE)
					//		              {
					//		              i_ReturnValue = -3;
					//		              }
					//		           break;
					//
					//		     case ADDIDATA_RTD_TYPE_Ni:
					//		           if (s_FileStat.st_size != ADDIDATA_RTD_TYPE_Ni_FILE_SIZE)
					//		              {
					//		              i_ReturnValue = -3;
					//		              }
					//		           break;
					//
					//		     default:
					//		   	if (i_ReturnValue != 0)
					//		     }

					if (i_ReturnValue == 0)
					{
						while ((feof (pf_FileHandle) == 0) &&
								(ps_RTDStruct -> dw_NumberOfValue < (dw_NbrMaxValue)) &&
								(i_ErrorCode == 0))
						{
							/* Read string */
							if (fgets (c_ReadString, 300, pf_FileHandle)!=NULL)
							{
								/* Decompose the string and save the value in the buffer */
								if ((i_ErrorCode = i_APCI3200_DecomposeConvertFileString (c_ReadString,5,0.2,d_ResistanceValue,d_TempValue,&w_NbrOfValue)) == 0)
								{
									ps_RTDStruct -> dw_NumberOfValue = ps_RTDStruct -> dw_NumberOfValue + w_NbrOfValue;

									/* Copy the value in the global array */
									for (w_Cpt = 1; w_Cpt <= w_NbrOfValue;w_Cpt++)
									{
										ps_RTDStruct -> pd_ResistanceValue [w_Index + w_Cpt] = d_ResistanceValue[w_Cpt - 1];
										ps_RTDStruct -> pd_TemperatureValue [w_Index + w_Cpt] = d_TempValue[w_Cpt - 1];
									}
									w_Index = w_Index + w_NbrOfValue;
								}
								else
								{
									i_ReturnValue = -3;
								}
							}
						}

						fclose (pf_FileHandle);
					}
					else
					{
						fclose (pf_FileHandle);
					}
				}/*if (stat(c_FileName,&s_FileStat) == 0)*/
				else
				{
					warn("%s:%d:%s:incorrect file size",__FUNCTION__,__LINE__,c_FileName);
					i_ReturnValue = -3;
				}
			}/*if (pf_FileHandle != NULL)*/
			else
			{
				err(errno,"%s:%d:%s:open",__FUNCTION__,__LINE__,c_FileName);
				i_ReturnValue = -3;
			}
		}/*if (((pd_ResistanceValue = calloc(...) != NULL ) && ((pd_TemperatureValue = calloc(...) != NULL ))*/
		else
			i_ReturnValue = -2;
	}/*if(i_ReturnValue == 0)*/

	if (i_ReturnValue != 0)
		printf ("%s: error = %d\n", __FUNCTION__, i_ReturnValue);
	return i_ReturnValue;
}

/** Complete the TH buffer passed at argument.
*
* @param [in]	b_ThermocoupleType	Type of Thermocouple:<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_B<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_E<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_J<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_K<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_N<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_R<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_S<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_T
*
* @param [out]	ps_THStruct			pointer to the TH buffer which will<br>
* 									be filled with the values of the<br>
* 									temperature convert file.
*
* @retval	0	No error occur.
* @retval	-1	Wrong TH type.
* @retval	-2	Error while allocating memory.
* @retval	-3	Error with the temperature convert file.
*/
int i_APCI3200_CompleteThermocoupleBuffer(unsigned char b_ThermocoupleType,pstr_APCI3200_THStruct ps_THStruct)
{
	int i_ReturnValue = 0;
	int i_ErrorCode = 0;
	double *pd_VoltageValue;	 /* Pointer to allocated buffer in the global structure */
	double *pd_TemperatureValue;	 /* Pointer to allocated buffer in the global structure */
	double d_VoltageValue[5];
	double d_TempValue[5];
	char c_FileName[300];
	char c_ReadString[300];
	unsigned long dw_NbrMaxValue = 0;
	FILE *pf_FileHandle;
	unsigned int w_Index = 0;
	unsigned int w_Cpt = 0;
	unsigned int w_NbrOfValue = 0;
	struct stat s_FileStat;

	if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_B)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_B_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_B_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_E)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_E_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_E_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_J)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_J_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_J_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_K)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_K_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_K_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_N)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_N_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_N_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_R)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_R_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_R_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_S)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_S_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_S_ARRAY_SIZE;
	}
	else if (b_ThermocoupleType == ADDIDATA_THERMOCOUPLE_TYPE_T)
	{
		sprintf(c_FileName,"%s/%s",getcsvdir(),ADDIDATA_TH_TYPE_T_FILE_NAME);
		dw_NbrMaxValue = ADDIDATA_TH_TYPE_T_ARRAY_SIZE;
	}
	else
	{
		i_ReturnValue = -1;
	}

	if (i_ReturnValue == 0)
	{
		/*
		 * Allocate memory to create the buffer with the values of the convert file
		 * and copy it to the structure passed in argument
		 */
		if (   ((pd_VoltageValue = calloc(dw_NbrMaxValue+1,sizeof(double))) != NULL )
				&& ((pd_TemperatureValue = calloc(dw_NbrMaxValue+1,sizeof(double))) != NULL ) )
		{
			ps_THStruct -> pd_VoltageValue  = pd_VoltageValue;
			ps_THStruct -> pd_TemperatureValue = pd_TemperatureValue;

			/*Open the file*/
			pf_FileHandle = fopen (c_FileName, "rt");

			if (pf_FileHandle != NULL)
			{
				/*Test the size of the file*/
				if (stat(c_FileName,&s_FileStat) == 0)
				{
					// Remove the file size test because the size is depending of the filesystem type.
					//		  switch(b_ThermocoupleType)
					//		     {
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_B:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_B_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_E:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_E_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_J:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_J_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_K:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_K_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_N:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_N_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_R:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_R_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_S:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_S_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     case ADDIDATA_THERMOCOUPLE_TYPE_T:
					//		           if (s_FileStat.st_size != ADDIDATA_TH_TYPE_T_FILE_SIZE)
					//		              i_ReturnValue = -3;
					//		           break;
					//
					//		     default:
					//		           i_ReturnValue = -3;
					//		     }/*switch(b_ThermocoupleType)*/

					if (i_ReturnValue == 0)
					{
						w_Index = 0;

						while ((feof (pf_FileHandle) == 0) &&
								(ps_THStruct -> dw_NumberOfValue < dw_NbrMaxValue) &&
								(i_ErrorCode == 0))
						{
							/* Read string*/
							fgets (c_ReadString, 300, pf_FileHandle);

							/* Decompose the string and save the value in the buffer*/
							i_ErrorCode = i_APCI3200_DecomposeConvertFileString (c_ReadString,
									5,
									0.2,
									d_VoltageValue,
									d_TempValue,
									&w_NbrOfValue);
							if (i_ErrorCode == 0)
							{
								ps_THStruct -> dw_NumberOfValue = ps_THStruct -> dw_NumberOfValue + w_NbrOfValue;

								/*copy the value in the global array*/
								for (w_Cpt = 1; w_Cpt <= w_NbrOfValue;w_Cpt++)
								{
									ps_THStruct -> pd_VoltageValue [w_Index + w_Cpt] = d_VoltageValue[w_Cpt - 1];
									ps_THStruct -> pd_TemperatureValue [w_Index + w_Cpt] = d_TempValue[w_Cpt - 1];
								}
								w_Index = w_Index + w_NbrOfValue;
							}
							else
								i_ReturnValue = -3;
						}/*while ((feof (pf_FileHandle) == 0) &&
			   (ps_THStruct -> dw_NumberOfValue < dw_NbrMaxValue) &&
			   (i_ErrorCode == 0))*/

						fclose (pf_FileHandle);
					}/*if(i_ReturnValue == 0)*/
					else
					{
						fclose (pf_FileHandle);
					}
				}/*if (stat(c_FileName,&s_FileStat) == 0)*/
				else
					i_ReturnValue = -3;
			}/*if (pf_FileHandle != NULL)*/
			else {
				i_ReturnValue = -3;
				err(errno,"%s:%d:%s:",__FUNCTION__,__LINE__,c_FileName);
			}
		}/*if (((pd_ResistanceValue = calloc(...) != NULL ) && ((pd_TemperatureValue = calloc(...) != NULL ))*/
		else
			i_ReturnValue = -2;
	}/*if(i_ReturnValue == 0)*/

	if (i_ReturnValue != 0)
		printf ("%s: error = %d\n", __FUNCTION__, i_ReturnValue);
	return i_ReturnValue;
}

/** Returns the RTD buffer corresponding to the selected RTD type.
*
* @param [in]		b_RTDType		Type of RTD:<br>
* 									- ADDIDATA_RTD_TYPE_PT<br>
* 									- ADDIDATA_RTD_TYPE_Ni
*
* @param [out]		ps_RTDStruct	Pointer to RTD buffer.
*
* @retval	0	no error occur.
* @retval	-1 Wrong RTD type.
* @retval	-2 Error while allocating memory.
* @retval	-3 Error with the temperature convert file.
*/
int i_APCI3200_GetRTDStruct (unsigned char b_RTDType, pstr_APCI3200_RTDStruct    *ps_APCI3200_RTDStruct )
{
	int i_ReturnValue = 0;

	switch(b_RTDType)
	{
	case ADDIDATA_RTD_TYPE_PT :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_RTDBuffers.b_TypePTArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteRTDBuffer(b_RTDType,
					&s_TemperatureBuffers.
					s_RTDBuffers.
					s_TypePT_RTDStruct) ) == 0)
			{
				s_TemperatureBuffers.s_RTDBuffers.b_TypePTArrayLoaded = 1;
			}/*if ((i_ReturnValue = i_APCI3200_CompleteRTDBuffer(...)*/
					else
					{

					}
		}/*if (s_TemperatureBuffers.s_RTDBuffers.b_TypePTArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_RTDStruct = &s_TemperatureBuffers.s_RTDBuffers.s_TypePT_RTDStruct;

		break;

	case ADDIDATA_RTD_TYPE_Ni :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_RTDBuffers.b_TypeNiArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteRTDBuffer(b_RTDType,
					&s_TemperatureBuffers.
					s_RTDBuffers.
					s_TypeNi_RTDStruct) ) == 0)
				s_TemperatureBuffers.s_RTDBuffers.b_TypeNiArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_RTDBuffers.b_TypePTArrayLoaded == 0)*/

		/*********************/
		/* Return the buffer */
		/*********************/
		*ps_APCI3200_RTDStruct = &s_TemperatureBuffers.s_RTDBuffers.s_TypeNi_RTDStruct;

		break;

	default:
		i_ReturnValue = -1;
	}/*switch(b_RTDType)*/

	if (i_ReturnValue != 0)
		printf ("%s: error = %d\n",__FUNCTION__, i_ReturnValue);
	return i_ReturnValue;
}

/** Returns the TH buffer corresponding to the selected Thermocouple type.
*
* @param [in]	b_ThermocoupleType	Type of Thermocouple:<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_B<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_E<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_J<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_K<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_N<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_R<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_S<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_T
*
* @param [out]	ps_THStruct			pointer to the TH buffer which will<br>
* 									be filled with the values of the<br>
* 									temperature convert file.
*
* @retval	0	No error occur.
* @retval	-1	Wrong TH type.
* @retval	-2	Error while allocating memory.
* @retval	-3	Error with the temperature convert file.
*/
int i_APCI3200_GetTHStruct (unsigned char b_ThermocoupleType, pstr_APCI3200_THStruct *ps_APCI3200_THStruct )
{
	int i_ReturnValue = 0;

	switch(b_ThermocoupleType)
	{
	case ADDIDATA_THERMOCOUPLE_TYPE_B :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeBArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeB_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeBArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeBArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeB_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_E :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeEArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeE_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeEArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeEArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeE_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_J :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeJArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeJ_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeJArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeJArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeJ_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_K :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeKArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeK_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeKArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeKArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeK_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_N :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeNArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeN_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeNArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeNArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeN_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_R :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeRArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeR_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeRArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeRArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeR_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_S :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeSArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeS_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeSArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeSArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeS_THStruct;

		break;

	case ADDIDATA_THERMOCOUPLE_TYPE_T :
		/* Test if the buffer must be loaded */
		if (s_TemperatureBuffers.s_THBuffers.b_TypeTArrayLoaded == 0)
		{
			if ((i_ReturnValue = i_APCI3200_CompleteThermocoupleBuffer(b_ThermocoupleType,
					&s_TemperatureBuffers.
					s_THBuffers.
					s_TypeT_THStruct) ) == 0)
				s_TemperatureBuffers.s_THBuffers.b_TypeTArrayLoaded = 1;
		}/*if (s_TemperatureBuffers.s_THBuffers.b_TypeTArrayLoaded == 0)*/

		/* Return the buffer */
		*ps_APCI3200_THStruct = &s_TemperatureBuffers.s_THBuffers.s_TypeT_THStruct;

		break;

	default:
		i_ReturnValue = -1;
	}/*switch(b_RTDType)*/

	if (i_ReturnValue != 0)
		printf ("%s: error = %d\n", __FUNCTION__, i_ReturnValue);
	return i_ReturnValue;
}


void v_ADDIDATA_ConvertDigitalToAnalogValue (unsigned char b_Polarity,
		double d_Gain,
		// Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
		double d_GainFactor,
		// End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
		int i_OffsetRangeSet,
		unsigned char b_OffsetNum,
		unsigned char b_OffsetDenom,
		unsigned char b_AutoCalibration,
		double d_Umax,
		double d_Uref,
		unsigned char b_InputResolution,
		unsigned long dw_CalOffsetValue,
		unsigned long dw_CalGainValue,
		unsigned long dw_DigitalValue,
		double *pd_RealValue)
{


	// Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
	// *pd_RealValue = ((d_Uref*((double)dw_DigitalValue-(double)dw_CalOffsetValue)) /
	//           (d_Gain*((double)dw_CalGainValue - (double)dw_CalOffsetValue)));
	*pd_RealValue = ((d_Uref*((double)dw_DigitalValue-(double)dw_CalOffsetValue)) /
			(d_Gain*d_GainFactor*((double)dw_CalGainValue - (double)dw_CalOffsetValue)));
	// End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1

}


/** Linearisation from the XValue.
*
* @param [in]	d_YInf
* @param [in]	d_YSup
* @param [in]	d_XInf
* @param [in]	d_XSup
* @param [in]	d_XValue
*
* @param [out]	d_LINValue
*
* @retval 0	No Error.
* @retval !=0	Error occur.
*/
void v_ADDIDATA_AnalogInputLinearisation (double d_YInf,
		double d_YSup,
		double d_XInf,
		double d_XSup,
		double d_XValue,
		double *pd_LINValue)
{
	*pd_LINValue = d_YInf + (((d_YSup - d_YInf) / (d_XSup - d_XInf)) * (d_XValue - d_XInf));
}

/** Convert the temp value to Thermocouple voltage value.
*
* @param [in]		b_RTDType				Type of RTD:<br>
* 											- ADDIDATA_RTD_TYPE_PT<br>
* 											- ADDIDATA_RTD_TYPE_Ni
* @param [in]		w_RTDValue				RTD value.
* @param [in]		d_CurrentSourceValue	Current source value.
* @param [in]		d_AnalogValue			Analog value.
*
* @param [out]		pd_TemperatureValue		Temperature value.
*
* @retval	0	No error.
* @retval	!=0	Error.
*/
int i_ADDIDATA_ConvertRTDAnalogToTemperatureValue (unsigned char b_RTDType,
		unsigned int w_RTDValue,
		double d_CurrentSourceValue,
		double d_AnalogValue,
		double *pd_TemperatureValue)
{

	double d_ResistanceINF = 0;
	double d_ResistanceSUP = 0;
	double d_TempINF = 0;
	double d_TempSUP = 0;
	double d_ResistanceValue = 0;
	double A = 3.9083 * pow(10,-3);
	double B = -5.775 * pow(10,-7);
	double d_RTDValue = 0.0;
	unsigned long ul_Cpt = 0;
	int i_ErrorCode = 0;
	pstr_APCI3200_RTDStruct ps_RTDStruct = NULL;


	if (d_CurrentSourceValue != 0.0)
	{
		d_ResistanceValue = d_AnalogValue / d_CurrentSourceValue;
		d_RTDValue = (double) w_RTDValue;

		/* Test if the RTD is a PT Type */
		if (b_RTDType == ADDIDATA_RTD_TYPE_PT)
		{
			/* Test if the temperature is negativ */
			if (d_ResistanceValue <= d_RTDValue)
			{
				d_ResistanceValue = d_ResistanceValue * (1000.00/ d_RTDValue);

				if ((i_ErrorCode = i_APCI3200_GetRTDStruct (b_RTDType,&ps_RTDStruct)) != 0) {
					printf ("%s:%d: error =%d\n",__FUNCTION__,__LINE__, i_ErrorCode);
					return -6;
				}

				if (i_ErrorCode == 0)
				{

					for (ul_Cpt = 1; ul_Cpt<ps_RTDStruct -> dw_NumberOfValue;ul_Cpt ++)
					{

						if ((ps_RTDStruct -> pd_ResistanceValue[ul_Cpt + 1] >= d_ResistanceValue) &&
								(ps_RTDStruct -> pd_ResistanceValue[ul_Cpt] <= d_ResistanceValue))
						{
							d_TempINF = ps_RTDStruct -> pd_TemperatureValue[ul_Cpt];
							d_TempSUP = ps_RTDStruct -> pd_TemperatureValue[ul_Cpt + 1];
							d_ResistanceINF = ps_RTDStruct -> pd_ResistanceValue[ul_Cpt];
							d_ResistanceSUP = ps_RTDStruct -> pd_ResistanceValue[ul_Cpt + 1];
							break;
						}
					}
					/* Test if the value is found */
					if (ul_Cpt < ps_RTDStruct -> dw_NumberOfValue)
					{
						/* Linearisation of the value */
						v_ADDIDATA_AnalogInputLinearisation (d_TempINF,
								d_TempSUP,
								d_ResistanceINF,
								d_ResistanceSUP,
								d_ResistanceValue,
								pd_TemperatureValue);
					}
					else
					{
						printf ("%s:%d: error\n",__FUNCTION__,__LINE__);
						i_ErrorCode = -4;
					}
				}
			}
			else
			{
				/* Calculate the real value */
				*pd_TemperatureValue =(((double)-(double)w_RTDValue*A) + pow((pow((double)w_RTDValue*A,2) - (4*(double)w_RTDValue* B* ((double)w_RTDValue-d_ResistanceValue))),0.5)) / (2*(double)w_RTDValue*B);
			}
		}
		/* Test if the RTD is a Ni Type */
		if (b_RTDType == ADDIDATA_RTD_TYPE_Ni)
		{
			d_ResistanceValue = d_ResistanceValue * (100.00/ d_RTDValue);
			if ((i_ErrorCode = i_APCI3200_GetRTDStruct (b_RTDType,&ps_RTDStruct)) != 0) {
				printf ("%s: error =%d\n",__FUNCTION__, -6);
				return -6;
			}
			if (i_ErrorCode == 0)
			{
				for (ul_Cpt = 1; ul_Cpt < ps_RTDStruct -> dw_NumberOfValue;ul_Cpt ++)
				{
					if ((ps_RTDStruct -> pd_ResistanceValue[ul_Cpt + 1] >= d_ResistanceValue) &&
							(ps_RTDStruct -> pd_ResistanceValue[ul_Cpt] <= d_ResistanceValue))
					{
						d_TempINF = ps_RTDStruct -> pd_TemperatureValue[ul_Cpt];
						d_TempSUP = ps_RTDStruct -> pd_TemperatureValue[ul_Cpt + 1];
						d_ResistanceINF = ps_RTDStruct -> pd_ResistanceValue[ul_Cpt];
						d_ResistanceSUP = ps_RTDStruct -> pd_ResistanceValue[ul_Cpt + 1];
						break;
					}
				}
				/* Test if the value is found */
				if ((ul_Cpt < ps_RTDStruct -> dw_NumberOfValue))
				{
					/* Linearisation of the value */
					v_ADDIDATA_AnalogInputLinearisation (d_TempINF,
							d_TempSUP,
							d_ResistanceINF,
							d_ResistanceSUP,
							d_ResistanceValue,
							pd_TemperatureValue);
				}
				else
				{
					i_ErrorCode = -4;
				}
			}
		}
	}
	else
	{
		i_ErrorCode = -5;
	}

	if (i_ErrorCode != 0)
		printf ("%s: error =%d\n", __FUNCTION__, i_ErrorCode);
	return (i_ErrorCode);
}

/** Convert the temp value to Thermocouple voltage value.
*
* @param [in]	b_ThermocoupleType	Type of Thermocouple:<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_B<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_E<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_J<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_K<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_N<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_R<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_S<br>
*									- ADDIDATA_THERMOCOUPLE_TYPE_T
*
* @param [in]	d_TemperatureValue	The temperature value.
*
* @param [out]	pd_VoltageValue		Voltage value.
*
* @retval	0	No error.
* @retval	!=0	Error.
*/
int i_ADDIDATA_ConvertTempValueToAnalogTHERMOCOUPLEValue (unsigned char b_ThermocoupleType,
		double d_TemperatureValue,
		double *pd_VoltageValue)
{

	double d_VoltageINF = 0;
	double d_VoltageSUP = 0;
	double d_TempINF = 0;
	double d_TempSUP = 0;
	ULONG ul_Cpt;
	int i_ErrorCode = 0;
	pstr_APCI3200_THStruct ps_THStruct = NULL;


	if ( (i_ErrorCode = i_APCI3200_GetTHStruct(b_ThermocoupleType,&ps_THStruct)) != 0)
	{
		printf ("%s: error =%d\n", __FUNCTION__, -5);
		return -5;
	}

	if (i_ErrorCode == 0)
	{
		/* Search the voltage value in the Array */
		for (ul_Cpt = 1; ul_Cpt < ps_THStruct -> dw_NumberOfValue; ul_Cpt++)
		{
			if (((ps_THStruct -> pd_TemperatureValue[ul_Cpt + 1] >= d_TemperatureValue) &&
					(ps_THStruct -> pd_TemperatureValue[ul_Cpt] <= d_TemperatureValue)))
			{
				d_TempINF = ps_THStruct -> pd_TemperatureValue[ul_Cpt];
				d_TempSUP = ps_THStruct -> pd_TemperatureValue[ul_Cpt + 1];
				d_VoltageINF = ps_THStruct -> pd_VoltageValue[ul_Cpt];
				d_VoltageSUP = ps_THStruct -> pd_VoltageValue[ul_Cpt + 1];
				break;
			}
		}

		/* Test if the value is found */
		if (ul_Cpt < ps_THStruct -> dw_NumberOfValue)
		{
			/* Linearisation of the value */
			v_ADDIDATA_AnalogInputLinearisation (d_VoltageINF,
					d_VoltageSUP,
					d_TempINF,
					d_TempSUP,
					d_TemperatureValue,
					pd_VoltageValue);


			/* Convert in V */
			*pd_VoltageValue = *pd_VoltageValue / 1000000.0;
		}
		else
		{
			i_ErrorCode = -4;
		}
	}

	if (i_ErrorCode != 0)
		printf ("%s: error =%d\n", __FUNCTION__, i_ErrorCode);
	return (i_ErrorCode);
}

/** Convert the temp value to Thermocouple voltage value
*
* @param [in]	b_ThermocoupleType		Type of Thermocouple:<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_B<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_E<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_J<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_K<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_N<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_R<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_S<br>
*										- ADDIDATA_THERMOCOUPLE_TYPE_T
*
* @param [in]	d_CJCAnalogValue		Analog value from the CJC.
* @param [in]	d_AnalogValue			Analog value.
* @param [out]	pd_TemperatureValue		Temperature value.
*
* @retval	0	No error.
* @retval	!=0	Error.
*/
int i_ADDIDATA_ConvertTHERMOCOUPLEAnalogToTemperatureValue (unsigned char b_ThermocoupleType,
		double d_CJCAnalogValue,
		double d_AnalogValue,
		double *pd_TemperatureValue)
{
	double d_VoltageINF = 0.0;
	double d_VoltageSUP = 0.0;
	double d_TempINF = 0.0;
	double d_TempSUP = 0.0;
	double d_AnalogValueToConvert = 0.0;
	unsigned long ul_Cpt = 0;
	int i_ErrorCode = 0;
	pstr_APCI3200_THStruct ps_THStruct = NULL;

	if ( (i_ErrorCode=i_APCI3200_GetTHStruct(b_ThermocoupleType,&ps_THStruct)) != 0) {
		printf ("%s:%d error = %d\n", __FUNCTION__, __LINE__, i_ErrorCode);
		return -5;
	}

	if (i_ErrorCode == 0)
	{
		/* 1000000.000 -> become uV */
		d_AnalogValueToConvert = (d_AnalogValue + d_CJCAnalogValue) * 1000000.000;

		/* Search the voltage value in the Array */
		for (ul_Cpt = 1; ul_Cpt < ps_THStruct -> dw_NumberOfValue; ul_Cpt ++)
		{
			if ((ps_THStruct -> pd_VoltageValue[ul_Cpt + 1] >= d_AnalogValueToConvert) &&
					(ps_THStruct -> pd_VoltageValue[ul_Cpt] <= d_AnalogValueToConvert))
			{
				d_TempINF = ps_THStruct -> pd_TemperatureValue[ul_Cpt];
				d_TempSUP = ps_THStruct -> pd_TemperatureValue[ul_Cpt + 1];
				d_VoltageINF = ps_THStruct -> pd_VoltageValue[ul_Cpt];
				d_VoltageSUP = ps_THStruct -> pd_VoltageValue[ul_Cpt + 1];
				break;
			}
		}

		/* Test if the value is found */
		if (ul_Cpt < ps_THStruct -> dw_NumberOfValue)
		{
			/* Linearisation of the value */
			v_ADDIDATA_AnalogInputLinearisation (d_TempINF,
					d_TempSUP,
					d_VoltageINF,
					d_VoltageSUP,
					d_AnalogValueToConvert,
					pd_TemperatureValue);
		}
		else
		{
			i_ErrorCode = -5;
			printf ("%s:%d error = %d\n", __FUNCTION__, __LINE__, i_ErrorCode);
		}
	}
	return(i_ErrorCode);
}

int i_ADDIDATA_ConvertDigitalToRealTemperatureValueWithCorrectionParameters (
		unsigned int w_AcquisitionType,
		unsigned char b_InputType,
		unsigned char b_TypePrecision,
		unsigned int w_InputTypeValue,
		unsigned char b_PolaritySelected,
		unsigned int w_GainSelected,
		double d_GainFactorValue,
		double d_CurrentSourceValue,
		double d_CurrentSourceCJCValue,
		unsigned long *pdw_DigitalValue,
		double *pd_RealValue,
		double d_ReferenceVoltage /* 1.25 or 2.5 */
		)
{
	/* Variable declaration */
	int i_ErrorCode = 0;
	unsigned long dw_CalOffsetValue = 0;
	unsigned long dw_CalGainValue = 0;
	unsigned long dw_CJCCalOffsetValue = 0;
	unsigned long dw_CJCCalGainValue = 0;
	double d_AnalogValue = 0.0;
	double d_CJCAnalogValue = 0.0;
	double d_CJCTempValue = 0.0;
	double d_CJCVoltageValue = 0.0;
	double d_GainAvailable[8];
	unsigned int w_CJCGain = APCI3200_OTHER;

	d_GainAvailable [0] = 1;
	d_GainAvailable [1] = 2;
	d_GainAvailable [2] = 4;
	d_GainAvailable [3] = 8;
	d_GainAvailable [4] = 16;
	d_GainAvailable [5] = 32;
	d_GainAvailable [6] = 64;
	d_GainAvailable [7] = 128;

	/* Test if the CJC is available */
	switch(b_InputType)
	{
	case ADDIDATA_THERMOCOUPLE:
		dw_CalOffsetValue = pdw_DigitalValue[2];
		dw_CalGainValue = pdw_DigitalValue[3];

		dw_CJCCalOffsetValue = pdw_DigitalValue[4];
		dw_CJCCalGainValue = pdw_DigitalValue[5];
		break;
	case ADDIDATA_RTD:
		dw_CalOffsetValue = pdw_DigitalValue[1];
		dw_CalGainValue = pdw_DigitalValue[2];
		break;
	default:
		warnx("%s:%d: unknown sensor type %d",__FUNCTION__,__LINE__,b_InputType);
	}

	/* Convert the digital Value in V or A */
	v_ADDIDATA_ConvertDigitalToAnalogValue(b_PolaritySelected,
			d_GainAvailable[w_GainSelected],
			d_GainFactorValue,
			0,
			1,
			6,
			0,
			d_ReferenceVoltage,
			d_ReferenceVoltage,
			18,
			dw_CalOffsetValue,
			dw_CalGainValue,
			pdw_DigitalValue[0],
			&d_AnalogValue);


	/* Test if RTD */
	switch(b_InputType)
	{

	case ADDIDATA_THERMOCOUPLE:
		/* In scan CJC gain = 1 */
		if (w_AcquisitionType == APCI3200_OTHER)
			w_CJCGain = 4;

		if (w_AcquisitionType == APCI3200_SCAN)
			w_CJCGain = 1;

		/* Convert the CJC digital Value in V or A */
		v_ADDIDATA_ConvertDigitalToAnalogValue(APCI3200_POLARITY_BIPOLAR, // bipolar
				w_CJCGain,
				d_GainFactorValue,
				0,
				1,
				6,
				0,
				d_ReferenceVoltage,
				d_ReferenceVoltage,
				18,
				dw_CJCCalOffsetValue,
				dw_CJCCalGainValue,
				pdw_DigitalValue[1],
				&d_CJCAnalogValue);

		/* Convert the CJC Analog Value in Temperature */
		i_ErrorCode = i_ADDIDATA_ConvertRTDAnalogToTemperatureValue (ADDIDATA_RTD_TYPE_PT,
				1000,
				d_CurrentSourceCJCValue,
				d_CJCAnalogValue,
				&d_CJCTempValue);

		if(i_ErrorCode) return i_ErrorCode;

		/* Convert the CJC Temperature in Analog Value (Type thermocouple) */
		i_ErrorCode = i_ADDIDATA_ConvertTempValueToAnalogTHERMOCOUPLEValue(b_TypePrecision,
				d_CJCTempValue,
				&d_CJCVoltageValue);
		if(i_ErrorCode) return i_ErrorCode;

		i_ErrorCode = i_ADDIDATA_ConvertTHERMOCOUPLEAnalogToTemperatureValue (b_TypePrecision,
					d_CJCVoltageValue,
					d_AnalogValue,
					pd_RealValue);
		break;
	case ADDIDATA_RTD: /* RTD */
		i_ErrorCode = i_ADDIDATA_ConvertRTDAnalogToTemperatureValue (b_TypePrecision,
				w_InputTypeValue,
				d_CurrentSourceValue,
				d_AnalogValue,
				pd_RealValue);
		break;
	default:
		warnx("%s:%d: unknown sensor type %d",__FUNCTION__,__LINE__,b_InputType);
	}

	return (i_ErrorCode);
}
