Excerpts from "AdcInput.c"

// Local Definitions

// Delay Period required for ADC Module before
// ADC Sampling starts.
#define ADC_usDELAY 5000L

// 7/8 averaging for Pressures/Temperatures.
// (7 Times old value, plus new, divided by 8).
#define ADC_AVERAGE    7U

// Half Scale ADC (zero AC Current)
#define HALVE_SCALE 2048U

// The zero Current point is 2048 ADC Units.
// Easy to change the Peak/Valley detection
// Values here, without any re-coding involved.
// High Side: 2048 to 4097; 3072 is ~ 4 Amps
// Low  Side: 2047 to    0; 1024 is ~-4 Amps
#define HI_THR_AMPS 3072U
#define LO_THR_AMPS 1024U


// Uninitialized local Data

static Uint16	loopVariable;

// AC Current associated Variables
static Uint16   phase_A_Curr[2];        // Raw ADC Phase Currents
static Uint16   phase_B_Curr[2];
static Uint16   phase_C_Curr[2];

static Uint16   sumPk_A_Curr;           // Summation Currents for all
static Uint16   sumVa_A_Curr;			//   three Phases, Peak & Valley
static Uint16   sumPk_B_Curr;
static Uint16   sumVa_B_Curr;
static Uint16   sumPk_C_Curr;
static Uint16   sumVa_C_Curr;

static Uint16   avePk_A_Curr;           // Average Currents for all
static Uint16   aveVa_A_Curr;			//   three Phases, Peak & Valley
static Uint16   avePk_B_Curr;
static Uint16   aveVa_B_Curr;
static Uint16   avePk_C_Curr;
static Uint16   aveVa_C_Curr;

static Uint16	count_A_Peak;			// Counts used for averaging
static Uint16	count_A_Vall;			//  Phase Peaks and Valleys
static Uint16	count_B_Peak;
static Uint16	count_B_Vall;
static Uint16	count_C_Peak;
static Uint16	count_C_Vall;

// Pressures (double sampled) and Temperatures
// (single sampled) - ADC based Values.
static Uint16   liq_Inp_PRaw[2];        // Pressure 1 double Raw Samples
static Uint16   liq_Inp_PAve;           // Pressure 1 Smoothed

static Uint16   liq_Out_PRaw[2];        // Pressure 2 double Raw Samples
static Uint16   liq_Out_PAve;           // Pressure 2 Smoothed

static Uint16   liq_Inp_TRaw;           // Temperature 1 Raw
static Uint16   liq_Inp_TAve;           // Temperature 1 Smoothed

static Uint16   liq_Out_TRaw;           // Temperature 2 Raw
static Uint16   liq_Out_TAve;           // Temperature 2 Smoothed

static Uint16   air_Inp_TRaw;           // Temperature 3 Raw
static Uint16   air_Inp_TAve;           // Temperature 3 Smoothed

static Uint16   air_Out_TRaw;           // Temperature 4 Raw
static Uint16   air_Out_TAve;           // Temperature 4 Smoothed

static Uint16   ac_MotorTRaw;           // Temperature 5 Raw
static Uint16   ac_MotorTAve;           // Temperature 5 Smoothed


