]> rtime.felk.cvut.cz Git - jenkicar/rpp-simulink.git/commitdiff
Implement HYDCTR board init block
authorMichal Horn <hornmich@fel.cvut.cz>
Thu, 27 Aug 2015 17:51:18 +0000 (19:51 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Thu, 3 Sep 2015 10:57:50 +0000 (12:57 +0200)
[Reworked by Michal Sojka]

rpp/blocks/.gitattributes
rpp/blocks/rpp_get_blocks.m
rpp/blocks/rpp_hydctr_init.slx [new file with mode: 0644]
rpp/blocks/sfunction_hydctr_init.c [new file with mode: 0644]
rpp/blocks/tlc_c/.gitattributes
rpp/blocks/tlc_c/sfunction_hydctr_init.tlc [new file with mode: 0644]

index a142f6cd559b70017d320d3a46c35b21d0bc9051..9acd345bc60aa2a72941ec0462aca2b6f9e1cafc 100644 (file)
@@ -1,4 +1,3 @@
-/.gitignore    eaton
 /Makefile      eaton
 /compile_blocks.m      eaton
 /config_rm48_hdk.h     eaton
@@ -11,6 +10,7 @@
 /rpp_gio_in.slx        eaton
 /rpp_gio_out.slx       eaton
 /rpp_hdk_ain.slx       eaton
+/rpp_hydctr_init.slx   eaton
 /rpp_overrun.slx       eaton
 /rpp_sci_cfg.slx       eaton
 /rpp_sci_printf.slx    eaton
@@ -23,6 +23,7 @@
 /sfunction_cantransmit.c       eaton
 /sfunction_gio_in.c    eaton
 /sfunction_gio_out.c   eaton
+/sfunction_hydctr_init.c       eaton
 /sfunction_scic.c      eaton
 /sfunction_scip.c      eaton
 /sfunction_scir.c      eaton
index 26b186310b20a717ea2f85b053c7ed741631a263..42778f388e11135e1c57c5e2adc5b41f4bb5c549 100644 (file)
@@ -13,7 +13,7 @@
 
 function blocks = rpp_get_blocks()
     target = rpp_get_target();
-    if strcmp(target, 'rm48_hdk') || strcmp(target, 'tms570_hdk') || strcmp(target, 'tms570_hydctr'),
+    if strcmp(target, 'rm48_hdk') || strcmp(target, 'tms570_hdk'),
         blocks = {
                 'rpp_can_rx',
                 'rpp_can_setup',
@@ -27,6 +27,21 @@ function blocks = rpp_get_blocks()
                 'rpp_sci_rx',
                 'rpp_sci_tx'
                  };
+    elseif strcmp(target, 'tms570_hydctr'),
+        blocks = {
+                'rpp_can_rx',
+                'rpp_can_setup',
+                'rpp_can_tx',
+                'rpp_gio_in',
+                'rpp_gio_out',
+                'rpp_hdk_ain',
+                'rpp_overrun',
+                'rpp_sci_cfg',
+                'rpp_sci_printf',
+                'rpp_sci_rx',
+                'rpp_sci_tx',
+                'rpp_hydctr_init'
+                 };
     elseif strcmp(target, 'tms570_rpp'),
         blocks = {
                 'rpp_aout',
diff --git a/rpp/blocks/rpp_hydctr_init.slx b/rpp/blocks/rpp_hydctr_init.slx
new file mode 100644 (file)
index 0000000..814cb9f
Binary files /dev/null and b/rpp/blocks/rpp_hydctr_init.slx differ
diff --git a/rpp/blocks/sfunction_hydctr_init.c b/rpp/blocks/sfunction_hydctr_init.c
new file mode 100644 (file)
index 0000000..5e2b56a
--- /dev/null
@@ -0,0 +1,232 @@
+/* Copyright (C) 2015 Czech Technical University in Prague
+ *
+ * Authors:
+ *     - Michal Horn <hornmich@fel.cvut.cz>
+ *     - Michal Sojka <sojkam1@fel.cvut.cz>
+ *
+ * This document contains proprietary information belonging to Czech
+ * Technical University in Prague. Passing on and copying of this
+ * document, and communication of its contents is not permitted
+ * without prior written authorization.
+ *
+ * File : sfunction_hydctr_init.c
+ * Abstract:
+ *     C-MEX S-function block for initial configuring SPI devices on
+ *     TMS570 HYDCTR board.
+ *
+ * Compile with:
+ *     <matlabroot>/bin/mex sfunction_hydctr_init.c
+ */
+
+/*
+%YAML 1.2
+---
+Name: Board Init
+Category: IO blocks
+Header: rpp/spi.h
+Mnemonic: BINIT
+
+Inputs:
+
+Outputs:
+
+Parameters:
+  - { name: "Thermal1 SPI data (MCP6S93):",           type: "uint16 vector of length 2" }
+  - { name: "Thermal2 SPI data (MCP6S93):",           type: "uint16 vector of length 2" }
+  - { name: "ADCS SPI data (6*MCP6S93 daisy chain):", type: "uint16 matrix 2x6" }
+  - { name: "Power supply SPI data (TPS65381):",      type: "uint16 vector of arbitrary length" }
+  - { name: "Sensor supply SPI data (MCP6S93):",      type: "uint16 vector of length 2" }
+  - { name: "DAC ADC loopback SPI data (MCP6S93):",   type: "uint16 vector of length 2" }
+
+# Description and Help is in Markdown mark-up
+Description: &desc |
+
+  This block initializes selected SPI peripherals on the Eaton
+  Hydraulics Controller board at board start. Only one block of this
+  type per model is allowed.
+
+  The format of block parameters depends on the SPI chip. The MCP6S93
+  needs two commands to be properly initialized – channel selection
+  command and gain selection command. Block parameters for those chips
+  are vector of two 16 bit numbers, for example `[0x4000; 0x4100]`.
+  Each element of the vector stands for one command.
+
+  For ADC Conditioning, six MCP6S93 are connected in daisy chain. One
+  SPI transfer for these devices is 96 bits long and we need two
+  transfers to fully configure the chips. Block parameter for this is
+  a 2-by-6 matrix of 16 bit numbers. For example `[4000 4000 4000 4000
+  4000 4000; 4100 4100 4100 4100 4100 4100]`. Each row represents one
+  SPI transfer.
+
+  The TPS65381 chip can be configured by a set of 16 bit commands. The
+  parameter is a arbitrary length vector of 16 bit numbers, for
+  example `[1234; 5678; 01010; 02020; 03030; 04040]`.
+
+Help: *desc
+
+Status: Stable
+
+RPP API functions used:
+  - rpp_spi_transfer()
+  - rpp_spi_transfer16()
+
+Relevant demos:
+  - board_init_hydctr.slx
+...
+*/
+
+#define S_FUNCTION_NAME sfunction_hydctr_init
+#include "header.c"
+
+/** Identifiers of the block parameters */
+enum params {
+       PARAM_THERMISTOR1_ID,
+       PARAM_THERMISTOR2_ID,
+       PARAM_ADC_SCALE_ID,
+       PARAM_POWER_SUPPLY_ID,
+       PARAM_SENSOR_SUPPLY_ID,
+       PARAM_DAC_ADC_LOOP_ID,
+       PARAM_COUNT
+};
+
+#define THERMISTOR1_VEC_PARAM(S)      ssGetSFcnParam(S, PARAM_THERMISTOR1_ID)
+#define THERMISTOR2_VEC_PARAM(S)      ssGetSFcnParam(S, PARAM_THERMISTOR2_ID)
+#define ADCS_VEC_PARAM(S)             ssGetSFcnParam(S, PARAM_ADC_SCALE_ID)
+#define POWER_SUPPLY_VEC_PARAM(S)     ssGetSFcnParam(S, PARAM_POWER_SUPPLY_ID)
+#define SENSOR_SUPPLY_VEC_PARAM(S)    ssGetSFcnParam(S, PARAM_SENSOR_SUPPLY_ID)
+#define DAC_ADC_LOOPBACK_VEC_PARAM(S) ssGetSFcnParam(S, PARAM_DAC_ADC_LOOP_ID)
+
+#define IS_PARAM_UINT16(pVal) (mxIsNumeric(pVal) && !mxIsLogical(pVal) && \
+                               !mxIsEmpty(pVal) && !mxIsSparse(pVal) &&   \
+                               !mxIsComplex(pVal) && mxIsUint16(pVal))
+
+#if !defined(TRUE)
+# define TRUE  1
+#endif
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+
+static void mdlInitializeSizes(SimStruct *S)
+{
+    /*
+     * Configure parameters: 6
+     *  - Baud rate.
+     */
+    if (!rppSetNumParams(S, PARAM_COUNT)) {
+        return;
+    }
+
+    /*
+     * Configure input ports: 0
+     */
+    if (!ssSetNumInputPorts(S, 0)) {
+        return;
+    }
+
+    /*
+     * Configure output ports: 0
+     */
+    if (!ssSetNumOutputPorts(S, 0)) {
+        return;
+    }
+
+    /* Set standard options for this block */
+    rppSetStandardOptions(S);
+}
+
+
+#ifdef MATLAB_MEX_FILE
+/* Function: IsVector =======================================================
+* Abstract:
+*    This function returns TRUE if the array is a vector and FALSE
+*      otherwise. The input argument is a pointer to a matrix (Array)
+*/
+static int IsVector( const mxArray *mat )
+{
+    size_t m = mxGetM(mat);
+    size_t n = mxGetN(mat);
+    if ( (m != 1) && (n != 1) ) {     /* one of the dimensions must be 1 */
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+} /* end IsVector */
+
+
+#define MDL_CHECK_PARAMETERS
+static void mdlCheckParameters(SimStruct *S)
+{
+    /* Check if all parameters are valid */
+    /*
+    if ( !IS_PARAM_UINT16(THERMISTOR1_VEC_PARAM(S)) ||
+       !IS_PARAM_UINT16(THERMISTOR2_VEC_PARAM(S)) ||
+       !IS_PARAM_UINT16(ADCS_VEC_PARAM(S)) ||
+       !IS_PARAM_UINT16(POWER_SUPPLY_VEC_PARAM(S)) ) {
+       ssSetErrorStatus(S,
+                          "uint16");
+       return;
+    }
+    */
+
+    /* Check that all parameters are vectors */
+    if (!IsVector(THERMISTOR1_VEC_PARAM(S)) ||
+        !IsVector(THERMISTOR2_VEC_PARAM(S)) ||
+        !IsVector(SENSOR_SUPPLY_VEC_PARAM(S)) ||
+        !IsVector(DAC_ADC_LOOPBACK_VEC_PARAM(S)) ||
+        !IsVector(POWER_SUPPLY_VEC_PARAM(S))) {
+        ssSetErrorStatus(S,"All parameters to S-function "
+                           "must be double vectors");
+        return;
+    }
+
+    /* Check Thermistor and ADC parameters length */
+    if (mxGetM(THERMISTOR1_VEC_PARAM(S)) != 2 || mxGetN(THERMISTOR1_VEC_PARAM(S)) != 1) {
+        ssSetErrorStatus(S,"Thermistor 1 - matrix 2x1 expected");
+        return;
+    }
+    if (mxGetM(THERMISTOR2_VEC_PARAM(S)) != 2 || mxGetN(THERMISTOR2_VEC_PARAM(S)) != 1) {
+        ssSetErrorStatus(S,"Thermistor 2 - matrix 2x1 expected");
+        return;
+    }
+    if (mxGetM(SENSOR_SUPPLY_VEC_PARAM(S)) != 2 || mxGetN(SENSOR_SUPPLY_VEC_PARAM(S)) != 1) {
+        ssSetErrorStatus(S,"Sensor supply - matrix 2x1 expected");
+        return;
+    }
+    if (mxGetM(DAC_ADC_LOOPBACK_VEC_PARAM(S)) != 2 || mxGetN(DAC_ADC_LOOPBACK_VEC_PARAM(S)) != 1) {
+        ssSetErrorStatus(S,"DAC loopback - matrix 2x1 expected");
+        return;
+    }
+    if (mxGetM(ADCS_VEC_PARAM(S)) != 2 || mxGetN(ADCS_VEC_PARAM(S)) != 6) {
+        /*static char* msg[128];
+        sprintf(msg, "%d, %d", (int)mxGetM(ADCS_VEC_PARAM(S)), (int)mxGetN(ADCS_VEC_PARAM(S)));
+        ssSetErrorStatus(S, msg);*/
+
+        ssSetErrorStatus(S,"ADC Scale - Matrix 2x6 expected.");
+        return;
+    }
+}
+#endif
+
+
+#ifdef MATLAB_MEX_FILE
+#define MDL_SET_WORK_WIDTHS
+static void mdlSetWorkWidths(SimStruct *S)
+{
+       if(!ssSetNumRunTimeParams(S, PARAM_COUNT))
+       return;
+
+       ssRegDlgParamAsRunTimeParam(S, PARAM_THERMISTOR1_ID,   PARAM_THERMISTOR1_ID,   "thermistor1",  SS_UINT16);
+       ssRegDlgParamAsRunTimeParam(S, PARAM_THERMISTOR2_ID,   PARAM_THERMISTOR2_ID,   "thermistor2",  SS_UINT16);
+       ssRegDlgParamAsRunTimeParam(S, PARAM_ADC_SCALE_ID,     PARAM_ADC_SCALE_ID,     "adcs",         SS_UINT16);
+       ssRegDlgParamAsRunTimeParam(S, PARAM_POWER_SUPPLY_ID,  PARAM_POWER_SUPPLY_ID,  "powersupply",  SS_UINT16);
+       ssRegDlgParamAsRunTimeParam(S, PARAM_SENSOR_SUPPLY_ID, PARAM_SENSOR_SUPPLY_ID, "sensorsupply", SS_UINT16);
+       ssRegDlgParamAsRunTimeParam(S, PARAM_DAC_ADC_LOOP_ID,  PARAM_DAC_ADC_LOOP_ID,  "dacloopback",  SS_UINT16);
+}
+#endif
+
+
+#define COMMON_MDLINITIALIZESAMPLETIMES_INHERIT
+#define UNUSED_MDLOUTPUTS
+#define UNUSED_MDLTERMINATE
+#include "trailer.c"
index 68c496f758e1977a77ddb60e7cf47848185cc12b..4609f0e2f57571040f3973f4be3b2f6a4d4be084 100644 (file)
@@ -6,6 +6,7 @@
 /sfunction_cantransmit.tlc     eaton
 /sfunction_gio_in.tlc  eaton
 /sfunction_gio_out.tlc eaton
+/sfunction_hydctr_init.tlc  eaton
 /sfunction_scic.tlc    eaton
 /sfunction_scip.tlc    eaton
 /sfunction_scir.tlc    eaton
diff --git a/rpp/blocks/tlc_c/sfunction_hydctr_init.tlc b/rpp/blocks/tlc_c/sfunction_hydctr_init.tlc
new file mode 100644 (file)
index 0000000..82886b8
--- /dev/null
@@ -0,0 +1,87 @@
+%% Copyright (C) 2013-2015 Czech Technical University in Prague
+%%
+%% Authors:
+%%     - Michal Horn <hornmich@fel.cvut.cz>
+%%
+%% This document contains proprietary information belonging to Czech
+%% Technical University in Prague. Passing on and copying of this
+%% document, and communication of its contents is not permitted
+%% without prior written authorization.
+%%
+%% File : sfunction_hydctr_init.tlc
+%% Abstract:
+%%     TLC file for inlining RPP HYDCTR board init block.
+%%
+%% References:
+%%     BlockTypeSetup() : refs/rtw_tlc.pdf p. 277
+%%     Outputs()        : refs/rtw_tlc.pdf p. 281
+
+
+%implements sfunction_hydctr_init "C"
+
+%include "common.tlc"
+
+
+%% Function: BlockInstanceSetup ================================================
+%function BlockInstanceSetup(block, system) void
+    %if EXISTS("rpp_hydctrinit_in_model") == 0
+        %assign ::rpp_hydctrinit_in_model = 1
+        %<LibAddToCommonIncludes("drv/drv.h")>
+    %else
+        %<LibBlockReportError(block, "Only one Board Init block is allowed in the model.")>
+    %endif
+%endfunction
+
+%% Function: BlockTypeSetup ====================================================
+%function BlockTypeSetup(block, system) void
+
+    %% Ensure required header files are included
+    %<RppCommonBlockTypeSetup(block, system)>
+    %<LibAddToCommonIncludes("rpp/rpp.h")>
+    %<LibAddToCommonIncludes("drv/endian.h")>
+%endfunction
+
+
+%% Function: Start =============================================================
+%function Start(block, system) Output
+
+    %if !SLibCodeGenForSim()
+
+        #define SPI_TX_ERR()  do { \
+            rpp_sci_printk("ERROR: SPI transmission failed.\r\n"); \
+            while (1); \
+        } while(0)
+
+
+        /% Single-value devices %/
+        %assign dev_id   = ["SPIDEV_MCP6S93_TH1", "SPIDEV_MCP6S93_TH2", "SPIDEV_TPS65381_PWR", "SPIDEV_MCP6S93_SENSUP", "SPIDEV_MCP6S93_DAC"]
+        %assign par_name = ["thermistor1",        "thermistor2",        "powersupply",         "sensorsupply",          "dacloopback"]
+
+        %foreach dev = SIZE(dev_id, 1)
+          %assign count = LibBlockParameterWidth(%<par_name[dev]>)
+          %foreach idx = count
+                %assign val = LibBlockParameterValue(%<par_name[dev]>, idx)
+                if (rpp_spi_transfer16(%<dev_id[dev]>, %<val>, NULL) != SUCCESS)
+                    SPI_TX_ERR();
+            %endforeach
+        %endforeach
+
+        /% Daisy chained device %/
+        %assign size = LibBlockParameterDimensions(adcs)
+        %foreach command = size[0]
+            {
+              uint16_t data[%<size[1]>] = {
+                %foreach data = size[1]
+                  cpu_to_be16(%<LibBlockParameterValue(adcs, size[0]*data + command)>),
+                %endforeach
+              };
+              if (rpp_spi_transfer(SPIDEV_MCP6S93_6ADC, sizeof(data), &data, NULL) != SUCCESS)
+                SPI_TX_ERR();
+            }
+        %endforeach
+    %endif
+
+%endfunction
+
+
+%% [EOF]