/****************************************************************************/
/* Copyright 2003 MBARI.                                                    */
/* Monterey Bay Aquarium Research Institute Proprietary Information.        */
/* All rights reserved.                                                     */
/****************************************************************************/
#if defined(__PCM__)
#include <16f873.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=3580000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use standard_io(A)
#use standard_io(B)
#use standard_io(D)
#use standard_io(E)
#endif

#include <stdlib.h>
#include <string.h>
#include "gfd.h"

/********************************** GLOBS ***********************************/

long clock_ticks = 0;
/* default to echo mode on */
int echo_mode = 1;
/* default to loop mode on */
int loop_mode = 1;

/********************************** GLOBS ***********************************/

#INT_RTCC
clock_isr()
{
    clock_ticks++;
}

void clear_ticks()
{
    disable_interrupts(INT_RTCC);
    set_rtcc(0);
    clock_ticks = 0;
    enable_interrupts(INT_RTCC);
}

/**************************** parsing functions *****************************/
int get_command(char* cmd)
{
    static int char_count = 0;
    static char line[MAX_CHARS] = "";
    char terminator = '\r';
    int got_line;
    int c;
    int i;

    got_line = FALSE;

    if (  kbhit() )
    {
        c = getc();

        if ( echo_mode )
        {
            if (c == '\r')
            {
                putc('\r');
                putc('\n');
            }
            else
            {
                putc(c);
            }
        }

        if ( c != terminator )
        {
            if ( (c != 8) && (char_count < MAX_CHARS) )
                line[char_count++] = c;
            else if ( char_count > 0 )
                --char_count;

            cmd[0] = '\0';
        } 
        else
        {
            got_line = TRUE;
            line[char_count] = '\0';
            for (i = 0; i <= char_count; i++)
                cmd[i] = line[i];
            char_count = 0;
        }
    }

    return got_line;
}

int is_number(char* num_str)
{
    int is_num = 1;
    int i = 0;

    while (num_str[i] != 0)
    {
        if (!isamoung(num_str[i++],"+-0123456789"))
            is_num = 0;
    }

    return is_num;
}

void put_err(int err_code)
{
    if ( err_code )
    {
        printf("ERR %2X\r", err_code);
        if (echo_mode)
            putc('\n');
    }

    printf("RDY\r");
    
    if (echo_mode)
        putc('\n');

    return;
}

void put_echo()
{
    if (echo_mode)
        putc('\n');
}

/**************************** command functions *****************************/

#SEPARATE
void sample_gf_high(int verbose)
{
    int16 sample;
    
    if (verbose)
        printf("SAMPLING HIGH SIDE...");
	
    /* set the bit high */
    output_bit(HIGH_SIDE, 1);

    delay_ms(1000);
    
    if (verbose) 
    {
        putc('\r');
        put_echo();
    }

    /* take the sample */
	sample = read_adc();
    
    /* set the bit low */
    output_bit(HIGH_SIDE, 0);
	
    if (verbose)
        printf("HIGH SAMPLE = %ld\r", sample);
    else
        printf("%ld", sample);
    
    
    if (verbose)
    {
        put_echo();
        put_err(ERR_SUCCESS);
    }
    
    return;
}

#SEPARATE
void sample_gf_low(int verbose)
{
    int16 sample;

    if (verbose)
        printf("SAMPLING LOW SIDE...");
	
    /* set the bit high */
    output_bit(LOW_SIDE, 1);

    delay_ms(1000);
    
    if (verbose) 
    {
        putc('\r');
        put_echo();
    }

    /* take the sample */
	sample = read_adc();
    
    /* set the bit low */
    output_bit(LOW_SIDE, 0);
	
    if (verbose)
        printf("LOW SAMPLE = %ld\r", sample);
    else
        printf("%ld", sample);

    
    if (verbose)
    {    
        put_echo();
        put_err(ERR_SUCCESS);
    }
    
    return;
}

#SEPARATE
void toggle_echo()
{
    echo_mode = !echo_mode;

    put_err(0);
    return;
}

/****************************************************************************/
/***                          start debug commands                        ***/
/****************************************************************************/

/****************************************************************************/
/***                           end debug commands                         ***/
/****************************************************************************/

void process_cmds()
{
    char *token;
    char usr_cmd[MAX_CHARS];
    char cmd_str[MAX_CHARS];
    char delim[2];

    strcpy(delim, " ");

    if ( !get_command(usr_cmd) )
        return;

    if ( usr_cmd[0] == '\0' )
    {
        put_err(0);
        return;
    }

    /* grab first token */
    token = strtok(usr_cmd, delim);

    /********************************** H ***********************************/
    strcpy(cmd_str, "H");

    if ( stricmp(token, cmd_str) == 0 )
    {
        sample_gf_high(TRUE);
        return;
    }

    /********************************** L ***********************************/
    strcpy(cmd_str, "L");

    if ( stricmp(token, cmd_str) == 0 )
    {
        sample_gf_low(TRUE);
        return;
    }

    /********************************** S ***********************************/
    strcpy(cmd_str, "S");

    if ( stricmp(token, cmd_str) == 0 )
    {
        loop_mode = !loop_mode;
        return;
    }

    /******************************** ECHO **********************************/
    strcpy(cmd_str, "ECHO");

    if ( stricmp(token, cmd_str) == 0 )
    {
        toggle_echo();
        return;
    }

    /************************************************************************/
    /***                        start debug commands                      ***/
    /************************************************************************/


    /************************************************************************/
    /***                         end debug commands                       ***/
    /************************************************************************/

    /****************************** END CMDS ********************************/

    put_err(NO_COMMAND_MATCH);
    return;
}

main()
{
    /* setup I/O */
    output_bit(LOW_SIDE, 0);
    output_bit(HIGH_SIDE, 0);

    /* setup the system clock */
    setup_counters(RTCC_INTERNAL, RTCC_DIV_64);

    /* setup the ADC */
    setup_adc_ports(RA0_RA1_RA3_ANALOG);
    setup_adc(ADC_CLOCK_DIV_32);
    set_adc_channel(0);
   

    /* clear clock ticks */
    clear_ticks();

    /*make sure interrupts are enabled */
    enable_interrupts(INT_RTCC);
    enable_interrupts(GLOBAL);

    /* main loop */
    while(TRUE)
    {
        /* if in loop mode run gfd check in a loop  */
        /* sample format "HIGH, LOW<CR><LF>"        */
        if ( loop_mode )
        {
            sample_gf_high(FALSE);
            printf(", ");
            sample_gf_low(FALSE);
            printf("\r\n");
        }
        
        process_cmds();
    }
}