/****************************************************************************
*  FUNCTION:
*   void InitAdcModule (void)
*
*  PURPOSE:
*   Power up and initializes the on chip A/D converter.
*
****************************************************************************/
void initAdcModule (void)
{
   static struct ADC_REGS 	adcRegs;


   // To power-up the ADC the ADCENCLK bit should be set first to enable
   // clocks, followed by powering up the band-gap, reference circuitry,
   // and ADC core.
   // Before the first conversion is performed, a 5ms delay must be observed
   // after power up, to give all analog circuits time to power up/settle.

   // Note that ADCENCLK must be enabled in 'InitModClocks()' Function,
   // located within "SysCtrl.c" Module. 

   AdcRegs.ADCTRL1.bit.RESET = 1;         // reset ADC

   DELAY_US(1);                           // Delay after reset (> 2 ADCCLK)

   // The (almost) full Buffer Fill provides two sets of Current Samples for
   // all 3 VAC Phases.  Also two sets of in/out Liquid Pressure Samples.
   // All of these are temporally spaced 150µS apart, close to half the
   // 312.50µS ADC trigger Period.  The five Temperatures are sampled once.
   //
   // There are four ways to slow down the (effective) ADC Clock from the
   // SYSCLKOUT input Reference.  Three of these involve dividing SYSCLKOUT
   // by Prescaler Values (HSPCLK, ADCCLKPS and CPS), to each physically slow
   // the input ADC Clock.
   //
   // The first method uses HSPCLK, set to 50 (HISPCP Register set within
   // "SysCtrl.c").  This divides SYSCLKOUT by 100, and reduces the System
   // Clock from 20MHz to 200kHz (input ADC Clock).  This gives a 5µS ADC
   // Clock Period.
   //
   // The second method, ADCCLKPS, supports slowing down the input ADC Clock,
   // with variable values.
   //
   // The third method, the CPS Bit, halves the ADC Clock, when set.
   //
   // The fourth method is to add one or more additional ADC Sample Clocks,
   // prior to each ADC Conversion.  This method is employed, to lengthen
   // the sampling Period from the minimum of 1, to 2 ADC Clock intervals.
   //
   // ADCTRL3.bit.ADCCLKPS   <3..0>  Prescaler of 0..15  multiplied by 2.
   // ADCTRL1.bit.CPS           <0>  Prescaler of 0.. 1  1 or 2 multiply.
   // ADCTRL1.bit.ACQ_PS     <3..0>  Sample ticks 0..15  (1..16) ADC Clocks.
   //
   // For zero ACQ_PS delay, each ADC Sample/Conversion completes in 2 ADC
   // Clocks.  Minimum sampling time is 1 ADC Clock.
   //
   // Texas Instrument's Example of Sequential Sampling Mode (Section 1.2.1
   // within "spru716d.pdf") shows an Acquisition Window stretched from 1
   // to 2 ADC Clocks, with ACQ_PS is set to 1.  Each ADC Sample/Conversion
   // then effectively takes 3 ADC Clocks.  This is what is adopted.

   // CPS is reset to 0, allowing the slowest HSPCLK possible (power save).
   //
   // 15 ADC conversions are performed per full Buffer, which should take
   // 225µS (15 * 15µS).  This falls well within Timer1 Schedule Interval
   // (312.5µS), also driving Scheduled Tasks in the Background.
   //
   // Problems were found getting ANY of the Peripheral Interrupt Expansion
   // Module Interrupts to work.  CPU-Timer1 does not go through the PIE
   // Module, but it works.  It calls the ADC Service routine (in Flash).
   //
   // 8 ADC full-Buffers should be collected per nominal 2.5mS (1/400Hz)
   // Cycle Period.  (2500µS / 312.5µS).

   // Note that AC Current monitoring is by far the largest CPU load on
   // the Cooling System Software.  The ADC Paths need to be efficient.
   //
   // Set ADCTRL1 (b14..4 used) as follows:

   // RESET            = 0  No effect (b14)
   // SUSMOD           = 0  Emulation suspend ignored (b13..12)
   // ACQ_PS           = 1  Additional Sample hold of 2 ADC Clock Cycles (bit11..8)
   // CPS              = 0  Core clock PreScaler (halves ADC Clock when set) (b7)
   // CONT_RUN         = 0  Continuous run mode disabled (b6)
   // SEQ_OVRD         = 0  Stop sequencing at end of Buffer (b5)
   // SEQ_CASC         = 1  Cascaded Sequence, SEQ1+2 (b4)


   adcRegs.ADCTRL1.all           = 0;		// Clear default
   adcRegs.ADCTRL1.bit.ACQ_PS    = 1;		// One extra (2 total) Sampling Clocks.
   adcRegs.ADCTRL1.bit.CPS       = 0;		// Leave ADC Clock unchanged (/ 1).
   adcRegs.ADCTRL1.bit.SEQ_CASC  = 1;		// Cascaded SEQ (SEQ1 + SEQ2)

   AdcRegs.ADCTRL1.all = adcRegs.ADCTRL1.all;


   // Set ADCTRL2 as follows:
   // ePWM_SOCB_SEQ2   = 0  ePWM SOCB enable bit for SEQ2 (b15)
   // RST_SEQ1         = 0  No reset of SEQ1 (b14)
   // SOC_SEQ1         = 0  Clear a pending SOC Trigger (b13)

   // INT_ENA_SEQ1     = 0  SEQ1 Interrupt Disable (b11)
   // INT_MOD_SEQ1     = 0  Set INT_SEQ1 Flag upon every SEQ1 completion (b10)

   // ePWM_SOCA_SEQ1   = 0  SEQ1 cannot be started by ePWMx SOCA trigger (b8)
   // EXT_SOC_SEQ1     = 0  No external SEQ1 action to start Conversion (b7)
   // RST_SEQ2         = 0  No action to reset SEQ2 (b6)
   // SOC_SEQ2         = 0  Clear a pending SOC trigger (b5)

   // INT_ENA_SEQ2     = 0  SEQ2 Interrupt Disable (b3)
   // INT_MOD_SEQ2     = 0  Set INT_SEQ2 Flag upon every SEQ2 completion (b2)

   // ePWM_SOCB_SEQ    = 0  No action (for ePWM SOCB) (b0)

   adcRegs.ADCTRL2.all = 0;    	// Clear default

   AdcRegs.ADCTRL2.all = adcRegs.ADCTRL2.all;


   // Set ADCTRL3 as follows:
   // ADCBGFRDN        = 3  Bandgap and Reference Circuits powered up (b7..6)
   // ADCPWDN          = 1  Analog circuitry powered up (b5)
   // ADCCLKPS         = 0  Pre-Scaler ADC Clock unchanged (b4..1)
   // SMODE_SEL        = 0  Sequential sampling Mode disabled (b0)

   adcRegs.ADCTRL3.all           = 0;       // Clear default
   adcRegs.ADCTRL3.bit.ADCBGRFDN = 3;       // The band-gap & reference circuits powered up.
   adcRegs.ADCTRL3.bit.ADCPWDN   = 1;       // The analog circuitry is powered up.
   adcRegs.ADCTRL3.bit.ADCCLKPS  = 0;       // ADCCLKPS = Prescale ADC Clock / 1 (b4..1)

   AdcRegs.ADCTRL3.all = adcRegs.ADCTRL3.all;


   // Set number of ADC Samples to collect for the full Buffer.
   AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 14;   // SEQ (cascaded SEQ1+2) ADC count = 15


   // Please note that for the 5mS delay function below to operate correctly,
   // the CPU_CLOCK_SPEED define statement in the DSP280x_Examples.h file
   // must contain the correct CPU clock period (in nanoseconds).
   // The TI Assembler Function is run from Flash (it locks-up in RAM).
   DELAY_US(ADC_usDELAY);           // Delay before converting ADC channels

   setAdcChannel();


   return;
}	


