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.

TDA4VM: C66X caculated performance

Part Number: TDA4VM
Other Parts Discussed in Thread: 4213

Hi, experts.

We're doing caculated performance test of DSP C66X, and compare the result with other manufacturers DSP(the frequency of which is lower than C66X). The result is worse.There is the compared results.

Function execution time, in microseconds.

Num Core Average2Calc Average2Cfg RmsPLLCalc DCComponentCalc PllCalc
1 C66X_1 0.029 0.018 0.035 0.054 2.617
2 C66X_2 0.029 0.018 0.035 0.054 2.617
3 Other DSP 0.019 0.017 0.033 0.036 2.759

These functions are frequently-used,please help to analysis why a long time to execute.

Board:TDA4VMSK

SDK:08_06_01_02

PDK:08_06_01_03

based on ipc_echo_test:

    make -s ipc_echo_test_freertos BOARD=j721e_evm CORE=c66xdsp_1
    make -s ipc_echo_test_freertos BOARD=j721e_evm CORE=c66xdsp_2

test method:

     Add GPIO configuration and timer configuration to the demo, invoke the test function during timer interruption

     (1) Set GPIO to 1

     (2) Loop call test function N times

     (3) Set GPIO to 0

    Externally measure the time T of GPIO set 1 and calculate each run time T/N.

Attachments are functions and test cases.

Regards.

#include <../../mathnotlib/app_test.h>
/**
  @brief 有效值计算
  @param prms  有效值信息配置地址
  @param in 输入信号
  @param PLLFlag 锁相环标志
  @return 计算出的有效值
*/
FLOAT32 RmsPLLCalc(RMS_OBJ *prms, FLOAT32 in, bool PLLFlag)
{

    prms->sum += POW2(in);
    prms->index = prms->index + 1;
    if((PLLFlag && (prms->flag == 0)) || (prms->index >= MAXINDEX))
    {
        prms->out = SQRTF(DIVF32(prms->sum, prms->index));
        prms->sum = 0;
        prms->index = 0;
    }
    prms->flag = PLLFlag;
    return prms->out;
}

/**
  @brief 平均值计算配置函数
  @param pave  平均值信息配置地址
  @param in 输入信号
  @return 无
*/
FLOAT32 Average2Cfg(AVE2_OBJ *pave , FLOAT32 in)
{
    pave->sum += in;
    pave->index ++;
}

/**
  @brief 平均值计算函数
  @param pave  平均值信息配置地址
  @param in 输入信号
  @return 计算出的平均值
*/
FLOAT32 Average2Calc(AVE2_OBJ *pave , FLOAT32 in)
{

    if(pave->index == 0)
        pave->out = pave->sum;
    else
        pave->out = DIVF32(pave->sum, pave->index);

    pave->sum = 0;
    pave->index = 0;

    return pave->out;
}

/**
  @brief 直流侧分量计算函数
  @param pmean  直流侧分量计算信息配置地址
  @param freq  输入信号的频率
  @param ts  采样周期,单位为s
  @param in 输入信号
  @return 计算出的直流侧分量,一个输入信号周期更新一次
*/
FLOAT32 DCComponentCalc(DC_OBJ *pmean, const FLOAT32 freq, const FLOAT32 ts, const FLOAT32 in)
{
    pmean->rank = ROUND(INVF32(freq * ts));

    pmean->sum += in;
    if(++pmean->index >= pmean->rank)
    {
        pmean->index = 0;
        pmean->out = DIVF32(pmean->sum, pmean->rank);
        pmean->sum = 0;
    }
    
    return pmean->out;
}
#include "pll.h"

extern void setGPIO();
extern void clrGPIO();


void testPLLCalc(UINT32 idx)
{
    void *handle = NULL;
    INT32 i= 0;
    FLOAT32 a, b, c;
    PLLOUT_OBJ out_obj = {0};
    // struct hwtimer_ctrl_info info, info2;

    handle = PLLCfg(0.00003, PLL_LPF_WC, PLL_FREQ_KP, PLL_FREQ_KI, PLL_PI_LIMIT);

    //DELAY_US(100);
    a = 123.45;
    b = 456.45;
    c = 778.45;
    out_obj.ua_inv_sample = &a;
    out_obj.ub_inv_sample = &b;
    out_obj.uc_inv_sample = &c;

    GPIO_write(idx, 1);
    for (i = 0; i < 2; i++) {
        PLLCalc(&out_obj, handle, 0.00003);
    }
    GPIO_write(idx, 0);
}

