#include "core/config.h" #if CONFIG_AUTOMAT_MODE || CONFIG_LEDS #define ROUTINE_SEQUENCE_AUTOMAT_C #include "rseq.h" //------------------------------------------------------------------------------ #define NULL ((void*)0) #define NULL_Routine ((fRoutine_t*)NULL) //------------------------------------------------------------------------------ bool rsa_sequence_init( sRoutineSequence_t * pSeq, void * arg, fRoutine_t ** papfRoutineList, uint32_t size ); bool rsa_sequence_insert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine ); bool rsa_sequence_remove_routine( sRoutineSequence_t * pSeq ); bool rsa_sequence_call( sRoutineSequence_t * pSeq ); bool rsa_sequence_reset( sRoutineSequence_t * pSeq ); bool rsa_sequence_clear( sRoutineSequence_t * pSeq ); #if RSA_USE_LOCKERS > 0 bool rsa_sequence_iinsert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine ); bool rsa_sequence_iremove_routine( sRoutineSequence_t * pSeq ); bool rsa_sequence_icall( sRoutineSequence_t * pSeq ); bool rsa_sequence_ireset( sRoutineSequence_t * pSeq ); bool rsa_sequence_iclear( sRoutineSequence_t * pSeq ); #endif //------------------------------------------------------------------------------ static bool rsa_stub_locker( void * arg ) { return true; } //------------------------------------------------------------------------------ // rsa_sequence_init() // Initialize sRoutineSequence_t before any operations // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be initialized // * IN [ void * ] @arg - an user argument to be passed into each routine // * IN [ fRoutine_t **] @papfRoutineList - the routine list to hold the values // * IN [ uint32_t ] @size - the size of routine list array @papfRoutineList // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_init( sRoutineSequence_t * pSeq, void * arg, fRoutine_t ** papfRoutineList, uint32_t size ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq || NULL == papfRoutineList || 0 == size ) return false; #endif pSeq->count = 0; pSeq->idx = 0; pSeq->arg = arg; pSeq->papfRoutineList = papfRoutineList; pSeq->size = size; #if RSA_USE_LOCKERS > 0 pSeq->fLocker = rsa_stub_locker; pSeq->fUnlocker = rsa_stub_locker; #endif return true; } //------------------------------------------------------------------------------ #if RSA_USE_LOCKERS > 0 // rsa_sequence_setlockers() // Specifies a special Lock/Unlock function to be used during all procedures // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be initialized // * IN [ fRoutine_t * ] @fLocker - a function to be used to lock the object @pSeq // * IN [ fRoutine_t * ] @fUnlocker - a function to be used to unlock the object @pSeq // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_setlockers( sRoutineSequence_t * pSeq, fRoutine_t * fLocker, fRoutine_t * fUnlocker ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq || NULL == fLocker || NULL == fUnlocker ) return false; #endif pSeq->fLocker = fLocker; pSeq->fUnlocker = fUnlocker; return true; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_iinsert_routine() // Inserts a routine into the routine sequence without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // * IN [ fRoutine_t * ] @routine - a routine to be inserted // Returns: // [ bool ], result of operation, true = success, false = error #if RSA_USE_LOCKERS > 0 bool rsa_sequence_iinsert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine ) #else bool rsa_sequence_insert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq || NULL == routine ) return false; #endif if( pSeq->count < pSeq->size ) { pSeq->papfRoutineList[ pSeq->count++ ] = routine; return true; } return false; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_insert_routine() // Inserts a routine into the routine sequence with locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // * IN [ fRoutine_t * ] @routine - a routine to be inserted // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_insert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq || NULL == routine ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_iinsert_routine( pSeq, routine ); pSeq->fUnlocker( pSeq ); } return result; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_iskip_routine() // Skips the current routine into the routine sequence without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error #if RSA_USE_LOCKERS > 0 bool rsa_sequence_iskip_routine( sRoutineSequence_t * pSeq ) #else bool rsa_sequence_skip_routine( sRoutineSequence_t * pSeq ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; #endif if( pSeq->idx + 1 < pSeq->count ) { pSeq->idx++; return true; } return false; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_skip_routine() // Skips the current routine into the routine sequence with locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_skip_routine( sRoutineSequence_t * pSeq ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_iskip_routine( pSeq ); pSeq->fUnlocker( pSeq ); } return result; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_iback_routine() // Rolls the routine sequence back and make the previous routine to be called without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error #if RSA_USE_LOCKERS > 0 bool rsa_sequence_iback_routine( sRoutineSequence_t * pSeq ) #else bool rsa_sequence_back_routine( sRoutineSequence_t * pSeq ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; #endif if( pSeq->idx - 1 > 0 ) { pSeq->idx--; return true; } return false; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_back_routine() // Rolls the routine sequence back and make the previous routine to be called with locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_back_routine( sRoutineSequence_t * pSeq ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_iback_routine( pSeq ); pSeq->fUnlocker( pSeq ); } return result; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_iremove_routine() // Removes the lastest routine from the routine sequence without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error #if RSA_USE_LOCKERS > 0 bool rsa_sequence_iremove_routine( sRoutineSequence_t * pSeq ) #else bool rsa_sequence_remove_routine( sRoutineSequence_t * pSeq ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; #endif if( pSeq->count > 0 ) { pSeq->papfRoutineList[ --pSeq->count ] = NULL_Routine; return true; } return false; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_remove_routine() // Removes the lastest routine from the routine sequence // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_remove_routine( sRoutineSequence_t * pSeq ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_iremove_routine( pSeq ); pSeq->fUnlocker( pSeq ); } return result; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_icall() // Implements an ordinar call of the routines sequence without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], end of sequence sign, true = sequence completed, false = sequence is in progress #if RSA_USE_LOCKERS > 0 bool rsa_sequence_icall( sRoutineSequence_t * pSeq ) #else bool rsa_sequence_call( sRoutineSequence_t * pSeq ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; #endif if( (pSeq->count > 0) && (pSeq->idx < pSeq->count) ) { if( pSeq->papfRoutineList[ pSeq->idx ]( pSeq->arg ) ) { pSeq->idx++; } return ( pSeq->idx >= pSeq->count ); } return true; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_call() // Implements an ordinar call of the routines sequence with locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], end of sequence sign, true = sequence completed, false = sequence is in progress bool rsa_sequence_call( sRoutineSequence_t * pSeq ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_icall( pSeq ); pSeq->fUnlocker( pSeq ); } return result; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_ireset() // Resets the routines sequence and makes it to be restarted without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error #if RSA_USE_LOCKERS > 0 bool rsa_sequence_ireset( sRoutineSequence_t * pSeq ) #else bool rsa_sequence_reset( sRoutineSequence_t * pSeq ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; #endif pSeq->idx = 0; return true; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_reset() // Resets the routines sequence and makes it to be restarted with locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_reset( sRoutineSequence_t * pSeq ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_ireset( pSeq ); pSeq->fUnlocker( pSeq ); } return result; } #endif // ----------------------------------------------------------------------------- // rsa_sequence_iclear() // Clears all the routines in the sequence without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error #if RSA_USE_LOCKERS > 0 bool rsa_sequence_iclear( sRoutineSequence_t * pSeq ) #else bool rsa_sequence_clear( sRoutineSequence_t * pSeq ) #endif { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; #endif pSeq->count = 0; pSeq->idx = 0; return true; } // ----------------------------------------------------------------------------- #if RSA_USE_LOCKERS > 0 // rsa_sequence_reset() // Clears all the routines in the sequence without locking // Params: // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified // Returns: // [ bool ], result of operation, true = success, false = error bool rsa_sequence_clear( sRoutineSequence_t * pSeq ) { #if RSA_STRICT_CHECKS > 0 if( NULL == pSeq ) return false; if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker ) { return false; } #endif bool result = false; if( pSeq->fLocker( pSeq ) ) { result = rsa_sequence_iclear( pSeq ); pSeq->fUnlocker( pSeq ); } return result; } #endif #endif