X-Git-Url: http://rtime.felk.cvut.cz/gitweb/mf624-simulink.git/blobdiff_plain/e59ef4188f14905ef3b4552c7ecc783ec4d18726..a2b0c2e846459ae30cf85ac287b19c7b275ab16f:/sfReadPWM.c diff --git a/sfReadPWM.c b/sfReadPWM.c index ca4f74b..979f046 100644 --- a/sfReadPWM.c +++ b/sfReadPWM.c @@ -1,3 +1,35 @@ +/* + * 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 @@ -14,7 +46,9 @@ */ #include "simstruc.h" +#ifndef WITHOUT_HW #include "mf624_SIMULINK.h" +#endif /*WITHOUT_HW*/ /* Error handling * -------------- @@ -130,52 +164,31 @@ 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; - } - - } + #ifndef WITHOUT_HW + 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,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR0))); - ssSetIWorkValue(S,1,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR1))); - ssSetIWorkValue(S,2,(unsigned int)mf624_read32(MFST2REG(mfst,4,CTR2))); - ssSetIWorkValue(S,3,(unsigned int)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)); + #endif /*WITHOUT_HW*/ } #endif /* MDL_START */ @@ -193,23 +206,28 @@ static void mdlOutputs(SimStruct *S, int_T tid) real_T *y2 = ssGetOutputPortSignal(S,2); 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)); - + #ifndef WITHOUT_HW + 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 = (unsigned int)(c4-(unsigned int)ssGetIWorkValue(S,3)); - + 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); ssSetIWorkValue(S,2,c2); ssSetIWorkValue(S,3,c4); + #else /*WITHOUT_HW*/ + y0[0] = y1[0] = y2[0] = 0; + #endif /*WITHOUT_HW*/ } @@ -252,34 +270,13 @@ static void mdlOutputs(SimStruct *S, int_T tid) */ static void mdlTerminate(SimStruct *S) { - if(mfst!=NULL){ - mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL)); - free(mfst); - mfst=NULL; - } else { - 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; - } - mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL)); - free(mfst); - mfst=NULL; - } + #ifndef WITHOUT_HW + if (mf624_check(NULL) != 0) + return; + + mf624_write32(CTR_STOP,MFST2REG(mfst,4,CTRXCTRL_reg)); + mf624_done(); + #endif /*WITHOUT_HW*/ }