/****************************************************************************/
/* Copyright 2009 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include <p24fxxxx.h>
#include <stdio.h>
#include <string.h>

#include "spi.h"
#include "parser.h"
#include "errors.h"
#include "serial.h"
#include "sys_defs.h"

/* JTAG/Code Protect/Write Protect/Clip-on Emulation mode
Watchdog Timer/ICD pins select */
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2) 
/* Enable CLK switch, Disable CLK monitor, OSCO or Fosc/2, 
Primary Oscillator Mode: Disabled, Internal Fast RC oscillator */
_CONFIG2(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_XT & FNOSC_PRI)
/* Disable CLK switch and CLK monitor, OSCO or Fosc/2, HS oscillator,
Primary oscillator */

#define MAX_CHARS   80  /* maximum command line entry length */

extern int enableCounter;

int getCommand(char* cmd);

int main(void)
{
    int i = 0;
    int led_step = 1;
    unsigned int port_a = 0;
    unsigned int port_b = 0;

    int ret_val;
    char cmd_buff[MAX_CHARS];
    char err_buff[32];
   
    char* cmd_ptr;
    
    /* Map UARTs to pins */
    RPOR5bits.RP11R = 3;     /* Make Pin RP10 U1TX */
    RPINR18bits.U1RXR = 10;  /* Make Pin RP11 U1RX */

    /* Map SPI pins */
    RPOR7bits.RP14R = 8;    /* SCK  RP14 */
    RPOR6bits.RP13R = 7;    /* SO   RP13 */

    AD1PCFGbits.PCFG12 = 1; /* Configure pin for dig intput */
    RPINR20bits.SDI1R = 12; /* SI   RP12 */

    /* Setup SPI bus #CS */
    LATBbits.LATB15 = 1;    /* Make bit RB15 the CS */
    Nop();
    TRISBbits.TRISB15 = 0;
    Nop();

    /* Setup proto board LEDs */
    TRISBbits.TRISB8 = 0;
    TRISBbits.TRISB9 = 0;
    LATBbits.LATB8 = 1;
    LATBbits.LATB9 = 1;

    /* init stuff here */
    serInit();
    spiInit();
    
#define WR_SPIO 0x40
#define RD_SPIO 0x41

    /* set the portA to outputs */
    spiCS(0);
    spiReadWrite(WR_SPIO);
    spiReadWrite(0x00);
    spiReadWrite(0x00);
    spiCS(1);

    /* add small dealy for better visibility on o-scope */
    Nop();
    Nop();
    Nop();
    Nop();

    /* turn on portB pull-ups */
    spiCS(0);
    spiReadWrite(WR_SPIO);
    spiReadWrite(0x0D);
    spiReadWrite(0xFF);
    spiCS(1);

    /* show the sign-on banner */
    sprintf(cmd_buff, "\r\nMBARI PIC24 PROTO %s, %s\r\n", __DATE__, __TIME__);
    serPutString(SER_CONSOLE, cmd_buff);

    sprintf(cmd_buff, "CVS tag \"%s\"\r\n\r\n", "$Name:  $");
    serPutString(SER_CONSOLE, cmd_buff);

    /* main loop */
    for(;;)
    {
        /* get command */
        if ( !getCommand(cmd_buff) )
        {
            ret_val = ERR_NO_LINE;
        }
        else
        {
            /* Skip white space here */
            cmd_ptr = prsSkip(cmd_buff, " \t");

            /* If the cmd from getCommand was empty then return here. */
            if ( !strlen(cmd_ptr) )
                ret_val = ERR_EMPTY_LINE;
            else
                ret_val = prsParse(cmd_ptr, cmdsRoot, ERR_NO_COMMAND);
        }

        /* display ERR code or RDY prompt */
        if ( ret_val != ERR_NO_LINE)
        {
            if ((ret_val != ERR_SUCCESS) && (ret_val != ERR_EMPTY_LINE))
            {
                sprintf(err_buff,"ERR %04d\r\n", ret_val);
                serPutString(SER_CONSOLE, err_buff);
            }

            serPutString(SER_CONSOLE, "RDY\r\n");
        }

        /* read portB */
        spiCS(0);
        spiReadWrite(RD_SPIO);
        spiReadWrite(0x13);
        port_b = spiReadWrite(0x00);
        spiCS(1);

        /* mirror proto LED's with portB inputs */
        if ( port_b & 0x01 )
            LATBbits.LATB8 = 1;
        else
            LATBbits.LATB8 = 0;           
/*
        if ( port_b & 0x80 )
            LATBbits.LATB9 = 1;
        else
            LATBbits.LATB9 = 0;
*/

        /* do binary count on portA */
        if ( ++i == 500 )
        {

LATBbits.LATB9 = 0;           
Nop();
Nop();
LATBbits.LATB9 = 1;

            /* clear the counter */
            i = 0;

            if ( enableCounter )
            {

                switch ( led_step )
                {
                    case 1: port_a = 0x01; break;
                    case 2: port_a = 0x02; break;
                    case 3: port_a = 0x04; break;
                    case 4: port_a = 0x08; break;
                    case 5: port_a = 0x10; break;
                    case 6: port_a = 0x20; break;
                    case 7: port_a = 0x40; break;
                    case 8: port_a = 0x80; break;
                    case 9: port_a = 0x40; break;
                    case 10: port_a = 0x20; break;
                    case 11: port_a = 0x10; break;
                    case 12: port_a = 0x08; break;
                    case 13: port_a = 0x04; break;
                    case 14: port_a = 0x02; break;
                }

                if ( led_step == 14 )
                    led_step = 1;
                else
                    ++led_step;


#if 0
                /* read port A */
                spiCS(0);
                spiReadWrite(RD_SPIO);
                spiReadWrite(0x12);
                port_a = spiReadWrite(0x00);
                spiCS(1);

                if ( port_a == 0xFF )
                    port_a = 0x00;
                else
                    ++port_a;
#endif

                /* write port A */
                spiCS(0);
                spiReadWrite(WR_SPIO);
                spiReadWrite(0x12);
                spiReadWrite(port_a);
                spiCS(1);
            }
        }
    }

    return 0;
}

#define ECHO_MODE   1
int getCommand(char* cmd)
{
    static int char_count = 0;
    static char line[MAX_CHARS] = "";
    const unsigned char terminator = '\r';
    int got_line;
    unsigned char b;
    int i;
    
    got_line = FALSE;

    if ( serGetByte(1, &b) )
    {
        if ( ECHO_MODE )
        {
            serPutByte(1, b);
            if (b == '\r') serPutByte(1, '\n');
        }

        if ( b != terminator )
        {
            if ( (b != '\b') && (char_count < MAX_CHARS) )
                line[char_count++] = b;
            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;
}


