]> rtime.felk.cvut.cz Git - pes-rpp/rpp-simulink.git/blobdiff - rpp/blocks/sfunction_din.c
Change license to MIT
[pes-rpp/rpp-simulink.git] / rpp / blocks / sfunction_din.c
index fafd98e0d763fcfaa66e58cca850c0b486dc902b..9889ca319fddba281cd6eb403c855442e4596e62 100644 (file)
-/* Copyright (C) 2013 Czech Technical University in Prague
+/* Copyright (C) 2013, 2014 Czech Technical University in Prague
  *
  * Authors:
  *     - Carlos Jenkins <carlos@jenkins.co.cr>
  *
- * This program 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.
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
  *
- * This program 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.
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  *
  * File : sfunction_din.c
  * Abstract:
  *     C-MEX S-function block for RPP digital input.
  *
  * References:
- *     mdlCheckParameters()       : sfunctions.pdf p. 421
- *     mdlInitializeSizes()       : sfunctions.pdf p. 441
- *     mdlInitializeSampleTimes() : sfunctions.pdf p. 436
- *     mdlSetWorkWidths()         : sfunctions.pdf p. 489
- *     mdlStart()                 : sfunctions.pdf p. 492
- *     mdlOutputs()               : sfunctions.pdf p. 447
- *     mdlTerminate()             : sfunctions.pdf p. 493
- *     mdlRTW()                   : sfunctions.pdf p. 458
+ *     header.c
+ *     trailer.c
  *
- *     Compile with <matlabroot>/bin/mex -v -g sfunction_din.c
+ * Compile with:
+ *     <matlabroot>/bin/mex sfunction_din.c
  */
 
-
 /*
- * Must specify the S_FUNCTION_NAME as the name of the S-function.
- */
-#define S_FUNCTION_NAME                sfunction_din
-#define S_FUNCTION_LEVEL               2
+%YAML 1.2
+---
+Name: Digital Input
+Category: IO blocks
+Header: rpp/din.h
+Mnemonic: DIN
 
-/*
- * Include common header and utilities
- */
-#include "utils.c"
+Inputs:
 
-#define MDL_CHECK_PARAMETERS
-#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
+Outputs:
+  - { name: "Digital Input", type: "bool" }
+  - { name: "ErrFlag",       type: "bool" }
 
