/****************************************************************************/
/* Copyright 2015 MBARI                                                     */
/****************************************************************************/
/* Summary  : Digital I/O Support for OASIS5 on PIC32MX470F512L             */
/* Filename : dig_io.c                                                      */
/* Author   : Robert Herlien (rah)                                          */
/* Project  : OASIS Mooring Replacement (OASIS5)                            */
/* Revision: 1.0                                                            */
/* Created  : 07/13/2015                                                    */
/*                                                                          */
/* MBARI provides this documentation and code "as is", with no warranty,    */
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium  */
/* Research Institute to assist in its use, correction, modification, or    */
/* enhancement. This information should not be published or distributed to  */
/* third parties without specific written permission from MBARI.            */
/*                                                                          */
/****************************************************************************/
/* Modification History:                                                    */
/* 13jul2015 rah - created                                                  */
/****************************************************************************/

#include <xc.h>
#include <mbariTypes.h>					/* MBARI type definitions			*/
#include <oasis.h>						/* OASIS controller definitions		*/
#include <dig_io.h>
#include <sem.h>						/* OASIS Semaphore library			*/


/********************************/
/*  Module Local Data           */
/********************************/

MLocal unsigned int	pwrState;
MLocal Semaphore	relaySem;
	

/************************************************************************/
/* Function    : digInit                                                */
/* Purpose     : Initialize digital I/O ports on PIC32MX                */
/* Inputs      : None                                                   */
/* Outputs     : None                                                   */
/************************************************************************/
void digInit()
{
    /* Note: the ANSEL and TRIS registers have to be set on 
       ADC pins if you want to use them as digital I/O pins */    

    ANSELA = 0;
    ANSELB = 0x07c0;
    ANSELC = 0;
    ANSELD = 0;
    ANSELE = 0;
    ANSELF = 0;
    ANSELG = 0;

    TRISA = 0x0600;
    TRISB = 0x47dc;
    TRISC = 0x6014;
    TRISD = 0x980f;
    TRISE = 0x0200;
    TRISF = 0x001c;
    TRISG = 0x0100;

    LATA = 0xc038;
    LATB = 0;
    LATC = 0x0008;
    LATD = 0x2000;
    LATE = 0;
    LATF = 0;
    LATG = 0;

    ODCA  = 0x0008;
    ODCD  = 0x2000;

    CNPUA = 0x0008;
    CNPUC = 0x6004;
    CNPUD = 0x100e;

	CNPDB = 0x1c;
	CNPDD = 1;
	CNPDE = 0x200;

    clearRelayCoils();
}


/************************************************************************/
/* Function    : digSerEnable                                           */
/* Purpose     : Enable Tx on a serial port                             */
/* Inputs      : Serial port number                                     */
/* Outputs     : None                                                   */
/************************************************************************/
void digSerEnable(int port)
{
    switch(port)
    {
      case 0: digTx0En();  return;
      case 1: digTx1En();  return;
      case 2: digTx2En();  return;
      case 3: digTx3En();  return;
      case 4: digTx4En();  return;
    }
}

/************************************************************************/
/* Function    : digSerDisable                                          */
/* Purpose     : Disable Tx on a serial port                            */
/* Inputs      : Serial port number                                     */
/* Outputs     : None                                                   */
/************************************************************************/
void digSerDisable(int port)
{
    switch(port)
    {
      case 0: digTx0Dis();  return;
      case 1: digTx1Dis();  return;
      case 2: digTx2Dis();  return;
      case 3: digTx3Dis();  return;
      case 4: digTx4Dis();  return;
    }
}

/************************************************************************/
/* Function    : digSnd485                                              */
/* Purpose     : Put Modbus port into 485 Send mode                     */
/* Inputs      : Serial port number                                     */
/* Outputs     : None                                                   */
/************************************************************************/
void digSnd485(int port)
{
    switch(port)
    {
      case 1: dig1Snd485();  return;
      case 2: dig2Snd485();  return;
      case 3: dig3Snd485();  return;
      case 4: dig4Snd485();  return;
    }
}

