mirror of https://github.com/ARMmbed/mbed-os.git
Add tests for ticker HAL API.
parent
03d7141797
commit
c32ccf69b1
|
@ -0,0 +1,56 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup hal_lp_ticker_tests
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef LP_TICKER_API_TESTS_H
|
||||
#define LP_TICKER_API_TESTS_H
|
||||
|
||||
#include "device.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Test that the ticker has the correct frequency and number of bits.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker information data is obtained.
|
||||
* Then collected data indicates that ticker frequency is between 8KHz and 64KHz and the counter is at least 12 bits wide.
|
||||
*/
|
||||
void lp_ticker_info_test(void);
|
||||
|
||||
/** Test that the ticker continues operating in deep sleep mode.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker has interrupt set and board enters deep-sleep mode.
|
||||
* Then ticker continues operating.
|
||||
*/
|
||||
void lp_ticker_deepsleep_test(void);
|
||||
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**@}*/
|
|
@ -1,5 +1,5 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2016 ARM Limited
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -13,177 +13,93 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
#include "rtos.h"
|
||||
#include "lp_ticker_api_tests.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
#if !DEVICE_LOWPOWERTIMER
|
||||
#error [NOT_SUPPORTED] Low power timer not supported for this target
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#endif
|
||||
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
|
||||
#include "mbed.h"
|
||||
#include "lp_ticker_api.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static volatile bool complete;
|
||||
static volatile timestamp_t complete_time;
|
||||
static ticker_event_t delay_event;
|
||||
static const ticker_data_t *lp_ticker_data = get_lp_ticker_data();
|
||||
static Timer timer;
|
||||
static LowPowerTimer lp_timer;
|
||||
volatile int intFlag = 0;
|
||||
|
||||
/* Timeouts are quite arbitrary due to large number of boards with varying level of accuracy */
|
||||
#define LONG_TIMEOUT (100000)
|
||||
#define SHORT_TIMEOUT (600)
|
||||
#define TICKER_INT_VAL 5000
|
||||
#define TICKER_DELTA 50
|
||||
|
||||
void cb_done(uint32_t id) {
|
||||
if ((uint32_t)&delay_event == id) {
|
||||
complete_time = timer.read_us();
|
||||
complete = true;
|
||||
} else {
|
||||
// Normal ticker handling
|
||||
TimerEvent::irq(id);
|
||||
void ticker_event_handler_stub(const ticker_data_t * const ticker)
|
||||
{
|
||||
/* Indicate that ISR has been executed in interrupt context. */
|
||||
if (IS_IRQ_MODE()) {
|
||||
intFlag++;
|
||||
}
|
||||
|
||||
/* Clear and disable ticker interrupt. */
|
||||
lp_ticker_clear_interrupt();
|
||||
lp_ticker_disable_interrupt();
|
||||
}
|
||||
|
||||
void cb_done_deepsleep(uint32_t id) {
|
||||
if ((uint32_t)&delay_event == id) {
|
||||
complete_time = lp_timer.read_us();
|
||||
complete = true;
|
||||
} else {
|
||||
// Normal ticker handling
|
||||
TimerEvent::irq(id);
|
||||
void wait_cycles(volatile unsigned int cycles)
|
||||
{
|
||||
while (cycles--);
|
||||
}
|
||||
|
||||
/* Test that the ticker has the correct frequency and number of bits. */
|
||||
void lp_ticker_info_test()
|
||||
{
|
||||
const ticker_info_t* p_ticker_info = lp_ticker_get_info();
|
||||
|
||||
TEST_ASSERT(p_ticker_info->frequency >= 8000);
|
||||
TEST_ASSERT(p_ticker_info->frequency <= 64000);
|
||||
TEST_ASSERT(p_ticker_info->bits >= 12);
|
||||
}
|
||||
|
||||
/* Test that the ticker continues operating in deep sleep mode. */
|
||||
void lp_ticker_deepsleep_test()
|
||||
{
|
||||
intFlag = 0;
|
||||
|
||||
set_lp_ticker_irq_handler(ticker_event_handler_stub);
|
||||
|
||||
lp_ticker_init();
|
||||
|
||||
/* Wait for green tea UART transmission before entering deep-sleep mode. */
|
||||
wait_cycles(40000);
|
||||
|
||||
const uint32_t tick_count = lp_ticker_read();
|
||||
|
||||
/* Set interrupt. Interrupt should be fired when tick count is equal to:
|
||||
* tick_count + TICKER_INT_VAL. */
|
||||
lp_ticker_set_interrupt(tick_count + TICKER_INT_VAL);
|
||||
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
|
||||
while (!intFlag) {
|
||||
sleep();
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(1, intFlag);
|
||||
}
|
||||
|
||||
void lp_ticker_delay_us(uint32_t delay_us, uint32_t tolerance)
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
complete = false;
|
||||
uint32_t delay_ts;
|
||||
|
||||
ticker_set_handler(lp_ticker_data, cb_done);
|
||||
ticker_remove_event(lp_ticker_data, &delay_event);
|
||||
delay_ts = ticker_read(lp_ticker_data) + delay_us;
|
||||
|
||||
timer.reset();
|
||||
timer.start();
|
||||
ticker_insert_event(lp_ticker_data, &delay_event, delay_ts, (uint32_t)&delay_event);
|
||||
while (!complete);
|
||||
timer.stop();
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(tolerance, delay_us, complete_time);
|
||||
TEST_ASSERT_TRUE(complete);
|
||||
}
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
void lp_ticker_1s_deepsleep()
|
||||
{
|
||||
complete = false;
|
||||
uint32_t delay_ts;
|
||||
|
||||
/*
|
||||
* Since deepsleep() may shut down the UART peripheral, we wait for 10ms
|
||||
* to allow for hardware serial buffers to completely flush.
|
||||
|
||||
* This should be replaced with a better function that checks if the
|
||||
* hardware buffers are empty. However, such an API does not exist now,
|
||||
* so we'll use the wait_ms() function for now.
|
||||
*/
|
||||
wait_ms(10);
|
||||
|
||||
ticker_set_handler(lp_ticker_data, cb_done_deepsleep);
|
||||
ticker_remove_event(lp_ticker_data, &delay_event);
|
||||
delay_ts = ticker_read(lp_ticker_data) + 1000000;
|
||||
|
||||
/*
|
||||
* We use here the low power timer instead of microsecond timer for start and
|
||||
* end because the microseconds timer might be disable during deepsleep.
|
||||
*/
|
||||
lp_timer.reset();
|
||||
lp_timer.start();
|
||||
ticker_insert_event(lp_ticker_data, &delay_event, delay_ts, (uint32_t)&delay_event);
|
||||
/* Make sure deepsleep is allowed, to go to deepsleep */
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
|
||||
sleep();
|
||||
while (!complete);
|
||||
lp_timer.stop();
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(LONG_TIMEOUT, 1000000, complete_time);
|
||||
TEST_ASSERT_TRUE(complete);
|
||||
}
|
||||
|
||||
void lp_ticker_1s_sleep()
|
||||
{
|
||||
complete = false;
|
||||
uint32_t delay_ts;
|
||||
|
||||
ticker_set_handler(lp_ticker_data, cb_done);
|
||||
ticker_remove_event(lp_ticker_data, &delay_event);
|
||||
delay_ts = ticker_read(lp_ticker_data) + 1000000;
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
timer.reset();
|
||||
timer.start();
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed");
|
||||
ticker_insert_event(lp_ticker_data, &delay_event, delay_ts, (uint32_t)&delay_event);
|
||||
sleep();
|
||||
while (!complete);
|
||||
timer.stop();
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(LONG_TIMEOUT, 1000000, complete_time);
|
||||
TEST_ASSERT_TRUE(complete);
|
||||
}
|
||||
#endif /* DEVICE_SLEEP */
|
||||
|
||||
void lp_ticker_500us(void)
|
||||
{
|
||||
lp_ticker_delay_us(500, SHORT_TIMEOUT);
|
||||
}
|
||||
|
||||
void lp_ticker_1ms(void)
|
||||
{
|
||||
lp_ticker_delay_us(1000, SHORT_TIMEOUT);
|
||||
}
|
||||
|
||||
void lp_ticker_1s(void)
|
||||
{
|
||||
lp_ticker_delay_us(1000000, LONG_TIMEOUT);
|
||||
}
|
||||
|
||||
void lp_ticker_5s(void)
|
||||
{
|
||||
lp_ticker_delay_us(5000000, LONG_TIMEOUT);
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
|
||||
greentea_case_failure_abort_handler(source, reason);
|
||||
return STATUS_CONTINUE;
|
||||
GREENTEA_SETUP(20, "default_auto");
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("500us lp_ticker", lp_ticker_500us, greentea_failure_handler),
|
||||
Case("1ms lp_ticker", lp_ticker_1ms, greentea_failure_handler),
|
||||
Case("1s lp_ticker", lp_ticker_1s, greentea_failure_handler),
|
||||
Case("5s lp_ticker", lp_ticker_5s, greentea_failure_handler),
|
||||
#if DEVICE_SLEEP
|
||||
Case("1s lp_ticker sleep", lp_ticker_1s_sleep, greentea_failure_handler),
|
||||
Case("1s lp_ticker deepsleep", lp_ticker_1s_deepsleep, greentea_failure_handler),
|
||||
#endif /* DEVICE_SLEEP */
|
||||
Case("lp ticker info test", lp_ticker_info_test),
|
||||
Case("lp ticker sleep test", lp_ticker_deepsleep_test),
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
|
||||
GREENTEA_SETUP(20, "default_auto");
|
||||
lp_ticker_data->interface->init();
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
Specification specification(test_setup, cases);
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
||||
int main() {
|
||||
Harness::run(specification);
|
||||
int main()
|
||||
{
|
||||
return !Harness::run(specification);
|
||||
}
|
||||
|
|
|
@ -13,67 +13,392 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
|
||||
#include "mbed.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "ticker_api.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
#include "ticker_api_tests.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
#if !DEVICE_USTICKER
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#endif
|
||||
|
||||
#define FORCE_OVERFLOW_TEST (false)
|
||||
#define TICKER_INT_VAL 2000
|
||||
#define TICKER_DELTA 50
|
||||
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
#define TICKER_OVERFLOW_DELTA 0 // this will allow to detect that ticker counter rollovers to 0
|
||||
#else
|
||||
#define TICKER_OVERFLOW_DELTA 50
|
||||
#endif
|
||||
|
||||
#define TICKER_100_TICKS 100
|
||||
|
||||
#define MAX_FUNC_EXEC_TIME_US 20
|
||||
#define DELTA_FUNC_EXEC_TIME_US 5
|
||||
#define NUM_OF_CALLS 1000
|
||||
|
||||
#define NUM_OF_CYCLES 100000
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace {
|
||||
volatile bool complete;
|
||||
const ticker_interface_t* intf;
|
||||
volatile int intFlag = 0;
|
||||
const ticker_interface_t* intf;
|
||||
|
||||
/* Auxiliary function to count ticker ticks elapsed during execution of N cycles of empty while loop.
|
||||
* Parameter <step> is used to disable compiler optimisation. */
|
||||
uint32_t count_ticks(volatile uint32_t cycles, uint32_t step)
|
||||
{
|
||||
/* Init the ticker. */
|
||||
intf->init();
|
||||
|
||||
core_util_critical_section_enter();
|
||||
|
||||
const uint32_t start = intf->read();
|
||||
|
||||
while (cycles -= step) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
const uint32_t stop = intf->read();
|
||||
|
||||
core_util_critical_section_exit();
|
||||
|
||||
return (stop - start);
|
||||
}
|
||||
|
||||
/* Ticker init should be run just once, thus read should always return a value that
|
||||
* increases (no reset).
|
||||
*/
|
||||
void test_ticker_init(void)
|
||||
void ticker_event_handler_stub(const ticker_data_t * const ticker)
|
||||
{
|
||||
intf->init();
|
||||
uint32_t previous = intf->read();
|
||||
if (ticker == get_us_ticker_data()) {
|
||||
us_ticker_clear_interrupt();
|
||||
} else {
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
lp_ticker_clear_interrupt();
|
||||
#endif
|
||||
}
|
||||
|
||||
intf->init();
|
||||
uint32_t current = intf->read();
|
||||
TEST_ASSERT_TRUE_MESSAGE(previous <= current, "init() changed the counter");
|
||||
|
||||
previous = intf->read();
|
||||
intf->init();
|
||||
current = intf->read();
|
||||
TEST_ASSERT_TRUE_MESSAGE(previous <= current, "init() changed the counter");
|
||||
}
|
||||
|
||||
/* Read multiple times, each returned time should be bigger than the previous one
|
||||
* Counter up.
|
||||
*/
|
||||
void test_ticker_read(void)
|
||||
{
|
||||
// this test assumes that to wrap around we would need to run >60 minutes
|
||||
// therefore wrapping should not happen - previous <= current
|
||||
const uint32_t test_loop = 15000;
|
||||
uint32_t previous = intf->read();
|
||||
uint32_t current;
|
||||
for (uint32_t i = 0UL; i < test_loop; i++) {
|
||||
current = intf->read();
|
||||
TEST_ASSERT_TRUE_MESSAGE(previous <= current, "us ticker counter wrapped around");
|
||||
/* Indicate that ISR has been executed in interrupt context. */
|
||||
if (IS_IRQ_MODE()) {
|
||||
intFlag++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement simple read while loop to check if time is increasing (counter up)
|
||||
*/
|
||||
void test_ticker_read_loop()
|
||||
void wait_cycles(volatile unsigned int cycles)
|
||||
{
|
||||
uint32_t future_time = intf->read() + 10000UL;
|
||||
while (intf->read() < future_time);
|
||||
TEST_ASSERT_TRUE_MESSAGE(future_time <= intf->read(), "Future time is in the past");
|
||||
while (cycles--);
|
||||
}
|
||||
|
||||
utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index_of_case)
|
||||
/* Test that ticker_init can be called multiple times and
|
||||
* ticker_init resets the internal count and disables the ticker interrupt.
|
||||
*/
|
||||
void ticker_init_test()
|
||||
{
|
||||
intFlag = 0;
|
||||
|
||||
intf->init();
|
||||
|
||||
/* Wait a while - let the ticker to count. */
|
||||
wait_cycles(10000);
|
||||
|
||||
const uint32_t ticks_start = intf->read();
|
||||
|
||||
intf->set_interrupt(ticks_start + TICKER_INT_VAL);
|
||||
|
||||
/* Re-initialise the ticker. */
|
||||
intf->init();
|
||||
|
||||
const uint32_t ticks_after_reinit = intf->read();
|
||||
|
||||
/* Wait long enough to fire ticker interrupt (should not be fired). */
|
||||
while (intf->read() < (ticks_start + 2 * TICKER_INT_VAL)) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
TEST_ASSERT(intf->read() >= (ticks_start + 2 * TICKER_INT_VAL));
|
||||
TEST_ASSERT(ticks_start > ticks_after_reinit);
|
||||
TEST_ASSERT_EQUAL(0, intFlag);
|
||||
}
|
||||
|
||||
/* Test that ticker frequency is non-zero and counter is at least 8 bits */
|
||||
void ticker_info_test(void)
|
||||
{
|
||||
const ticker_info_t* p_ticker_info = intf->get_info();
|
||||
|
||||
TEST_ASSERT(p_ticker_info->frequency != 0);
|
||||
TEST_ASSERT(p_ticker_info->bits >= 8);
|
||||
}
|
||||
|
||||
/* Test that ticker interrupt fires only when the ticker counter increments to the value set by ticker_set_interrupt. */
|
||||
void ticker_interrupt_test(void)
|
||||
{
|
||||
uint32_t ticker_timeout[] = { 100, 500, 1000, 2000 };
|
||||
|
||||
intf->init();
|
||||
|
||||
for (uint32_t i = 0; i < (sizeof(ticker_timeout) / sizeof(uint32_t)); i++) {
|
||||
intFlag = 0;
|
||||
const uint32_t tick_count = intf->read();
|
||||
|
||||
/* Set interrupt. Interrupt should be fired when tick count is equal to:
|
||||
* tick_count + ticker_timeout[i]. */
|
||||
intf->set_interrupt(tick_count + ticker_timeout[i]);
|
||||
|
||||
/* Wait until ticker count reach value: tick_count + ticker_timeout[i] - TICKER_DELTA.
|
||||
* Interrupt should not be fired. */
|
||||
while (intf->read() < (tick_count + ticker_timeout[i] - TICKER_DELTA)) {
|
||||
/* Indicate failure if interrupt has fired earlier. */
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(0, intFlag, "Interrupt fired too early");
|
||||
}
|
||||
|
||||
/* Wait until ticker count reach value: tick_count + ticker_timeout[i].
|
||||
* Interrupt should be fired after this time. */
|
||||
while (intf->read() < (tick_count + ticker_timeout[i])) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(1, intFlag);
|
||||
|
||||
/* Wait until ticker count reach value: tick_count + 3 * ticker_timeout[i].
|
||||
* Interrupt should not be triggered again. */
|
||||
while (intf->read() < (tick_count + 3 * ticker_timeout[i])) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(1, intFlag);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that ticker interrupt is not triggered when ticker_set_interrupt */
|
||||
void ticker_past_test(void)
|
||||
{
|
||||
intFlag = 0;
|
||||
|
||||
intf->init();
|
||||
|
||||
const uint32_t tick_count = intf->read();
|
||||
|
||||
/* Set interrupt tick count to value in the past.
|
||||
* Interrupt should not be fired. */
|
||||
intf->set_interrupt(tick_count - TICKER_DELTA);
|
||||
|
||||
wait_cycles(1000);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, intFlag);
|
||||
}
|
||||
|
||||
/* Test that ticker can be rescheduled repeatedly before the handler has been called. */
|
||||
void ticker_repeat_reschedule_test(void)
|
||||
{
|
||||
intFlag = 0;
|
||||
|
||||
intf->init();
|
||||
|
||||
const uint32_t tick_count = intf->read();
|
||||
|
||||
/* Set interrupt. Interrupt should be fired when tick count is equal to:
|
||||
* tick_count + TICKER_INT_VAL. */
|
||||
intf->set_interrupt(tick_count + TICKER_INT_VAL);
|
||||
|
||||
/* Reschedule interrupt - it should not be fired yet.
|
||||
* Re-schedule interrupt. */
|
||||
intf->set_interrupt(tick_count + (2 * TICKER_INT_VAL));
|
||||
intf->set_interrupt(tick_count + (3 * TICKER_INT_VAL));
|
||||
|
||||
/* Wait until ticker count reach value: tick_count + 3*TICKER_INT_VAL - TICKER_DELTA.
|
||||
* Interrupt should not be fired. */
|
||||
while (intf->read() < (tick_count + 3 * TICKER_INT_VAL - TICKER_DELTA)) {
|
||||
/* Indicate failure if interrupt has fired earlier. */
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(0, intFlag, "Interrupt fired too early");
|
||||
}
|
||||
|
||||
/* Wait until ticker count reach value: tick_count + 3*TICKER_INT_VAL + TICKER_DELTA.
|
||||
* Interrupt should be fired after this time. */
|
||||
while (intf->read() < (tick_count + 3 * TICKER_INT_VAL + TICKER_DELTA)) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(1, intFlag);
|
||||
}
|
||||
|
||||
/* Test that ticker_fire_interrupt causes and interrupt to get fired immediately. */
|
||||
void ticker_fire_now_test(void)
|
||||
{
|
||||
intFlag = 0;
|
||||
|
||||
intf->init();
|
||||
|
||||
intf->fire_interrupt();
|
||||
|
||||
/* On some platforms set_interrupt function sets interrupt in the nearest feature. */
|
||||
wait_cycles(1000);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, intFlag);
|
||||
}
|
||||
|
||||
/* Test that the ticker correctly handles overflow. */
|
||||
void ticker_overflow_test(void)
|
||||
{
|
||||
const ticker_info_t* p_ticker_info = intf->get_info();
|
||||
|
||||
/* We need to check how long it will take to overflow.
|
||||
* We will perform this test only if this time is no longer than 30 sec.
|
||||
*/
|
||||
const uint32_t max_count = (1 << p_ticker_info->bits) - 1;
|
||||
const uint32_t required_time_sec = (max_count / p_ticker_info->frequency);
|
||||
|
||||
if (required_time_sec > 30 && !FORCE_OVERFLOW_TEST) {
|
||||
TEST_ASSERT_TRUE(true);
|
||||
printf("Test has been skipped.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
intFlag = 0;
|
||||
|
||||
intf->init();
|
||||
|
||||
/* Wait for max count. */
|
||||
while (intf->read() != (max_count - TICKER_OVERFLOW_DELTA)) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
/* Now we are near/at the overflow point. Detect rollover. */
|
||||
while (intf->read() > TICKER_OVERFLOW_DELTA);
|
||||
|
||||
const uint32_t after_overflow = intf->read();
|
||||
|
||||
/* Now we are just after overflow. Wait a while assuming that ticker still counts. */
|
||||
while (intf->read() < TICKER_100_TICKS) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
const uint32_t next_after_overflow = intf->read();
|
||||
|
||||
/* Check that after the overflow ticker continue count. */
|
||||
TEST_ASSERT(after_overflow <= TICKER_OVERFLOW_DELTA);
|
||||
TEST_ASSERT(next_after_overflow >= TICKER_100_TICKS);
|
||||
TEST_ASSERT_EQUAL(0, intFlag);
|
||||
|
||||
const uint32_t tick_count = intf->read();
|
||||
|
||||
/* Check if interrupt scheduling still works. */
|
||||
intf->set_interrupt(tick_count + TICKER_INT_VAL);
|
||||
|
||||
/* Wait for the interrupt. */
|
||||
while (intf->read() < (tick_count + TICKER_INT_VAL + TICKER_DELTA)) {
|
||||
/* Just wait. */
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(1, intFlag);
|
||||
}
|
||||
|
||||
/* Test that the ticker increments by one on each tick. */
|
||||
void ticker_increment_test(void)
|
||||
{
|
||||
intf->init();
|
||||
|
||||
const ticker_info_t* p_ticker_info = intf->get_info();
|
||||
|
||||
/* Perform test based on ticker speed. */
|
||||
if (p_ticker_info->frequency <= 250000) { // low frequency tickers
|
||||
const uint32_t base_tick_count = intf->read();
|
||||
uint32_t next_tick_count = base_tick_count;
|
||||
|
||||
while (next_tick_count == base_tick_count) {
|
||||
next_tick_count = intf->read();
|
||||
}
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(1, next_tick_count, base_tick_count);
|
||||
} else { // high frequency tickers
|
||||
const uint32_t base_tick_count = count_ticks(NUM_OF_CYCLES, 1);
|
||||
uint32_t next_tick_count = base_tick_count;
|
||||
uint32_t inc_val = 0;
|
||||
|
||||
while (next_tick_count == base_tick_count) {
|
||||
next_tick_count = count_ticks(NUM_OF_CYCLES + inc_val, 1);
|
||||
inc_val++;
|
||||
}
|
||||
|
||||
/* Since we are here we know that next_tick_count != base_tick_count.
|
||||
* The accuracy of our measurement method is +/- 1 tick, so it is possible that
|
||||
* next_tick_count == base_tick_count - 1. This is also valid result.
|
||||
*/
|
||||
TEST_ASSERT_UINT32_WITHIN(1, next_tick_count, base_tick_count);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test that common ticker functions complete with the required amount of time. */
|
||||
void ticker_speed_test(void)
|
||||
{
|
||||
Timer timer;
|
||||
int counter = NUM_OF_CALLS;
|
||||
|
||||
intf->init();
|
||||
|
||||
/* ---- Test ticker_read function. ---- */
|
||||
timer.reset();
|
||||
timer.start();
|
||||
while (counter--) {
|
||||
intf->read();
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
|
||||
|
||||
/* ---- Test ticker_clear_interrupt function. ---- */
|
||||
counter = NUM_OF_CALLS;
|
||||
timer.reset();
|
||||
timer.start();
|
||||
while (counter--) {
|
||||
intf->clear_interrupt();
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
|
||||
|
||||
/* ---- Test ticker_set_interrupt function. ---- */
|
||||
counter = NUM_OF_CALLS;
|
||||
timer.reset();
|
||||
timer.start();
|
||||
while (counter--) {
|
||||
intf->set_interrupt(0);
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
|
||||
|
||||
/* ---- Test fire_interrupt function. ---- */
|
||||
counter = NUM_OF_CALLS;
|
||||
timer.reset();
|
||||
timer.start();
|
||||
while (counter--) {
|
||||
intf->fire_interrupt();
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
|
||||
|
||||
/* ---- Test disable_interrupt function. ---- */
|
||||
counter = NUM_OF_CALLS;
|
||||
timer.reset();
|
||||
timer.start();
|
||||
while (counter--) {
|
||||
intf->disable_interrupt();
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
TEST_ASSERT(timer.read_us() < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US)));
|
||||
}
|
||||
|
||||
|
||||
utest::v1::status_t hf_ticker_setup(const Case *const source, const size_t index_of_case)
|
||||
{
|
||||
intf = get_us_ticker_data()->interface;
|
||||
|
||||
set_us_ticker_irq_handler(ticker_event_handler_stub);
|
||||
|
||||
return greentea_case_setup_handler(source, index_of_case);
|
||||
}
|
||||
|
||||
|
@ -81,30 +406,45 @@ utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index
|
|||
utest::v1::status_t lp_ticker_setup(const Case *const source, const size_t index_of_case)
|
||||
{
|
||||
intf = get_lp_ticker_data()->interface;
|
||||
|
||||
set_lp_ticker_irq_handler(ticker_event_handler_stub);
|
||||
|
||||
return greentea_case_setup_handler(source, index_of_case);
|
||||
}
|
||||
#endif
|
||||
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(30, "default_auto");
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("us ticker HAL - Init", us_ticker_setup, test_ticker_init),
|
||||
Case("us ticker HAL - Read", us_ticker_setup, test_ticker_read),
|
||||
Case("us ticker HAL - Read in the loop", us_ticker_setup, test_ticker_read_loop),
|
||||
Case("hf ticker init is safe to call repeatedly", hf_ticker_setup, ticker_init_test),
|
||||
Case("hf ticker info test", hf_ticker_setup, ticker_info_test),
|
||||
Case("hf ticker interrupt test", hf_ticker_setup, ticker_interrupt_test),
|
||||
Case("hf ticker past interrupt test", hf_ticker_setup, ticker_past_test),
|
||||
Case("hf ticker reschedule test", hf_ticker_setup, ticker_repeat_reschedule_test),
|
||||
Case("hf ticker fire interrupt", hf_ticker_setup, ticker_fire_now_test),
|
||||
Case("hf ticker overflow test", hf_ticker_setup, ticker_overflow_test),
|
||||
Case("hf ticker increment test", hf_ticker_setup, ticker_increment_test),
|
||||
Case("hf ticker speed test", hf_ticker_setup, ticker_speed_test),
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
Case("lp ticker HAL - Init", lp_ticker_setup, test_ticker_init),
|
||||
Case("lp ticker HAL - Read", lp_ticker_setup, test_ticker_read),
|
||||
Case("lp ticker HAL - Read in the loop", lp_ticker_setup, test_ticker_read_loop),
|
||||
Case("lp ticker init is safe to call repeatedly", lp_ticker_setup, ticker_init_test),
|
||||
Case("lp ticker info test", lp_ticker_setup, ticker_info_test),
|
||||
Case("lp ticker interrupt test", lp_ticker_setup, ticker_interrupt_test),
|
||||
Case("lp ticker past interrupt test", lp_ticker_setup, ticker_past_test),
|
||||
Case("lp ticker reschedule test", lp_ticker_setup, ticker_repeat_reschedule_test),
|
||||
Case("lp ticker fire interrupt", lp_ticker_setup, ticker_fire_now_test),
|
||||
Case("lp ticker overflow test", lp_ticker_setup, ticker_overflow_test),
|
||||
Case("lp ticker increment test", lp_ticker_setup, ticker_increment_test),
|
||||
Case("lp ticker speed test", lp_ticker_setup, ticker_speed_test),
|
||||
#endif
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(20, "default_auto");
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
Specification specification(test_setup, cases);
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
||||
int main()
|
||||
int main()
|
||||
{
|
||||
Harness::run(specification);
|
||||
return !Harness::run(specification);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup hal_ticker_tests */
|
||||
/** @{*/
|
||||
|
||||
#ifndef TICKER_API_TESTS_H
|
||||
#define TICKER_API_TESTS_H
|
||||
|
||||
#include "device.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Test that ticker_init can be called multiple times and
|
||||
* ticker_init resets the internal count and disables the ticker interrupt.
|
||||
*
|
||||
* Given ticker is initialised and interrupt is set.
|
||||
* When ticker is re-initialised.
|
||||
* Then ticker resets the internal count and disables the ticker interrupt.
|
||||
*/
|
||||
void ticker_init_test(void);
|
||||
|
||||
/** Test that ticker frequency is non-zero and counter is at least 8 bits
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker information data is obtained.
|
||||
* Then ticker information indicate that frequency is non-zero and counter is at least 8 bits.
|
||||
*/
|
||||
void ticker_info_test(void);
|
||||
|
||||
/** Test that the ticker increments by one on each tick.
|
||||
*
|
||||
* We have the following assumption for the timer clock frequency:
|
||||
*
|
||||
* NOTE:
|
||||
* high freq ticker: 250 KHz (1 tick per 4 us) - 8 Mhz (1 tick per 1/8 us)
|
||||
* low power ticker: 8 KHz (1 tick per 125 us) - 64 KHz (1 tick per ~15.6 us)
|
||||
*
|
||||
* Lowest CPU speed is 16 MHz (1 tick per 1/16 us).
|
||||
*
|
||||
* For the boards with ticker clock freq less than or equal to 250 KHz we will try to prove that ticker is incremented by one
|
||||
* straightforward by reading ticker count value in the loop in order to detect a single ticker value update (hopefully by one).
|
||||
* For faster tickers we need to prove this indirectly using additional count_ticks() function which returns number of
|
||||
* ticks needed to perform N cycles of the empty while loop. For the same number of cycles function result should be the same with
|
||||
* accuracy +/- 1 tick. After the first test we will call count_ticks again with number of cycles equal N, N+1, N+2, ...
|
||||
* until we get other ticks result.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker is initialised.
|
||||
* Then ticker counter is incremented by one.
|
||||
*/
|
||||
void ticker_increment_test(void);
|
||||
|
||||
/** Test that ticker interrupt fires only when the ticker counter increments to the value set by ticker_set_interrupt.
|
||||
*
|
||||
* Given ticker is available, initialised.
|
||||
* When ticker interrupt is set.
|
||||
* Then ticker interrupt fires at the valid time.
|
||||
*/
|
||||
void ticker_interrupt_test(void);
|
||||
|
||||
/** Test that ticker interrupt is not triggered when ticker_set_interrupt is called with a time from the past
|
||||
*
|
||||
* Given ticker is available, initialised.
|
||||
* When ticker interrupt is set to the time in the past.
|
||||
* Then ticker interrupt is not triggered.
|
||||
*/
|
||||
void ticker_past_test(void);
|
||||
|
||||
/** Test that ticker can be rescheduled repeatedly before the handler has been called.
|
||||
*
|
||||
* Given ticker is available, initialised.
|
||||
* When ticker interrupt is set and then rescheduled (interrupt time is modified).
|
||||
* Then ticker interrupt is triggered according the rescheduled time.
|
||||
*/
|
||||
void ticker_repeat_reschedule_test(void);
|
||||
|
||||
/** Test that ticker_fire_interrupt causes the interrupt to get fired immediately.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker_fire_interrupt is called.
|
||||
* Then ticker interrupt is triggered.
|
||||
*/
|
||||
void ticker_fire_now_test(void);
|
||||
|
||||
/** Test that common ticker functions complete with the required amount of time.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker_read, ticker_clear_interrupt, ticker_set_interrupt, ticker_fire_interrupt or ticker_disable_interrupt function is called.
|
||||
* Then its execution is not longer than 20 us.
|
||||
*/
|
||||
void ticker_speed_test(void);
|
||||
|
||||
/** Test that the ticker correctly handles overflow.
|
||||
*
|
||||
* Note that for high frequency timers we will only prove that ticker counter rollovers and
|
||||
* continue counting (it is not possible to prove in deterministic way that after rollover next value is 0).
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker has overflows.
|
||||
* Then ticker continues counting from the beginning and interrupt scheduling works.
|
||||
*/
|
||||
void ticker_overflow_test(void);
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**@}*/
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is the mbed device part of the test to verify if mbed board ticker
|
||||
* freqency is valid.
|
||||
*/
|
||||
|
||||
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "ticker_api_test_freq.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
#if !DEVICE_USTICKER
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#endif
|
||||
|
||||
#define US_PER_S 1000000
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
const ticker_interface_t* intf;
|
||||
|
||||
static volatile unsigned int overflowCounter;
|
||||
|
||||
unsigned int ticks_to_us(unsigned int ticks, unsigned int freq)
|
||||
{
|
||||
return (unsigned int)((unsigned long long)ticks * US_PER_S / freq);
|
||||
}
|
||||
|
||||
void ticker_event_handler_stub(const ticker_data_t * const ticker)
|
||||
{
|
||||
if (ticker == get_us_ticker_data()) {
|
||||
us_ticker_clear_interrupt();
|
||||
} else {
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
lp_ticker_clear_interrupt();
|
||||
#endif
|
||||
}
|
||||
|
||||
overflowCounter++;
|
||||
}
|
||||
|
||||
/* Test that the ticker is operating at the frequency it specifies. */
|
||||
void ticker_frequency_test()
|
||||
{
|
||||
char _key[11] = { };
|
||||
char _value[128] = { };
|
||||
int expected_key = 1;
|
||||
const unsigned int ticker_freq = intf->get_info()->frequency;
|
||||
const unsigned int ticker_bits = intf->get_info()->bits;
|
||||
const unsigned int ticker_max = (1 << ticker_bits) - 1;
|
||||
|
||||
overflowCounter = 0;
|
||||
|
||||
intf->init();
|
||||
|
||||
/* Detect overflow for tickers with lower counters width. */
|
||||
intf->set_interrupt(0);
|
||||
|
||||
greentea_send_kv("timing_drift_check_start", 0);
|
||||
|
||||
/* Wait for 1st signal from host. */
|
||||
do {
|
||||
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
|
||||
expected_key = strcmp(_key, "base_time");
|
||||
} while (expected_key);
|
||||
|
||||
const unsigned int begin_ticks = intf->read();
|
||||
|
||||
/* Assume that there was no overflow at this point - we are just after init. */
|
||||
greentea_send_kv(_key, ticks_to_us(begin_ticks, ticker_freq));
|
||||
|
||||
/* Wait for 2nd signal from host. */
|
||||
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
|
||||
|
||||
const unsigned int end_ticks = intf->read();
|
||||
|
||||
greentea_send_kv(_key, ticks_to_us(end_ticks + overflowCounter * ticker_max, ticker_freq));
|
||||
|
||||
/* Get the results from host. */
|
||||
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail...");
|
||||
|
||||
intf->disable_interrupt();
|
||||
}
|
||||
|
||||
utest::v1::status_t hf_ticker_case_setup_handler_t(const Case * const source, const size_t index_of_case)
|
||||
{
|
||||
intf = get_us_ticker_data()->interface;
|
||||
set_us_ticker_irq_handler(ticker_event_handler_stub);
|
||||
return greentea_case_setup_handler(source, index_of_case);
|
||||
}
|
||||
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
utest::v1::status_t lp_ticker_case_setup_handler_t(const Case * const source, const size_t index_of_case)
|
||||
{
|
||||
intf = get_lp_ticker_data()->interface;
|
||||
set_lp_ticker_irq_handler(ticker_event_handler_stub);
|
||||
return greentea_case_setup_handler(source, index_of_case);
|
||||
}
|
||||
#endif
|
||||
|
||||
utest::v1::status_t ticker_case_teardown_handler_t(const Case * const source, const size_t passed, const size_t failed,
|
||||
const failure_t reason)
|
||||
{
|
||||
return greentea_case_teardown_handler(source, passed, failed, reason);
|
||||
}
|
||||
|
||||
// Test cases
|
||||
Case cases[] = {
|
||||
Case("hf ticker frequency test", hf_ticker_case_setup_handler_t, ticker_frequency_test,
|
||||
ticker_case_teardown_handler_t),
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
Case("lp ticker frequency test", lp_ticker_case_setup_handler_t, ticker_frequency_test,
|
||||
ticker_case_teardown_handler_t),
|
||||
#endif
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(120, "timing_drift_auto");
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
||||
int main()
|
||||
{
|
||||
Harness::run(specification);
|
||||
}
|
|
@ -14,12 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup hal_lp_ticker_tests
|
||||
* @{
|
||||
*/
|
||||
/** \addtogroup hal_ticker_tests */
|
||||
/** @{*/
|
||||
|
||||
#ifndef LP_TICKER_API_TESTS_H
|
||||
#define LP_TICKER_API_TESTS_H
|
||||
#ifndef TICKER_API_TEST_FREQ_H
|
||||
#define TICKER_API_TEST_FREQ_H
|
||||
|
||||
#include "device.h"
|
||||
|
||||
|
@ -28,16 +27,13 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** Test that the ticker has the right frequency and number of bits
|
||||
/** Test that the ticker is operating at the frequency it specifies.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker specifies its frequency.
|
||||
* Then the specified frequency is valid.
|
||||
*/
|
||||
void lp_ticker_info_test(void);
|
||||
|
||||
/** Test that the ticker operates in deep sleep mode
|
||||
*
|
||||
*/
|
||||
void lp_ticker_deepsleep_test(void);
|
||||
void ticker_frequency_test(void);
|
||||
|
||||
|
||||
/**@}*/
|
|
@ -1,103 +0,0 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017-2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup hal_ticker_tests */
|
||||
/** @{*/
|
||||
|
||||
#ifndef TICKER_API_TESTS_H
|
||||
#define TICKER_API_TESTS_H
|
||||
|
||||
#include "device.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Test that ticker_init can be called multiple times
|
||||
*
|
||||
*/
|
||||
void ticker_init_test(void);
|
||||
|
||||
/** Test that ticker has a valid frequency and bitwidth
|
||||
*
|
||||
*/
|
||||
void ticker_info_test(void);
|
||||
|
||||
/** Test that the ticker increments by one on each tick
|
||||
*
|
||||
*/
|
||||
void ticker_increment_test(void);
|
||||
|
||||
/** Test that the interrupt fires at the right time
|
||||
*
|
||||
*/
|
||||
void ticker_interrupt_test(void);
|
||||
|
||||
/** Test that an interrupt is not triggered when ticker_set_interrupt is called with a time from the past
|
||||
*
|
||||
*/
|
||||
void ticker_past_test(void);
|
||||
|
||||
/** Test that a ticker can be rescheduled repeatedly before the handler has been called
|
||||
*
|
||||
*/
|
||||
void ticker_repeat_reschedule_test(void);
|
||||
|
||||
/** Test that ticker_fire_interrupt causes and interrupt to get fired immediately
|
||||
*
|
||||
*/
|
||||
void ticker_fire_now_test(void);
|
||||
|
||||
/** Test that common ticker functions complete with the required amount of time
|
||||
*
|
||||
* Ensure that ticker_read, ticker_clear_interrupt, ticker_set_interrupt
|
||||
* and ticker_fire_interrupt take less than 20us to complete.
|
||||
*
|
||||
*/
|
||||
void ticker_speed_test(void);
|
||||
|
||||
/** Test that the ticker correctly handles overflows
|
||||
*
|
||||
* This test verifies that rollover is properly handled and
|
||||
* that scheduling for a time after overflow works.
|
||||
*
|
||||
*/
|
||||
void ticker_overflow_test(void);
|
||||
|
||||
/** Test that rescheduling does not cause drift
|
||||
*
|
||||
* This test verifies that repeated rescheduling does not cause a
|
||||
* drift.
|
||||
*
|
||||
*/
|
||||
void ticker_reschedule_test(void);
|
||||
|
||||
/** Test that the ticker is operating at the frequency it specifies
|
||||
*
|
||||
*/
|
||||
void ticker_frequency_test(void);
|
||||
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**@}*/
|
|
@ -0,0 +1,54 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "mbed.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
#include "us_ticker_api_tests.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
|
||||
#if !DEVICE_USTICKER
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#endif
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
/* Test that the ticker has the correct frequency and number of bits. */
|
||||
void us_ticker_info_test()
|
||||
{
|
||||
const ticker_info_t* p_ticker_info = us_ticker_get_info();
|
||||
|
||||
TEST_ASSERT(p_ticker_info->frequency >= 250000);
|
||||
TEST_ASSERT(p_ticker_info->frequency <= 8000000);
|
||||
TEST_ASSERT(p_ticker_info->bits >= 16);
|
||||
}
|
||||
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(20, "default_auto");
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("us ticker info test", us_ticker_info_test),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
||||
int main()
|
||||
{
|
||||
return !Harness::run(specification);
|
||||
}
|
|
@ -27,9 +27,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** Test that the ticker has the right frequency and number of bits
|
||||
/** Test that the ticker has the correct frequency and number of bits.
|
||||
*
|
||||
* Given ticker is available.
|
||||
* When ticker information data is obtained.
|
||||
* Then ticker information indicate that frequency between 250KHz and 8MHz and the counter is at least 16 bits wide.
|
||||
*/
|
||||
void us_ticker_info_test(void);
|
||||
|
Loading…
Reference in New Issue