www.pudn.com > communicationmatlab.rar > REGSHIFT.C


/* 
 * REGSHIFT   A SIMULINK trigged register_buff shift 
 * 
 *           Syntax:  [sys, x0] = regshift(t,x,u,flag,outDelay,tirgThreshold) 
 *  This function has two inputs and number of outputs. The first input is 
 *  the signal to be stored and output. The second signal is the clock pulse. 
 *  The function refresh its register_buff and output only at the raising edge of 
 *  the clock pulse. The function assign maximum delay number in outDelay as its 
 *  register numebr. When the function finish refreshing all register, it is 
 *  call a cycle. 
 * 
 *  outDelay is a scalar or vector which contains integers of desired delay 
 *           steps from the input. The size of the vector determines the 
 *           size of the output. 
 *  trigThreshold is the threshold in detecting the raising edge of the clock 
 *          pulse. 
 *  the size of the output of this function is the size of outDelay pulse one. 
 *  Each output element outputs the delay step as indicated in the corrsponding 
 *  value in outDelay. The last output is zero. It is one only at the time when 
 *  the register_buff and output are triggered in a complete cycle (a cycle of 
 *  complete a refresh cycle). The pulse keeps the same length as the input 
 *  trigger pulse. 
 * 
 * Wes Wang  August 22, 1994 
 * Copyright (c) 1994-96 by The MathWorks, Inc. 
 * All Rights Reserved 
 * $Revision: 1.1 $  $Date: 1996/04/01 19:03:56 $ 
 */ 
 
#define S_FUNCTION_NAME regshift 
 
#include     /* needed for declaration of sprintf */ 
 
#ifdef MATLAB_MEX_FILE 
#include "mex.h"      /* needed for declaration of mexErrMsgTxt */ 
#endif 
 
/* 
 * need to include simstruc.h for the definition of the SimStruct and 
 * its associated macro definitions. 
 */ 
 
#include "simstruc.h" 
 
/* 
 * Defines for easy access of the input parameters 
 */ 
 
#define NUM_ARGS   2 
#define REGISTER_DELAY ssGetArg(S,0) 
#define TRIG_THRESHOLD     ssGetArg(S,1) 
 
/* 
 * mdlInitializeSizes - called to initialize the sizes array stored in 
 *                      the SimStruct.  The sizes array defines the 
 *                      characteristics (number of inputs, outputs, 
 *                      states, etc.) of the S-Function. 
 */ 
 
static void mdlInitializeSizes(S) 
    SimStruct *S; 
{ 
    /* 
     * Set-up size information. 
     */  
     
    if (ssGetNumArgs(S) == NUM_ARGS) { 
      int i, regDelay, numOutput, maxDelay; 
/*    char    err_msg[256]; 
 */ 
     numOutput = mxGetN(REGISTER_DELAY) * mxGetM(REGISTER_DELAY); 
    if (numOutput < 1) { 
#ifdef MATLAB_MEX_FILE 
      char err_msg[256]; 
      sprintf(err_msg, "Output buffer is empty"); 
     mexErrMsgTxt(err_msg); 
           
#endif   
        } 
        
        maxDelay = 1; 
   for(i=0; i regDelay) ? maxDelay : regDelay; 
        } 
/*    sprintf(err_msg, "From initialization maxDelay %d, numOutput %d.\n", maxDelay, numOutput); 
    mexPrintf(err_msg); 
 */ 
     ssSetNumContStates(    S, 0); 
   ssSetNumDiscStates(    S, 0); 
   ssSetNumInputs(        S, 2); 
   ssSetNumOutputs(       S, 1 + numOutput); 
       ssSetDirectFeedThrough(S, 1); 
   ssSetNumInputArgs(     S, NUM_ARGS); 
    ssSetNumSampleTimes(   S, 1); 
   ssSetNumRWork(         S, maxDelay+1); 
  ssSetNumIWork(         S, 2); 
   ssSetNumPWork(         S, 0); 
    } else { 
#ifdef MATLAB_MEX_FILE 
 char err_msg[256]; 
      sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.\n" 
             "%d input arguments were passed in when expecting %d input arguments.\n", ssGetNumArgs(S) + 4, NUM_ARGS + 4); 
   mexErrMsgTxt(err_msg); 
#endif 
    } 
} 
 
/* 
 * mdlInitializeSampleTimes - initializes the array of sample times stored in 
 *                            the SimStruct associated with this S-Function. 
 */ 
 
static void mdlInitializeSampleTimes(S) 
    SimStruct *S; 
{ 
    /* 
     * Note, blocks that are continuous in nature should have a single 
     * sample time of 0.0. 
     */ 
 
    ssSetSampleTimeEvent(S, 0, 0.0); 
    ssSetOffsetTimeEvent(S, 0, 0.0); 
} 
 
/* 
 * mdlInitializeConditions - initializes the states for the S-Function 
 */ 
 