-/* Function: mdlCheckParameters ================================================
- * Abstract:
- *    mdlCheckParameters verifies new parameter settings whenever parameter
- *    change or are re-evaluated during a simulation. When a simulation is
- *    running, changes to S-function parameters can occur at any time during
- *    the simulation loop.
- */
-static void mdlCheckParameters(SimStruct *S)
-{
-  /*
-   * Check the parameter 1
-   */
-  if EDIT_OK(S, 0) {
-    int_T dimsArray[2] = { 1, 1 };
-
-    /* Check the parameter attributes */
-    ssCheckSFcnParamValueAttribs(S, 0, "P1", DYNAMICALLY_TYPED, 2, dimsArray, 0);
-  }
-
-  /*
-   * Check the parameter 2 (sample time)
-   */
-  if EDIT_OK(S, 1) {
-    const double * sampleTime = NULL;
-    const size_t stArraySize = mxGetM(SAMPLE_TIME) * mxGetN(SAMPLE_TIME);
-
-    /* Sample time must be a real scalar value or 2 element array. */
-    if (IsRealMatrix(SAMPLE_TIME) &&
-        (stArraySize == 1 || stArraySize == 2) ) {
-      sampleTime = mxGetPr(SAMPLE_TIME);
-    } else {
-      ssSetErrorStatus(S,
-                       "Invalid sample time. Sample time must be a real scalar value or an array of two real values.");
-      return;
-    }
+Parameters:
+  - { name: "Pin number",             type: "uint8", range: "[0-15]"           }
+  - { name: "Use variable threshold", type: "bool"                             }
+  - { name: "Pull",                   type: "Choice from Pull-down or Pull-up" }
+  - { name: "Active",                 type: "Choice from Active or Tri-stated" }
 
-    if (sampleTime[0] < 0.0 && sampleTime[0] != -1.0) {
-      ssSetErrorStatus(S,
-                       "Invalid sample time. Period must be non-negative or -1 (for inherited).");
-      return;
-    }
+# Description and Help is in Markdown mark-up
+Description: |
 
-    if (stArraySize == 2 && sampleTime[0] > 0.0 &&
-        sampleTime[1] >= sampleTime[0]) {
-      ssSetErrorStatus(S,
-                       "Invalid sample time. Offset must be smaller than period.");
-      return;
-    }
+  Gets the digital value of the specified digital input pin on the RPP board.
 
-    if (stArraySize == 2 && sampleTime[0] == -1.0 && sampleTime[1] != 0.0) {
-      ssSetErrorStatus(S,
-                       "Invalid sample time. When period is -1, offset must be 0.");
-      return;
-    }
+  If pin is high the output is 1, 0 if the pin is low.
 
-    if (stArraySize == 2 && sampleTime[0] == 0.0 &&
-        !(sampleTime[1] == 1.0)) {
-      ssSetErrorStatus(S,
-                       "Invalid sample time. When period is 0, offset must be 1.");
-      return;
-    }
-  }
-}
+  If an error is detected while getting the pin, the ErrFlag is set high.
+
+Help: |
+
+  This block allows to read the digital inputs on the RPP board. For pins number 0-7 is not
+  relevant and not visible parameter 'Use variable threshold' and only one block for each pin
+  can be in model. And oppositely for other pins (8-15) are not relevant and visible parameters
+  of names 'Pull' and 'Active'. The variable threshold check change the read mode of the pin. For
+  setting it see Digital Input Configure block.
+
+  The ErrFlag should raise if `rpp_din_update()` or `rpp_din_get()` returns error. `rpp_din_update()`
+  is called just by the first DIN block in the model and thus only the first block could raise the
+  flag because of this. In case an errors occurs the return value will always be LOW (0). Because the
+  ErrFlag should never set, once set the following steps will never clear it back.
+
+Status: Stable
+
+RPP API functions used:
+    - rpp_din_setup()
+    - rpp_din_update()
+    - rpp_din_get()
+
+Relevant demos:
+    - digital_passthrough
+    - hbridge_digital_control
+...
+*/
+
+#define S_FUNCTION_NAME sfunction_din
+#include "header.c"
 
-#endif
 
