/****************************************************************************/
/* Copyright 2010 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include "dig_io.h"
#include "p24Fxxxx.h"
//#include "sys_defs.h"

static int dummyBit;

/* init registers */
void digInit()
{
    /* set outputs here */

	TRISBbits.TRISB0 = 0;	//Unused
	TRISBbits.TRISB1 = 0;	//Unused
        TRISBbits.TRISB2 = 0;	//Unused
	TRISBbits.TRISB3 = 0;	//Unused
	TRISBbits.TRISB4 = 0;	//Unused
        TRISBbits.TRISB5 = 0;	//Unused

        TRISCbits.TRISC13 = 0;	//Unused
        TRISCbits.TRISC14 = 0;	//Unused

	TRISDbits.TRISD6 = 0;	//UART_1_*SHDN
	TRISDbits.TRISD7 = 0;	//UART_2_*SHDN
	TRISDbits.TRISD8 = 0;	//UART_3_*SHDN
        TRISDbits.TRISD11 = 0;	//Unused

	TRISEbits.TRISE0 = 0;	//INSTR_1_ON
	TRISEbits.TRISE1 = 0;	//INSTR_1_OFF
	TRISEbits.TRISE2 = 0;	//INSTR_2_ON
	TRISEbits.TRISE3 = 0;	//INSTR_2_OFF
        TRISEbits.TRISE4 = 0;	//INSTR_3_ON
        TRISEbits.TRISE5 = 0;	//INSTR_3_OFF
	TRISEbits.TRISE6 = 0;	//INSTR_4_ON
	TRISEbits.TRISE7 = 0;	//INSTR_4_OFF

	TRISFbits.TRISF4 = 0;	//Unused
	TRISFbits.TRISF5 = 0;	//LED
	TRISFbits.TRISF6 = 0;	//DC-DC_CNTL

	TRISGbits.TRISG2 = 0;	//ADC_SHDN
	TRISGbits.TRISG6 = 0;	//SPI_CS

       
    /* set inputs here */
   
	TRISFbits.TRISF0 = 1;	//INSTR_1_STATE
	TRISFbits.TRISF1 = 1;	//INSTR_2_STATE
	TRISFbits.TRISF2 = 1;	//INSTR_3_STATE
        TRISFbits.TRISF3 = 1;	//INSTR_4_STATE

        TRISGbits.TRISG3 = 1;	//ADC_BUSY

	TRISBbits.TRISB8  = 1;  //Hardware Config switches
	TRISBbits.TRISB9  = 1;
	TRISBbits.TRISB10 = 1;
	TRISBbits.TRISB11 = 1;
	TRISBbits.TRISB12 = 1;
	TRISBbits.TRISB13 = 1;
	TRISBbits.TRISB14 = 1;
	TRISBbits.TRISB15 = 1;



    /* put out bits in default state here */
    Nop();
    INSTR_1_ON = 0;  // 1 on
    Nop();
    INSTR_2_ON = 0;  // 2 on
    Nop();
    INSTR_3_ON = 0;  // 3 on
    Nop();
    INSTR_4_ON = 1;  // 4 on
    Nop();
    INSTR_1_OFF = 0; // 1 off
    Nop();
    INSTR_2_OFF = 0; // 2 off
    Nop();
    INSTR_3_OFF = 0; // 3 off
    Nop();
    INSTR_4_OFF = 1; // 4 off
    Nop();
    UART_1_SHDN = 1;  // uart 1 shdn
    Nop();
    UART_2_SHDN = 1;
    Nop();
    UART_3_SHDN = 1;
    Nop();
    LED_BIT = 0;
    Nop();
    DC_CTRL = 0;
    Nop();
    ADC_SHDN = 1;
    Nop();
    SPI_CS = 1;
    Nop();
			//Remaining output bits unused, initialized high	
    OUT_BIT_14 = 1;
    Nop();
    OUT_BIT_15 = 1;
    Nop();
    OUT_BIT_16 = 1;
    Nop();
    OUT_BIT_17 = 1;
    Nop();
    OUT_BIT_18 = 1;
    Nop();
    OUT_BIT_19 = 1;
    Nop();
    OUT_BIT_20 = 1;
    Nop();
    OUT_BIT_21 = 1;
    Nop();
    OUT_BIT_22 = 1;
    Nop();
    OUT_BIT_23 = 1;
    Nop();
    OUT_BIT_24 = 1;
    Nop();
}