#include "pll.h"

typedef struct
{
    UINT16   rank;      //!<IIR滤波器的阶数
    UINT16   rankadd;
    FLOAT32 *pcoeffan;  //!<IIR滤波器输入各阶系数的地址
    FLOAT32 *pcoeffbn;  //!<IIR滤波器输出各阶系数的地址
    FLOAT32 *pxn;       //!<采样输入的地址
    FLOAT32 *pyn;       //!<滤波输出数组的地址
    UINT16   index;     //!<当前的滤波索引值
}IIR_OBJ;

#ifdef _FLASH
#pragma CODE_SECTION(IirCfg,".TI.ramfunc");
#pragma CODE_SECTION(IirCalc,".TI.ramfunc");
#pragma CODE_SECTION(DigitalFilterCfg,".TI.ramfunc");
#pragma CODE_SECTION(DigitalFilterCalc,".TI.ramfunc");
#pragma CODE_SECTION(PidCfg,".TI.ramfunc");
#pragma CODE_SECTION(PidCalc,".TI.ramfunc");
#pragma CODE_SECTION(ABC2d,".TI.ramfunc");
#pragma CODE_SECTION(ABC2q,".TI.ramfunc");
#pragma CODE_SECTION(ABC2dq,".TI.ramfunc");
#pragma CODE_SECTION(PLLCfg,".TI.ramfunc");
#pragma CODE_SECTION(PLLCalc,".TI.ramfunc");
#endif
IIR_OBJ iir_obj = {0};
FLOAT32 iir_buf[6][2] = {0};
/**
 * @brief  IIR配置函数       H(Z) = Y(Z)/X(Z) = ∑(0 to n)(an * Z^-n) / ∑(0 to n)(bn * Z^-n)
 *         即Yn = a0*X(0) + a1*X(-1) + ... + an*X(-n) - (b1*Y(-1) + b2*Y(-2) + ... + bn*Y(-n))
 * @param  rank             IIR的阶数n (UINT16)
 * @param  coeffan          输入的各阶系数an(FLOAT32型数组)
 * @param  coeffbn          输出的各阶系数bn (FLOAT32型数组)
 * @return 存放IIR配置信息的地址(Handle)
 */
Handle IirCfg(const UINT16 rank, const FLOAT32* coeffan, const FLOAT32* coeffbn)
{
    IIR_OBJ *iir;
    INT16 i;

    iir = &iir_obj;//(IIR_OBJ*)calloc((1), sizeof(IIR_OBJ));

    if(iir != NULL)
	{
		iir->pcoeffan = iir_buf[0];//(FLOAT32*)calloc((rank+1), sizeof(FLOAT32));
		if(iir->pcoeffan == NULL)
		{
			goto ERR;
		}
		iir->pcoeffbn = iir_buf[1];//(FLOAT32*)calloc((rank+1), sizeof(FLOAT32));
		if(iir->pcoeffbn == NULL)
		{
			goto ERR;
		}
		iir->pxn = iir_buf[2];//(FLOAT32*)calloc((rank+1), sizeof(FLOAT32));
		if(iir->pxn == NULL)
		{
			goto ERR;
		}
		iir->pyn = iir_buf[3];//(FLOAT32*)calloc((rank+1), sizeof(FLOAT32));
		if(iir->pyn == NULL)
		{
			goto ERR;
		}
		iir->rank   = rank;
		iir->rankadd  = iir->rank  + 1;

		for(i=0; i<=rank; i++)
		{
			iir->pcoeffan[i] = coeffan[i];
			iir->pcoeffbn[i] = coeffbn[i];
		}
		iir->pcoeffbn[0] = 1;
	}
    return (Handle)iir;

	ERR:
	return NULL;
}

/**
 * @brief  IIR计算函数       H(Z) = Y(Z)/X(Z) = ∑(0 to n)(an * Z^-n) / ∑(0 to n)(bn * Z^-n)
 *         即Yn = a0*X(0) + a1*X(-1) + ... + an*X(-n) - (b1*Y(-1) + b2*Y(-2) + ... + bn*Y(-n))
 * @param  piir             存放IIR配置信息的地址(Handle)
 * @param  xn               当前采样值X(0) (FLOAT32型)
 * @return 滤波后的输出值Yn (FLOAT32型)
 */
