/****************************************************************************/
/* Copyright 2016 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.  
 * Change log
 * 18MAY BDJ 
 *  -Adding rotational maintenance function
 * 19AUG16 BDJ v1.2b
 *  -switch baud to 19200 so straight through programming comms
 *  -integrate "advance" function
 * 
 * 30NOV2023 move position to eeprom                                        */
/****************************************************************************/

//#include <p24fxxxx.h>
//#include <p24FV16KM202.h>
#include <stdio.h>
#include <string.h>
#include <xc.h>
#include "uart1.h"
#include "timer.h"
#include "eeprom.h"
#include "crc.h"
#include "CN.h"
#include "i2c1.h"
#include "ABP2.h"

#define VER "2.3"

/* general definitions */
#include "typedefs.h" //True/False, UINT16, etc...


// Configuration Bits to make the part run from Internal FRCDIV
// Oscillator.



// PIC24FV16KM202 Configuration Bit Settings

// 'C' source line config statements

// FBS
#pragma config BWRP = OFF               // Boot Segment Write Protect (Disabled)
#pragma config BSS = OFF                // Boot segment Protect (No boot program flash segment)

// FGS
#pragma config GWRP = OFF               // General Segment Write Protect (General segment may be written)
#pragma config GSS0 = OFF                // General Segment Code Protect (No Protection)

// FOSCSEL
#pragma config FNOSC = FRC              // Oscillator Select (Fast RC Oscillator (FRC))
#pragma config SOSCSRC = DIG            // SOSC Source Type (Analog Mode for use with crystal)
//#pragma config SOSCSRC = ANA            // SOSC Source Type (Analog Mode for use with crystal)
#pragma config LPRCSEL = LP             // LPRC Oscillator Power and Accuracy (Low Power, Low Accuracy Mode)
#pragma config IESO = OFF                // Internal External Switch Over bit (Internal External Switchover mode enabled (Two-speed Start-up enabled))
//#pragma config IESO = ON                // Internal External Switch Over bit (Internal External Switchover mode enabled (Two-speed Start-up enabled))

// FOSC
#pragma config POSCMOD = HS           // Primary Oscillator Configuration bits (Primary oscillator disabled)
//#pragma config POSCMOD = NONE           // Primary Oscillator Configuration bits (Primary oscillator disabled)
#pragma config OSCIOFNC = 1          // CLKO Enable Configuration bit (CLKO output signal enabled)
#pragma config POSCFREQ = HS            // Primary Oscillator Frequency Range Configuration bits (Primary oscillator/external clock input frequency greater than 8MHz)
#pragma config SOSCSEL = SOSCHP         // SOSC Power Selection Configuration bits (Secondary Oscillator configured for high-power operation)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Both Clock Switching and Fail-safe Clock Monitor are disabled)

// FWDT
#pragma config WDTPS = PS32768          // Watchdog Timer Postscale Select bits (1:32768)
#pragma config FWPSA = PR128            // WDT Prescaler bit (WDT prescaler ratio of 1:128)
#pragma config FWDTEN = OFF              // Watchdog Timer Enable bits (WDT enabled in hardware)
#pragma config WINDIS = OFF             // Windowed Watchdog Timer Disable bit (Standard WDT selected(windowed WDT disabled))

// FPOR
#pragma config BOREN = BOR3             // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware, SBOREN bit disabled)
//#pragma config RETCFG = 1             //  (Retention regulator is not available)
#pragma config PWRTEN = ON              // Power-up Timer Enable bit (PWRT enabled)
#pragma config I2C1SEL = PRI            // Alternate I2C1 Pin Mapping bit (Use Default SCL1/SDA1 Pins For I2C1)
//#pragma config BORV = V18               // Brown-out Reset Voltage bits (Brown-out Reset set to lowest voltage (1.8V))
#pragma config MCLRE = ON               // MCLR Pin Enable bit (RA5 input pin disabled, MCLR pin enabled)

// FICD
#pragma config ICS = PGx3               // ICD Pin Placement Select bits (EMUC/EMUD share PGC3/PGD3)

