Computational routine
eng


eye_scope

File content


/* Modnumlib Scicos interfacing function
 * Copyright (C) 2009-2011 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.
 */
 
/* eye_scope Scicos Eye diagram scope block
 *
 * - Based on Scilab NG routines
 *
 * Type 4 simulation function ver 1.0 - scilab-4.1
 * 17 Avril 2007 - INRIA - Author : A.Layec
 */

/* REVISION HISTORY :
 * $Log$
 */

/*Standarc C include*/
#include <stdio.h>
#include <string.h>
/*#include <../include/math.h>*/

/*for NG*/
#include "SetProperty.h"
#include "GetProperty.h"
#include "InitObjects.h"
#include "bcg.h"
#include "DrawObjects.h"
#include "BuildObjects.h"
#include "ObjectStructure.h"
#include "DestroyObjects.h"

/*Scicos block st include*/
#include "scicos_block.h"

/*Scilab include*/
#include "machine.h"

/*some macros*/
#ifndef min
 #define min(a,b) ((a) <= (b) ? (a) : (b))
#endif

#ifndef max
#define max(a,b) ((a) >= (b) ? (a) : (b))
#endif

#define PI0 (integer *) 0
#define PD0 (double *) 0

#define Abs(x) ( ( (x) >= 0) ? (x) : -( x) )

/*external functions*/
extern integer C2F(dr1)();
extern integer C2F(xgrid)();

/*work structure of that block*/
typedef struct work_st {
  long   hdl;    /*hdl of the NG scope*/
  int    wid;    /*wid of the NG scope*/
  /*y axis autoscale variables*/
  double y_up;
  double y_down;
  double y_delta;
  double *buf_in; /*input buffer*/
} work_struct;

/* eyeview_draw :
 *  Initialization and re-initialization
 *   of the eye_scope block
 */
