This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GRID TIE software PLL compile error

Dear all,

I am doing software for single phase PLL for grid applications.

I written the software for PLL when compiling using CCSV6 some error occurs.

Error:

Description    Resource    Path    Location    Type
unresolved symbol __IQ15sqrt, first referenced in ./Ti_spll_main.obj    SPLL_TI_forum             C/C++ Problem
unresolved symbol __IQ15isqrt, first referenced in ./Ti_spll_main.obj    SPLL_TI_forum             C/C++ Problem
unresolved symbol __IQ15div, first referenced in ./Ti_spll_main.obj    SPLL_TI_forum             C/C++ Problem
unresolved symbol _SGENT_3D_calc, first referenced in ./Ti_spll_main.obj    SPLL_TI_forum             C/C++ Problem

Please give the suggestion to solve this problem.

/*
 * task_main.c
 *
 *  Created on: Aug 28, 2014
 *  Author: selvanm
 */
#include "F2806x_Device.h"
#include "F2806x_Examples.h"
#include "F2806x_EPwm_defines.h"     // useful defines for initialization
#include "sgen.h"
#include "DSP28x_Project.h"
#include "IQmathLib.h"
#include "SPLL_1ph.h"
#include "SineAnalyzer_diff.h"




//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// FUNCTION PROTOTYPES

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//void DeviceInit(void);
void InitFlash(void);
void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr);
void cpu_timer0_isr(void);
void ADC_init(void);
void EPWM_init(void);

//void InitPieCtrl(void);

#define PI 3.14156

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// VARIABLE DECLARATIONS - GENERAL

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



// Used for running BackGround in flash and the ISR in RAM

extern Uint16 RamfuncsLoadStart, RamfuncsLoadEnd, RamfuncsRunStart;

Uint16 duty_cycle_A=500;     // Set duty 50% initially

Uint16 duty_cycle_B=500;     // Set duty 50% initially

Uint16 duty_cycle_C=500;     // Set duty 50% initially



//SGENT_1 sgen=SGENT_1_DEFAULTS;

SGENT_3D sgen=SGENT_3D_DEFAULTS;

int x11,x12,x13,x21,x22,x23;



unsigned int pippo=0, peppe;

Uint16 Adc_Results,i;

int32 Vac_in;

_iq15 InvSine,InvSine1,appoggio_InvSine1,VrmsReal, InvSine3,VavgReal,Vfreq,InvSine2,Theta_pi,sen_theta,theta,kappa,theta_old=0;

_iq16 fase;

float var_float;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// FUNCTION

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



void ADC_init(void)
{

    EALLOW;

      AdcRegs.ADCCTL1.bit.ADCREFSEL   = 0;     // use internal band gap reference
      AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;  // power up band gap
      AdcRegs.ADCCTL1.bit.ADCREFPWD = 1;  // power up reference
      AdcRegs.ADCCTL1.bit.ADCPWDN = 1;  // power up rest of ADC
      AdcRegs.ADCCTL1.bit.ADCENABLE = 1;  // enable ADC output
      for(i=0; i<5000; i++){}                        // wait 60000 cycles = 1ms (each iteration is 12 cycles)
      AdcRegs.ADCCTL1.bit.INTPULSEPOS    = 1;  // create int pulses 1 cycle prior to output latch
      //EOC = end of conversion event, SOC = start of conversion event
      AdcRegs.INTSEL1N2.bit.INT1SEL = 1;       // ADCCH1 (ADC-A1) EOC causes ADCInterrupt1
//    AdcRegs.INTSEL1N2.bit.INT1CONT = 1;      // set ADCInterrupt 1 to auto clr (continuous conversion)
      AdcRegs.INTSEL1N2.bit.INT1CONT = 0; // clear ADCINT1 flag to begin a new set of conversions
      AdcRegs.ADCINTFLG.bit.ADCINT1 = 0;  // clear interrupt flag for ADCINT1
      AdcRegs.INTSEL1N2.bit.INT1E = 1;         // enable ADCInterrupt1; 0=none, 1=ADCInt1, 2=ADCInt2

//   AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 1;       // ADCInterrupt1 causes SOC1

      AdcRegs.ADCINTSOCSEL1.all=0x0000;  // No ADCInterrupt will trigger SOCx

      AdcRegs.ADCINTSOCSEL2.all=0x0000;

      AdcRegs.ADCSOC1CTL.bit.CHSEL= 1;         // convert ADC-A1 (CH1) when SOC1 is received

      AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;        // set S/H window to 6 clk cycles (117ns)

      AdcRegs.ADCSOC1CTL.bit.TRIGSEL=9;  //Epwm3 adc socA trigger source

      EDIS;

      AdcRegs.ADCSOCFRC1.all = 0x2;            // kick start ADC by causing an ADCInterrupt1 event

}



