/*
 * File:   main.c
 * Author: hamilton
 *
 * Created on November 4, 2013, 4:11 PM
 */

#include <dsp.h>
#include <stdio.h>
#include "xc.h"
#include "UART.h"
#include "config.h"
#include "extern.h"
#include "conv.h"
#include "init.h"
#include "can.h"
#include "BatterySignalDecode.h"




_FOSCSEL(FNOSC_FRC)  // FNOSC<2:0> = 000(FRC oscillator)  IES0 = 1  (Start with FRC and then switch to user selected clock when ready)
_FOSC(FCKSM_CSECMD & OSCIOFNC_ON)  // FCKSM<1:0> = 01 (clock switching enable, fail safe clock monitor disabled)   OSCIOFNC = 0 (OSC2 pin is GPIO)     POSCMD<1:0> = 11  (Primary oscillator disabled)
_FWDT(FWDTEN_OFF)  // FWDTEN = 0(watchdog timer software enabled/disabled)  WINDIS = 1 (watchdog timer in non-window mode)  PLLKEN = 1 (clock switch to pll will wait for lock signal)  WDTPRE = 1 (1:128 watchdog prescaler)  WDTPOST<3:0> = 1111 (watchdog postscaler = 1:32768)
_FPOR(FPWRT_PWR128)  //PWMPIN = 1 (MCPWM pins controlled by PORT register at device reset)   HPOL = 1 (MCPWM high side pins are active high)  LPOL = 1 (MCPWM low side pins are active high) FPWRT<2:0> = 11 (power on reset timer value = 128ms)
_FICD(ICS_PGD1 & JTAGEN_OFF) // JTAGEN = 0 (JTAG disabled)   ICS<1:0> = 11  (ICD communicate on PGEC1 and PGED1

    float PH1PWM_DC = 0;
    float PH2PWM_DC = 0;
    float PH3PWM_DC = 0;
    const int MC_PWM_Period = 0x7fff;


    int step;
    unsigned int halls = 0;
    unsigned int pos;

    void SampADC(int ch);
    void ScanADC( void );



void (*getErrLoc(void))(void);  // Get Address Error Loc
void (*errLoc)(void);           // Function Pointer   


int main(void) {

    int j;
    char s[256];
    float last_time = 0;

    /* Configure Oscillator to operate the device at ~10Mhz
       Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
       Fosc= 7.37*(43)/(2*8)=19.806875Mhz for Fosc, Fcy = 9.9034375Mhz */
    /* Configure PLL prescaler, PLL postscaler, PLL divisor */
    PLLFBD = 41; /* M = PLLFBD + 2 */
    CLKDIVbits.PLLPOST = 0; /* N1 = 2 */
    CLKDIVbits.PLLPRE = 0; /* N2 = 2 */
    __builtin_write_OSCCONH(0x01); /* New Oscillator selection from FRC only, to FRC w/ PLL */
    //__builtin_write_OSCCONL(0x01); /* Request oscillator switch */
    __builtin_write_OSCCONL(0x03); /* Enable secondary (LP) oscillator and Request oscillator switch */

    while (OSCCONbits.COSC != 0b001); /* Wait for Oscillator to switch to FRC w/ PLL */
    while (OSCCONbits.LOCK != 1); /* Wait for Pll to Lock */

//Set up UARTS
    InitU1();

//init TMR1 to interrupt at 25Hz, based on 32768Hz crystal SOSC
    _T1IP = 2;   //Set to lower priority than all the rest.
    TMR1 = 0;  //Clear the timer

#if OUTPUT_RATE==25
    PR1 =1311;  //Should give a 25Hz interrupt at 32768Hz clock
    T1CON = 0x8002;  //enabled, prescaler 1:1, external clock (SOSC)
#endif
#if OUTPUT_RATE==10
    PR1 =3277;  //Should give a 10Hz interrupt at 32768Hz clock
    T1CON = 0x8002;  //enabled, prescaler 1:1, external clock (SOSC)
#endif
#if OUTPUT_RATE==5
    PR1 =6554;  //Should give a 10Hz interrupt at 32768Hz clock
    T1CON = 0x8002;  //enabled, prescaler 1:1, external clock (SOSC)
#endif
    _T1IF = 0;  //Clear Interrupt
    _T1IE = 0;  //Keep Interrupt disabled until everything is set up.


// init TMR3 to provide the timebase for interrupt that starts the AIO process
    T3CON = 0x8000;
    PR3 = 283-1;  //Rolls over at 139 kHz and adc sampling.  
    _T3IF = 0;  //Clear interrupt
    _T3IE = 0;  //Keep Interrupt disabled.


//Setup digital outputs
    TRISAbits.TRISA9 = 1;   //Don't make this an output, it's connected to ground as Vref-.
    TRISAbits.TRISA10 = 1;  //Don't make this an output, it's connected to 3.3V as Vref+.


//    TRISD = 0xffff;
//    TRISDbits.TRISD0 = 0;  //CAN loopback pin, set low to make CAN work properly, or leave it an input?
//   TRISDbits.TRISD2 = 0;  //Gas Bypass enable
//    TRISDbits.TRISD3 = 0;  //Stepper Enable
//    TRISDbits.TRISD12 = 0;  //Laser Rangefinder enable
//    TRISDbits.TRISD15 = 0;  //UART1 RTS
    TRISD = 0x6ff2;
    _RD0 = 0;  //Set CAN loopback pin low
    _RD12 = 0;  //Disable rangefinder switch
    
    TRISE = 0xff00;


    TRISGbits.TRISG15 = 0;  //EM cable tester enable

    //Set up motor control module, this periphial controls the PWM outputs that drive the relays.
   // InitMCPWM();

//Set Up CN pins  CN14 cooresponds to RD5
    //CNPU1bits.CN14PUE = 1;
    CNEN1bits.CN14IE = 1;          // Enable CN14 pin for interrupt detection
    IEC1bits.CNIE = 1;            // Enable CN interrupts
    IFS1bits.CNIF = 0;


//Set up DMA channel and ADC
    InitDma0();  //Argument is number of samples to transfer per interrupt.
    InitADC_WithIntrpt();  


//init CAN bus
 //   InitCAN1();  //Setup CAN1
 //   InitDma12();  //Setup two DMA channels for use with CAN1
 //   for(j=0;j<ECAN1_NUM_TX_BUFFERS;j++)  //Setup CAN messages type and frame type for each message.
 //     {
 //     message[j].message_type = CAN_MSG_DATA; //data message
 //     message[j].frame_type = CAN_FRAME_EXT; //extended (29 bit identifier)
 //     }

//Setup FIR filters
    FIRDelayInit(&ADC_Filter);

// Enable Timer interrupts now that everything is set up.
    _T1IE = 1;  //Enable 25Hz Interrupt, _T1Interrupt gets called at the beginning of each period.


    while (1) {
      if(time != last_time)  //Wait for time to be updated.
      {
      
      last_time = time;
#ifdef ALLOW_CALIBRATION
       if(raw==1)
           sprintf(s,"%.1f    %d     %d\r\n",time,
                   Pressure_Buf[0],
                   I_Flow_Buf[0]);
       else
#endif

 sprintf(s,"%.1f    %3.0f         %.1f   %5.1f    %6.2f\r\n",time,
         FlowRate_2,
         time_relative,
         FlowTotal_2,
         60.0*FlowTotal_2/time_relative
        );
      
           putsU1(s);
      }
    }
    return 0;
}  //main