void setAdcChannel (void)
{
   // Configure ADCs collected for cascaded SEQ (SEQ1 + SEQ2).
   // These map ADC Input Pin Numbers into A (IM Currents)
   // and B (Temperatures & Pressures) Channels.

   // SEQ1
   AdcRegs.ADCCHSELSEQ1.all = (ADCIN_A_PH_A_I        |		// CONV00 -> [0]
                              (ADCIN_B_PRES_1 <<  4) |      // CONV01 -> [0]
                              (ADCIN_A_PH_B_I <<  8) |      // CONV02 -> [0]
                              (ADCIN_B_PRES_2 << 12) );     // CONV03 -> [0]

   AdcRegs.ADCCHSELSEQ2.all = (ADCIN_A_PH_C_I        |      // CONV04 -> [0]
                              (ADCIN_B_TEMP_1 <<  4) |      // CONV05
                              (ADCIN_B_TEMP_2 <<  8) |      // CONV06
                              (ADCIN_B_TEMP_3 << 12) );     // CONV07

   // SEQ2
   AdcRegs.ADCCHSELSEQ3.all = (ADCIN_B_TEMP_4        |      // CONV08
                              (ADCIN_B_TEMP_5 <<  4) |      // CONV09
                              (ADCIN_A_PH_A_I <<  8) |      // CONV10 -> [1]
                              (ADCIN_B_PRES_1 << 12) );     // CONV11 -> [1]

   AdcRegs.ADCCHSELSEQ4.all = (ADCIN_A_PH_B_I        |      // CONV12 -> [1]
                              (ADCIN_B_PRES_2 <<  4) |      // CONV13 -> [1]
                              (ADCIN_A_PH_C_I <<  8) |      // CONV14 -> [1]
                              (DUMMY_ADC_INPT << 12) );     // CONV15
   return;
}