void eyeview_draw(scicos_block *block)
{
 /*"fouretout" variables*/
 int i;

 /*variables to get rpar/ipar ptr*/
 double *rpar;
 int    *ipar;

 /*variables to store main parameters*/
 double xmin, xmax;
 double ymin, ymax;

 double Tse;

 int min_win;
 int max_win;

 /*graphic ptr variables*/
 char wnam[100];
 char x_label[30];
 char y_label[30];

 sciPointObj *pTemp;
 sciPointObj *pTemp2;
 sciPointObj *pPolyline;

 double *x_vect;
 double *y_vect;

 /*scope variables*/
 int nsubwin    =  1;
 int ncurves    =  1;
 int color      =  1;
 int line_size  =  1;
 int dim        =  2;

 int win_pos[2] = {-1,-1};
 int win_dim[2] = {-1,-1};

 int wid; /*the windows id*/
 int ne;
 int ns;
 int nt;

 /*ptr of the struct of that block*/
 work_struct *work;

 /*get he struct of that block*/
 work     = (work_struct*) *block->work;

 /*get rpar/ipar*/
 rpar = block->rpar;
 ipar = block->ipar;

 wid  = ipar[0];
 ne   = ipar[1]; /*samples per symbol*/
 ns   = ipar[2]; /*number of symbol*/
 nt   = ipar[3]; /*number of trace*/

 win_dim[0] = ipar[5];
 win_dim[1] = ipar[6];

 Tse     = rpar[0];
 ymin    = rpar[1];
 ymax    = rpar[2];

 min_win = 0;
 max_win = ne*ns;

 /* compute xmin/xmax bound of the scope */
 xmin = 0;
 xmax = ne*ns*Tse-Tse;

 /* get wid of the scope
  * and store it in my_st*/
 if (wid<0) {
   work->wid = 20000 + get_block_number();
 }
 else {
   work->wid = wid;
 }

 /* set title and axes labels of the scope
  */
 sprintf(wnam,"Eye diagram Scope (%d)",work->wid);
 /* axis labels */
 sprintf(x_label,"Time [s]"); /*x axis*/

 sprintf(y_label,"Level");

 /* Alocation/initialization of temporary x/y vectors
  * to build polyline
  */
 if ((x_vect=(double*)
       scicos_malloc(sizeof(double)*(ne*ns))) == NULL) {
        set_block_error(-16); return;
 }
 if ((y_vect=(double*)
       scicos_malloc(sizeof(double)*(ne*ns))) == NULL) {
        set_block_error(-16); return;
 }
 for(i=0;i<(ne*ns);i++) { /*init*/
   x_vect[i] = i*Tse;
   y_vect[i] = 0;
 }

 /* init NG scope
  */
 DeleteObjs(work->wid);
 sciSetUsedWindow(work->wid);
 pTemp = sciGetCurrentFigure();
 sciSetName(pTemp,wnam,strlen(wnam));
 pTemp2 = sciGetPointerFromHandle(sciGetHandle(sciGetSelectedSubWin(pTemp)));
 sciSetFontDeciWidth(pTemp2, 0);
 sciSetIsBoxed(pTemp2,TRUE);
 pSUBWIN_FEATURE(pTemp2)->tight_limits = TRUE;
 pSUBWIN_FEATURE(pTemp2)->WRect[0] = 0;
 pSUBWIN_FEATURE(pTemp2)->WRect[1] = 0;
 pSUBWIN_FEATURE(pTemp2)->WRect[2] = 1;
 pSUBWIN_FEATURE(pTemp2)->WRect[3] = 1;
 pSUBWIN_FEATURE(pTemp2)->axes.axes_visible[1] = TRUE;
 pSUBWIN_FEATURE(pTemp2)->SRect[2] = ymin;
 pSUBWIN_FEATURE(pTemp2)->SRect[3] = ymax;
 pSUBWIN_FEATURE(pTemp2)->axes.axes_visible[0] = TRUE;
 pSUBWIN_FEATURE(pTemp2)->SRect[0] = xmin;
 pSUBWIN_FEATURE(pTemp2)->SRect[1] = xmax;
 sciSetUsedWindow(work->wid);

 for(i=0;i<nt;i++) {
   pPolyline=ConstructPolyline(pTemp2,x_vect,y_vect,NULL,0,ne*ns,1,1, \
                               NULL,NULL,NULL,NULL,NULL,FALSE,FALSE,TRUE,FALSE);
   pPOLYLINE_FEATURE(pPolyline)->n1 = ne*ns;
   sciSetIsClipping(pPolyline, 0);
   sciSetForeground(pPolyline, color);
   sciSetIsLine(pPolyline, 1);
   sciSetIsMark(pPolyline, 0);
   sciSetLineWidth(pPolyline,line_size);
   sciSetMarkSize(pPolyline,line_size);
 }
 sciSetText(pSUBWIN_FEATURE(pTemp2)->mon_x_label,x_label,500);
 sciSetFontDeciWidth(pSUBWIN_FEATURE(pTemp2)->mon_x_label, 0);
 sciSetText(pSUBWIN_FEATURE(pTemp2)->mon_y_label,y_label,500);
 sciSetFontDeciWidth(pSUBWIN_FEATURE(pTemp2)->mon_y_label, 0);

 if (win_dim[0] >= 0) {
   sciSetDim(pTemp,  &win_dim[0], &win_dim[1]);
   sciSetDim(pTemp2, &win_dim[0], &win_dim[1]);
 }

 C2F(xgrid)((i=12,&i)); /*show grid*/
 sciDrawObj(pTemp); /*draw scope*/

 /*store hld in work_st to know if window has been closed
  * during simulation
  */
 work->hdl = sciGetHandle(pTemp);

 /*free vectors no more needed*/
 scicos_free(x_vect);
 scicos_free(y_vect);

 /***** end of the display part ****/
}

