%implements "genrtzcfcn" "C"
%function rt_ZCFcn(fctInfo,fileH,fileC) void
%assign zcfcnStr = "rt_ZCFcn"
%openfile buf
/*
* %<fctInfo.FileName>.h
*
%<SLibCommonUtilHeaderInfo()>/
*/
%closefile buf
%<SLibCacheUtilCodeToFile("util_hdr_banner", fileH, buf)>
%openfile buf
#include "%<SLibCoderTypesFilename()>"
%closefile buf
%<SLibCacheUtilCodeToFile("util_hdr_incl", fileH, buf)>
%openfile buf
#include "solver_zc.h"
%if SLibIsERTTarget()
#include "%<SLibCoderZerocrossingTypesFilename()>"
%endif
#ifndef slZcHadEvent
#define slZcHadEvent(ev, zcsDir) (((ev) & (zcsDir)) != 0x00 )
#endif
%closefile buf
%<SLibCacheMacroToUtilityFile("slZcHadEvent", buf, "util_hdr_defines", fileH)>
%openfile buf
#ifndef slZcUnAliasEvents
#define slZcUnAliasEvents(evL, evR) /
((((slZcHadEvent((evL), (SL_ZCS_EVENT_N2Z)) && /
slZcHadEvent((evR), (SL_ZCS_EVENT_Z2P))) || /
(slZcHadEvent((evL), (SL_ZCS_EVENT_P2Z)) && /
slZcHadEvent((evR), (SL_ZCS_EVENT_Z2N)))) ? /
(SL_ZCS_EVENT_NUL) : (evR)))
#endif
%closefile buf
%<SLibCacheMacroToUtilityFile("slZcUnAliasEvents", buf, "util_hdr_defines", fileH)>
%assign msFcn = SLibGetMemSecCategoryForUtilityFcn()
%assign fcnName = zcfcnStr
%openfile buf
%<FcnGenOpenExternCForCPP()>
%<SLibGetFcnMemSecPragmaOnDecl(fcnName, msFcn, "Pre")>/
%<LibStaticOrExternInFcnDecls()>ZCEventType %<zcfcnStr>(ZCDirection zcDir, /
ZCSigState *prevZc, /
real_T currValue);
%<SLibGetFcnMemSecPragmaOnDecl(fcnName, msFcn, "Post")>/
%<FcnGenCloseExternCForCPP()>
%closefile buf
%<SLibCacheUtilCodeToFile("util_hdr_decl", fileH, buf)>
%openfile buf
/*
* %<fctInfo.FileName>.%<LangFileExt>
*
%<SLibCommonUtilHeaderInfo()>/
*/
%closefile buf
%<SLibCacheUtilCodeToFile("util_src_banner", fileC, buf)>
%openfile buf
#include "rt_zcfcn.h"
%closefile buf
%<SLibCacheUtilCodeToFile("util_src_incl", fileC, buf)>
%openfile buf
%if GenCPP
extern "C" {
%endif
%assign fcnReturns = "ZCEventType"
%assign fcnParams = "ZCDirection zcDir, ZCSigState* prevZc, real_T currValue"
%assign fcnAbstract = "Detect zero crossings events."
%assign functionSpecifier = LibStaticInFcnDecls()
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "utility"; GeneratedBy "genrtzcfcn.tlc"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<SLibGetFcnMemSecPragma(fcnName, msFcn, "Pre")>/
%<functionSpecifier> %<fcnReturns> %<fcnName>(%<fcnParams>)
{
slZcEventType zcsDir;
slZcEventType tempEv;
ZCEventType zcEvent = NO_ZCEVENT; /* assume */
/* zcEvent matrix */
static const slZcEventType eventMatrix[4][4] = {
/* ZER POS NEG UNK */
{SL_ZCS_EVENT_NUL,SL_ZCS_EVENT_Z2P,SL_ZCS_EVENT_Z2N,SL_ZCS_EVENT_NUL},/* ZER */
{SL_ZCS_EVENT_P2Z,SL_ZCS_EVENT_NUL,SL_ZCS_EVENT_P2N,SL_ZCS_EVENT_NUL},/* POS */
{SL_ZCS_EVENT_N2Z,SL_ZCS_EVENT_N2P,SL_ZCS_EVENT_NUL,SL_ZCS_EVENT_NUL},/* NEG */
{SL_ZCS_EVENT_NUL,SL_ZCS_EVENT_NUL,SL_ZCS_EVENT_NUL,SL_ZCS_EVENT_NUL} /* UNK */
};
/* get prevZcEvent and prevZcSign from prevZc */
slZcEventType prevEv = (slZcEventType)(((uint8_T)(*prevZc)) >> 2);
slZcSignalSignType prevSign = (slZcSignalSignType)(((uint8_T)(*prevZc)) & (uint8_T)0x03);
/* get current zcSignal sign from current zcSignal value */
slZcSignalSignType currSign = (slZcSignalSignType)((currValue) > 0.0 ? SL_ZCS_SIGN_POS :
((currValue) < 0.0 ? SL_ZCS_SIGN_NEG : SL_ZCS_SIGN_ZERO));
/* get current zcEvent based on prev and current zcSignal value */
slZcEventType currEv = eventMatrix[prevSign][currSign];
/* get slZcEventType from ZCDirection */
switch (zcDir) {
case ANY_ZERO_CROSSING:
zcsDir = SL_ZCS_EVENT_ALL;
break;
case FALLING_ZERO_CROSSING:
zcsDir = SL_ZCS_EVENT_ALL_DN;
break;
case RISING_ZERO_CROSSING:
zcsDir = SL_ZCS_EVENT_ALL_UP;
break;
default:
zcsDir = SL_ZCS_EVENT_NUL;
break;
}
/*had event, check if double zc happend remove double detection. */
if ( slZcHadEvent(currEv, zcsDir)) {
currEv = (slZcEventType)(slZcUnAliasEvents(prevEv, currEv));
} else{
currEv = SL_ZCS_EVENT_NUL;
}
/* Update prevZc */
tempEv = (slZcEventType)(currEv << 2); /* shift left by 2 bits */
*prevZc = (ZCSigState)((currSign) | (tempEv));
if ((currEv & SL_ZCS_EVENT_ALL_DN) != 0) {
zcEvent = FALLING_ZCEVENT;
}else if ((currEv & SL_ZCS_EVENT_ALL_UP) != 0){
zcEvent = RISING_ZCEVENT;
}else{
zcEvent = NO_ZCEVENT;
}
return zcEvent;
} /* %<zcfcnStr> */
%<SLibGetFcnMemSecPragma(fcnName, msFcn, "Post")>/
%if GenCPP
}
%endif
%closefile buf
%<SLibCacheUtilCodeToFile("util_src_fcn_defn", fileC, buf)>
%endfunction