-/* Function: mdlInitializeSizes ================================================
- * Abstract:
- *    The sizes information is used by Simulink to determine the S-function
- *    block's characteristics (number of inputs, outputs, states, etc.).
- */
 static void mdlInitializeSizes(SimStruct *S)
 {
-  /* Number of expected parameters */
-  ssSetNumSFcnParams(S, 2);
-
-#if defined(MATLAB_MEX_FILE)
+    /*
+     * Configure parameters: 1
+     *  - Pin number: [1-16]
+     *  - Use variable threshold: [true|false]
+     *  - Pull: [Pull-up|Pull-down]
+     *  - Active: [Active|Tristate]
+     */
+    if (!rppSetNumParams(S, 4)) {
+        return;
+    }
 
-  if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
     /*
-     * If the number of expected input parameters is not equal
-     * to the number of parameters entered in the dialog box return.
-     * Simulink will generate an error indicating that there is a
-     * parameter mismatch.
+     * Configure input ports: 0
      */
-    mdlCheckParameters(S);
-    if (ssGetErrorStatus(S) != NULL) {
-      return;
+    if (!ssSetNumInputPorts(S, 0)) {
+        return;
     }
-  } else {
-    /* Return if number of expected != number of actual parameters */
-    return;
-  }
 
-#endif
+    /*
+     * Configure output ports: 2
+     *  - Digital input.
+     *  - Error flag.
+     */
+    if (!ssSetNumOutputPorts(S, 2)) {
+        return;
+    }
+    rppAddOutputPort(S, 0, SS_BOOLEAN);
+    rppAddOutputPort(S, 1, SS_BOOLEAN);
 
-  /* Set the parameter's tunable status */
-  ssSetSFcnParamTunable(S, 0, 1);
-  ssSetSFcnParamTunable(S, 1, 0);
-
-  ssSetNumPWork(S, 0);
-
-  if (!ssSetNumDWork(S, 0))
-    return;
-
-  /*
-   * Set the number of input ports.
-   */
-  if (!ssSetNumInputPorts(S, 1))
-    return;
-
-  /*
-   * Configure the input port 1
-   */
-  ssSetInputPortDataType(S, 0, SS_UINT8);
-  ssSetInputPortWidth(S, 0, 1);
-  ssSetInputPortComplexSignal(S, 0, COMPLEX_NO);
-  ssSetInputPortDirectFeedThrough(S, 0, 1);
-  ssSetInputPortAcceptExprInRTW(S, 0, 1);
-  ssSetInputPortOverWritable(S, 0, 1);
-  ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
-  ssSetInputPortRequiredContiguous(S, 0, 1);
-
-  /*
-   * Set the number of output ports.
-   */
-  if (!ssSetNumOutputPorts(S, 0))
-    return;
-
-  /*
-   * This S-function can be used in referenced model simulating in normal mode.
-   */
-  ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK);
-
-  /*
-   * Set the number of sample time.
-   */
-  ssSetNumSampleTimes(S, 1);
-
-  /*
-   * All options have the form SS_OPTION_<name> and are documented in
-   * matlabroot/simulink/include/simstruc.h. The options should be
-   * combined with bitwise OR as in
-   *   ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))
-   */
-  ssSetOptions(S,
-               SS_OPTION_USE_TLC_WITH_ACCELERATOR |
-               SS_OPTION_CAN_BE_CALLED_CONDITIONALLY |
-               SS_OPTION_EXCEPTION_FREE_CODE |
-               SS_OPTION_WORKS_WITH_CODE_REUSE |
-               SS_OPTION_SFUNCTION_INLINED_FOR_RTW |
-               SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME);
+    /* Set standard options for this block */
+    rppSetStandardOptions(S);
 }
 
-/* Function: mdlInitializeSampleTimes ==========================================
- * Abstract:
- *    This function is used to specify the sample time(s) for your
- *    S-function. You must register the same number of sample times as
- *    specified in ssSetNumSampleTimes.
- */
-static void mdlInitializeSampleTimes(SimStruct *S)
+
+#ifdef MATLAB_MEX_FILE
+#define MDL_CHECK_PARAMETERS
+static void mdlCheckParameters(SimStruct *S)
 {
-  double * const sampleTime = mxGetPr(SAMPLE_TIME);
-  const  size_t stArraySize = mxGetM(SAMPLE_TIME) * mxGetN(SAMPLE_TIME);
-  ssSetSampleTime(S, 0, sampleTime[0]);
-  if (stArraySize == 1) {
-    ssSetOffsetTime(S, 0, (sampleTime[0] == CONTINUOUS_SAMPLE_TIME?
-      FIXED_IN_MINOR_STEP_OFFSET: 0.0));
-  } else {
-    ssSetOffsetTime(S, 0, sampleTime[1]);
-  }
+    /* Check the parameter 1 */
+    if (!rppValidParamRange(S, 0, 0, 15)) {
+        return;
+    }
 
-#if defined(ssSetModelReferenceSampleTimeDefaultInheritance)
+    /* Check the parameter 2 */
+    if (!rppValidParamBoolean(S, 1)) {
+        return;
+    }
 
-  ssSetModelReferenceSampleTimeDefaultInheritance(S);
+    /* Check the parameter 3 */
+    if (!rppValidParamRange(S, 2, 0, 2)) {
+        return;
+    }
 
+    /* Check the parameter 4 */
+    if (!rppValidParamRange(S, 3, 0, 2)) {
+        return;
+    }
+}
 #endif
 