/************************************************************************/
/* Function    : digRcv485                                              */
/* Purpose     : Put Modbus port into 485 Receive mode                  */
/* Inputs      : Serial port number                                     */
/* Outputs     : None                                                   */
/************************************************************************/
void digRcv485(int port)
{
    switch(port)
    {
      case 1: dig1Rcv485();  return;
      case 2: dig2Rcv485();  return;
      case 3: dig3Rcv485();  return;
      case 4: dig4Rcv485();  return;
    }
}

/************************************************************************/
/* Function    : digSense485                                            */
/* Purpose     : Read 485/232 sense bit                                 */
/* Inputs      : Serial port number                                     */
/* Outputs     : Zero for RS-232, non-zero for RS-485                   */
/************************************************************************/
int  digSense485(int port)
{
    switch(port)
    {
      case 1: return(dig1Is485());
      case 2: return(dig2Is485());
      case 3: return(dig3Is485());
      case 4: return(dig4Is485());
    }

    return(0);
}


/************************************************************************/
/* Function    : digPwrOn                                               */
/* Purpose     : Turn on a power relay                                  */
/* Inputs      : Power port number                                      */
/* Outputs     : None                                                   */
/************************************************************************/
void digPwrOn(int port)
{
    dig12vEnable();

    switch(port)
    {
      case 1: relay1SetOn(); break;
      case 2: relay2SetOn(); break;
      case 3: relay3SetOn(); break;
      case 4: relay4SetOn(); break;
      default: dig12vDisable(); return;
    }

    tmrDelayMs(RELAY_DELAY_MS);

    clearRelayCoils();
    dig12vDisable();
    
    pwrState |= (1 << port);
}

/************************************************************************/
/* Function    : digPwrOff                                              */
/* Purpose     : Turn off a power relay                                 */
/* Inputs      : Power port number                                      */
/* Outputs     : None                                                   */
/************************************************************************/
void digPwrOff(int port)
{
    dig12vEnable();

    switch(port)
    {
      case 1: relay1ResetOn(); break;
      case 2: relay2ResetOn(); break;
      case 3: relay3ResetOn(); break;
      case 4: relay4ResetOn(); break;
      default: dig12vDisable(); return;
    }

    tmrDelayMs(RELAY_DELAY_MS);

    clearRelayCoils();
    dig12vDisable();

    pwrState &= ~(1 << port);
}


/************************************************************************/
/* Function    : digPwrSet                                              */
/* Purpose     : Turn on/off a power relay                              */
/* Inputs      : Power port number, state                               */
/* Outputs     : None                                                   */
/************************************************************************/
void digPwrSet(int port, int state)
{
    if (state)
        digPwrOn(port);
    else
        digPwrOff(port);
}


/************************************************************************/
/* Function    : digPwrVecGet                                           */
/* Purpose     : Return state of power bits                             */
/* Inputs      : None                                                   */
/* Outputs     : Power Vector                                           */
/************************************************************************/
int digPwrVecGet(void)
{
    return(pwrState);
}


/************************************************************************/
/* Function    : digPwrVecSet                                           */
/* Purpose     : Set all power relays to given state					*/
/* Inputs      : Power Vector                                           */
/* Outputs     : None                                                   */
/************************************************************************/
void digPwrVecSet(int state)
{
    dig12vEnable();

	if (state & 2)
		relay1SetOn();
	else
		relay1ResetOn();

	if (state & 4)
		relay2SetOn();
	else
		relay2ResetOn();

	if (state & 8)
		relay3SetOn();
	else
		relay3ResetOn();

	if (state & 0x10)
		relay4SetOn();
	else
		relay4ResetOn();

    tmrDelayMs(RELAY_DELAY_MS);

    clearRelayCoils();
    dig12vDisable();

    pwrState = state;
}


/************************************************************************/
/* Function    : digPwrAllOff                                           */
/* Purpose     : Turn off all power/serial relays                       */
/* Inputs      : None                                                   */
/* Outputs     : None                                                   */
/************************************************************************/
void digPwrAllOff(void)
{
    dig12vEnable();
    relay1ResetOn();
    relay2ResetOn();
    relay3ResetOn();
    relay4ResetOn();
    
    tmrDelayMs(RELAY_DELAY_MS);

    clearRelayCoils();
    dig12vDisable();

    pwrState = 0;
}