FLOAT32 IirCalc(Handle piir, const FLOAT32 xn)
{
    IIR_OBJ *p = (IIR_OBJ*)piir;
    UINT16   ptr,ptr1;
    UINT16 i;

    ptr1 = p->index;
    p->pxn[ptr1] = xn;
    p->pyn[ptr1] = 0;

    for(i=0; i <= p->rank; i++)
    {
        ptr = (ptr1 + p->rankadd -i) % p->rankadd;
        p->pyn[ptr1] += p->pxn[ptr] * p->pcoeffan[i];
        if(i > 0)
        {
            p->pyn[ptr1] -= p->pyn[ptr] * p->pcoeffbn[i];
        }
    }

    p->index = (p->index + 1) % p->rankadd;

    return p->pyn[ptr1];
}


typedef enum DF_Type
{
    LOWPASS_1ST  = 0,     //!<一阶低通滤波器
    HIGHPASS_1ST = 1,     //!<一阶高通滤波器
    LOWPASS_2ND  = 2,     //!<二阶低通滤波器
    HIGHPASS_2ND = 3,     //!<二阶高通滤波器
    BANDPASS_2ND = 4,     //!<二阶带通滤波器
    BANDREJ_2ND  = 5,     //!<二阶带阻滤波器
}DF_TYPE;

typedef struct
{
    IIR_OBJ     *piir;     //!<iir滤波器组件
    DF_TYPE      type;     //!<本次配置的滤波器类型
    FLOAT32      Ts;       //!<配置的滤波器采样周期,单位为s
    FLOAT32      wc;       //!<配置的滤波器截止频率
    FLOAT32      lambda;   //!<配置的滤波器阻尼系数(一阶滤波器无该系数,可写为0)
}DF_OBJ;
DF_OBJ df_obj = {0};
Handle DigitalFilterCfg(const DF_TYPE type, const FLOAT32 Ts, const FLOAT32 wc, const FLOAT32 lambda)
{
    FLOAT32  coeffan[3],coeffbn[3];
	FLOAT32  tswc_1st=0, coeffb0_1st, coeffb0_rcp_1st=0, coeffb1_1st=0;
	FLOAT32  tswc_2nd, tswc2_2nd=0, interVar_2nd=0, coeffb0_2nd, coeffb0_rcp_2nd=0, coeffb1_2nd=0, coeffb2_2nd=0;
	UINT16   rank;
	DF_OBJ  *df;

    df = &df_obj; //(DF_OBJ*)calloc((1), sizeof(DF_OBJ));
	if(df == NULL)
	   goto ERR;

	if((type == LOWPASS_1ST)||(type == HIGHPASS_1ST))
	{
		rank = 1;
		tswc_1st = Ts * wc;
		coeffb0_1st =  tswc_1st + 2;
		coeffb0_rcp_1st = INVF32(coeffb0_1st);
		coeffb1_1st =  1 - 4 * coeffb0_rcp_1st;
	}
	else
	{
        rank = 2;
		tswc_2nd = Ts * wc;
        tswc2_2nd = tswc_2nd * tswc_2nd;
		interVar_2nd = 4 * tswc_2nd * lambda;
        coeffb0_2nd = tswc2_2nd + interVar_2nd + 4;
        coeffb0_rcp_2nd = INVF32(coeffb0_2nd);
        coeffb1_2nd = (2 * tswc2_2nd - 8 ) * coeffb0_rcp_2nd;
        coeffb2_2nd = (tswc2_2nd - interVar_2nd + 4) * coeffb0_rcp_2nd;
	}

	switch(type)
	{
		case LOWPASS_1ST:	                                                            //一阶低通滤波器
			coeffbn[0] = 1;
			coeffbn[1] = coeffb1_1st;
			coeffan[0] = tswc_1st * coeffb0_rcp_1st;
			coeffan[1] = coeffan[0];
			break;
		case HIGHPASS_1ST:                                                             //一阶高通滤波器
		    coeffbn[0] = 1;
			coeffbn[1] = coeffb1_1st;
			coeffan[0] = 2 * coeffb0_rcp_1st;
			coeffan[1] = -2 * coeffb0_rcp_1st;
			break;
		case LOWPASS_2ND:                                                             //二阶低通滤波器
			coeffbn[0] = 1;
			coeffbn[1] = coeffb1_2nd;
			coeffbn[2] = coeffb2_2nd;
			coeffan[0] = tswc2_2nd * coeffb0_rcp_2nd;
			coeffan[1] = 2 * coeffan[0];
			coeffan[2] = coeffan[0];
			break;
		case HIGHPASS_2ND:                                                             //二阶高通滤波器
			coeffbn[0] = 1;
			coeffbn[1] = coeffb1_2nd;
			coeffbn[2] = coeffb2_2nd;
			coeffan[0] = 4 * coeffb0_rcp_2nd;
			coeffan[1] = -8 * coeffb0_rcp_2nd;
			coeffan[2] = coeffan[0];
			break;
		case BANDPASS_2ND:                                                             //二阶带通滤波器
		    coeffbn[0] = 1;
			coeffbn[1] = coeffb1_2nd;
			coeffbn[2] = coeffb2_2nd;
			coeffan[0] = interVar_2nd * coeffb0_rcp_2nd;
			coeffan[1] = 0;
			coeffan[2] = -coeffan[0];
			break;
		case BANDREJ_2ND:                                                             //二阶带阻滤波器
		    coeffbn[0] = 1;
			coeffbn[1] = coeffb1_2nd;
			coeffbn[2] = coeffb2_2nd;
			coeffan[0] = (tswc2_2nd + 4) * coeffb0_rcp_2nd;
			coeffan[1] = (2 * tswc2_2nd - 8)* coeffb0_rcp_2nd;
			coeffan[2] = coeffan[0];
			break;
	}
	df->piir = (IIR_OBJ*)IirCfg(rank, coeffan, coeffbn);
	if(df->piir == NULL)
	   goto ERR;

	df->type = type;
	df->Ts = Ts;
	df->wc = wc;
	df->lambda = lambda;

	return (Handle)df;

	ERR:
	return NULL;
}

