/*
 * SNSAMPLE  N-Sample Enable block.
 * DSP Blockset S-Function which outputs TRUE (1) for first N samples;
 * thereafter, outputs FALSE (0).
 * This SIMULINK S-function is called by the N-Sample Enable block in the
 * DSP Blockset.
 *
 * Syntax:  [sys, x0] = snsample(t,x,u,flag, N,Ts);
 *
 *  Copyright 1995-2000 The MathWorks, Inc.
 *  $Revision: 1.11 $  $Date: 2000/06/14 14:28:01 $
 */

#define S_FUNCTION_NAME snsample

#include "dsp_sim.h"

/*
 * Defines for easy access of the input parameters
 */
#define NUM_ARGS        2
#define TARGETCNT_ARG   ssGetArg(S,0)
#define SAMPLETIME_ARG  ssGetArg(S,1)

/*
 * IWork indices:
 */
#define CURRCNT_IDX   0
#define TARGETCNT_IDX 1


#ifdef MATLAB_MEX_FILE
#define MDL_CHECK_PARAMETERS
static void mdlCheckParameters(SimStruct *S) {
    const char *msg = NULL;
    real_T d;
    int_T  i;

    if ((mxGetN(TARGETCNT_ARG) != 1) || (mxGetM(TARGETCNT_ARG) != 1)) {
        msg = "The sample count must be a scalar";
        goto FCN_EXIT;
    }
    d = mxGetPr(TARGETCNT_ARG)[0];
    i = (int_T)d;
    if ((d!=i) || (d<0)) {
        msg = "The sample count must be a positive integer.";
        goto FCN_EXIT;
    }

    if ( (mxGetM(SAMPLETIME_ARG) != 1) ||
         (mxGetN(SAMPLETIME_ARG) != 1) && (mxGetN(SAMPLETIME_ARG) != 2)
       ) {
        msg = "The sample time must be a scalar or a 2-element row vector";
        goto FCN_EXIT;
    }

FCN_EXIT:
    ssSetErrorStatus(S, msg);
}
#endif



static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(    S, NUM_ARGS);

#if defined(MATLAB_MEX_FILE)
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;
    mdlCheckParameters(S);
    if (ssGetErrorStatus(S) != NULL) return;
#endif

    ssSetNumInputs(        S, 0);
    ssSetNumOutputs(       S, 1);
    ssSetDirectFeedThrough(S, 0);
    ssSetNumSampleTimes(   S, 1);
    ssSetNumIWork(         S, 2);
    ssSetOptions(          S, SS_OPTION_EXCEPTION_FREE_CODE);
}


static void mdlInitializeSampleTimes(SimStruct *S)
{
    real_T sampleTime = mxGetPr(SAMPLETIME_ARG)[0];
    real_T offsetTime = (mxGetN(SAMPLETIME_ARG) == 1)
                      ? 0.0 : mxGetPr(SAMPLETIME_ARG)[1];
    ssSetSampleTimeEvent(S, 0, sampleTime);
    ssSetOffsetTimeEvent(S, 0, offsetTime);
}


static void mdlInitializeConditions(real_T *x0, SimStruct *S)
{

    /* Initialize the target and current sample counts: */
    ssSetIWorkValue(S, TARGETCNT_IDX, (int_T)(mxGetPr(TARGETCNT_ARG)[0]));
    ssSetIWorkValue(S, CURRCNT_IDX, 0);
}


static void mdlOutputs(real_T *y, const real_T *x, const real_T *u, 
                       SimStruct *S, int_T tid)
{
    int_T *sample_cnt = ssGetIWork(S) + CURRCNT_IDX;
    if (*sample_cnt == ssGetIWorkValue(S, TARGETCNT_IDX)) {
        *y = 0.0;
    } else {
        *y = 1.0;
        ++(*sample_cnt);
    }
}


static void mdlUpdate(real_T *x, const real_T *u, SimStruct *S, int_T tid)
{
}

static void mdlDerivatives(real_T *dx, const real_T *x, const real_T *u, 
                           SimStruct *S, int_T tid)
{
}

static void mdlTerminate(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
