diff --git a/include/etl/callback_timer.h b/include/etl/callback_timer.h index 9c833dbb..55a54930 100644 --- a/include/etl/callback_timer.h +++ b/include/etl/callback_timer.h @@ -732,6 +732,30 @@ namespace etl return delta; } + //******************************************* + /// Checks if a timer is currently active. + /// Returns true if the timer is active, otherwise false. + //******************************************* + bool is_active(etl::timer::id::type id_) const + { + // Valid timer id? + if (is_valid_timer_id(id_)) + { + if (has_active_timer()) + { + const etl::callback_timer_data& timer = timer_array[id_]; + + // Registered timer? + if (timer.id != etl::timer::id::NO_TIMER) + { + return timer.is_active(); + } + } + } + + return false; + } + protected: //******************************************* @@ -751,6 +775,14 @@ namespace etl private: + //******************************************* + /// Check that the timer id is valid. + //******************************************* + bool is_valid_timer_id(etl::timer::id::type id_) const + { + return (id_ < MAX_TIMERS); + } + // The array of timer data structures. callback_timer_data* const timer_array; diff --git a/include/etl/callback_timer_atomic.h b/include/etl/callback_timer_atomic.h index 2a886de2..f3e53b4b 100644 --- a/include/etl/callback_timer_atomic.h +++ b/include/etl/callback_timer_atomic.h @@ -327,6 +327,34 @@ namespace etl return delta; } + //******************************************* + /// Checks if a timer is currently active. + /// Returns true if the timer is active, otherwise false. + //******************************************* + bool is_active(etl::timer::id::type id_) const + { + bool result = false; + + // Valid timer id? + if (is_valid_timer_id(id_)) + { + ++process_semaphore; + if (has_active_timer()) + { + const timer_data& timer = timer_array[id_]; + + // Registered timer? + if (timer.id != etl::timer::id::NO_TIMER) + { + result = timer.is_active(); + } + } + --process_semaphore; + } + + return result; + } + protected: //************************************************************************* @@ -408,6 +436,14 @@ namespace etl private: + //******************************************* + /// Check that the timer id is valid. + //******************************************* + bool is_valid_timer_id(etl::timer::id::type id_) const + { + return (id_ < MAX_TIMERS); + } + //************************************************************************* /// A specialised intrusive linked list for timer data. //************************************************************************* diff --git a/include/etl/callback_timer_interrupt.h b/include/etl/callback_timer_interrupt.h index 831565aa..b744a123 100644 --- a/include/etl/callback_timer_interrupt.h +++ b/include/etl/callback_timer_interrupt.h @@ -1,4 +1,4 @@ -/****************************************************************************** + /****************************************************************************** The MIT License(MIT) Embedded Template Library. @@ -329,6 +329,33 @@ namespace etl return delta; } + //******************************************* + /// Checks if a timer is currently active. + /// Returns true if the timer is active, otherwise false. + //******************************************* + bool is_active(etl::timer::id::type id_) const + { + // Valid timer id? + if (is_valid_timer_id(id_)) + { + if (has_active_timer()) + { + TInterruptGuard guard; + (void)guard; // Silence 'unused variable warnings. + + const timer_data& timer = timer_array[id_]; + + // Registered timer? + if (timer.id != etl::timer::id::NO_TIMER) + { + return timer.is_active(); + } + } + } + + return false; + } + protected: //************************************************************************* @@ -409,6 +436,14 @@ namespace etl private: + //******************************************* + /// Check that the timer id is valid. + //******************************************* + bool is_valid_timer_id(etl::timer::id::type id_) const + { + return (id_ < MAX_TIMERS); + } + //************************************************************************* /// A specialised intrusive linked list for timer data. //************************************************************************* diff --git a/include/etl/callback_timer_locked.h b/include/etl/callback_timer_locked.h index c7480ba8..caf788ec 100644 --- a/include/etl/callback_timer_locked.h +++ b/include/etl/callback_timer_locked.h @@ -339,6 +339,34 @@ namespace etl return delta; } + //******************************************* + /// Checks if a timer is currently active. + /// Returns true if the timer is active, otherwise false. + //******************************************* + bool is_active(etl::timer::id::type id_) const + { + bool result = false; + + // Valid timer id? + if (is_valid_timer_id(id_)) + { + if (has_active_timer()) + { + lock(); + const timer_data& timer = timer_array[id_]; + + // Registered timer? + if (timer.id != etl::timer::id::NO_TIMER) + { + result = timer.is_active(); + } + unlock(); + } + } + + return result; + } + protected: //************************************************************************* @@ -603,6 +631,14 @@ namespace etl timer_data* const ptimers; }; + //******************************************* + /// Check that the timer id is valid. + //******************************************* + bool is_valid_timer_id(etl::timer::id::type id_) const + { + return (id_ < MAX_TIMERS); + } + // The array of timer data structures. timer_data* const timer_array; diff --git a/test/test_callback_timer.cpp b/test/test_callback_timer.cpp index cdb6bb99..e800990d 100644 --- a/test/test_callback_timer.cpp +++ b/test/test_callback_timer.cpp @@ -759,6 +759,41 @@ namespace CHECK(test_obj.called == 1); } + //************************************************************************* + TEST(callback_timer_is_active) + { + etl::callback_timer<4> timer_controller; + + etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); + etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); + etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Single_Shot); + + timer_controller.start(id1); + timer_controller.start(id3); + timer_controller.start(id2); + + timer_controller.enable(true); + + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_TRUE(timer_controller.is_active(id3)); + + timer_controller.tick(11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(23 - 11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(37 - 23); + CHECK_FALSE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + } + //************************************************************************* #if REALTIME_TEST diff --git a/test/test_callback_timer_atomic.cpp b/test/test_callback_timer_atomic.cpp index 73047903..97d1b366 100644 --- a/test/test_callback_timer_atomic.cpp +++ b/test/test_callback_timer_atomic.cpp @@ -764,6 +764,41 @@ namespace CHECK(test_obj.called == 1); } + //************************************************************************* + TEST(callback_timer_is_active) + { + etl::callback_timer_atomic<3, std::atomic_uint32_t> timer_controller; + + etl::timer::id::type id1 = timer_controller.register_timer(member_callback1, 37, etl::timer::mode::Single_Shot); + etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback1, 23, etl::timer::mode::Single_Shot); + etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + + timer_controller.start(id1); + timer_controller.start(id3); + timer_controller.start(id2); + + timer_controller.enable(true); + + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_TRUE(timer_controller.is_active(id3)); + + timer_controller.tick(11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(23 - 11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(37 - 23); + CHECK_FALSE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + } + //************************************************************************* #if REALTIME_TEST diff --git a/test/test_callback_timer_interrupt.cpp b/test/test_callback_timer_interrupt.cpp index b0fdba64..e13683d1 100644 --- a/test/test_callback_timer_interrupt.cpp +++ b/test/test_callback_timer_interrupt.cpp @@ -772,6 +772,41 @@ namespace CHECK_FALSE(timer_controller.has_active_timer()); } + //************************************************************************* + TEST(callback_timer_is_active) + { + etl::callback_timer_interrupt<3, ScopedGuard> timer_controller; + + etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); + etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); + etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + + timer_controller.start(id1); + timer_controller.start(id3); + timer_controller.start(id2); + + timer_controller.enable(true); + + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_TRUE(timer_controller.is_active(id3)); + + timer_controller.tick(11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(23 - 11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(37 - 23); + CHECK_FALSE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + } + //************************************************************************* class test_object { diff --git a/test/test_callback_timer_locked.cpp b/test/test_callback_timer_locked.cpp index c9f07cd4..c0e21bd1 100644 --- a/test/test_callback_timer_locked.cpp +++ b/test/test_callback_timer_locked.cpp @@ -871,6 +871,46 @@ namespace CHECK_EQUAL(4, timer_controller.time_to_next()); } + //************************************************************************* + TEST(callback_timer_is_active) + { + locks.clear(); + try_lock_type try_lock = try_lock_type::create(); + lock_type lock = lock_type::create(); + unlock_type unlock = unlock_type::create(); + + etl::callback_timer_locked<3> timer_controller(try_lock, lock, unlock); + + etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); + etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); + etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + + timer_controller.start(id1); + timer_controller.start(id3); + timer_controller.start(id2); + + timer_controller.enable(true); + + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_TRUE(timer_controller.is_active(id3)); + + timer_controller.tick(11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_TRUE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(23 - 11); + CHECK_TRUE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + + timer_controller.tick(37 - 23); + CHECK_FALSE(timer_controller.is_active(id1)); + CHECK_FALSE(timer_controller.is_active(id2)); + CHECK_FALSE(timer_controller.is_active(id3)); + } + //************************************************************************* TEST(message_timer_time_to_next_with_has_active_timer) {