/* 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; } } } }