void EPWM_init(void)
{

    #define period 1680                                          // 60kHz when PLL is set to 0xC (60MHz)

  //    period 500                             // 120kHz when PLL is set to 0xC (60MHz)



//****************************Epwm 2**************************

      EPwm2Regs.TBPRD = period;                   // Set timer period, PWM frequency = 1 / period

      EPwm2Regs.TBPHS.all = 0;                          // Time-Base Phase Register

      EPwm2Regs.TBCTR = 0;                              // Time-Base Counter Register

    EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;  // Set Immediate load

    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count-up mode: used for asymmetric PWM

      EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;     // Disable phase loading

      EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

      EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

      EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;



      // Setup shadow register load on ZERO

      EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

      EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

      EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // load on CTR=Zero

      EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;  // load on CTR=Zero



      // Set Compare values

      EPwm2Regs.CMPA.half.CMPA = duty_cycle_A;    // Set duty 50% initially

      EPwm2Regs.CMPB = duty_cycle_B;                 // Set duty 50% initially



      // Set actions



      EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM2A on Zero

      EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM2A on event A, up count



      EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET;          // Set PWM2B on Zero

      EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;            // Clear PWM2B on event B, up count



//****************************Epwm 3**************************

      EPwm3Regs.TBPRD = period;                   // Set timer period, PWM frequency = 1 / period

      EPwm3Regs.TBPHS.all = 0;                          // Time-Base Phase Register

      EPwm3Regs.TBCTR = 0;                              // Time-Base Counter Register

    EPwm3Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;  // Set Immediate load

    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count-up mode: used for asymmetric PWM

      EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE;     // Disable phase loading

      EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

      EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

      EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;



      // Setup shadow register load on ZERO

      EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

      EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

      EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // load on CTR=Zero

      EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;  // load on CTR=Zero



      EPwm3Regs.CMPA.half.CMPA = duty_cycle_C;    // Set duty 50% initially

      EPwm3Regs.CMPB = duty_cycle_C;                 // Set duty 50% initially



      EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM2A on Zero

      EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM2A on event A, up count



      EPwm3Regs.AQCTLB.bit.ZRO = AQ_SET;          // Set PWM2B on Zero

      EPwm3Regs.AQCTLB.bit.CBU = AQ_CLEAR;            // Clear PWM2B on event B, up count



      // SOC for PLL

      EPwm3Regs.ETSEL.bit.SOCAEN   = 1;

      EPwm3Regs.ETSEL.bit.SOCASEL = 3;   // Use PRD event as trigger for ADC SOC

    EPwm3Regs.ETPS.bit.SOCAPRD     = 2;        // Generate pulse on 2nd event



//****************************Epwm 4**************************

      EPwm4Regs.TBPRD = period;                   // Set timer period, PWM frequency = 1 / period

      EPwm4Regs.TBPHS.all = 0;                          // Time-Base Phase Register

      EPwm4Regs.TBCTR = 0;                              // Time-Base Counter Register

    EPwm4Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;  // Set Immediate load

    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count-up mode: used for asymmetric PWM

      EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE;     // Disable phase loading

      EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

      EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

      EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;



      // Setup shadow register load on ZERO

      EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

      EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

      EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // load on CTR=Zero

      EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;  // load on CTR=Zero



      EPwm4Regs.CMPA.half.CMPA = duty_cycle_C;    // Set duty 50% initially

      EPwm4Regs.CMPB = duty_cycle_C;                 // Set duty 50% initially



      EPwm4Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM2A on Zero

      EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM2A on event A, up count



      EPwm4Regs.AQCTLB.bit.ZRO = AQ_SET;          // Set PWM2B on Zero

      EPwm4Regs.AQCTLB.bit.CBU = AQ_CLEAR;            // Clear PWM2B on event B, up count



}

// ------------- Sine Analyzer Block to measure RMS, frequency and ZCD

      SineAnalyzer_diff sine_mainsV = SineAnalyzer_diff_DEFAULTS;



      SPLL_1ph spll1;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// MAIN CODE - starts here

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

void main(void)

{



//=================================

//    INITIALISATION - General

//=================================



      //DeviceInit();     // Device Life support & GPIO mux settings



// Only used if running from FLASH

// Note that the variable FLASH is defined by the compiler (-d FLASH)

#ifdef FLASH

// Copy time critical code and Flash setup code to RAM

// The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart

// symbols are created by the linker. Refer to the linker files.

      MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);



// Call Flash Initialization to setup flash waitstates

// This function must reside in RAM

      InitFlash();      // Call the flash wrapper init function

#endif //(FLASH)



//-------------------------------------------------------------





//****************************Configurazione interrupt timer0 **************************



// Step 3. Clear all interrupts and initialize PIE vector table:

// Disable CPU interrupts

   DINT;

// Initialize the 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 DSP2802x_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 DSP2802x_DefaultIsr.c.

// This function is found in DSP2802x_PieVect.c.

   InitPieVectTable();

// Interrupts that are used in this example are re-mapped to