-}
 
+#ifdef MATLAB_MEX_FILE
 #define MDL_SET_WORK_WIDTHS
-#if defined(MDL_SET_WORK_WIDTHS) && defined(MATLAB_MEX_FILE)
-
-/* Function: mdlSetWorkWidths ==================================================
- * Abstract:
- *      The optional method, mdlSetWorkWidths is called after input port
- *      width, output port width, and sample times of the S-function have
- *      been determined to set any state and work vector sizes which are
- *      a function of the input, output, and/or sample times.
- *
- *      Run-time parameters are registered in this method using methods
- *      ssSetNumRunTimeParams, ssSetRunTimeParamInfo, and related methods.
- */
 static void mdlSetWorkWidths(SimStruct *S)
 {
-  /* Set number of run-time parameters */
-  if (!ssSetNumRunTimeParams(S, 1))
-    return;
-
-  /*
-   * Register the run-time parameter 1
-   */
-  ssRegDlgParamAsRunTimeParam(S, 0, 0, "p1", ssGetDataTypeId(S, "uint8"));
-}
-
-#endif
-
-#define MDL_START
-#if defined(MDL_START)
-
-/* Function: mdlStart ==========================================================
- * Abstract:
- *    This function is called once at start of model execution. If you
- *    have states that should be initialized once, this is the place
- *    to do it.
- */
-static void mdlStart(SimStruct *S)
-{
-    UNUSED_PARAMETER(S);
-}
+    /* Set number of run-time parameters */
+    if (!ssSetNumRunTimeParams(S, 4)) {
+        return;
+    }
 
-#endif
+    /* Register the run-time parameter 1 */
+    ssRegDlgParamAsRunTimeParam(S, 0, 0, "p1", SS_INT8);
 
-/* Function: mdlOutputs ========================================================
- * Abstract:
- *    In this function, you compute the outputs of your S-function
- *    block. Generally outputs are placed in the output vector(s),
- *    ssGetOutputPortSignal.
- */
-static void mdlOutputs(SimStruct *S, int_T tid)
-{
-    UNUSED_PARAMETER(S);
-    UNUSED_PARAMETER(tid);
-}
+    /* Register the run-time parameter 2 */
+    ssRegDlgParamAsRunTimeParam(S, 1, 1, "p2", SS_BOOLEAN);
 
-/* Function: mdlTerminate ======================================================
- * Abstract:
- *    In this function, you should perform any actions that are necessary
- *    at the termination of a simulation.
- */
-static void mdlTerminate(SimStruct *S)
-{
-    UNUSED_PARAMETER(S);
-}
+    /* Register the run-time parameter 3 */
+    ssRegDlgParamAsRunTimeParam(S, 2, 2, "p3", SS_UINT8);
 
-#define MDL_RTW
-#if defined(MATLAB_MEX_FILE) && defined(MDL_RTW)
-
-/* Function: mdlRTW ============================================================
- * Abstract:
- *    This function is called when the Real-Time Workshop is generating
- *    the model.rtw file.
- */
-static void mdlRTW(SimStruct *S)
-{
-    UNUSED_PARAMETER(S);
+    /* Register the run-time parameter 4 */
+    ssRegDlgParamAsRunTimeParam(S, 3, 3, "p4", SS_UINT8);
 }
-
 #endif
 
 
-/*
- * Required S-function trailer
- */
-#ifdef MATLAB_MEX_FILE
-# include "simulink.c"
-#else
-# include "cg_sfun.h"
-#endif
+#define COMMON_MDLINITIALIZESAMPLETIMES_INHERIT
+#define UNUSED_MDLOUTPUTS
+#define UNUSED_MDLTERMINATE
+#include "trailer.c"