/****************************************************************************/
/* Copyright 2010 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include <p24fxxxx.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sys_defs.h"

#include "actions.h"
#include "errors.h"
#include "parser.h"
#include "serial.h"
#include "dig_io.h"
#include "spi_io.h"

#define MAX_CHARS   80  /* maximum command line entry length */
static char msg_buff[64];
char cmd_buff[MAX_CHARS];
#define ChipSelect OUT_BIT_13

/****************************************************************************/
/*                               Root commands                              */
/****************************************************************************/
int actGetCmd(char* s)
{
    return prsParse(s, cmdsGet, ERR_NO_SUB_COMMAND);
}

int actSetCmd(char* s)
{
    return prsParse(s, cmdsSet, ERR_NO_SUB_COMMAND);
}

int actClrCmd(char* s)
{
    return prsParse(s, cmdsClr, ERR_NO_SUB_COMMAND);
}

int actHelloKittyCmd(char* s)
{
    serPutString(SER_CONSOLE, "MEOW\r\n");
    return ERR_SUCCESS;
}

/****************************************************************************/
/*                               Get commands                               */
/****************************************************************************/

int actGetDinCmd(char* s)
{
    int bit = atoi(s);
    
    if ( digGetInBit(bit) )
        sprintf(msg_buff, "BIT %d IS HI\r\n", bit);
    else
        sprintf(msg_buff, "BIT %d IS LO\r\n", bit);

    serPutString(SER_CONSOLE, msg_buff);


    return ERR_SUCCESS;
}

int actGetDoutCmd(char* s)
{
    int bit = atoi(s);
    
    if ( digGetOutBit(bit) )
        sprintf(msg_buff, "BIT %d IS HI\r\n", bit);
    else
        sprintf(msg_buff, "BIT %d IS LO\r\n", bit);

    serPutString(SER_CONSOLE, msg_buff);


    return ERR_SUCCESS;
}



/****************************************************************************/
/*                               Set commands                               */
/****************************************************************************/
int actSetDoutCmd(char* s)
{
    int bit = atoi(s);
    
    digSetOutBit(bit, 1);

    return ERR_SUCCESS;
}





/****************************************************************************/
/*                              Clear commands                              */
/****************************************************************************/
int actClrDoutCmd(char* s)
{
    int bit = atoi(s);
    
    digSetOutBit(bit, 0);

    return ERR_SUCCESS;
}


		



/****************************************************************************/
/*                    LVLS Board commands		                            */
/****************************************************************************/

int actGetADCCmd(char* s)
{
	int bit = atoi(s);
	unsigned int analog1 = 0;
	unsigned int analog2 = 0;
	unsigned int analog3 = 0;
	unsigned int analog4 = 0;
	unsigned int analog5 = 0;
	unsigned int analog6 = 0;
	int i=0; 
	int conword = 0;
  	double value = 0;

	switch (bit) // Establish Control Word for each bit
	{
		case 0: conword = 151; break; // 8341 ch 0
		case 1: conword = 215; break; // 8341 ch 1
		case 2: conword = 167; break; // 8341 ch 2
		case 3: conword = 231; break; // 8341 ch 3
		default: return;
	}

	CSAddSet(1);
	SPI2STATbits.SPIROV = 0;
	spiReadWrite2(3); // setup up clock type in ADC chip (internal)
	Nop();
	
	spiReadWrite2(conword);     // Send ADC control word
	//for(i = 0; i < 5; ++i)
    //Nop();
	analog1 = spiReadWrite2(0); // MSB
	analog2 = spiReadWrite2(0); // LSB
	analog3 = spiReadWrite2(0); // Extra Bit + Trailing zeroes?

   	CSAddSet(99);

	sprintf(cmd_buff, "\r\nanalog1 = %f\r\n", analog1);
	serPutString(SER_CONSOLE, cmd_buff);

	sprintf(cmd_buff, "\r\nanalog2 = %f\r\n", analog2);
	serPutString(SER_CONSOLE, cmd_buff);

	sprintf(cmd_buff, "\r\nanalog3 = %f\r\n", analog3);
	serPutString(SER_CONSOLE, cmd_buff);

	/* Combine 2 8-bit analog words to 1 16-bit word */	
	analog4 = analog1;
   
	analog4 <<= 8;

    analog4 |= (0x00FF & analog2);

	analog4 <<=1; // shift resulting word 1 bit left

	analog3 >>= 7; // shift Extra bit to '1' position
	analog5 = 0x0000;
	analog5 <<=8;
	analog5 |= (0x00FF & analog3); // Mask Extra bit into 16-bit word

	analog6 = (analog4 | analog5); // Add Extra bit onto 16-bit word

	//sprintf(cmd_buff, "\r\nanalog6 = %d\r\n", analog6);
	//serPutString(SER_CONSOLE, cmd_buff);

	value = anaConvSample(bit, analog6,0);
	
	sprintf(cmd_buff, "\r\nReturned Value = %f\r\n", value);
	serPutString(SER_CONSOLE, cmd_buff);
	
	return ERR_SUCCESS;
}


void CSAddSet(int address)
{
	switch(address)
	{
		case 0: // DIO_01_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,0);  // Add A2
			digSetOutBit(2,0);  // Add A1
			digSetOutBit(3,0);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}
		case 1: // ADC_01_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,0);  // Add A2
			digSetOutBit(2,0);  // Add A1
			digSetOutBit(3,1);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}

		case 2: // POT_01_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,0);  // Add A2
			digSetOutBit(2,1);  // Add A1
			digSetOutBit(3,0);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}

		case 3: // POT_02_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,0);  // Add A2
			digSetOutBit(2,1);  // Add A1
			digSetOutBit(3,1);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}
		case 4: // DIO_02_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,1);  // Add A2
			digSetOutBit(2,0);  // Add A1
			digSetOutBit(3,0);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}
	
		case 5: // ADC_02_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,1);  // Add A2
			digSetOutBit(2,0);  // Add A1
			digSetOutBit(3,1);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}
		case 6: // POT_03_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,1);  // Add A2
			digSetOutBit(2,1);  // Add A1
			digSetOutBit(3,0);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}
		case 7: // POT_04_CS
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,1);  // Add A2
			digSetOutBit(2,1);  // Add A1
			digSetOutBit(3,1);	// Add A0
			digSetOutBit(4,0);  // Add EN
			break;
		}
		default: 
		{
			digSetOutBit(0,0);  // Add A3
			digSetOutBit(1,0);  // Add A2
			digSetOutBit(2,0);  // Add A1
			digSetOutBit(3,0);	// Add A0
			digSetOutBit(4,1);  // Add EN
			break;
		}
	}
	 
	return;
}
