X-Git-Url: http://rtime.felk.cvut.cz/gitweb/mf624-simulink.git/blobdiff_plain/7a3dd5a2dc0bcb926f958f7270218286f4419d9a..feb21df26f15113aa8596193a4142273a84b5e12:/sfReadPWM.c diff --git a/sfReadPWM.c b/sfReadPWM.c index 1f7e01b..33399ae 100644 --- a/sfReadPWM.c +++ b/sfReadPWM.c @@ -1,11 +1,43 @@ +/* + * S-function to measure external PWM signal duty cycle on Humusoft MF624 card + * + * Copyright (C) 2013 Michal Kreč + * Copyright (C) 2013 Michal Sojka + * + * 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. + */ #define S_FUNCTION_NAME sfReadPWM #define S_FUNCTION_LEVEL 2 -#define PERIOD_PRM(S) (mxGetScalar(ssGetSFcnParam(S, 0))) -#define CTRX_MODE 2083 //=100000100011, count up, repeat, outpu low,gate by ctrIn +#define CTRX_MODE 10275 //=10100000100011, count up, repeat, outpu low,gate by ctrIn, gate high #define CTR4_MODE 35 //100011, count upm, repeat,output low #define CTR_START ((1 << 0) | (1 << 6) | (1 << 12) | (1 << 24)) //start counters 0,1,2,4 +#define CTR_STOP ((1 << 1) | (1 << 7) | (1 << 13) | (1 << 25)) //stop counters 0,1,2,4 #define CTRCLOCK 50000000 /* @@ -53,7 +85,7 @@ static void mdlInitializeSizes(SimStruct *S) { /* See sfuntmpl_doc.c for more details on the macros below */ - ssSetNumSFcnParams(S, 1); /* Number of expected parameters */ + ssSetNumSFcnParams(S, 0); /* Number of expected parameters */ if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { /* Return if number of expected != number of actual parameters */ return; @@ -62,16 +94,8 @@ static void mdlInitializeSizes(SimStruct *S) ssSetNumContStates(S, 0); ssSetNumDiscStates(S, 0); - if (!ssSetNumInputPorts(S, 1)) return; - ssSetInputPortWidth(S, 0, 1); - ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/ - /* - * Set direct feedthrough flag (1=yes, 0=no). - * A port has direct feedthrough if the input is used in either - * the mdlOutputs or mdlGetTimeOfNextVarHit functions. - * See matlabroot/simulink/src/sfuntmpl_directfeed.txt. - */ - ssSetInputPortDirectFeedThrough(S, 0, 1); + if (!ssSetNumInputPorts(S, 0)) return; + if (!ssSetNumOutputPorts(S, 3)) return; ssSetOutputPortWidth(S, 0, 1); @@ -101,7 +125,7 @@ static void mdlInitializeSizes(SimStruct *S) */ static void mdlInitializeSampleTimes(SimStruct *S) { - ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME); + ssSetSampleTime(S, 0, 0.00005); ssSetOffsetTime(S, 0, 0.0); } @@ -138,50 +162,29 @@ static void mdlInitializeSampleTimes(SimStruct *S) */ static void mdlStart(SimStruct *S) { - if(mfst==NULL){ - #define BUFF_SMALL 32 - 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; - } - - } + if (mf624_init(NULL) != 0) + return; /*Configuration of desired counter modes*/ - mf624_write32(CTRX_MODE,MFST2REG(mfst,4,CTR0MODE)); - mf624_write32(CTRX_MODE,MFST2REG(mfst,4,CTR1MODE)); - mf624_write32(CTRX_MODE,MFST2REG(mfst,4,CTR2MODE)); - mf624_write32(CTR4_MODE,MFST2REG(mfst,4,CTR4MODE)); + mf624_write32(CTRX_MODE,MFST2REG(mfst,4,CTR0MODE_reg)); + mf624_write32(CTRX_MODE,MFST2REG(mfst,4,CTR1MODE_reg)); + mf624_write32(CTRX_MODE,MFST2REG(mfst,4,CTR2MODE_reg)); + mf624_write32(CTR4_MODE,MFST2REG(mfst,4,CTR4MODE_reg)); /*Set reload values of ctrs 0,1,2,4 to 0 just to be sure*/ - mf624_write32(0,MFST2REG(mfst,4,CTR0)); - mf624_write32(0,MFST2REG(mfst,4,CTR1)); - mf624_write32(0,MFST2REG(mfst,4,CTR2)); - mf624_write32(0,MFST2REG(mfst,4,CTR4)); + mf624_write32(0,MFST2REG(mfst,4,CTR0_reg)); + mf624_write32(0,MFST2REG(mfst,4,CTR1_reg)); + mf624_write32(0,MFST2REG(mfst,4,CTR2_reg)); + mf624_write32(0,MFST2REG(mfst,4,CTR4_reg)); /*Read values from counters and initialize IWork values with them*/ - ssSetIWorkValue(S,0,(uint)mf624_read32(MFST2REG(mfst,4,CTR0))); - ssSetIWorkValue(S,1,(uint)mf624_read32(MFST2REG(mfst,4,CTR1))); - ssSetIWorkValue(S,2,(uint)mf624_read32(MFST2REG(mfst,4,CTR2))); - ssSetIWorkValue(S,3,(uint)mf624_read32(MFST2REG(mfst,4,CTR4))); + ssSetIWorkValue(S,0,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR0_reg))); + ssSetIWorkValue(S,1,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR1_reg))); + ssSetIWorkValue(S,2,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR2_reg))); + ssSetIWorkValue(S,3,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR4_reg))); /*Start counters 0,1,2, tehy are gated with their inputs so no worries about premature start*/ - mf624_write32(CTR_START,MFST2REG(mfst,4,CTRXCTRL)); + mf624_write32(CTR_START,MFST2REG(mfst,4,CTRXCTRL_reg)); } @@ -196,24 +199,25 @@ static void mdlInitializeSampleTimes(SimStruct *S) */ static void mdlOutputs(SimStruct *S, int_T tid) { - const real_T *u = (const real_T*) ssGetInputPortSignal(S,0); real_T *y0 = ssGetOutputPortSignal(S,0); real_T *y1 = ssGetOutputPortSignal(S,1); real_T *y2 = ssGetOutputPortSignal(S,2); - uint period; - uint c0,c1,c2,c4; - + unsigned int period; + unsigned int c0,c1,c2,c4; - c0 = mf624_read32(MFST2REG(mfst,4,CTR0)); - c1 = mf624_read32(MFST2REG(mfst,4,CTR1)); - c2 = mf624_read32(MFST2REG(mfst,4,CTR2)); - c4 = mf624_read32(MFST2REG(mfst,4,CTR4)); + if (mf624_check(S) != 0) + return; + + c0 = mf624_read32(MFST2REG(mfst,4,CTR0_reg)); + c1 = mf624_read32(MFST2REG(mfst,4,CTR1_reg)); + c2 = mf624_read32(MFST2REG(mfst,4,CTR2_reg)); + c4 = mf624_read32(MFST2REG(mfst,4,CTR4_reg)); - period = (uint)(c4-(uint)ssGetIWorkValue(S,3)); + period = (unsigned int)(c4-(unsigned int)ssGetIWorkValue(S,3)); - y0[0] = (c0-(uint)ssGetIWorkValue(S,0))/period; - y1[0] = (c1-(uint)ssGetIWorkValue(S,1))/period; - y2[0] = (c2-(uint)ssGetIWorkValue(S,2))/period; + y0[0] = (real_T)(c0-(unsigned int)ssGetIWorkValue(S,0))/(real_T)period; + y1[0] = (real_T)(c1-(unsigned int)ssGetIWorkValue(S,1))/(real_T)period; + y2[0] = (real_T)(c2-(unsigned int)ssGetIWorkValue(S,2))/(real_T)period; ssSetIWorkValue(S,0,c0); ssSetIWorkValue(S,1,c1); @@ -261,9 +265,11 @@ static void mdlOutputs(SimStruct *S, int_T tid) */ static void mdlTerminate(SimStruct *S) { - if(mfst!=NULL){ - free(mfst); - } + if (mf624_check(NULL) != 0) + return; + + mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL_reg)); + mf624_done(); }