/* Copyright 1994-2002 The MathWorks, Inc. * * File: rt_i32zcfcn.c $Revision: 1.3 $ * * Abstract: * Real-Time Workshop zero crossing event detection routine for use with * real-time (fixed-step) and nonreal-time (variable-step) generated code. */ #include "rtlibsrc.h" /* Function: rt_I32ZCFcn ======================================================= * Abstract: * Detect zero crossings events. */ ZCEventType rt_I32ZCFcn(ZCDirection direction, ZCSigState *prevSigStatePtr, int32_T zcSig) { /*********************************************************** * First update the sampled zero crossing events if needed * ***********************************************************/ ZCEventType zcEvent = NO_ZCEVENT; /* assume */ ZCSigState prevSigState = *prevSigStatePtr; if (prevSigState == UNINITIALIZED_ZCSIG) { /* * If previous zero crossing time isn't initialized, then we * haven't had a previous zero crossing, so we just initialize the * previous zc signal. */ *prevSigStatePtr = ((zcSig < 0)? NEG_ZCSIG: (zcSig > 0? POS_ZCSIG: ZERO_ZCSIG)); } else { /* * Update sampled zero crossing events */ ZCSigState sigState = ((zcSig < 0)? NEG_ZCSIG: (zcSig > 0? POS_ZCSIG: ZERO_ZCSIG)); /********************** * Check for an event * **********************/ if (prevSigState != sigState) { # define LOOK_NEGATIVE(d) ((d) != RISING_ZERO_CROSSING) # define LOOK_POSITIVE(d) ((d) != FALLING_ZERO_CROSSING) ZCEventType lastZCEvent = NO_ZCEVENT; if (prevSigState == ZERO_RISING_EV_ZCSIG) { /* Just had a negative to zero event */ if (sigState == ZERO_ZCSIG) { *prevSigStatePtr = ZERO_ZCSIG; return(NO_ZCEVENT); } lastZCEvent = RISING_ZCEVENT; prevSigState = ZERO_ZCSIG; } else if (prevSigState == ZERO_FALLING_EV_ZCSIG) { /* Just had a positive to zero event */ if (sigState == ZERO_ZCSIG) { *prevSigStatePtr = ZERO_ZCSIG; return(NO_ZCEVENT); } lastZCEvent = FALLING_ZCEVENT; prevSigState = ZERO_ZCSIG; } if (prevSigState == POS_ZCSIG) { if (LOOK_NEGATIVE(direction)) { zcEvent = FALLING_ZCEVENT; } } else if (prevSigState == ZERO_ZCSIG) { if (sigState == POS_ZCSIG) { if (LOOK_POSITIVE(direction)) { zcEvent = RISING_ZCEVENT; } } else if (sigState == NEG_ZCSIG) { if (LOOK_NEGATIVE(direction)) { zcEvent = FALLING_ZCEVENT; } } } else { /* prevSigState == NEG_ZCSIG */ if (LOOK_POSITIVE(direction)) { zcEvent = RISING_ZCEVENT; } } if (zcEvent == lastZCEvent) { zcEvent = NO_ZCEVENT; } /* * Update prev sig state for next time. */ if (sigState == ZERO_ZCSIG) { if (zcEvent == RISING_ZCEVENT) { *prevSigStatePtr = ZERO_RISING_EV_ZCSIG; } else if (zcEvent == FALLING_ZCEVENT) { *prevSigStatePtr = ZERO_FALLING_EV_ZCSIG; } else { *prevSigStatePtr = sigState; } } else { *prevSigStatePtr = sigState; } } } return(zcEvent); } /* end rt_I32ZCFcn */ /* [EOF] rt_i32zcfcn.c */