
/** \file XPortGPIO.cc */

/****************************************************************************/
/* Copyright (c) 2008 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  : Implements XPort GPIO API                                     */
/* Filename : XPortGPIO.cc                                                  */
/* Author   : K Headley                                                     */
/* Project  : Benthic Imaging AUV                                           */
/* Created  : 04/01/2008                                                    */
/****************************************************************************/
/* Modification History:                                                    */
/*  $Id: XPortGPIO.cc,v 1.6 2012/04/06 01:09:39 headley Exp $   */
/*  $Name: FastSim $ */
/****************************************************************************/

#include "XPortGPIO.h"
#ifdef _QNX
#include "System.h"
#endif
#include "BicamConsts.h"

/** Default destructor */
XPortGPIO::~XPortGPIO(){}

/** Default no argument constructor */
XPortGPIO::XPortGPIO(){
  _selectMask=CFG_MASK_GPIO_SEL_ALL;
  _directionMask=CFG_GPIO_ALL_OUTPUTS;
  _activeLevelMask=CFG_GPIO_ACTIVE_HI;
  _stateMask=CFG_GPIO_ALL_INACTIVE;
}
/** Initializing constructor 
    @param pXPort XPort to use
    @param selMask GPIO pin select mask (pins to activate when triggering)
    @param activeMask GPIO levels to set when ACTIVE
    @param inactiveMask GPIO levels to when when INACTIVE
*/
XPortGPIO::XPortGPIO(XPort *pXPort,
		     unsigned int selMask,
		     unsigned int dirMask, 
		     unsigned int levMask,
		     unsigned int staMask){
  configure(pXPort,selMask,dirMask,levMask,staMask);

}

/** Initializing constructor 
    @param selMask GPIO pin select mask (pins to activate when triggering)
    @param activeMask GPIO levels to set when ACTIVE
    @param inactiveMask GPIO levels to set when INACTIVE
*/
XPortGPIO::XPortGPIO(unsigned int selMask,
		     unsigned int dirMask, 
		     unsigned int levMask,
		     unsigned int staMask){
  configure(selMask,dirMask,levMask,staMask);
}

/** Configure XPort parameters 
    @param pXPort XPort to use
    @param selMask GPIO pin select mask (pins to activate when triggering)
    @param activeMask GPIO levels to set when ACTIVE
    @param inactiveMask GPIO levels to set when INACTIVE
*/
int XPortGPIO::configure(unsigned int selMask,
			 unsigned int dirMask, 
			 unsigned int levMask,
			 unsigned int staMask){

  _selectMask=selMask;
  _directionMask=dirMask;
  _activeLevelMask=levMask;
  _stateMask=staMask;
  return OK;
}
/** Configure XPort parameters 
    @param pXPort XPort to use
    @param selMask GPIO pin select mask (pins to activate when triggering)
    @param activeMask GPIO levels to set when ACTIVE
    @param inactiveMask GPIO levels to set when INACTIVE
*/
int XPortGPIO::configure(XPort *pXPort,
			 unsigned int selMask,
			 unsigned int dirMask, 
			 unsigned int levMask,
			 unsigned int staMask){

  int retval=OK;
  XPortResponse xpr;
  /* set member variables */
  retval=configure(selMask,dirMask,levMask,staMask);

  /* set xport reference */
  xport=pXPort;
  /* configure hardware pin 
     using just-configured default masks and values
     ** don't do this: XPort sets GPIO pins inactive
     ** when setActiveLevel or setDirect commands
     ** are received
  */
  //setActiveLevel(levVals,&xpr);
  //setDirection(dirVals,&xpr);
  return retval;
}
/** Establish XPort socket connections for GPIO and serial communications.
    @param host XPort TCP/IP host name/address
    @param gpioIPPort XPort TCP/IP port for GPIO
    @param dirMask GPIO direction control mask
    @param dirValues GPIO direction value mask (set input/output)
    @param levelMask GPIO level control mask 
    @param levelValues GPIO level value mask
*/
XPort *XPortGPIO::connect( char *host,
			      int gpioIPPort, 
			      unsigned int dirMask,
			      unsigned int dirValues,
			      unsigned int levelMask,
			      unsigned int levelValues){
  XPortConnection *xpc;
  xpc=xport->getConnection();
  xpc->configHost(host);
  xpc->configGPIO(gpioIPPort, 
		  dirMask,
		  dirValues,
		  levelMask,
		  levelValues);
  if(xport->connectxp(XPCON_GPIO)==ERROR){
    cout << "connect: ERROR - connectxp failed"<<endl;
    return NULL;
  }
  
  return xport;
}
/** @return XPort member variable */
XPort *XPortGPIO::getXPort(){
  return xport;
}
/** Set XPort member variable
    @param xp pointer to XPort
*/
void XPortGPIO::setXPort(XPort *xp){
  xport=xp;
}

