X-Git-Url: https://rtime.felk.cvut.cz/gitweb/mf624-simulink.git/blobdiff_plain/ac50e6ad8f2b22280368106e148b4e32214ea04d..f68e0aa7d1b39a46e039a8c3b7bc8cca4ae7e86c:/sfAnalogOutput.c diff --git a/sfAnalogOutput.c b/sfAnalogOutput.c index a3fa03d..d2d0ad0 100644 --- a/sfAnalogOutput.c +++ b/sfAnalogOutput.c @@ -1,12 +1,34 @@ /* - * sfuntmpl_basic.c: Basic 'C' template for a level 2 S-function. + * S-function to support analog outputs on Humusoft MF624 card * - * ------------------------------------------------------------------------- - * | See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template | - * ------------------------------------------------------------------------- + * Copyright (C) 2013 Michal Kreč + * Copyright (C) 2013 Michal Sojka * - * Copyright 1990-2002 The MathWorks, Inc. - * $Revision: 1.27.4.2 $ + * Department of Control Engineering + * Faculty of Electrical Engineering + * Czech Technical University in Prague (CTU) + * + * The S-Function for ERT Linux can be distributed in compliance + * with GNU General Public License (GPL) version 2 or later. + * Other licence can negotiated with CTU. + * + * Next exception is granted in addition to GPL. + * Instantiating or linking compiled version of this code + * to produce an application image/executable, does not + * by itself cause the resulting application image/executable + * to be covered by the GNU General Public License. + * This exception does not however invalidate any other reasons + * why the executable file might be covered by the GNU Public License. + * Publication of enhanced or derived S-function files is required + * although. + * + * Linux ERT code is available from + * http://rtime.felk.cvut.cz/gitweb/ert_linux.git + * More CTU Linux target for Simulink components are available at + * http://lintarget.sourceforge.net/ + * + * sfuntmpl_basic.c by The MathWorks, Inc. has been used to accomplish + * required S-function structure. */ @@ -18,12 +40,17 @@ #define S_FUNCTION_NAME sfAnalogOutput #define S_FUNCTION_LEVEL 2 +#define CHNL_PRM(S) (mxGetScalar(ssGetSFcnParam(S, 0))) + /* * Need to include simstruc.h for the definition of the SimStruct and * its associated macro definitions. */ #include "simstruc.h" -#include "mf624.h" + +#ifndef WITHOUT_HW +#include "mf624_SIMULINK.h" +#endif /*WITHOUT_HW*/ /* Error handling * -------------- @@ -62,7 +89,7 @@ static void mdlInitializeSizes(SimStruct *S) { /* See sfuntmpl_doc.c for more details on the macros below */ - ssSetNumSFcnParams(S, 0); /* Number of expected parameters */ + ssSetNumSFcnParams(S, 1); /* Number of expected parameters */ if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { /* Return if number of expected != number of actual parameters */ return; @@ -87,7 +114,7 @@ static void mdlInitializeSizes(SimStruct *S) ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); - ssSetNumPWork(S, 1); + ssSetNumPWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs(S, 0); @@ -107,7 +134,7 @@ static void mdlInitializeSizes(SimStruct *S) */ static void mdlInitializeSampleTimes(SimStruct *S) { - ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); + ssSetSampleTime(S, 0, -1); ssSetOffsetTime(S, 0, 0.0); } @@ -144,31 +171,12 @@ static void mdlInitializeSampleTimes(SimStruct *S) */ static void mdlStart(SimStruct *S) { - //TODO: get pointer to mfst state structure and store it in pwork - #define TEST - #if defined(TEST) - #define BUFF_SMALL 32 - mf624_state_t* mfst = malloc(sizeof(mf624_state_t)); - char buff[BUFF_SMALL]; - memset(buff, '\0', BUFF_SMALL); - mfst->uio_dev = "uio0"; - - strncat(buff, "/dev/", 5); - strncat(buff, mfst->uio_dev, sizeof(buff) - 6); - - mfst->device_fd = open_device(buff); - if (mfst->device_fd < 0) { - ssSetErrorStatus(S,"open failed"); - return; - } - if (mmap_regions(mfst) < 0) { - ssSetErrorStatus(S,"mmap_regions failed"); - return; - } - + #ifndef WITHOUT_HW + if (mf624_init(NULL) != 0) + return; DAC_enable(mfst); - ssSetPWorkValue(S, 0, mfst); - #endif + #endif /*WITHOUT_HW*/ + //ssSetPWorkValue(S, 0, mfst); } #endif /* MDL_START */ @@ -182,8 +190,13 @@ static void mdlInitializeSampleTimes(SimStruct *S) static void mdlOutputs(SimStruct *S, int_T tid) { const real_T *u = (const real_T*) ssGetInputPortSignal(S,0); - mf624_state_t* mfst = ssGetPWorkValue(S,0); + //mf624_state_t* mfst = ssGetPWorkValue(S,0); int out; + + #ifndef WITHOUT_HW + if (mf624_check(S) != 0) + return; + if(u[0] > 9.9988){ out = 0x3FFF; } @@ -193,7 +206,8 @@ static void mdlOutputs(SimStruct *S, int_T tid) else { out = (int) ((u[0] + 10) * 8192 / 10 + 0.5); } - DAC_write(mfst, DA0, out); + mf624_write16(out, MFST2REG(mfst, 2, dac_channel2reg[(int)CHNL_PRM(S)-1])); + #endif /*WITHOUT_HW*/ } @@ -236,10 +250,18 @@ static void mdlOutputs(SimStruct *S, int_T tid) */ static void mdlTerminate(SimStruct *S) { - #if defined(TEST) - free(ssGetPWorkValue(S,0)); - #endif - + #ifndef WITHOUT_HW + //mf624_state_t* mfst = ssGetPWorkValue(S,0); + if (mf624_check(NULL) != 0) + return; + + /*At the end of simulation disable D/A outputs*/ + mf624_write32((mf624_read32(MFST2REG(mfst, 0, GPIOC_reg)) + & ~GPIOC_DACEN_mask), // disable output, + MFST2REG(mfst, 0, GPIOC_reg)); + + mf624_done(); + #endif /*WITHOUT_HW*/ }