1 /* Copyright (C) 2013 Czech Technical University in Prague
4 * - Carlos Jenkins <carlos@jenkins.co.cr>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * File : sfunction_lout.c
21 * C-MEX S-function block for RPP digital output.
24 * mdlCheckParameters() : sfunctions.pdf p. 421
25 * mdlInitializeSizes() : sfunctions.pdf p. 441
26 * mdlInitializeSampleTimes() : sfunctions.pdf p. 436
27 * mdlSetWorkWidths() : sfunctions.pdf p. 489
28 * mdlStart() : sfunctions.pdf p. 492
29 * mdlOutputs() : sfunctions.pdf p. 447
30 * mdlTerminate() : sfunctions.pdf p. 493
31 * mdlRTW() : sfunctions.pdf p. 458
33 * Compile with <matlabroot>/bin/mex -v -g sfunction_lout.c
38 * Must specify the S_FUNCTION_NAME as the name of the S-function.
40 #define S_FUNCTION_NAME sfunction_lout
41 #define S_FUNCTION_LEVEL 2
44 * Include common header and utilities
48 #define MDL_CHECK_PARAMETERS
49 #if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
51 /* Function: mdlCheckParameters ================================================
53 * mdlCheckParameters verifies new parameter settings whenever parameter
54 * change or are re-evaluated during a simulation. When a simulation is
55 * running, changes to S-function parameters can occur at any time during
56 * the simulation loop.
58 static void mdlCheckParameters(SimStruct *S)
61 * Check the parameter 1
64 int_T dimsArray[2] = { 1, 1 };
66 /* Check the parameter attributes */
67 ssCheckSFcnParamValueAttribs(S, 0, "P1", DYNAMICALLY_TYPED, 2, dimsArray, 0);
71 * Check the parameter 2 (sample time)
74 const double * sampleTime = NULL;
75 const size_t stArraySize = mxGetM(SAMPLE_TIME) * mxGetN(SAMPLE_TIME);
77 /* Sample time must be a real scalar value or 2 element array. */
78 if (IsRealMatrix(SAMPLE_TIME) &&
79 (stArraySize == 1 || stArraySize == 2) ) {
80 sampleTime = mxGetPr(SAMPLE_TIME);
83 "Invalid sample time. Sample time must be a real scalar value or an array of two real values.");
87 if (sampleTime[0] < 0.0 && sampleTime[0] != -1.0) {
89 "Invalid sample time. Period must be non-negative or -1 (for inherited).");
93 if (stArraySize == 2 && sampleTime[0] > 0.0 &&
94 sampleTime[1] >= sampleTime[0]) {
96 "Invalid sample time. Offset must be smaller than period.");
100 if (stArraySize == 2 && sampleTime[0] == -1.0 && sampleTime[1] != 0.0) {
102 "Invalid sample time. When period is -1, offset must be 0.");
106 if (stArraySize == 2 && sampleTime[0] == 0.0 &&
107 !(sampleTime[1] == 1.0)) {
109 "Invalid sample time. When period is 0, offset must be 1.");
117 /* Function: mdlInitializeSizes ================================================
119 * The sizes information is used by Simulink to determine the S-function
120 * block's characteristics (number of inputs, outputs, states, etc.).
122 static void mdlInitializeSizes(SimStruct *S)
124 /* Number of expected parameters */
125 ssSetNumSFcnParams(S, 2);
127 #if defined(MATLAB_MEX_FILE)
129 if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
131 * If the number of expected input parameters is not equal
132 * to the number of parameters entered in the dialog box return.
133 * Simulink will generate an error indicating that there is a
134 * parameter mismatch.
136 mdlCheckParameters(S);
137 if (ssGetErrorStatus(S) != NULL) {
141 /* Return if number of expected != number of actual parameters */
147 /* Set the parameter's tunable status */
148 ssSetSFcnParamTunable(S, 0, 1);
149 ssSetSFcnParamTunable(S, 1, 0);
153 if (!ssSetNumDWork(S, 0))
157 * Set the number of input ports.
159 if (!ssSetNumInputPorts(S, 1))
163 * Configure the input port 1
165 ssSetInputPortDataType(S, 0, SS_UINT8);
166 ssSetInputPortWidth(S, 0, 1);
167 ssSetInputPortComplexSignal(S, 0, COMPLEX_NO);
168 ssSetInputPortDirectFeedThrough(S, 0, 1);
169 ssSetInputPortAcceptExprInRTW(S, 0, 1);
170 ssSetInputPortOverWritable(S, 0, 1);
171 ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
172 ssSetInputPortRequiredContiguous(S, 0, 1);
175 * Set the number of output ports.
177 if (!ssSetNumOutputPorts(S, 0))
181 * This S-function can be used in referenced model simulating in normal mode.
183 ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK);
186 * Set the number of sample time.
188 ssSetNumSampleTimes(S, 1);
191 * All options have the form SS_OPTION_<name> and are documented in
192 * matlabroot/simulink/include/simstruc.h. The options should be
193 * combined with bitwise OR as in
194 * ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))
197 SS_OPTION_USE_TLC_WITH_ACCELERATOR |
198 SS_OPTION_CAN_BE_CALLED_CONDITIONALLY |
199 SS_OPTION_EXCEPTION_FREE_CODE |
200 SS_OPTION_WORKS_WITH_CODE_REUSE |
201 SS_OPTION_SFUNCTION_INLINED_FOR_RTW |
202 SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME);
205 /* Function: mdlInitializeSampleTimes ==========================================
207 * This function is used to specify the sample time(s) for your
208 * S-function. You must register the same number of sample times as
209 * specified in ssSetNumSampleTimes.
211 static void mdlInitializeSampleTimes(SimStruct *S)
213 double * const sampleTime = mxGetPr(SAMPLE_TIME);
214 const size_t stArraySize = mxGetM(SAMPLE_TIME) * mxGetN(SAMPLE_TIME);
215 ssSetSampleTime(S, 0, sampleTime[0]);
216 if (stArraySize == 1) {
217 ssSetOffsetTime(S, 0, (sampleTime[0] == CONTINUOUS_SAMPLE_TIME?
218 FIXED_IN_MINOR_STEP_OFFSET: 0.0));
220 ssSetOffsetTime(S, 0, sampleTime[1]);
223 #if defined(ssSetModelReferenceSampleTimeDefaultInheritance)
225 ssSetModelReferenceSampleTimeDefaultInheritance(S);
231 #define MDL_SET_WORK_WIDTHS
232 #if defined(MDL_SET_WORK_WIDTHS) && defined(MATLAB_MEX_FILE)
234 /* Function: mdlSetWorkWidths ==================================================
236 * The optional method, mdlSetWorkWidths is called after input port
237 * width, output port width, and sample times of the S-function have
238 * been determined to set any state and work vector sizes which are
239 * a function of the input, output, and/or sample times.
241 * Run-time parameters are registered in this method using methods
242 * ssSetNumRunTimeParams, ssSetRunTimeParamInfo, and related methods.
244 static void mdlSetWorkWidths(SimStruct *S)
246 /* Set number of run-time parameters */
247 if (!ssSetNumRunTimeParams(S, 1))
251 * Register the run-time parameter 1
253 ssRegDlgParamAsRunTimeParam(S, 0, 0, "p1", ssGetDataTypeId(S, "uint8"));
259 #if defined(MDL_START)
261 /* Function: mdlStart ==========================================================
263 * This function is called once at start of model execution. If you
264 * have states that should be initialized once, this is the place
267 static void mdlStart(SimStruct *S)
274 /* Function: mdlOutputs ========================================================
276 * In this function, you compute the outputs of your S-function
277 * block. Generally outputs are placed in the output vector(s),
278 * ssGetOutputPortSignal.
280 static void mdlOutputs(SimStruct *S, int_T tid)
283 UNUSED_PARAMETER(tid);
286 /* Function: mdlTerminate ======================================================
288 * In this function, you should perform any actions that are necessary
289 * at the termination of a simulation.
291 static void mdlTerminate(SimStruct *S)
297 #if defined(MATLAB_MEX_FILE) && defined(MDL_RTW)
299 /* Function: mdlRTW ============================================================
301 * This function is called when the Real-Time Workshop is generating
302 * the model.rtw file.
304 static void mdlRTW(SimStruct *S)
313 * Required S-function trailer
315 #ifdef MATLAB_MEX_FILE
316 # include "simulink.c"
318 # include "cg_sfun.h"