/**
 * @brief  数字滤波器计算函数
 * @param  pDF              存放数字滤波器配置信息的地址(Handle)
 * @param  xn               当前采样值 (FLOAT32型)
 * @return 滤波后的输出值 (FLOAT32型)
 */
FLOAT32 DigitalFilterCalc(Handle pdf, const FLOAT32 xn)
{
	DF_OBJ *p = (DF_OBJ*)pdf;
	Handle    piir;
	FLOAT32   yn;

	piir = (Handle)p->piir;
	yn = IirCalc(piir,xn);

	return yn;
}

typedef struct
{
    Handle   pki;
    Handle   pkd;
    FLOAT32  ts_val;   //!<采样周期
    FLOAT32  kp_val;   //!<比例系数
    FLOAT32  ki_val;   //!<积分系数
    FLOAT32  kd_val;   //!<微分系数
    UINT16   pid_rst;  //!<积分器及微分器复位标志
    FLOAT32  xz_val;   //!<PID控制器当前时刻输入
    FLOAT32  yz_val;   //!<PID控制器当前时刻输出
    FLOAT32  previ_xz; //!<积分器上一时刻输入
    FLOAT32  previ_yz; //!<积分器上一时刻输出
    FLOAT32  prevd_xz; //!<微分器上一时刻输入
    FLOAT32  prevd_yz; //!<微分器上一时刻输出
    FLOAT32  intg_thr; //!<积分器限值
    FLOAT32  deri_thr;  //!<微分器限值
    FLOAT32  pid_thr;  //!<PID控制器限值
    FLOAT32  yz_prop;  //!<比例器当前时刻输出
    FLOAT32  yz_intg;  //!<积分器当前时刻输出
    FLOAT32  yz_deri;   //!<微分器当前时刻输出
}PID_OBJ;

PID_OBJ pid_obj = {0};
/**
 * @brief             PID控制器配置函数
 * @param  ts_val     采样周期Ts
 * @param  kp_val     比例系数Kp
 * @param  ki_val     积分系数Ki
 * @param  kd_val     微分系数Kd
 * @param  intg_thr   积分器限值
 * @param  deri_thr   微分器限值
 * @param  pid_thr    PID控制器限值
 * @return Handle     存放PID_OBJ配置信息的地址
 */
Handle PidCfg(FLOAT32 ts_val, FLOAT32 kp_val, FLOAT32 ki_val, FLOAT32 kd_val, FLOAT32 intg_thr, FLOAT32 deri_thr, UINT16 pid_thr)
{
    PID_OBJ *p;
    FLOAT32  an_i[2],bn_i[2];
    FLOAT32  an_d[2],bn_d[2];

    p = &pid_obj;//(PID_OBJ*)calloc((1), sizeof(PID_OBJ));
    p->ts_val   = ts_val;
    p->kp_val   = kp_val;
    p->ki_val   = ki_val;
    p->kd_val   = kd_val;
    p->intg_thr = intg_thr;
    p->deri_thr = deri_thr;
    p->pid_thr  = pid_thr;

    an_i[0] = p->ki_val*p->ts_val;
    an_i[1] = 0;
    bn_i[0] = 1;
    bn_i[1] = -1;
    p->pki = IirCfg(1, an_i, bn_i);

    an_d[0] = DIVF32(p->kd_val, p->ts_val);
    an_d[1] = -DIVF32(p->kd_val, p->ts_val);
    bn_d[0] = 1;
    bn_d[1] = 0;
    p->pkd = IirCfg(1, an_d, bn_d);

    if((p == NULL))
    {
        free(p);
    }

    return (Handle)p;
}