void digSetBlinky(int state)
{
    Nop();
    
    if ( state )
        LED_BIT = 1;
    else
        LED_BIT = 0;
    
    Nop();
}

int digGetBlinky()
{
    Nop();
    return (int)LED_BIT;
}


/* power bit API */
void digSetOutBit(int bit, int state)
{
    /* state is non zero, set it to one */
    if ( state )
        state = 1;
    
    Nop();

    switch (bit)
    {
        case 0: OUT_BIT_0 = state; break;
        case 1: OUT_BIT_1 = state; break;
        case 2: OUT_BIT_2 = state; break;
        case 3: OUT_BIT_3 = state; break;
        case 4: OUT_BIT_4 = state; break;
        case 5: OUT_BIT_5 = state; break;
        case 6: OUT_BIT_6 = state; break;
        case 7: OUT_BIT_7 = state; break;
        case 8: OUT_BIT_8 = state; break;
        case 9: OUT_BIT_9 = state; break;
        case 10: OUT_BIT_10 = state; break;
        case 11: OUT_BIT_11 = state; break;
        case 12: OUT_BIT_12 = state; break;
        case 13: OUT_BIT_13 = state; break;
        case 14: OUT_BIT_14 = state; break;
        case 15: OUT_BIT_15 = state; break;
        case 16: OUT_BIT_16 = state; break;
        case 17: OUT_BIT_17 = state; break;
        case 18: OUT_BIT_18 = state; break;
        case 19: OUT_BIT_19 = state; break;
        case 20: OUT_BIT_20 = state; break;
        case 21: OUT_BIT_21 = state; break;
        case 22: OUT_BIT_22 = state; break;
        case 23: OUT_BIT_23 = state; break;
        case 24: OUT_BIT_24 = 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)OUT_BIT_0;
        case 1: return (int)OUT_BIT_1;
        case 2: return (int)OUT_BIT_2;
        case 3: return (int)OUT_BIT_3;
        case 4: return (int)OUT_BIT_4;
        case 5: return (int)OUT_BIT_5;
        case 6: return (int)OUT_BIT_6;
        case 7: return (int)OUT_BIT_7;
	case 8: return (int)OUT_BIT_8;
        case 9: return (int)OUT_BIT_9;
        case 10: return (int)OUT_BIT_10;
        case 11: return (int)OUT_BIT_11;
        case 12: return (int)OUT_BIT_12;
        case 13: return (int)OUT_BIT_13;
        case 14: return (int)OUT_BIT_14;
        case 15: return (int)OUT_BIT_15;
	case 16: return (int)OUT_BIT_16;
        case 17: return (int)OUT_BIT_17;
        case 18: return (int)OUT_BIT_18;
        case 19: return (int)OUT_BIT_19;
        case 20: return (int)OUT_BIT_20;
        case 21: return (int)OUT_BIT_21;
        case 22: return (int)OUT_BIT_22;
        case 23: return (int)OUT_BIT_23;
	case 24: return (int)OUT_BIT_24;
        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)IN_BIT_0;
        case 1: return (int)IN_BIT_1;
        case 2: return (int)IN_BIT_2;
        case 3: return (int)IN_BIT_3;
        case 4: return (int)IN_BIT_4;
        case 5: return (int)IN_BIT_5;
        case 6: return (int)IN_BIT_6;
        case 7: return (int)IN_BIT_7;
        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;
}