/** Activates GPIO pins set
    using the configure method.
*/
int XPortGPIO::setActive(){
  return setCurrentState(_selectMask,_stateMask,NULL);
}

/** Deactivates GPIO pins set
    using the configure method.
*/
int XPortGPIO::setInactive(){
  return setCurrentState(_selectMask,~_stateMask,NULL);
}

/** Activates then deactivates GPIO pins set
    using the configure method.
*/
int XPortGPIO::pulse(){
  setActive();
#ifdef _QNX
  System::milliSleep(100);
#else
	usleep(100000);	
#endif
  setInactive();
  return OK;
}

/** Set GPIO pin direction using current select and direction mask values.
    @param response Contains XPort response returned
    @return IS_VALID if successful, ERR_NULL if response set to NULL or other error code otherwise.
 */
int XPortGPIO::setDirection(unsigned int values, XPortResponse *response){
  return setDirection(_selectMask,values,response);
}

/** Set GPIO pin direction
    @param mask Pin selection mask (1: set pin 0: ignore pin)
    @param values Direction value mask (1: output 0: input)
    @param response Contains XPort response returned
    @return IS_VALID if successful, ERR_NULL if response set to NULL or other error code otherwise.
 */
int XPortGPIO::setDirection(unsigned int mask, unsigned int values,XPortResponse *response){
  XPortCommand cmd;

  /* set up XPort command. */
  cmd.set(XP_CMD_SET_DIRECTIONS,mask,values);

  /* Set direction of selected GPIO pins.
     XPort response is returned in response
  */
   return xport->writeRead(&cmd,response);
}

/** Set GPIO pin active levels using current select and active level mask values.
    @param response Contains XPort response returned
    @return IS_VALID if successful, ERR_NULL if response set to NULL or other error code otherwise.
 */
int XPortGPIO::setActiveLevel(unsigned int values, XPortResponse *response){
  return setActiveLevel(_selectMask ,values,response);
}
/** Set GPIO pin active level
    @param mask Pin selection mask (1: set pin 0: ignore pin)
    @param values Level value mask (1: active LO, 0: active HI)
    @param response Contains XPort response returned
    @return IS_VALID if successful, ERR_NULL if response set to NULL or other error code otherwise.
 */
int XPortGPIO::setActiveLevel(unsigned int mask, unsigned int values,XPortResponse *response){
  XPortCommand cmd;

  /* set up XPort command. */
  cmd.set(XP_CMD_SET_ACTIVE_LEVELS,mask,values);

  /* Change active level of selected GPIO pins.
     XPort response is returned in response
  */
  return xport->writeRead(&cmd,response);
}

/** Set state of GPIO pins using current select and state mask values.
    @param response Contains XPort response returned
    @return IS_VALID if successful, ERR_NULL if response set to NULL or other error code otherwise.
*/
int XPortGPIO::setCurrentState(unsigned int values, XPortResponse *response){
  return setCurrentState(_selectMask,values,response);
}

/** Set state of GPIO pins using specified select and value mask values.

    @param mask Pin selection mask (1: set pin 0: ignore pin)
    @param values Level value mask (1: active, 0: inactive)
    @param response Contains XPort response returned
    @return IS_VALID if successful, ERR_NULL if response set to NULL or other error code otherwise.
*/
int XPortGPIO::setCurrentState(unsigned int mask, unsigned int values,XPortResponse *response){
  XPortCommand cmd;

  /* set up XPort command. */
  cmd.set(XP_CMD_SET_CURRENT_STATES,mask,values);

  /* Change state of selected GPIO pins.
     XPort response is returned in response
  */
  return xport->writeRead(&cmd,response);

}

/** @return select mask member variable */
unsigned int XPortGPIO::getSelectMask(){
  return _selectMask;
}
/** @return direction mask member variable */
unsigned int XPortGPIO::getDirectionMask(){
  return _directionMask;
}
/** @return active level mask member variable */
unsigned int XPortGPIO::getActiveLevelMask(){
  return _activeLevelMask;
}
/** @return GPIO pin state mask member variable */
unsigned int XPortGPIO::getStateMask(){
  return _stateMask;
}
/** Set select mask member variable */
void XPortGPIO::setSelectMask(unsigned int mask){
  _selectMask=mask;
}
/** Set direction mask member variable
    @param mask new mask value
*/
void XPortGPIO::setDirectionMask(unsigned int mask){
  _directionMask=mask;
}
/** Set active level mask member variable
    @param mask new mask value
*/
void XPortGPIO::setActiveLevelMask(unsigned int mask){
  _activeLevelMask=mask;
}
/** Set GPIO pin state mask member variable */
void XPortGPIO::setStateMask(unsigned int mask){
  _stateMask=mask;
}
