Computational routine
eng


vco_c

File content


/* vco Scicos discrete VCO block with frequency divider
 * Type 4 simulation function ver 1.0 - scilab-4.1
 * 21 Mars 2007 - INRIA - Author : A.Layec
 */
#include <math.h>

#include "modnum_lib.h"
#include "scicos_block.h"

#ifndef M_PI
#define M_PI		3.14159265358979323846
#endif
/*
 * ys(t)  = cos(wot + phi(t))
 *
 * phi(t) = int(F(u3(t) + w(t))dt)
 *
 */

void vco_c(scicos_block *block,int flag)
{
 int i,k;

 double *u1;
 double *u2;
 double *u3;
 double *u__1;
 double *y;
 /*double *y10;*/

 double w__n;    /* white noise on input */
 double *phi__n; /* phase noise */

 double h;
 double omega;
 double *theta;
 double *theta2;

 double kv;
 double alpha;
 double beta;
 double gamma;
 double sigma;

 double *f__u;

 double *cnt;
 double *err;
 double *err2;

 double cross_val;
 double cross_val2;

 int with_dyncross;
 int with_infunc;
 int with_2evout;
 int with_wnoise; /* white noise on input */
 int with_pnoise; /* phase noise */

 u1 = block->inptr[0];  /* input voltage */
 u2 = block->inptr[1];  /* divider value or phase noise*/
 u3 = block->inptr[2];  /* phase noise*/

 y = block->outptr[0]; /* cos(theta) */

 h          = block->rpar[0];
 omega      = block->rpar[1];
 cross_val  = block->rpar[2];
 cross_val2 = block->rpar[3];

 kv    = block->rpar[4];
 alpha = block->rpar[5];
 beta  = block->rpar[6];
 gamma = block->rpar[7];
 sigma = block->rpar[8];

 with_dyncross = block->ipar[0];
 with_infunc   = block->ipar[1];
 with_2evout   = block->ipar[2];
 with_wnoise   = block->ipar[3];
 with_pnoise   = block->ipar[4];

 cnt    = &block->z[0];
 theta  = &block->z[1];
 theta2 = &block->z[2];

 u__1   = &block->z[3]; /* last input */
 err    = &block->z[4]; /* last phase */
 err2   = &block->z[5]; /* last phase */
 f__u   = &block->z[6]; /* last theta */
 phi__n = &block->z[7]; /* phase noise */

 /* compute output */
 if(flag==1) {

   /* get input */
   (*f__u) = u1[0];

   if (with_infunc!=0) {
     (*f__u) = alpha * tanh(beta * (*f__u));
   }

   (*f__u) = (*f__u) * kv;

   /* get white noise on input */
   w__n = 0;

   if (with_wnoise!=0) {
     noiseblk_c((i=1,&i),(k=1,&k),\
                &sigma,&gamma,&w__n);
   }

   (*f__u) = (*f__u) + w__n;

   /* get phase noise */
   (*phi__n) = 0;

   if (with_pnoise!=0) {
     if(with_dyncross!=0) {
       (*phi__n) = u3[0];
     }
     else {
       (*phi__n) = u2[0];
     }
     /* test on phase noise */
     if (((*phi__n) >= (M_PI/4))||((*phi__n) <= -(M_PI/4))) {
       set_block_error(-6);
       return;
     }
   }

   /* compute theta */
   (*theta) = (*err) + \
              h * omega + \
              (h/2) * ((*f__u) + (*u__1)) + \
              (*phi__n);

    if(with_2evout!=0) {
     (*theta2) = (*err2) + \
                 h * omega + \
                 (h/2) * ((*f__u) + (*u__1)) + \
                 (*phi__n);
    }

   y[0] = cos(*theta);

   /* store input */
   (*u__1) = (*f__u);

 }

 /* compute date of crossing */
 else if(flag==3) {

   if(with_dyncross!=0) {
    cross_val = cross_val * u2[0];
   }

   if((*theta) >= cross_val) {
     block->evout[0] = ((cross_val - (*err)) * h) / ((*theta) - (*err));
   }

   (*err) = (*theta) - (*phi__n);

   if( (*err) >= cross_val) {
     (*err) = (*err) - cross_val;
   }

   if(with_2evout!=0) {
     if((*theta2) >= cross_val2) {
      block->evout[1] = ((cross_val2 - (*err2)) * h) / ((*theta2) - (*err2));
     }

     (*err2) = (*theta2) - (*phi__n);

     if( (*err2) >= cross_val2) {
      (*err2) = (*err2) - cross_val2;
     }
   }

 }
}