From: Michal Horn Date: Thu, 27 Aug 2015 17:51:18 +0000 (+0200) Subject: Implement HYDCTR board init block X-Git-Tag: eaton-0.6~10 X-Git-Url: http://rtime.felk.cvut.cz/gitweb/pes-rpp/rpp-simulink.git/commitdiff_plain/55e87a21d5de993b4de6975ecc21073c75a3734e?hp=8c488567e5ca075903ea55a9519ed0c6ac625c1e Implement HYDCTR board init block [Reworked by Michal Sojka] --- diff --git a/rpp/blocks/.gitattributes b/rpp/blocks/.gitattributes index a142f6c..9acd345 100644 --- a/rpp/blocks/.gitattributes +++ b/rpp/blocks/.gitattributes @@ -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 diff --git a/rpp/blocks/rpp_get_blocks.m b/rpp/blocks/rpp_get_blocks.m index 26b1863..42778f3 100644 --- a/rpp/blocks/rpp_get_blocks.m +++ b/rpp/blocks/rpp_get_blocks.m @@ -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 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 index 0000000..5e2b56a --- /dev/null +++ b/rpp/blocks/sfunction_hydctr_init.c @@ -0,0 +1,232 @@ +/* Copyright (C) 2015 Czech Technical University in Prague + * + * Authors: + * - Michal Horn + * - Michal Sojka + * + * 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: + * /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" diff --git a/rpp/blocks/tlc_c/.gitattributes b/rpp/blocks/tlc_c/.gitattributes index 68c496f..4609f0e 100644 --- a/rpp/blocks/tlc_c/.gitattributes +++ b/rpp/blocks/tlc_c/.gitattributes @@ -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 index 0000000..82886b8 --- /dev/null +++ b/rpp/blocks/tlc_c/sfunction_hydctr_init.tlc @@ -0,0 +1,87 @@ +%% Copyright (C) 2013-2015 Czech Technical University in Prague +%% +%% Authors: +%% - Michal Horn +%% +%% 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 + % + %else + % + %endif +%endfunction + +%% Function: BlockTypeSetup ==================================================== +%function BlockTypeSetup(block, system) void + + %% Ensure required header files are included + % + % + % +%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(%) + %foreach idx = count + %assign val = LibBlockParameterValue(%, idx) + if (rpp_spi_transfer16(%, %, NULL) != SUCCESS) + SPI_TX_ERR(); + %endforeach + %endforeach + + /% Daisy chained device %/ + %assign size = LibBlockParameterDimensions(adcs) + %foreach command = size[0] + { + uint16_t data[%] = { + %foreach data = size[1] + cpu_to_be16(%), + %endforeach + }; + if (rpp_spi_transfer(SPIDEV_MCP6S93_6ADC, sizeof(data), &data, NULL) != SUCCESS) + SPI_TX_ERR(); + } + %endforeach + %endif + +%endfunction + + +%% [EOF]