
//
// FILE:	Main_MCU_SAMPLER.c
//


#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <file.h>

#include "DSP28x_Project.h"     // DSP28x Headerfile
#include "ti_ascii.h"
#include "sci_io.h"

__interrupt void adc_isr(void); // Use the ADC Interrupt Service to collect samples and communicate downstream

//
// Micro-seconds to wait for ADC conversion. Longer than necessary.
//
#define CONV_WAIT 1L

//
// Globals
//

Uint16 LoopCount;
Uint16 ConversionCount;
float Va;
float Vb;
float Vc;
float Ia;
float Ib;
float Ic;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern void DSP28x_usDelay(Uint32 Count);



const unsigned char escRed[] = {0x1B, 0x5B, '3','1', 'm'};// 1B=Escape, 5B= '[','3'= end of text,'1'=start of heading
const unsigned char escWhite[] = {0x1B, 0x5B, '3','7', 'm'};//'7'=bell, 'm'=6D
const unsigned char escLeft[] = {0x1B, 0x5B, '3','7', 'm'};
const unsigned char pucTempString[] = "Current Temperature:";





//
// clearTextBox - 
//
void clearTextBox(void)
{
    putchar(0x08);
 
    // 
    // Move back 24 columns
    //
    putchar(0x1B);
    putchar('[');
    putchar('2');
    putchar('6');
    putchar('D');
    
    //
    // Move up 3 lines
    //
    putchar(0x1B);
    putchar('[');
    putchar('3');
    putchar('A');
    
    //
    // Change to Red text
    //
    putchar(escRed[0]);
    putchar(escRed[1]);
    putchar(escRed[2]);
    putchar(escRed[3]);
    putchar(escRed[4]);
    
    printf((char*)pucTempString);
    
    //
    // Move down 1 lines
    //
    putchar(0x1B);
    putchar('[');
    putchar('1');
    putchar('B');
    
    //
    // Move back 20 columns
    //
    putchar(0x1B);
    putchar('[');
    putchar('2');
    putchar('0');
    putchar('D');
    
    //
    // Save cursor position
    //
    putchar(0x1B);
    putchar('[');
    putchar('s');
    
}




void sendValues(void)
{
    //
    // Restore cursor position
    //
    //putchar(0x1B);
    //putchar('[');
    //putchar('u');
    


   printf(" Va = %f , Vb = %f, Vc = %f , Ia = %f, Iba = %f , Ic = %f\n ", Va, Vb,Vc,Ia,Ib,Ic);
}




//
// scia_init - SCIA  8-bit word, baud rate 0x000F, default, 1 STOP bit, 
// no parity
//
void scia_init()
{
    //
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
    //
 	
    //
    // 1 stop bit,  No loopback, No parity,8 char bits, async mode, 
    // idle-line protocol
    //
    SciaRegs.SCICCR.all =0x0007;   
	
    //
    // enable TX, RX, internal SCICLK, Disable RX ERR, SLEEP, TXWAKE
    //
    SciaRegs.SCICTL1.all =0x0003;  

	SciaRegs.SCICTL2.bit.TXINTENA =1;
	SciaRegs.SCICTL2.bit.RXBKINTENA =1;

	//
    // 115200 baud @LSPCLK = 22.5MHz (90 MHz SYSCLK).
    //
    SciaRegs.SCIHBAUD    =0x0000;  
    
    SciaRegs.SCILBAUD    =0x0017;

	SciaRegs.SCICTL1.all =0x0023;  // Relinquish SCI from Reset
  
    return;
}