static void mdlInitializeConditions(x0, S) 
    double *x0; 
    SimStruct *S; 
{ 
    double *register_buff       = ssGetRWork(S); 
 
    int    *regIndex       = ssGetIWork(S); 
    int    *lastTrig       = ssGetIWork(S) + 1;     
 
    int     numOutput      = ssGetNumOutputs(S); 
    int     maxDelay       = ssGetNumRWork(S) - 1; 
     
    double *lastTime       = ssGetRWork(S) + maxDelay; 
     
    int i; 
     
    /*  
     * Initialize the register_buff to all zeros. 
     */ 
     
    for (i = 0; i < maxDelay; i++) 
     *register_buff++ = 0.0; 
 
    /* 
     * Initialize the current buffer position and buffer start 
     */ 
     
    *regIndex       = 0; 
    *lastTrig       = 0; 
    *lastTime       = -1.0; 
} 
 
/* 
 * mdlOutputs - computes the outputs of the S-Function 
 */ 
 
static void mdlOutputs(y, x, u, S, tid) 
    double *y, *x, *u; 
    SimStruct *S; 
    int tid; 
{ 
    double *register_buff        = ssGetRWork(S); 
    double  trigThreshold   = mxGetPr(TRIG_THRESHOLD)[0]; 
    int    *regIndex        = ssGetIWork(S); 
    int    *lastTrig        = ssGetIWork(S) + 1;     
    int     numOutput       = ssGetNumOutputs(S) - 1; 
    int     maxDelay        = ssGetNumRWork(S) - 1; 
    double *lastTime        = ssGetRWork(S) + maxDelay; 
     
    int     i, outnum; 
    double  currentTime     = ssGetT(S); 
 
/*    char    err_msg[256]; 
    sprintf(err_msg, "**MAXDELAY %d, u[1] %f, *lastTrig %d, thrshold %f, time %f.\n", maxDelay, u[1], *lastTrig, trigThreshold, currentTime); 
    mexPrintf(err_msg);     
 */ 
    /* 
     * acquire the buffer data 
     */ 
 
    if ((u[1] >= trigThreshold) & (*lastTrig == 0)) { 
 
        for (i = 0; i < numOutput; i++) { 
            outnum = mxGetPr(REGISTER_DELAY)[i]; 
 
            if (outnum == 0) 
                y[i] = *u; 
            else 
                y[i] = register_buff[(maxDelay + *regIndex - outnum) % maxDelay]; 
        } 
        if (*regIndex == 0) 
            y[numOutput] = 1.0; 
        else 
            y[numOutput] = 0.0; 
         
        register_buff[(*regIndex)++] = *u; 
        *regIndex %= maxDelay; 
        *lastTrig = 1; 
        *lastTime = currentTime; 
     } else { 
            if (currentTime <= 0.0) { 
            for (i = 0; i < numOutput; i++) 
                y[i] = 0.0; 
     } else if ((currentTime - *lastTime) / currentTime < 0.00000001) { 
      /* keep the most recent change in the buffer */ 
         /* this is backup the case when there are tow calls at the same time. 
            * the two values of the same time are different. 
        * This is assume the time variable is always increasing 
         */ 
 
         if (u[1] >= trigThreshold) { 
                int backIndex; 
/*                char    err_msg[256]; 
*/ 
                 backIndex = *regIndex - 1; 
              if (backIndex < 0) 
                  backIndex = maxDelay - 1;                 
 
/*                sprintf(err_msg, "backIndex %d, regIndex %d, maxDelay %d\n", backIndex, *regIndex, maxDelay); 
                mexPrintf(err_msg); 
 */               
/*                sprintf(err_msg, "currentTime %f, lastTime %f, current u %f, last u %f\n", currentTime, *lastTime, *u, register_buff[backIndex]); 
                mexPrintf(err_msg); 
 */                    
                for (i = 0; i < numOutput; i++) { 
 
                    outnum = mxGetPr(REGISTER_DELAY)[i]; 
/*          sprintf(err_msg, "outnum %d, modulo(outnum)%d\n", outnum, (maxDelay + backIndex - outnum) % maxDelay); 
            mexPrintf(err_msg); 
 */ 
                    if (outnum == 0) 
                        y[i] = *u; 
/*                    else 
                        y[i] = register_buff[(maxDelay + backIndex - outnum) % maxDelay]; 
 */                         
                } 
                if (backIndex == 0) 
                    y[numOutput] = 1.0; 
                else 
                    y[numOutput] = 0.0;          
 
                    register_buff[backIndex] = *u; 
              } 
           } 
           if (*lastTrig == 1) { 
               if (u[1] < trigThreshold) { 
                 *lastTrig = 0; 
                y[numOutput] = 0.0; 
            } 
          } 
   } 
} 
 
/* 
 * mdlUpdate - computes the discrete states of the S-Function 
 */ 
 
static void mdlUpdate(x, u, S, tid) 
    double *x, *u; 
    SimStruct *S; 
    int tid; 
{ 
} 
 
/* 
 * mdlDerivatives - computes the derivatives of the S-Function 
 */ 
 
static void mdlDerivatives(dx, x, u, S, tid) 
    double *dx, *x, *u; 
    SimStruct *S; 
    int tid; 
{ 
} 
 
/* 
 * mdlTerminate - called at termination of model execution. 
 */ 
 
static void mdlTerminate(S) 
    SimStruct *S; 
{ 
} 
 
#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */ 
#include "simulink.c"      /* MEX-File interface mechanism */ 
#else 
#include "cg_sfun.h"       /* Code generation registration function */ 
#endif