// Simulant of ADC SEQ Interrupt...
void read_ADC_Casc (void)
{
   // Copy cascaded SEQ ADCRESULT0..14

   // ADCRESULT0..4 are the first set of
   // double Samples, Currents & Pressures.
   phase_A_Curr[0] = AdcRegs.ADCRESULT0;	// AI
   liq_Inp_PRaw[0] = AdcRegs.ADCRESULT1;	// P1
   phase_B_Curr[0] = AdcRegs.ADCRESULT2;	// BI
   liq_Out_PRaw[0] = AdcRegs.ADCRESULT3;	// P2
   phase_C_Curr[0] = AdcRegs.ADCRESULT4;	// CI

   // ADCRESULT5..9 are the single
   // Samples, for Temperature Sensing.
   liq_Inp_TRaw    = AdcRegs.ADCRESULT5;	// T1
   liq_Out_TRaw    = AdcRegs.ADCRESULT6;	// T2
   air_Inp_TRaw    = AdcRegs.ADCRESULT7;	// T3
   air_Out_TRaw    = AdcRegs.ADCRESULT8;	// T4
   ac_MotorTRaw    = AdcRegs.ADCRESULT9;	// T5

   // ADCRESULT10..14 are the second set of
   // double Samples, Currents & Pressures.
   phase_A_Curr[1] = AdcRegs.ADCRESULT10;	// AI
   liq_Inp_PRaw[1] = AdcRegs.ADCRESULT11;	// P1
   phase_B_Curr[1] = AdcRegs.ADCRESULT12;	// BI
   liq_Out_PRaw[1] = AdcRegs.ADCRESULT13;	// P2
   phase_C_Curr[1] = AdcRegs.ADCRESULT14;	// CI


   // All ADCs Values have been copied out.

   // Reset SEQ1 to start at ADCBUFFER0.
   AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;

   // Reload the number-1 of collected ADC.
   AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 14;

   // Start cascaded SEQ ADC collection.
   AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;

   // Process the previous ADC Buffer content,
   // while the new ADC content commences.

   // Liquid Pressures and Phase Currents
   // are double sampled, per full Buffer.
   for (loopVariable = 0U;loopVariable < 2U; loopVariable++)
   {
      // Multiply the averaged Pump Input
      // Pressure ADC Value by 7, add the
      // Sample A ADC Value, then shift
      // right three times to divide by 8.
      liq_Inp_PAve =
         ( (liq_Inp_PAve * ADC_AVERAGE) +
            liq_Inp_PRaw[loopVariable]) >> 3;

...

      // Check whether Phase A Current (raw ADC Units),
      // is forming a Peak or Valley.
      if (phase_A_Curr[loopVariable] > HALVE_SCALE)
      {
         // Sum ADC Value for present Phase Peak.
         sumPk_A_Curr +=
         	(phase_A_Curr[loopVariable] - HALVE_SCALE);

	     // Count number of Peak Samples.
	     count_A_Peak++;

         // Check for the first ADC Peak Current
         // at, or above 3/4 Raw Scale (~4 Amps).
         if (phase_A_Curr[loopVariable] >= HI_THR_AMPS)
         {
...

