/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012                                                                         *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
    Description:
	Pilote d'interface avec un module d'entrées discrètes SEAIO470
	Hérite de CAnalogInputModule et réimplémente les fonctions virtuelles d'accès aux
	données du module mixte externes.
    
*/

/* ************************************************************************** */
/* Revision:
### 20121213 JFM
    Verision d'origine.
    
### YYYYMMDD Description du besoin ou du bug
    Description du changement.
 */

/* ************************************************************************** */

#include "Seaio470driver.h"

CSeaIO470Module::CSeaIO470Module(CSeaMaxLin *ModuleDriverPtr)
{
  mModuleDriverPtr = ModuleDriverPtr;
  mModuleType = EXT_IO_TYPE_470;
  mCurInput = 0;
}

//Reimplement the base class OpenModule() since the 470 module needs some more operations than the 430 and 440 modules.
//
unsigned int CSeaIO470Module::OpenModule(unsigned int SlaveAddress, CSeaMaxLin *DriverPtr, unsigned int ModuleID)
{
	if(mIsOpened == true)
		return EXT_MOD_RET_MODULE_ALREADY_OPENED;

	if(SetModuleDriverPtr(DriverPtr) == RET_ERROR)
	{
		CEngLog::instance()->AddLogString("Erreur Fatale: CExternalIOModule::OpenModule, le pointeur DriverPtr est invalide",1);
		return EXT_MOD_RET_ERR_INVALID_POINTER;
	}

	unsigned short buf[50];
	unsigned short ModuleType;
	int Ret;
	mModuleAddress = SlaveAddress;
	mModuleID = ModuleID;
	Ret = mModuleDriverPtr->Ioctl(mModuleAddress,IOCTL_READ_COMM_PARAM,buf);
	if(Ret != 0)
	{
		CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: CExternalIOModule::OpenModule, aucune réponse du module Type: %d, addresse: %d, ID: %d",mModuleType,SlaveAddress,ModuleID),1);
		return EXT_MOD_RET_ERR_MODULE_OFFLINE;
	}
	ModuleType = buf[0];
	if((eExternalModuleType_t)ModuleType != mModuleType)
	{
		CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: le module à l'addresse %d est configuré de type %d mais est plutôt de type %d",SlaveAddress,(unsigned short)mModuleType,ModuleType),1);
		mIsOpened = false;
		return EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH;
	}

	//Force analog inputs config.
	//
	adda_config ModuleConfig;
    ModuleConfig.device.channel_mode = CURRENT_LOOP;
    ModuleConfig.device.channel_mode = ANALOG_OFFSET;
    ModuleConfig.channels.ch_1 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_2 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_3 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_4 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_5 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_6 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_7 = ZERO_TO_TEN;
    ModuleConfig.channels.ch_8 = ZERO_TO_TEN;


//	ModuleConfig.device.channel_mode = SINGLE_ENDED;
//	ModuleConfig.device.channel_mode = ANALOG_OFFSET;
//	ModuleConfig.channels.ch_1 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_2 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_3 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_4 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_5 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_6 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_7 = ZERO_TO_FIVE;
//	ModuleConfig.channels.ch_8 = ZERO_TO_FIVE;
	int result = mModuleDriverPtr->Ioctl(mModuleAddress,IOCTL_SET_ADDA_CONFIG,&ModuleConfig);
	if(result < 0)
	{
//		qDebug("Impossible de configurer le module 470");
	}


	CEngLog::instance()->AddLogString(QString("").sprintf("Module ouvert avec succès. Addresse: %d, Type: %d, ID: %d",SlaveAddress,(unsigned short)mModuleType,ModuleID),3);
	mIsOpened = true;

	return EXT_MOD_RET_OK;
}

unsigned int CSeaIO470Module::ReadInput(int Channel)
{
	if(mModuleDriverPtr == 0)
		return RET_ERROR;

	if(Channel < 1 || Channel > SEAIO_470_MAX_CHANNEL)
		return RET_ERROR;

	mSeaIOModuleType = INPUTREG;    //Input type
	mRegisterStart = Channel;      //Assign channel to read
	mRegisterRange = 1;            //only 1 input


	int result = mModuleDriverPtr->Read(mModuleAddress,INPUTREG,Channel,1,&mInputBuffer[0]);
	if(result < 0)
	{
//		qDebug("impossible de lire l'entrée ananogique");
	}

	//We know the module is configured in 0 - 10V range (see the Open() function).
	mCurInput = (mInputBuffer[0] << 8) + (mInputBuffer[1]);

	return RET_OK;
}

unsigned int CSeaIO470Module::GetAnalogInput(int Channel, int *Data)
{
	if(ReadInput(Channel) == RET_ERROR)
		return RET_ERROR;

	*Data = mCurInput;

	return RET_OK;
}

unsigned int CSeaIO470Module::GetAnalogInput(int Channel, double &Data)
{
	if(ReadInput(Channel) == RET_ERROR)
		return RET_ERROR;

	Data = (double)mCurInput;

	return RET_OK;
}
