//
// Included Files

//

#include "F28x_Project.h"

#include "F2837xD_Ipc_drivers.h"


#define REFERENCE_VDAC        3

#define REFERENCE_VREF        2

#define DACB                  2

#define REFERENCE             REFERENCE_VDAC

#define CPUFREQ_MHZ1           200

#define DAC_NUM1              DACB   // pin no 70


void ConfigureADC1(void);

void SetupADCContinuous1(Uint16 channel1);

void configureDAC1(Uint16 dac_num1);

interrupt void cpu_timer1_isr(void);


volatile struct DAC_REGS* DAC_PTR[4] = {0x0,&DacaRegs,&DacbRegs,&DaccRegs};

Uint32 samplingFreq_hz1 = 5000;

float freqResolution_hz1 = 0;

float cpuPeriod_us1 = 0;

Uint32 interruptCycles1 = 0;

float interruptDuration_us1 = 0;

float samplingPeriod_us1 = 0;



//

// Main

//

void main(void)

{

InitSysCtrl();
    
DINT;      
// Disable CPU interrupts
  
InitPieCtrl();
// Initialize the PIE control registers to their default state.


// Disable CPU interrupts and clear all CPU interrupt flags:

    
IER = 0x0000;

IFR = 0x0000;

    
InitPieVectTable();

//

//--- Let CPU1 know that CPU2 is ready

       IpcRegs.IPCSET.bit.IPC17 = 1;     // Set IPC17 to release CPU1



//
// Power up the ADC_B and DAC_B

//
   
       EALLOW;

       CpuSysRegs.PCLKCR13.bit.ADC_C = 1;
 
       CpuSysRegs.PCLKCR16.bit.DAC_B = 1;

       ConfigureADC1(); // Configure the ADC and power it up
   
       SetupADCContinuous1(3);// Setup the ADC for continuous conversions on channel 0

    
       EINT;  // Enable Global interrupt INTM
  
       ERTM;  // Enable Global realtime interrupt DBGM

    
//

// Map Cpu Timer0 interrupt function to the PIE vector table
 
//

       EALLOW;
     
       PieVectTable.TIMER0_INT = &cpu_timer1_isr;
       
       EDIS;

 
       cpuPeriod_us1 = (1.0/CPUFREQ_MHZ1);
      
       samplingPeriod_us1 = (1000000.0/samplingFreq_hz1);

     
       configureDAC1(DAC_NU      // Configure DAC

    
       InitCpuTimers();        // Initialize Cpu Timers


//

// Configure Cpu Timer0 to interrupt at specified sampling frequency
 
//
 
       ConfigCpuTimer(&CpuTimer0, CPUFREQ_MHZ1, 1000000.0/samplingFreq_hz1);

//
    
// Start Cpu Timer0
    
//
     
       CpuTimer0Regs.TCR.all = 0x4000;

  
//
    
// Enable interrupt
   
//
         
      IER |= M_INT1;
     
      PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
  
      EINT;
      
      ERTM;




  do                 // take conversions indefinitely in loop
     
     {
    //
    //enable ADCINT flag
    //
      
      EALLOW;
      
      AdccRegs.ADCINTSEL1N2.bit.INT1E = 1;
       
      AdccRegs.ADCINTFLGCLR.all = 0x000F;
      
      EDIS;

      
      AdccRegs.ADCSOCFRC1.all = 0x0001;     //software force start SOC0
       
      AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
// make sure INT1 flag is cleared
   
//
    
//disable  ADCINT flag to stop sampling
    
//
      
       EALLOW;
  
       AdccRegs.ADCINTSEL1N2.bit.INT1E = 0;
      
       EDIS;
     
     }while(1);
   
 }
    
//
    
//DAC configuration
    
//
    
void configureDAC1(Uint16 dac_num1)

    {

      EALLOW;

      DAC_PTR[dac_num1]->DACCTL.bit.DACREFSEL = REFERENCE;

      DAC_PTR[dac_num1]->DACOUTEN.bit.DACOUTEN = 1;
  
      DAC_PTR[dac_num1]->DACVALS.all = 0;
  
      DELAY_US(1000); // Delay for buffered DAC to power up

      EDIS;
   
    }
    
//
    
// ConfigureADC - Write ADC configurations and power up the ADC for both
  
//                ADC A and ADC B
    
void ConfigureADC1(void)         //write configurations
       
    {
   
     EALLOW;
   
     AdccRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    
     AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
 
     AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;          //Set pulse positions to late
        
     AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;             //power up the ADC
       
     DELAY_US(1000);//delay for 1ms to allow ADC time to power up
         
     EDIS;
      
    }

          
//

// SetupADCContinuous - setup the ADC to continuously convert on one channel
 
//
    
void SetupADCContinuous1(Uint16 channel1)
 
   {
    
    EALLOW;
      
    AdccRegs.ADCSOC0CTL.bit.CHSEL  = channel1;  //SOC will convert on channel
    
    AdccRegs.ADCSOC0CTL.bit.ACQPS  =14;
       
    AdccRegs.ADCINTSEL1N2.bit.INT1E = 0; //disable INT1 flag
   
    AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 1;
  
    AdccRegs.ADCINTSOCSEL1.bit.SOC0 = 2;
    
    EDIS;

    }


interrupt void cpu_timer1_isr(void)
 
       {
    
      CpuTimer1Regs.TCR.all = 0x0000;    // Start Cpu Timer1 to indicate begin of interrupt

//

// Write current ADC value to buffered DAC A(A0 pin no 30)

//

 
      DAC_PTR[DAC_NUM1]->DACVALS.all = AdccResultRegs.ADCRESULT0;     // ADC_A3 pin no 25
     
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;       // Acknowledge this interrupt to receive more interrupts from group 1
     
      CpuTimer1Regs.TCR.all = 0x0010;               // Stop Cpu Timer1 to indicate end of interrupt
     
      interruptCycles1 = 0xFFFFFFFFUL - CpuTimer1Regs.TIM.all;  // Calculate interrupt duration in cycles
  
      interruptDuration_us1 = cpuPeriod_us1 * interruptCycles1;   // Calculate interrupt duration in micro seconds

      CpuTimer1Regs.TCR.all = 0x0030;               // Reload Cpu Timer1

        }
