/****************************************************************************/
/* Copyright 2010 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include "dig_io.h"
#include "p24Fxxxx.h"
#include "sys_defs.h"

static int dummyBit;

#define TOTAL_OUT_BITS  19

#define PIC_DIO_01_RST LATFbits.LATF4 	//PIC_DIO_01_RST
#define PIC_DIO_02_RST LATFbits.LATF5	//PIC_DIO_02_RST	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_03_RST LATFbits.LATF6	//PIC_DIO_03_RST	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_04_RST LATGbits.LATG2	//PIC_DIO_O4_RST	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_05_RST LATEbits.LATE6	//PIC_DIO_05_RST
#define PIC_ADC_01_SHDN LATFbits.LATF0	//PIC_ADC_01_SHDN
#define PIC_ADC_02_SHDN LATFbits.LATF1	//PIC_ADC_02_SHDN
#define PIC_ADC_03_SHDN LATFbits.LATF2	//PIC_ADC_03_SHDN	*NOT USED ON CURRENT BOARD*
#define PIC_ADC_04_SHDN LATFbits.LATF3	//PIC_ADC_04_SHDN	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_05_CS LATEbits.LATE5	//PIC_DIO_05_CS
#define CS_ADD_EN LATEbits.LATE4		//CS_ADD_EN
#define CS_ADD_A0 LATEbits.LATE3		//CS_ADD_A0
#define CS_ADD_A1 LATEbits.LATE2		//CS_ADD_A1
#define CS_ADD_A2 LATEbits.LATE1		//CS_ADD_A2
#define CS_ADD_A3 LATEbits.LATE0		//CS_ADD_A3
#define BD_ADD_0 LATDbits.LATD0			//BD_ADD_0
#define BD_ADD_1 LATDbits.LATD1			//BD_ADD_1
#define BD_ADD_2 LATDbits.LATD2			//BD_ADD_2
#define PIC_INT_OE LATDbits.LATD11		//PIC_INT_OE 




#define TOTAL_IN_BITS  16

#define PIC_DIO_01_INT PORTDbits.RD3	//PIC_DIO_01_INT
#define PIC_DIO_02_INT PORTDbits.RD4	//PIC_DIO_02_INT	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_03_INT PORTDbits.RD5	//PIC_DIO_03_INT	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_04_INT PORTDbits.RD6	//PIC_DIO_04_INT	*NOT USED ON CURRENT BOARD*
#define PIC_DIO_05_INT PORTEbits.RE7	//PIC_DIO_05_INT 
#define IN_BIT_5 dummyBit				//SPI1_CS 
#define	IN_BIT_6 dummyBit
#define IN_BIT_7 dummyBit 
#define IN_BIT_8 dummyBit 

#define IN_BIT_9 dummyBit 
#define IN_BIT_10 dummyBit 
#define IN_BIT_11 dummyBit 
#define IN_BIT_12 dummyBit 
#define IN_BIT_13 dummyBit 
#define IN_BIT_14 dummyBit 
#define IN_BIT_15 dummyBit 


/* init registers */
//*updated* --JP

void digInit()
{
    /* Note: the AD1PCFGL and TRIS registers have to be set on 
    ADC pins if you want to use them as digital I/O pins */    
	
	/* Configure all analog/digital sharing pins to digital */
	// 1 = digital, 0 = analog (n=ADC#)

	AD1PCFG = 0xffff;			//onboard ADC not used on LV Switcher

    /* set inputs and outputs here */

	//Note: Not all inputs here are used on current version 
	//of the board; however they have been initialized as such

	TRISD =     0x0078;			//all outputs, except inputs D3-D6
	TRISE = 	0x0080;			//all outputs, except input E7
	TRISF = 	0x0000;			//all outputs
	TRISG = 	0x0000;			//all outputs
	
	CNPU1bits.CN13PUE = 0;  //input change notification, generates interrupt requests to the
							//processor in response to a change of state on selected input pins
   							//not sure what this was for. SEE SPI1.C  --JP

    /* put out bits in default state here */

    Nop();					// Nop() => do nothing for one clock cycle? --JP
   	PIC_DIO_01_RST = 0;		//INIT LOW
    Nop();
    PIC_DIO_02_RST = 0;    	//INIT LOW
    Nop();
    PIC_DIO_03_RST = 0;		//INIT LOW
    Nop();
    PIC_DIO_04_RST = 0;		//INIT LOW
    Nop();
    PIC_DIO_05_RST = 0;		//INIT LOW
    Nop();
    PIC_ADC_01_SHDN = 0;	//INIT HIGH, SHUTDOWN WHEN SET LOW
    Nop();
    PIC_ADC_02_SHDN = 0;	//INIT HIGH, SHUTDOWN WHEN SET LOW
    Nop();
    PIC_ADC_03_SHDN = 0;	//INIT HIGH, SHUTDOWN WHEN SET LOW
	Nop();
    PIC_ADC_04_SHDN = 0;	//INIT HIGH, SHUTDOWN WHEN SET LOW
	Nop();
    PIC_DIO_05_CS = 0;		//INIT HIGH, ACTIVE WHEN SET LOW
	Nop();
    CS_ADD_EN = 1;			//INIT HIGH, ACTIVE WHEN SET LOW
	Nop();
    CS_ADD_A0 = 0;			//INIT LOW
	Nop();
    CS_ADD_A1 = 0;			//INIT LOW
	Nop();
    CS_ADD_A2 = 0; 			//INIT LOW
	Nop();
    CS_ADD_A3 = 0;			//INIT LOW 
	Nop();
    BD_ADD_0 = 0; 			//INIT LOW
	Nop();
    BD_ADD_1 = 0; 			//INIT LOW
	Nop();
    BD_ADD_2 = 0; 			//INIT LOW
	Nop();
    PIC_INT_OE = 1; 		//INIT HIGH, ACTIVE WHEN SET LOW

}

