--- /dev/null
+/* 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"
--- /dev/null
+%% 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]