/**
 * @brief             PID控制器计算函数    G(s)= kp + ki/s + kd*s
 * @param  pid_p      存放PID_OBJ配置信息的地址
 * @param  xz_val     PID控制器当前时刻输入
 * @param  pid_rst    PID控制器复位标志位
 * @return FLOAT32    PID控制后的输出值yz_val(FLOAT32)
 */
FLOAT32 PidCalc(Handle pid_p, FLOAT32 xz_val, UINT16 pid_rst)
{
    PID_OBJ *p  = (PID_OBJ*)pid_p;

    //@lst 比例输出 Gp(s) = kp
    p->yz_prop = p->kp_val*xz_val; //比例器离散化

    //@lst 积分输出 Gi(s) = ki/s
    p->yz_intg = IirCalc(p->pki, xz_val);                   //积分器离散化-后向差分
    p->yz_intg = SAT(p->yz_intg, -p->intg_thr, p->intg_thr);//积分器限值

    if(p->pid_rst) //pid复位判断
    {
        p->previ_xz = 0.0;
        p->previ_yz = 0.0;
    }
    else
    {
        p->previ_xz = xz_val;
        p->previ_yz = p->yz_intg;
    }

    //@lst 微分输出 Gd(s) = kd*s
    p->yz_deri = IirCalc(p->pkd, xz_val);                   //微分器离散化-后向差分
    p->yz_deri = SAT(p->yz_deri, -p->deri_thr, p->deri_thr);//微分器限值

    if(p->pid_rst) //pid复位判断
    {
        p->prevd_xz = 0.0;
        p->prevd_yz = 0.0;
    }
    else
    {
        p->prevd_xz = xz_val;
        p->prevd_yz = p->yz_deri;
    }

    //@lst PID输出 = 比例输出 + 积分输出 + 微分输出 Gpid(s) = kp + ki/s + kd*s
    p->yz_val = p->yz_prop + p->yz_intg + p->yz_deri;
    p->yz_val = SAT(p->yz_val, -p->pid_thr, p->pid_thr);   //pid总限值

    return p->yz_val;
}

FLOAT32 ABC2d(const FLOAT32 *abc, const FLOAT32 wt)
{
    FLOAT32 lag,lead;

    lag	 = wt - PI2DIV3;
    lead = wt + PI2DIV3;

    return L2DIV3 * (abc[0] * COSF(wt)  +  abc[1] * COSF(lag)  +  abc[2] * COSF(lead));
}

FLOAT32 ABC2q(const FLOAT32 *abc, const FLOAT32 wt)
{
    FLOAT32 lag,lead;

    lag	 = wt - PI2DIV3;
    lead = wt + PI2DIV3;

    return -L2DIV3 * (abc[0] * SINF(wt)  +  abc[1] * SINF(lag)  +  abc[2] * SINF(lead));
}

#if 1
void ABC2dq(FLOAT32 *outdq, const FLOAT32 *srcabc, const FLOAT32 wt)
{
    outdq[0] = ABC2d(srcabc, wt);
    outdq[1] = ABC2q(srcabc, wt);
}
#else
void ABC2dq(FLOAT32 *outdq, const FLOAT32 *srcabc, const FLOAT32 wt);
#endif

typedef struct
{
    /* data */
    Handle df_p1;
    Handle df_p2;
    Handle df_p3;
    Handle df_p4;
    Handle pid_p;
}PLL_OBJ;