/* power bit API */
//Use this fuction to set bits low or high
void digSetOutBit(int bit, int state)
{
    /* state is non zero, set it to one */
    if ( state )
        state = 1;
    
    Nop();

    switch (bit)
    {
        case 0: PIC_DIO_01_RST = state; 	break;
        case 1: PIC_DIO_02_RST = state; 	break;
        case 2: PIC_DIO_03_RST = state; 	break;
        case 3: PIC_DIO_04_RST = state; 	break;
        case 4: PIC_DIO_05_RST = state; 	break;
        case 5: PIC_ADC_01_SHDN  = state; 	break;
        case 6: PIC_ADC_02_SHDN  = state; 	break;
        case 7: PIC_ADC_03_SHDN  = state; 	break;
		case 8: PIC_ADC_04_SHDN  = state; 	break;
        case 9: PIC_DIO_05_CS = state; 		break;
        case 10: CS_ADD_EN = state; 		break;
        case 11: CS_ADD_A0 = state; 		break;
        case 12: CS_ADD_A1 = state; 		break;
        case 13: CS_ADD_A2 = state; 		break;
        case 14: CS_ADD_A3 = state; 		break;
        case 15: BD_ADD_0 = state; 			break;
		case 16: BD_ADD_1 = state; 			break;
		case 17: BD_ADD_2 = state; 			break;
		case 18: PIC_INT_OE = state; 		break;
        default: return;
    }
}

int digGetOutBit(int bit)
{
    Nop();

    /* set dummyBit to 0 so undefined bits always read back as 0 */
    dummyBit = 0;
    
    switch (bit)
    {
        case 0: return (int)PIC_DIO_01_RST;
        case 1: return (int)PIC_DIO_02_RST;
        case 2: return (int)PIC_DIO_03_RST;
        case 3: return (int)PIC_DIO_04_RST;
        case 4: return (int)PIC_DIO_05_RST;
        case 5: return (int)PIC_ADC_01_SHDN;
        case 6: return (int)PIC_ADC_02_SHDN;
        case 7: return (int)PIC_ADC_03_SHDN;
		case 8: return (int)PIC_ADC_04_SHDN;
        case 9: return (int)PIC_DIO_05_CS;
        case 10: return (int)CS_ADD_EN;
        case 11: return (int)CS_ADD_A0;
        case 12: return (int)CS_ADD_A1;
        case 13: return (int)CS_ADD_A2;
        case 14: return (int)CS_ADD_A3;
        case 15: return (int)BD_ADD_0;
		case 16: return (int)BD_ADD_1;
		case 17: return (int)BD_ADD_2;
		case 18: return (int)PIC_INT_OE;
        default: return 0;
    }
}

void digSetOutPort(unsigned int val)
{
    int i;
    unsigned int bit = 0x0001;
     
    for (i = 0; i < TOTAL_OUT_BITS; ++i)
    {
        digSetOutBit(i, (val & bit));
        bit <<= 1;
    }
}

unsigned int digGetOutPort(void)
{
    int i;
    unsigned int bit = 0x0001;
    unsigned int val = 0;

    for (i = 0; i < TOTAL_OUT_BITS; ++i)
    {
        if ( digGetOutBit(i) )
            val += bit;
        
        bit <<= 1;
    }

    return val;
}

/* digital input API */
int digGetInBit(int bit)
{
    Nop();

    /* set dummyBit to 0 so undefined bits always read back as 0 */
    dummyBit = 0;
    
    switch (bit)
    {
        case 0: return (int)PIC_DIO_01_INT;
        case 1: return (int)PIC_DIO_02_INT;
        case 2: return (int)PIC_DIO_03_INT;
        case 3: return (int)PIC_DIO_04_INT;
        case 4: return (int)PIC_DIO_05_INT;
        case 5: return (int)IN_BIT_5;
		case 6: return (int)IN_BIT_6;
        case 7: return (int)IN_BIT_7;
		case 8: return (int)IN_BIT_8;
        case 9: return (int)IN_BIT_9;
        case 10: return (int)IN_BIT_10;
        case 11: return (int)IN_BIT_11;
        case 12: return (int)IN_BIT_12;
        case 13: return (int)IN_BIT_13;
        case 14: return (int)IN_BIT_14;
        case 15: return (int)IN_BIT_15;
        default: return 0;
    }
}

unsigned int digGetInPort(void)
{
    int i;
    unsigned int bit = 0x0001;
    unsigned int val = 0;

    for (i = 0; i < TOTAL_IN_BITS; ++i)
    {
        if ( digGetInBit(i) )
            val += bit;
        
        bit <<= 1;
    }

    return val;
}