/* main routine */
void eye_scope(scicos_block *block,int flag)
{
 /*"fouretout" variables*/
 int i,k;

 double zero=0.0;

 /*variables to get block ptr*/
 int *ipar;
 double *u1;

 /*ptr of the struct of that block*/
 work_struct *work;

 /*counters and indicies variables*/
 int ne;
 int ns;
 int nt;
 int cnt_ne;
 int cnt_ns;
 int cnt_nt;
 int inc_ns;
 int inc_nt;
 int ind_gr;
 int ind_in;
 int insz;

 /*some scope parameters*/
 int scaltyp; /*0:ymin/ymax/1:autoscale*/

 /*autoscale variables*/
 double min_y;
 double max_y;
 double y_height;
 double y_delta;
 double y_up;
 double y_down;
 double fact=0.4;

 /*graphic ptr variables*/
 sciPointObj *pTemp;
 sciPointObj *pTemp2;
 sciPointObj *pPolyline;
 sciSons *MySon;

 /*get block ptr*/
 ipar = block->ipar;
 u1   = block->inptr[0];

 /*get ipar variables*/
 ne      = ipar[1]; /*samples per symbol*/
 ns      = ipar[2]; /*number of symbol*/
 nt      = ipar[3]; /*number of trace*/
 scaltyp = ipar[4];

 /*ptr of the struct of that block*/
 work   = (work_struct*) *block->work;

 /*get size of input ports*/
 insz = block->insz[0];

 /*get counters value*/
 cnt_ne = (int)block->z[0];
 cnt_ns = (int)block->z[1];
 cnt_nt = (int)block->z[2];
 ind_gr = (int)block->z[3];

 if(flag==4) { /*flag 4*/

  if ((work=(work_struct*) /*my_st*/
        scicos_malloc(sizeof(work_struct))) == NULL) {
         set_block_error(-16); return;
  }

  if ((work->buf_in=(double *) /*input buffer*/
        scicos_malloc(sizeof(double)*(ne*ns*nt))) == NULL) {
         set_block_error(-16); return;
  }

  /*init. autoscale y axis bound*/
  work->y_up=1;
  work->y_down=0;
  work->y_delta=1;

  *block->work=(void *)work; /*store my_st in *block->work*/

  eyeview_draw(block); /*call specview_draw for initialization*/
 }

 else if(flag==2) { /*flag 2*/

  cnt_ne +=insz;
  if ( (cnt_ne) >= ne ){
    inc_ns = 0;
    while ( (cnt_ne) >= ne ) {
      inc_ns++;
      /*adjust number of samples counter*/
      cnt_ne -= ne;
    }
    cnt_ns += inc_ns;
    if ( (cnt_ns) >= ns ) {
      inc_nt = 0;
      while ( (cnt_ns) >= ns ) {
        inc_nt++;
        /*adjust number of symbol counter*/
        cnt_ns -= ns;
      }
      cnt_nt += inc_nt;
      if ( (cnt_nt) >= nt ) {
        ind_in = 0;

        while ( (cnt_nt) >= nt ) {
          /*complete input buffer*/
          for(i=ind_in;i<(ind_in + (ne*ns*nt) - ind_gr);i++) {
            work->buf_in[ind_gr+i-ind_in] = u1[i];
          }

          /*adjust in port size index*/
          ind_in = ind_in + ((ne*ns*nt) - ind_gr);
          /*adjust input buffer index*/
          ind_gr = 0;
          /*adjust number of traces counter*/
          cnt_nt -= nt;
        }

        /*-------------display part-------------*/
        /*--------------------------------------*/

        /*if window has been destroyed, then redraw it*/
        if (sciGetPointerFromHandle(work->hdl) == NULL) {
           eyeview_draw(block);
        }

        sciSetUsedWindow(work->wid);
        pTemp = sciGetCurrentFigure();
        pTemp2 = sciGetPointerFromHandle(sciGetHandle(sciGetSelectedSubWin(pTemp)));
        MySon = (sciGetRelationship (pTemp2)->psons);

        /*autoscale*/
        if (scaltyp==1) {
          min_y = work->buf_in[0];
          max_y = min_y;
          for(i=0;i<nt;i++) {
            pPolyline = MySon->pointobj;

            for(k=0;k<(ne*ns);k++) {
              pPOLYLINE_FEATURE(pPolyline)->pvy[k] = work->buf_in[i*(ne*ns)+k];
              min_y=min(min_y,pPOLYLINE_FEATURE(pPolyline)->pvy[k]);
              max_y=max(max_y,pPOLYLINE_FEATURE(pPolyline)->pvy[k]);
            }

            MySon = MySon->pnext;
          }

          y_height = max_y - min_y;
          y_delta  = min_y + y_height/2; /*also equal to max_y-y_height/2*/
          y_down   = y_delta - (1+fact) * y_height/2;
          y_up     = y_delta + (1+fact) * y_height/2;

          /*fprintf(stderr,"max_y = %f, min_y=%f\n",max_y,min_y);*/
          /*fprintf(stderr,"y_height = %f, y_delta=%f, y_down=%f, y_up=%f\n",y_height,y_delta,y_down,y_up);*/

          if ( (((1+fact) * y_height/2) > (1+fact) * work->y_delta) || \
               (((1+fact) * y_height/2) < (1-fact) * work->y_delta) ) {
            work->y_delta = ( (1+fact) * y_height/2);
            work->y_up = y_up;
            work->y_down = y_down;
          }

          /*fprintf(stderr,"fact = %f, work->y_delta=%f, work->y_down=%f, work->y_up=%f\n",fact,work->y_delta,work->y_down,work->y_up);*/

          pSUBWIN_FEATURE(pTemp2)->SRect[2] = work->y_down;
          pSUBWIN_FEATURE(pTemp2)->SRect[3] = work->y_up;

        }
        else {
          for(i=0;i<nt;i++) {
            pPolyline = MySon->pointobj;

            for(k=0;k<(ne*ns);k++) {
              pPOLYLINE_FEATURE(pPolyline)->pvy[k] = work->buf_in[i*(ne*ns)+k];
            }

            MySon = MySon->pnext;
          }
        }

        sciDrawObj(pTemp2); /*draw axes*/
        /*miscellaenous part to disable glitter of scope*/
        C2F(dr1)("xset","wwpc",PI0,PI0,PI0,PI0,PI0,PI0, \
                  PD0,PD0,PD0,PD0,0L,0L);  /*clear pixmap*/
        pFIGURE_FEATURE(pTemp)->pixmap=1; /*set pixmap mode*/
        C2F(xgrid)((i=12,&i)); /*draw grid in the pixmap*/
        C2F(dr1)("xset","wshow",PI0,PI0,PI0,PI0,PI0,PI0, \
                  PD0,PD0,PD0,PD0,0L,0L); /*show the pixmap*/
        pFIGURE_FEATURE(pTemp)->pixmap = 0; /*unset pixmap mode*/

        /*--------------------------------------*/
        /*--------------------------------------*/

        /*store data from input port in input buffer*/
        for(i=ind_in;i<insz;i++) {
          work->buf_in[ind_gr+(i-ind_in)] = u1[i];
        }
      }
      else {
        /*store data from input port in input buffer*/
        for(i=0;i<insz;i++) {
          work->buf_in[ind_gr+i] = u1[i];
        }
      }
    }
    else {
      /*store data from input port in input buffer*/
      for(i=0;i<insz;i++) {
        work->buf_in[ind_gr+i] = u1[i];
      }
    }
  }
  else {
    /*store data from input port in input buffer*/
    for(i=0;i<insz;i++) {
      work->buf_in[ind_gr+i] = u1[i];
    }
  }

  /*update index of input buffer*/
  ind_gr = cnt_ne + cnt_ns*ne + cnt_nt*ns*ne;

  /*save counter an index values in dstate*/
  block->z[0] = (double)cnt_ne;
  block->z[1] = (double)cnt_ns;
  block->z[2] = (double)cnt_nt;
  block->z[3] = (double)ind_gr;

 }

 else if (flag==5) { /*flag 5*/
  if (work!=NULL) {
    scicos_free(work->buf_in);
  }
  scicos_free(work);
 }

}