//globals
unsigned long AlarmCnt;//Global incremented in AlarmISR
//Globally accessible FIFO for UART port2
unsigned char RxFifo[RxFifoSz]; // The statically allocated FIFO buffer (500 bytes)
//                SCI1 FIFO routines are slightly modified versions from
//                "Embedded Microcomputer Systems: Real Time Interfacing",
//                Jonathan W. Valvano 9/7/00
unsigned char *RxPutPt;    // Pointer of where to put next char in SCI1 FIFO
unsigned char *RxGetPt;    // Pointer of where to get next char from SCI1 FIFO
                  // FIFO is empty if PutPt=GetPt 
                  // FIFO is full  if PutPt+1=GetPt
unsigned short val = 9999;

uint16_t gPORTA_CN_status;
uint16_t gPORTB_CN_status;
unsigned short revs;
unsigned short CNticks;
unsigned short ABP2Data[8];


int main(void)
{
    //unsigned int i;
    CHAR ch;
    int position=-1;
    int i = 0;
    
    
    // Set up output pin for LED
    TRISAbits.TRISA0 = 0;
    
    //turn on max322 converter
    TRISBbits.TRISB14=0;
    LATBbits.LATB14 = 1;
    
    vInitTimer1();    // Initialization of Timer1
    
    vInitCN(); //init change notice counter
    
    // init uarts
    vInitU1(); //main comms to vehicle
    vInitU2(); //comms to elmo
    
    //init I2C bus
    i2c1_init();
    
    printf("CANON SAMPLER MAXON %s\r\n",VER);
    
    //get the last valid position
    position = eeRead(ePOS);
    
    //DelaySecs ( 4 ); //let the elmo boot
    
    //check where elmo wants to go
    printf("Last pos=%d\r\n",position);
    
    //for (i=0;i<RxFifoSz;i++)printf("%c-",RxFifo[i]);
    
    //printf("MotionDir = 0x%x\n",ReadObject(MotionDir,MotionDirSubIndex));
    //WriteObject(MotionDir,MotionDirSubIndex,0x01,0);
    //printf("MotionDir = 0x%x\n",ReadObject(MotionDir,MotionDirSubIndex));
    
    //LED ON means good power up
    LATAbits.LATA0 = 1; //leave LED on
    
    
    while(1)
    {   
      printf("S>");     //prompt 
      while (!U1STAbits.URXDA); //wait for char
      ch = cGetCharU(1); //Read one character form UART1
      printf("%c\r\n",ch);  //echo
        
      switch(ch) //====================================================
       { // and depending upon the ch, do the appropriate action =======
         case '?' :  break; // causes directory prompt to be displayed
         case ' ' :  break; // wait for another character
         case  -1 :  break; // wait for another character
     
         case 'P' :  // read position
                    position = eeRead(ePOS);
                    printf("EEPROM=%d\r\n",position);
	                break;
         case 'C' :  // clear position
                    position = 0;
                    eeWrite(position,ePOS);
                    printf("EEPROM=%d\r\n",eeRead(ePOS));
                    //elmo_UI_set(1,position);
	                break;
         case '+' :  //increase position
                    position++;
                     eeWrite(position,ePOS);
                    printf("EEPROM=%d\r\n",eeRead(ePOS));
                    //elmo_UI_set(1,position);
                    break;
        case '-' :  //decrease position
                    position--;
                     eeWrite(position,ePOS);
                    printf("EEPROM=%d\r\n",eeRead(ePOS)); 
                    //elmo_UI_set(1,position);
	                break; 
        case 'S' : //sample!!!   
                    sample();
                    break;
        case 'E' : //talk directly to the elmo (power cycle to return)  
                    //elmo_passthru();
                    break;
        case 'R' : //rotate carousel 1x           
                    //elmo_rotational_maint();
                    break; 
        case 'H' : //rotate carousel 1x           
                    printf("Homing....\n");
                    val = Home(MAXHOMETIME);
                    printf("Home = %04x\n",val);
                    break;  
        case '1' : //change pump time  
                    eeChange(ePUMP);
                    printf("New pump revs (300revs/100ml) =%d\r\n",eeRead(ePUMP));
                    break;         
        case '2' : //change purge time  
                    eeChange(ePURGE);
                    printf("New purge revs (300revs/100ml) =%d\r\n",eeRead(ePURGE));
                    break;  
        case '3' : //stop motor motion
                    printf("Stopping motor\r\n");
                    StopMotor();
                    break; 
        case '4' : //change Home offset  
                    eeChange(eHOME);
                    printf("New HOME offset cnts = %d\r\n",eeRead(eHOME));
                    break;    
        case '5' : //change cnts between bags  
                    eeChange(eOFFSET);
                    printf("New between bags cnts = %d\r\n",eeRead(eOFFSET));
                    break;  
        case '6' : //init i2c
                    //i2c1_init();
                    i2c1_restart();
                    break;
        case '7' : //read pducer 10x
                    for (i = 0; i<9; i++)
                    {
                        ABP2_read();
                        //printf("%04x, %04x, %04x, %04x, %04x, %04x, %04x\r\n",
                        //        ABP2Data[0],ABP2Data[1],ABP2Data[2],ABP2Data[3],
                        //        ABP2Data[4],ABP2Data[5],ABP2Data[6]);
                        //printf("raw P = %lx, raw T = %lx\r\n", ABP2_pressure(),ABP2_temp());
                        printf("P = %f, T = %f\r\n",ABP2_P_psi(),ABP2_T_degC());
                        msWait(100);
                        //DelaySecs(1);
                    }
                    break;
        case 'T' : //test code chunks

                    
                    MoveCntsRelative(0x2710);
                    WaitForMotion(10000);
                    val = GetPosition();
                    printf("Position = %04x\n",val);
                    
                    
                    //printf("Enter pump time in seconds:");
                    //val = UI_parse(10000);
                    //printf("new pump time = %d s\n",val);
                    //WriteObject(SetOperationModeIndex,SetOperationModeSubIndex,0);
                    break;
        case 'M' : //test for motion
                    printf("Counts to move:");
                    val = UI_parse(10000);
                    printf("\n");
                    MoveCntsRelative(val);
                    WaitForMotion(MAXHOMETIME);
                    val = GetPosition();
                    printf("Position = %04x\n",val);
                    
                    break;   
        case 'O' : //turn on Pump
                    PumpOn();
                    //WriteObject(SetDigOutIndex,SetDigOutSubIndex,0,HomeSensPower);
                    break; 
        case 'G' : //Get Position
                    val = GetPosition();
                    printf("Position = %04x\n",val);
                    break;  
        case 'F' : //turn off Pump
                    //WriteObject(SetDigOutIndex,SetDigOutSubIndex,0,0);
                    PumpOff();
                    break;
        case 'A' : //read ABP2 p ducer
                    ABP2_read();
                    //printf("%04x, %04x, %04x, %04x, %04x, %04x, %04x\r\n",
                    //        ABP2Data[0],ABP2Data[1],ABP2Data[2],ABP2Data[3],
                    //        ABP2Data[4],ABP2Data[5],ABP2Data[6]);
                    //printf("raw P = %lx, raw T = %lx\r\n", ABP2_pressure(),ABP2_temp());
                    printf("P = %f, T = %f\r\n",ABP2_P_psi(),ABP2_T_degC());
                    break;
        case 'D' : //make eeprom parameters default
                    eeWrite(0,    ePOS);
                    eeWrite(500,  ePUMP);
                    eeWrite(150,  ePURGE);
                    eeWrite(1400, eHOME);
                    eeWrite(3900, eOFFSET);
                    break;
        case 'U' : //show menu and pump times
                    printf("CANON SAMPLER MAXON%s\r\n",VER);
                    printf(" S.ample      :  R.otate    : M.otion test\r\n");
                    printf(" 1.pump time  :  T.est code : C.lear position\r\n");
                    printf(" +.inc pos    :  -.dec pos  : P.osition\r\n");
                    printf(" O.n Pump     :  F. off Pump: G.etMotor Position\r\n");
                    printf(" 2.purge time :  H.ome      : 3.Stop motion\r\n");
                    printf(" 4.HOME ofset :  5.Bag ofset: D.efault eeprom \r\n");
                    printf(" A.BP2 reading: \r\n");
                    printf("Purge revs = %d : Pump revs = %d \r\n",eeRead(ePURGE),eeRead(ePUMP));
                    printf("HOME offset = %d cnts : Bag offset = %d cnts\r\n",eeRead(eHOME),eeRead(eOFFSET));
                    break;
        default  :  printf(" input unknown \r\n");

       } //==============================================================
        
    }
}