//
// Main
//
void main(void)
{
    volatile int status = 0;

    volatile FILE *fid;
    
    //
    // If running from flash copy RAM only functions to RAM
    //
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif      

    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2806x_SysCtrl.c file.
    //
    InitSysCtrl();

    //
    // Step 2. Initalize GPIO:
    // This example function is found in the F2806x_Gpio.c file and
    // illustrates how to set the GPIO to its default state.
    //
    // InitGpio(); Skipped for this example

    //
    // For this example, only init the pins for the SCI-A port.
    // This function is found in the F2806x_Sci.c file.
    //
    InitSciaGpio();

    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;

    //
    // Initialize PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2806x_PieCtrl.c file.
    //
    InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2806x_DefaultIsr.c.
    // This function is found in F2806x_PieVect.c.
    //
    InitPieVectTable();



    EALLOW;  // This is needed to write to EALLOW protected register
    PieVectTable.ADCINT1 = &adc_isr;
    EDIS;    // This is needed to disable write to EALLOW protected registers



    //
    // Initialize SCIA
    //
    scia_init();



    



    //
    // Configure the ADC: Initialize the ADC
    //
    InitAdc();  // Initialize the ADC
    InitAdcAio();
    //AdcOffsetSelfCal();



    //
    // Enable ADCINT1 in PIE
    //
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
    IER |= M_INT1;                     // Enable CPU Interrupt 1
    EINT;                              // Enable Global interrupt INTM
    ERTM;                              // Enable Global realtime interrupt DBGM






    EALLOW;
    AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;	//Enable non-overlap mode
    //
    // ADCINT1 trips after AdcResults latch
    //
    AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    AdcRegs.INTSEL1N2.bit.INT1E     = 1;  // Enabled ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;  // Disable ADCINT1 Continuous mode
    //
    // setup EOC1 to trigger ADCINT1 to fire
    //
    AdcRegs.INTSEL1N2.bit.INT1SEL   = 5;

    
    
    //Channels Setup

    AdcRegs.ADCSOC0CTL.bit.CHSEL  = 0;  // set SOC0 channe0 select to ADCINA0 (Va)
    AdcRegs.ADCSOC1CTL.bit.CHSEL  = 1;  // set SOC1 channel select to ADCINA1 (Vb)
    AdcRegs.ADCSOC2CTL.bit.CHSEL  = 2;  // set SOC2 channe2 select to ADCINA2 (Vc)
    AdcRegs.ADCSOC3CTL.bit.CHSEL  = 3;  // set SOC3 channe3 select to ADCINA3 (Ia)
    AdcRegs.ADCSOC4CTL.bit.CHSEL  = 4;  // set SOC4 channe4 select to ADCINA4 (Ib)
    AdcRegs.ADCSOC5CTL.bit.CHSEL  = 5;  // set SOC5 channe5 select to ADCINA5 (Ic)
    //
    // Set SOCx acquisition period to 26 ADCCLK
    //
    AdcRegs.ADCSOC0CTL.bit.ACQPS  = 25;   // this window can be reduced later when complete test is done
    AdcRegs.ADCSOC1CTL.bit.ACQPS  = 25;
    AdcRegs.ADCSOC2CTL.bit.ACQPS  = 25;
    AdcRegs.ADCSOC3CTL.bit.ACQPS  = 25;
    AdcRegs.ADCSOC4CTL.bit.ACQPS  = 25;
    AdcRegs.ADCSOC5CTL.bit.ACQPS  = 25;
    

    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts
    // first then SOC1
    //
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL  = 5;
    AdcRegs.ADCSOC1CTL.bit.TRIGSEL  = 5;
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL  = 5;
    AdcRegs.ADCSOC3CTL.bit.TRIGSEL  = 5;
    AdcRegs.ADCSOC4CTL.bit.TRIGSEL  = 5;
    AdcRegs.ADCSOC5CTL.bit.TRIGSEL  = 5;

    EDIS;


    /////////////////// ePWM Module Setup /////////////////////////////////////////////////

    //
    // ePWM1 clock is already enabled in InitSysCtrl();
    //
    EALLOW;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; //TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;
    EDIS;
    EPwm1Regs.ETSEL.bit.SOCAEN  = 1;        // Enable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = 2;        // Enable event time-base counter equal to period (TBCTR = TBPRD)
    EPwm1Regs.ETPS.bit.SOCAPRD  = 1;        // Generate pulse on 1st event
    //EPwm1Regs.CMPA.half.CMPA  = 0x0080;   // Set compare A value
    EPwm1Regs.TBPRD             = 0x30D3;   // Set period for ePWM1 Change later to 0x30D3
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;        // count up and start






    /////////////////// COMMUNICATIONS SCI UART  & PUTTY /////////////////////////////////////////////////

    //
    // Redirect STDOUT to SCI
    //
    status = add_device("scia", _SSA, SCI_open, SCI_close, SCI_read, SCI_write,
                        SCI_lseek, SCI_unlink, SCI_rename);
    fid = fopen("scia","w");
    freopen("scia:", "w", stdout);
    setvbuf(stdout, NULL, _IONBF, 0);
    
    

    //clearTextBox();
    

    

    //
    // Main program loop - continually sample Vs & Is
    //
    for(;;)
    {
       LoopCount++;
    }
}

////////////////////////// Suggestion if MCU becomes DSP calculate Ref. Voltages as well as the three thresholds
////////////////////////// By feeding and sampling nominal voltages (120VAC RMS) then calculate their RMS digitally
////////////////////////// save them to globals and then start monitoring for events.

__interrupt void
adc_isr(void)
{


    /* Digital Value = 4096 [(Input – VREFLO)/3.3v] */
    Va = AdcResult.ADCRESULT0 * 3.3/4096;
    Vb = AdcResult.ADCRESULT1 * 3.3/4096;
    Vc = AdcResult.ADCRESULT2 * 3.3/4096;
    Ia = AdcResult.ADCRESULT3 * 3.3/4096;
    Ib = AdcResult.ADCRESULT4 * 3.3/4096;
    Ic = AdcResult.ADCRESULT5 * 3.3/4096;

    sendValues();


    //
    // Clear ADCINT1 flag reinitialize for next SOC
    //
    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

    return;
}



//
// End of File
//

