/* Modnumlib Scicos interfacing function * Copyright (C) 2009 Alan Layec * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* 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 <stdio.h> #include "modnum_lib.h" #include "scicos_block.h" /* * ys(t) = cos(wot + phi(t)) * * phi(t) = int(F(u3(t) + w(t))dt) * */ void vcoblk(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 thetay; double theta2y; double kv; double alpha; double beta; double gamma; double sigma; double f__u; 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]; /*not needed*/ /*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 */ w__n = &block->z[6]; /* white noise */ /* not needed */ /*phi__n = &block->z[7];*/ /* phase noise */ switch(flag) { /* compute output */ case 6 : case 1 : /* get input */ f__u = u1[0]; if (with_infunc!=0) { f__u = alpha * tanh(beta * f__u); } /* 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 */ vcoy_c((i=1,&i),&f__u,&h,&omega,&kv, \ w__n,&phi__n,err,u__1,&thetay); if(with_2evout!=0) { vcoy_c((i=1,&i),&f__u,&h,&omega,&kv, \ w__n,&phi__n,err2,u__1,&theta2y); } y[0] = cos(thetay); break; /* compute discrete state */ case 4 : case 2 : /* get input */ f__u = u1[0]; if (with_infunc!=0) { f__u = alpha * tanh(beta * f__u); } /* 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; } } if(with_dyncross!=0) { cross_val = cross_val * u2[0]; } /* compute theta, store input, compute err */ if(with_2evout!=0) { vcoy_c((i=1,&i),&f__u,&h,&omega,&kv, \ w__n,&phi__n,err2,u__1,theta2); vcoz_c((i=1,&i),&f__u,&h,&omega,&kv, \ &cross_val,w__n,&phi__n,err,u__1,theta); (*err2) = (*theta2) - phi__n; if( (*err2) >= cross_val2) { (*err2) = (*err2) - cross_val2; } } else { vcoz_c((i=1,&i),&f__u,&h,&omega,&kv, \ &cross_val,w__n,&phi__n,err,u__1,theta); } if (with_wnoise!=0) { noiseblk_c((i=1,&i),(k=1,&k),&sigma,&gamma,w__n); } break; /* compute date of crossing */ case 3 : /* get input */ f__u = u1[0]; if (with_infunc!=0) { f__u = alpha * tanh(beta * f__u); } /* 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; } } if(with_dyncross!=0) { cross_val = cross_val * u2[0]; } /* compute theta */ vcoy_c((i=1,&i),&f__u,&h,&omega,&kv, \ w__n,&phi__n,err,u__1,&thetay); if((thetay) >= cross_val) { block->evout[0] = ((cross_val - (*err)) * h) / ((thetay) - (*err)); } if(with_2evout!=0) { vcoy_c((i=1,&i),&f__u,&h,&omega,&kv, \ w__n,&phi__n,err2,u__1,&theta2y); if((theta2y) >= cross_val2) { block->evout[1] = ((cross_val2 - (*err2)) * h) / ((theta2y) - (*err2)); } } break; /* finish */ case 5 : break; default : break; } }