/****************************************************************************/
/* 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  32

#define OUT_BIT_0 LATEbits.LATE0 // CS Address 3 (MSB)
#define OUT_BIT_1 LATEbits.LATE1 // CS Address 2 
#define OUT_BIT_2 LATEbits.LATE2 // CS Address 1
#define OUT_BIT_3 LATEbits.LATE3 // CS Address 0 (LSB)
#define OUT_BIT_4 LATEbits.LATE4 // CS Address Enable
#define OUT_BIT_5 LATEbits.LATE5 // DIO_05 CS
#define OUT_BIT_6 LATEbits.LATE6 // DIO_05 RST 
#define OUT_BIT_7 LATDbits.LATD11 // PIC_INT Output Enable  

#define OUT_BIT_8 LATFbits.LATF0 // ADC_01 Shutdown
#define OUT_BIT_9 LATFbits.LATF1 // ADC_02 Shutdown
#define OUT_BIT_10 LATFbits.LATF2 // ADC_03 Shutdown
#define OUT_BIT_11 LATFbits.LATF3 // ADC_04 Shutdown
#define OUT_BIT_12 LATFbits.LATF4 // DIO_01 Reset
#define OUT_BIT_13 LATFbits.LATF5 // DIO_02 Reset
#define OUT_BIT_14 LATFbits.LATF6 // DIO_03 Reset
#define OUT_BIT_15 LATGbits.LATG2 // DIO_04 Reset

#define OUT_BIT_16 LATBbits.LATB3 // V27 Spare
#define OUT_BIT_17 LATBbits.LATB6 // V39 Spare
#define OUT_BIT_18 LATBbits.LATB7 // V40 Spare 
#define OUT_BIT_19 LATBbits.LATB8 // V41 Spare 
#define OUT_BIT_20 LATBbits.LATB9 // V42 Spare 
#define OUT_BIT_21 LATBbits.LATB10 // V43 Spare  
#define OUT_BIT_22 LATBbits.LATB11 // V44 Spare 
#define OUT_BIT_23 LATBbits.LATB12 // V45 Spare 

#define OUT_BIT_24 LATBbits.LATB13 // V46 Spare 
#define OUT_BIT_25 LATBbits.LATB14 // V47 Spare
#define OUT_BIT_26 LATBbits.LATB15 // V48 Spare 
#define OUT_BIT_27 LATGbits.LATG3 // V36 Spare 
#define OUT_BIT_28 LATDbits.LATD8 // V50 Spare 
#define OUT_BIT_29 LATCbits.LATC13 // V37 Spare 
#define OUT_BIT_30 LATCbits.LATC14 // V38 Spare
#define OUT_BIT_31 LATDbits.LATD7 // V49 Spare 

#define TOTAL_IN_BITS  16

#define IN_BIT_0 PORTDbits.RD0 // Board Address 0
#define IN_BIT_1 PORTDbits.RD1 // Board Address 1
#define IN_BIT_2 PORTDbits.RD2 // Board Address 2
#define IN_BIT_3 PORTDbits.RD3 // DIO_01 Interrupt
#define IN_BIT_4 PORTDbits.RD4 // DIO_02 Interrupt
#define IN_BIT_5 PORTDbits.RD5 // DIO_03 Interrupt
#define IN_BIT_6 PORTDbits.RD6 // DIO_04 Interrupt
#define IN_BIT_7 PORTEbits.RE7 // DIO_05 Interrupt

#define IN_BIT_8 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_9 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_10 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_11 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_12 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_13 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_14 dummyBit // Placeholder for Spare_xx Inputs (if needed)
#define IN_BIT_15 dummyBit // Placeholder for Spare_xx Inputs (if needed)


/* init registers */
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#)

	AD1PCFGbits.PCFG0 = 1;
	AD1PCFGbits.PCFG1 = 1;
	AD1PCFGbits.PCFG2 = 1;
	AD1PCFGbits.PCFG3 = 1;
	AD1PCFGbits.PCFG4 = 1;
	AD1PCFGbits.PCFG5 = 1;
	AD1PCFGbits.PCFG6 = 1;
	AD1PCFGbits.PCFG7 = 1;
	AD1PCFGbits.PCFG8 = 1;
	AD1PCFGbits.PCFG9 = 1;
	AD1PCFGbits.PCFG10 = 1;
	AD1PCFGbits.PCFG11 = 1;
	AD1PCFGbits.PCFG12 = 1;
	AD1PCFGbits.PCFG13 = 1;
	AD1PCFGbits.PCFG14 = 1;
	AD1PCFGbits.PCFG15 = 1;


    /* set outputs here */

	TRISBbits.TRISB3 = 0;
	TRISBbits.TRISB6 = 0;
	TRISBbits.TRISB7 = 0;
	TRISBbits.TRISB8 = 0;
	TRISBbits.TRISB9 = 0;
	TRISBbits.TRISB10 = 0;
	TRISBbits.TRISB11 = 0;
	TRISBbits.TRISB12 = 0;	
	TRISBbits.TRISB13 = 0;
	TRISBbits.TRISB14 = 0;
	TRISBbits.TRISB15 = 0;

	TRISCbits.TRISC13 = 0;
	TRISCbits.TRISC14 = 0;	
	
	TRISDbits.TRISD7 = 0;
	TRISDbits.TRISD8 = 0;
	TRISDbits.TRISD11 = 0;

	TRISEbits.TRISE0 = 0;
	TRISEbits.TRISE1 = 0;
	TRISEbits.TRISE2 = 0;
	TRISEbits.TRISE3 = 0;
	TRISEbits.TRISE4 = 0;
	TRISEbits.TRISE5 = 0;	
	TRISEbits.TRISE6 = 0;

	TRISFbits.TRISF0 = 0;
	TRISFbits.TRISF1 = 0;
	TRISFbits.TRISF2 = 0;
	TRISFbits.TRISF3 = 0;
	TRISFbits.TRISF4 = 0;
	TRISFbits.TRISF5 = 0;
	TRISFbits.TRISF6 = 0;

	TRISGbits.TRISG2 = 0;
	TRISGbits.TRISG3 = 0;

	//TRISBbits.TRISB3 = 0; // Used for UART1 TxD 
       
    /* set inputs here */

   	// TRISBbits.TRISB12 = 1;
	// AD1PCFGbits.PCFG12 = 1;
	// TRISBbits.TRISB13 = 1;
	// AD1PCFGbits.PCFG13 = 1;

	TRISDbits.TRISD0 = 1;
	TRISDbits.TRISD1 = 1;
	TRISDbits.TRISD2 = 1;
	TRISDbits.TRISD3 = 1;
	TRISDbits.TRISD4 = 1;
	TRISDbits.TRISD5 = 1;
	TRISDbits.TRISD6 = 1;

	TRISEbits.TRISE7 = 1;
	
	//TRISBbits.TRISB2 = 1; // Used for UART1 RxD


    /* put out bits in default state here */
    Nop();
    OUT_BIT_0 = 0;
    Nop();
    OUT_BIT_1 = 0;    
    Nop();
    OUT_BIT_2 = 0;
    Nop();
    OUT_BIT_3 = 0;
    Nop();
    OUT_BIT_4 = 1;
    Nop();
    OUT_BIT_5 = 1;
    Nop();
    OUT_BIT_6 = 0;
    Nop();
    OUT_BIT_7 = 1;
	Nop();
    OUT_BIT_8 = 1;
	Nop();
    OUT_BIT_9 = 1;
	Nop();
    OUT_BIT_10 = 1;
	Nop();
    OUT_BIT_11 = 1;
	Nop();
    OUT_BIT_12 = 1;
	Nop();
    OUT_BIT_13 = 1;
	Nop();
    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();
    OUT_BIT_25 = 1;
	Nop();
    OUT_BIT_26 = 1;
	Nop();
    OUT_BIT_27 = 1;
	Nop();
    OUT_BIT_28 = 1;
	Nop();
    OUT_BIT_29 = 1;
	Nop();
    OUT_BIT_30 = 1;
	Nop();
    OUT_BIT_31 = 1;

}

/* 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;
        case 25: OUT_BIT_25 = state; break;
        case 26: OUT_BIT_26 = state; break;
        case 27: OUT_BIT_27 = state; break;
		case 28: OUT_BIT_28 = state; break;
		case 29: OUT_BIT_29 = state; break;
		case 30: OUT_BIT_30 = state; break;
		case 31: OUT_BIT_31 = 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;
        case 25: return (int)OUT_BIT_25;
        case 26: return (int)OUT_BIT_26;
        case 27: return (int)OUT_BIT_27;
		case 28: return (int)OUT_BIT_28;
		case 29: return (int)OUT_BIT_29;
		case 30: return (int)OUT_BIT_30;
		case 31: return (int)OUT_BIT_31;
        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;
		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;
}