PLL_OBJ pll_obj = {0};
Handle PLLCfg(const FLOAT32 Ts, const FLOAT32 lpf_wc, const FLOAT32 freq_kp, const FLOAT32 freq_ki, const FLOAT32 freq_limit)
{
    PLL_OBJ *pll;

    pll = &pll_obj;//(PLL_OBJ*)calloc(1,sizeof(PLL_OBJ));
    if(pll == NULL)
    goto ERR;

    pll->df_p1 = DigitalFilterCfg(LOWPASS_1ST, Ts, lpf_wc, 0);
    if(pll->df_p1 == NULL)
    goto ERR;

    pll->df_p2 = DigitalFilterCfg(LOWPASS_1ST, Ts, lpf_wc, 0);
    if(pll->df_p2 == NULL)
    goto ERR;

    pll->df_p3 = DigitalFilterCfg(LOWPASS_1ST, Ts, lpf_wc, 0);
    if(pll->df_p3 == NULL)
    goto ERR;

    pll->df_p4 = DigitalFilterCfg(LOWPASS_1ST, Ts, lpf_wc, 0);
    if(pll->df_p4 == NULL)
    goto ERR;

    pll->pid_p = PidCfg(Ts, freq_kp, freq_ki, 0, freq_limit, 0, freq_limit);
    if(pll->pid_p == NULL)
    goto ERR;

    return (Handle)pll;

    ERR:
    return NULL;
}


void PLLCalc(PLLOUT_OBJ *pllout_p, Handle pll_p, const FLOAT32 Ts)
{
    //中间变量
    FLOAT32 vdq_pos_sample[2];
    FLOAT32 vdq_neg_sample[2];
    FLOAT32 vd_pos_filt;
    FLOAT32 vq_pos_filt;
    FLOAT32 vd_neg_filt;
    FLOAT32 vq_neg_filt;
    FLOAT32 grid_omeg;
    FLOAT32 u_inv_sample[3];

    PLL_OBJ *p = (PLL_OBJ*)pll_p;

    u_inv_sample[0] = *(pllout_p->ua_inv_sample);
    u_inv_sample[1] = *(pllout_p->ub_inv_sample);
    u_inv_sample[2] = *(pllout_p->uc_inv_sample);

    ABC2dq(vdq_pos_sample, u_inv_sample, pllout_p->grid_theta);
    ABC2dq(vdq_neg_sample, u_inv_sample, -pllout_p->grid_theta);

    vd_pos_filt = DigitalFilterCalc(p->df_p1, pllout_p->vd_pos_final);
    vq_pos_filt = DigitalFilterCalc(p->df_p2, pllout_p->vq_pos_final);
    vd_neg_filt = DigitalFilterCalc(p->df_p3, pllout_p->vd_neg_final);
    vq_neg_filt = DigitalFilterCalc(p->df_p4, pllout_p->vq_neg_final);

    pllout_p->vd_pos_final = vdq_pos_sample[0] - vd_neg_filt*COSF(2*pllout_p->grid_theta) - vq_neg_filt*SINF(2*pllout_p->grid_theta);
    pllout_p->vq_pos_final = vdq_pos_sample[1] + vd_neg_filt*SINF(2*pllout_p->grid_theta) - vq_neg_filt*COSF(2*pllout_p->grid_theta);
    pllout_p->vd_neg_final = vdq_neg_sample[0] - vd_pos_filt*COSF(2*pllout_p->grid_theta) + vq_pos_filt*SINF(2*pllout_p->grid_theta);
    pllout_p->vq_neg_final = vdq_neg_sample[1] - vd_pos_filt*SINF(2*pllout_p->grid_theta) - vq_pos_filt*COSF(2*pllout_p->grid_theta);

    grid_omeg = PidCalc(p->pid_p, pllout_p->vq_pos_final, 0) + PI2*50;
    pllout_p->grid_theta += grid_omeg * Ts;
    pllout_p->grid_theta = FMODF(pllout_p->grid_theta, PI2);
    pllout_p->grid_freq = DIVF32(grid_omeg, PI2);

}
app_test.h

#include "pll.h"

extern void setGPIO();
extern void clrGPIO();


void testPLLCalc(UINT32 idx)
{
    void *handle = NULL;
    INT32 i= 0;
    FLOAT32 a, b, c;
    PLLOUT_OBJ out_obj = {0};
    // struct hwtimer_ctrl_info info, info2;

    handle = PLLCfg(0.00003, PLL_LPF_WC, PLL_FREQ_KP, PLL_FREQ_KI, PLL_PI_LIMIT);

    //DELAY_US(100);
    a = 123.45;
    b = 456.45;
    c = 778.45;
    out_obj.ua_inv_sample = &a;
    out_obj.ub_inv_sample = &b;
    out_obj.uc_inv_sample = &c;

    GPIO_write(idx, 1);
    for (i = 0; i < 2; i++) {
        PLLCalc(&out_obj, handle, 0.00003);
    }
    GPIO_write(idx, 0);
}