X-Git-Url: http://rtime.felk.cvut.cz/gitweb/mf624-simulink.git/blobdiff_plain/ac50e6ad8f2b22280368106e148b4e32214ea04d..e5b71077fab070bf1f18f7f41ec300f7f5be891b:/sfAnalogInput.c diff --git a/sfAnalogInput.c b/sfAnalogInput.c index bfee43a..940bf43 100644 --- a/sfAnalogInput.c +++ b/sfAnalogInput.c @@ -10,6 +10,7 @@ #define S_FUNCTION_NAME sfAnalogInput #define S_FUNCTION_LEVEL 2 +#define MASK_PRM(S) (mxGetScalar(ssGetSFcnParam(S, 0))) /* * Need to include simstruc.h for the definition of the SimStruct and @@ -17,7 +18,7 @@ */ #include "simstruc.h" -#include "mf624.h" +#include "mf624_SIMULINK.h" /* Error handling @@ -57,33 +58,37 @@ 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 */ + ssSetErrorStatus(S,"Parameter mismatch"); return; } ssSetNumContStates(S, 0); ssSetNumDiscStates(S, 0); + + int ADCCMask = (int)MASK_PRM(S); + int i; + if(ADCCMask > 255 || ADCCMask < 0) { + ssSetErrorStatus(S,"Invalid parameter mask, set to 0-255"); + } + + int ADCChannels = __builtin_popcount((uint)ADCCMask); //Counts number of set bits in ADCCMask + + + if (!ssSetNumInputPorts(S, 0)) return; + + - 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 (!ssSetNumOutputPorts(S, 1)) return; - ssSetOutputPortWidth(S, 0, 1); - + if (!ssSetNumOutputPorts(S, ADCChannels)) return; + for(i=0; i < ADCChannels;i++){ + ssSetOutputPortWidth(S, i, 1); + } ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, 0); - ssSetNumIWork(S, 0); - ssSetNumPWork(S, 1); + ssSetNumIWork(S, 1); + ssSetNumPWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs(S, 0); @@ -91,6 +96,8 @@ static void mdlInitializeSizes(SimStruct *S) ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE); ssSetOptions(S, 0); + + } @@ -110,7 +117,7 @@ static void mdlInitializeSampleTimes(SimStruct *S) -#define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */ +#undef MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */ #if defined(MDL_INITIALIZE_CONDITIONS) /* Function: mdlInitializeConditions ======================================== * Abstract: @@ -140,15 +147,47 @@ static void mdlInitializeSampleTimes(SimStruct *S) */ static void mdlStart(SimStruct *S) { - #if defined(TEST) - mf624_state_t* mfst = &mf624_state; - char buff[BUFF_SMALL]; - memset(buff, '\0', BUFF_SMALL); + 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; + } + + } + + int ADCCMask = (int)MASK_PRM(S); + int i; + if(ADCCMask > 255 || ADCCMask < 0) { + ssSetErrorStatus(S,"Invalid parameter mask, set to 0-255"); + } + + int ADCChannels = __builtin_popcount((uint)ADCCMask); //Counts number of set bits in ADCCMask + + ssSetIWorkValue(S, 0, ADCChannels); + + mfst->ADC_enabled = ADCCMask; + mfst->ADC_enabled &= 0xFF; + + mf624_write16(mfst->ADC_enabled, MFST2REG(mfst, 2, ADCTRL_reg)); - #endif - //TODO: inicializovat tady pointer na stavovou strukturu a ulozit ho do PWork } #endif /* MDL_START */ @@ -161,14 +200,42 @@ static void mdlInitializeSampleTimes(SimStruct *S) */ static void mdlOutputs(SimStruct *S, int_T tid) { - mf624_state_t* mfstPtr = ssGetPWork(S)[0]; - real_T *y = ssGetOutputPortSignal(S,0); - y[0] = ADC_read(mfstPtr, AD0); + + int ADCChannels = ssGetIWorkValue(S, 0); + real_T* y[ADCChannels]; + int i; + int res,res1; + + // Activate trigger to start conversion + mf624_read16(MFST2REG(mfst, 2, ADSTART_reg)); + + for(i=0; i < ADCChannels;i++){ + y[i]=ssGetOutputPortSignal(S,i); + } + + // Check if conversion has finished + while((mf624_read32(MFST2REG(mfst, 0, GPIOC_reg)) & GPIOC_EOLC_mask)) { + for (i = 0; i < 1000; i++) {} // small wait + } + + + for(i=1; i < ADCChannels;i+=2){ + res = mf624_read32(MFST2REG(mfst, 2, ADDATA0_reg)); + res1= res >> 16; + res = res & 0xFFFF; + *y[i-1] = (real_T) (10.0 * ((int16_t) (res << 2)) / (double) 0x8000); + *y[i] = (real_T) (10.0 * ((int16_t) (res1 << 2)) / (double) 0x8000); + } + + if(i == ADCChannels){ + res = mf624_read16(MFST2REG(mfst, 2, ADDATA0_reg)); + *y[ADCChannels-1]=(real_T)(10.0 * ((int16_t) (res << 2)) / (double) 0x8000); + } } -#define MDL_UPDATE /* Change to #undef to remove function */ +#undef MDL_UPDATE /* Change to #undef to remove function */ #if defined(MDL_UPDATE) /* Function: mdlUpdate ====================================================== * Abstract: @@ -184,7 +251,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) -#define MDL_DERIVATIVES /* Change to #undef to remove function */ +#undef MDL_DERIVATIVES /* Change to #undef to remove function */ #if defined(MDL_DERIVATIVES) /* Function: mdlDerivatives ================================================= * Abstract: @@ -206,6 +273,10 @@ static void mdlOutputs(SimStruct *S, int_T tid) */ static void mdlTerminate(SimStruct *S) { + if(mfst != NULL){ + free(mfst); + mfst=NULL; + } }