// ISR functions found within this file.

   EALLOW;  // This is needed to write to EALLOW protected registers

   PieVectTable.TINT0 = &cpu_timer0_isr;

   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize the Device Peripheral. This function can be

//         found in DSP2802x_CpuTimers.c

   InitCpuTimers();   // For this example, only initialize the Cpu Timers

// Configure CPU-Timer 0 to interrupt every 500 milliseconds:

// 60MHz CPU Freq, 50 millisecond Period (in uSeconds)

   ConfigCpuTimer(&CpuTimer0, 60, 50);

// To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any

// of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2802x_CpuTimers.h), the

// below settings must also be updated.

   CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0



// Enable CPU INT1 which is connected to CPU-Timer 0:

   IER |= M_INT1;

// Enable TINT0 in the PIE: Group 1 interrupt 7

   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;



// Enable global Interrupts and higher priority real-time debug events:

   EINT;   // Enable Global interrupt INTM

   ERTM;   // Enable Global realtime interrupt DBGM



//****************************EPWM INITIALISATION**************************

      EPWM_init();

//****************************ADC INITIALISATION**************************

      ADC_init();

  //=================================

  //  Forever LOOP

  //=================================

  // Just sit and loop forever:

  // No interrups needed in this example.

  // PWM pins can be observed with a scope.



      kappa=_IQ15(0.1);

      sgen.offset=0;

      sgen.gain=0x7fff; /* gain = 1 in Q15 */

      sgen.freq=5369; /* freq = (Required Freq/Max Freq)*2^15 */

      /* = (50/305.17)*2^15 = 5369 */

      sgen.step_max=1000; /* Max Freq= (step_max * sampling freq)/65536 */

      /* Max Freq = (1000*20k)/65536 = 305.17 */

      sgen.phase=0x4000; /* Phase = (required Phase)/180 in Q15 */

      /* = (+90/180) in Q15 = 4000h */



  //  for(;;)

      SPLL_1ph_init(50,_IQ21(0.00005),&spll1);

 //sine analyzer initialization

      sine_mainsV.Vin=0;

    sine_mainsV.SampleFreq=_IQ15(8571428.6);//(20000.0)

    sine_mainsV.Threshold=_IQ15(0.5);



      while(1)

      {

            EPwm2Regs.CMPA.half.CMPA = (x11/40)+819;      // Add duty_cycle_A to watch window

            EPwm2Regs.CMPB = (x12/40)+819;

//                EPwm3Regs.CMPA.half.CMPA = (x13/40)+819;

            EPwm3Regs.CMPA.half.CMPA = (InvSine/40)+819;

            EPwm3Regs.CMPB = (x21/40)+819;

            EPwm4Regs.CMPA.half.CMPA = (x22/40)+819;

            EPwm4Regs.CMPB = Adc_Results/2;



            if (sine_mainsV.ZCD==1){

                  if (x21==0){

                        sgen.phase++;

                  }

            }

            if (AdcRegs.ADCINTFLG.bit.ADCINT1 == 1){

                  pippo++;

            }



// ------------------------------------------------------------------------------

//    Connect inputs to the sine analyzer block , compute RMS, Freq, ZCD

// ------------------------------------------------------------------------------

            sine_mainsV.Vin =(long)((long)AdcResult.ADCRESULT1<<3);//-_IQ15(0.5);

            sine_mainsV.Vin = sine_mainsV.Vin <<1;

            SineAnalyzer_diff_MACRO (sine_mainsV);

//    VrmsReal = _IQ15mpy (KvInv, sine_mainsV.Vrms);

            VrmsReal = _IQ15(sine_mainsV.Vrms);

            Vfreq = _IQ15(sine_mainsV.SigFreq);





      }

}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

// Interrupt

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



interrupt void cpu_timer0_isr(void)

{

   //GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; // Toggle GPIO34 once per 500 milliseconds

      GpioDataRegs.GPATOGGLE.bit.GPIO16=1;

      CpuTimer0.InterruptCount++;

      //SPLL_1ph_run(&spll1);

      sgen.calc(&sgen);

      x11=sgen.out11;

      x12=sgen.out12;

      x13=sgen.out13;

      x21=sgen.out21;

      x22=sgen.out22;

      x23=sgen.out23;

      SPLL_1ph_MACRO(spll1);

      Vac_in=(long)((long)AdcResult.ADCRESULT1<<9);

      spll1.AC_input=Vac_in>>1;

      InvSine  = (long)(spll1.sin[0])>>6; // InvSine is in Q15

      InvSine2 = (long)(spll1.cos[0])>>6; // InvCos is in Q15

      //    InvSine3 = _IQ15(InvSine2 * _IQ15(0.1)) + InvSine;

      InvSine3 = _IQ15mpy(InvSine2,kappa)+ InvSine;

      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

      Adc_Results = AdcResult.ADCRESULT1;

      AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;          // Clear ADCINT1 flag



}

Regards,

Muthu