init

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2017, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "mbed.h"
00019 #include "greentea-client/test_env.h"
00020 #include "unity.h"
00021 #include "utest.h"
00022 #include "rtos.h"
00023 #include "hal/us_ticker_api.h"
00024 
00025 #if !DEVICE_LOWPOWERTIMER
00026 #error [NOT_SUPPORTED] test not supported
00027 #endif
00028 
00029 using namespace utest::v1;
00030 
00031 extern uint32_t SystemCoreClock;
00032 
00033 /* This test is created based on the test for Timer class.
00034  * Since low power timer is less accurate than regular
00035  * timer we need to adjust delta.
00036  */
00037 
00038 /* Macro to define delta based on CPU clock frequency.
00039  *
00040  * Note that some extra time is counted by the timer.
00041  * Additional time is caused by the function calls and
00042  * additional operations performed by wait and
00043  * stop functions before in fact timer is stopped. This may
00044  * add additional time to the counted result.
00045  *
00046  * To take in to account this extra time we introduce DELTA
00047  * value based on CPU clock (speed):
00048  *   DELTA = TOLERANCE_FACTOR / SystemCoreClock * US_FACTOR
00049  *
00050  *   e.g.
00051  *   For K64F          DELTA = (80000 / 120000000) * 1000000 = 666[us]
00052  *   For NUCLEO_F070RB DELTA = (80000 /  48000000) * 1000000 = 1666[us]
00053  *   For NRF51_DK      DELTA = (80000 /  16000000) * 1000000 = 5000[us]
00054  *
00055  * As low power timer cannot be too much accurate, this DELTA should not be more precise than 500us,
00056  * which corresponds to a maximum CPU clock around 130MHz
00057  */
00058 #define US_PER_SEC       1000000
00059 #define US_PER_MSEC      1000
00060 #define TOLERANCE_FACTOR 80000.0f
00061 #define US_FACTOR        1000000.0f
00062 #define CLOCK_MAX        130000000
00063 
00064 static const int delta_sys_clk_us = (SystemCoreClock < CLOCK_MAX? ((int) (TOLERANCE_FACTOR / (float) SystemCoreClock * US_FACTOR)):((int) (TOLERANCE_FACTOR / (float) CLOCK_MAX * US_FACTOR)));
00065 
00066 /* When test performs time measurement using Timer in sequence, then measurement error accumulates
00067  * in the successive attempts. */
00068  #define DELTA_US(i) (delta_sys_clk_us * i)
00069  #define DELTA_S(i)  ((float)delta_sys_clk_us * i / US_PER_SEC)
00070  #define DELTA_MS(i) (1 + ( (i * delta_sys_clk_us) / US_PER_MSEC))
00071 
00072 /* This test verifies if low power timer is stopped after
00073  * creation.
00074  *
00075  * Given Timer has been successfully created.
00076  * When read of timer elapsed time is requested.
00077  * Then result is always 0.
00078  */
00079 void test_lptimer_creation()
00080 {
00081     LowPowerTimer lp_timer;
00082 
00083     /* Check results. */
00084     TEST_ASSERT_EQUAL_FLOAT(0, lp_timer.read());
00085     TEST_ASSERT_EQUAL_INT32(0, lp_timer.read_ms());
00086     TEST_ASSERT_EQUAL_INT32(0, lp_timer.read_us());
00087     TEST_ASSERT_EQUAL_UINT64(0, lp_timer.read_high_resolution_us());
00088 
00089     /* Wait 10 ms.
00090      * After that operation timer read routines should still return 0. */
00091     wait_ms(10);
00092 
00093     /* Check results. */
00094     TEST_ASSERT_EQUAL_FLOAT(0, lp_timer.read());
00095     TEST_ASSERT_EQUAL_INT32(0, lp_timer.read_ms());
00096     TEST_ASSERT_EQUAL_INT32(0, lp_timer.read_us());
00097     TEST_ASSERT_EQUAL_UINT64(0, lp_timer.read_high_resolution_us());
00098 }
00099 
00100 /* This test verifies if read(), read_us(), read_ms(),
00101  * read_high_resolution_us()
00102  * functions return time accumulated between
00103  * low power timer starts and stops.
00104  *
00105  * Given Timer has been successfully created and
00106  * few times started and stopped after a specified period of time.
00107  * When timer read request is performed.
00108  * Then read functions return accumulated time elapsed between starts
00109  * and stops.
00110  */
00111 void test_lptimer_time_accumulation()
00112 {
00113     LowPowerTimer lp_timer;
00114 
00115     /* Start the timer. */
00116     lp_timer.start();
00117 
00118     /* Wait 10 ms. */
00119     wait_ms(10);
00120 
00121     /* Stop the timer. */
00122     lp_timer.stop();
00123 
00124     /* Check results - totally 10 ms have elapsed. */
00125     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.010f, lp_timer.read());
00126     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), 10, lp_timer.read_ms());
00127     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), 10000, lp_timer.read_us());
00128     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), 10000, lp_timer.read_high_resolution_us());
00129 
00130     /* Wait 50 ms - this is done to show that time elapsed when
00131      * the timer is stopped does not have influence on the
00132      * timer counted time. */
00133     wait_ms(50);
00134 
00135     /* ------ */
00136 
00137     /* Start the timer. */
00138     lp_timer.start();
00139 
00140     /* Wait 20 ms. */
00141     wait_ms(20);
00142 
00143     /* Stop the timer. */
00144     lp_timer.stop();
00145 
00146     /* Check results - totally 30 ms have elapsed. */
00147     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(2), 0.030f, lp_timer.read());
00148     TEST_ASSERT_INT32_WITHIN(DELTA_MS(2), 30, lp_timer.read_ms());
00149     TEST_ASSERT_INT32_WITHIN(DELTA_US(2), 30000, lp_timer.read_us());
00150     TEST_ASSERT_UINT64_WITHIN(DELTA_US(2), 30000, lp_timer.read_high_resolution_us());
00151 
00152     /* Wait 50 ms - this is done to show that time elapsed when
00153      * the timer is stopped does not have influence on the
00154      * timer counted time. */
00155 
00156     /* ------ */
00157 
00158     /* Start the timer. */
00159     lp_timer.start();
00160 
00161     /* Wait 30 ms. */
00162     wait_ms(30);
00163 
00164     /* Stop the timer. */
00165     lp_timer.stop();
00166 
00167     /* Check results - totally 60 ms have elapsed. */
00168     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(3), 0.060f, lp_timer.read());
00169     TEST_ASSERT_INT32_WITHIN(DELTA_MS(3), 60, lp_timer.read_ms());
00170     TEST_ASSERT_INT32_WITHIN(DELTA_US(3), 60000, lp_timer.read_us());
00171     TEST_ASSERT_UINT64_WITHIN(DELTA_US(3), 60000, lp_timer.read_high_resolution_us());
00172 
00173     /* Wait 50 ms - this is done to show that time elapsed when
00174      * the timer is stopped does not have influence on the
00175      * timer time. */
00176     wait_ms(50);
00177 
00178     /* ------ */
00179 
00180     /* Start the timer. */
00181     lp_timer.start();
00182 
00183     /* Wait 1 sec. */
00184     wait_ms(1000);
00185 
00186     /* Stop the timer. */
00187     lp_timer.stop();
00188 
00189     /* Check results - totally 1060 ms have elapsed. */
00190     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(4), 1.060f, lp_timer.read());
00191     TEST_ASSERT_INT32_WITHIN(DELTA_MS(4), 1060, lp_timer.read_ms());
00192     TEST_ASSERT_INT32_WITHIN(DELTA_US(4), 1060000, lp_timer.read_us());
00193     TEST_ASSERT_UINT64_WITHIN(DELTA_US(4), 1060000, lp_timer.read_high_resolution_us());
00194 }
00195 
00196 /* This test verifies if reset() function resets the
00197  * low power timer counted time.
00198  *
00199  * Given timer has been started and stopped once, then reset
00200  * operation was performed.
00201  * When timer is started and stopped next time.
00202  * Then timer read functions returns only the the second
00203  * measured time.
00204  */
00205 void test_lptimer_reset()
00206 {
00207     LowPowerTimer lp_timer;
00208 
00209     /* First measure 10 ms delay. */
00210     lp_timer.start();
00211 
00212     /* Wait 10 ms. */
00213     wait_ms(10);
00214 
00215     /* Stop the timer. */
00216     lp_timer.stop();
00217 
00218     /* Check results - totally 10 ms elapsed. */
00219     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.010f, lp_timer.read());
00220     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), 10, lp_timer.read_ms());
00221     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), 10000, lp_timer.read_us());
00222     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), 10000, lp_timer.read_high_resolution_us());
00223 
00224     /* Reset the timer - previous measured time should be lost now. */
00225     lp_timer.reset();
00226 
00227     /* Now measure 20 ms delay. */
00228     lp_timer.start();
00229 
00230     /* Wait 20 ms. */
00231     wait_ms(20);
00232 
00233     /* Stop the timer. */
00234     lp_timer.stop();
00235 
00236     /* Check results - 20 ms elapsed since the reset. */
00237     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.020f, lp_timer.read());
00238     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), 20, lp_timer.read_ms());
00239     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), 20000, lp_timer.read_us());
00240     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), 20000, lp_timer.read_high_resolution_us());
00241 }
00242 
00243 /* This test verifies if calling start() for already
00244  * started low power timer does nothing.
00245  *
00246  * Given timer is already started.
00247  * When timer is started again.
00248  * Then second start operation is ignored.
00249  */
00250 void test_lptimer_start_started_timer()
00251 {
00252     LowPowerTimer lp_timer;
00253 
00254     /* Start the timer. */
00255     lp_timer.start();
00256 
00257     /* Wait 10 ms. */
00258     wait_ms(10);
00259 
00260     /* Now start timer again. */
00261     lp_timer.start();
00262 
00263     /* Wait 20 ms. */
00264     wait_ms(20);
00265 
00266     /* Stop the timer. */
00267     lp_timer.stop();
00268 
00269     /* Check results - 30 ms have elapsed since the first start. */
00270     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(2), 0.030f, lp_timer.read());
00271     TEST_ASSERT_INT32_WITHIN(DELTA_MS(2), 30, lp_timer.read_ms());
00272     TEST_ASSERT_INT32_WITHIN(DELTA_US(2), 30000, lp_timer.read_us());
00273     TEST_ASSERT_UINT64_WITHIN(DELTA_US(2), 30000, lp_timer.read_high_resolution_us());
00274 }
00275 
00276 /* This test verifies low power timer float operator.
00277  *
00278  * Given timer is created and a time period time is counted.
00279  * When timer object is casted on float type.
00280  * Then counted type in seconds is returned by means of
00281  * read() function.
00282  */
00283 void test_lptimer_float_operator()
00284 {
00285     LowPowerTimer lp_timer;
00286 
00287     /* Start the timer. */
00288     lp_timer.start();
00289 
00290     /* Wait 10 ms. */
00291     wait_ms(10);
00292 
00293     /* Stop the timer. */
00294     lp_timer.stop();
00295 
00296     /* Check result - 10 ms elapsed. */
00297     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.010f, (float )(lp_timer));
00298 }
00299 
00300 /* This test verifies if time counted by the low power timer is
00301  * valid.
00302  *
00303  * Given timer is created.
00304  * When timer is used to measure 1ms/10ms/100ms/1s
00305  * delays.
00306  * Then the results are valid (within acceptable range).
00307  */
00308 template<int wait_val_us>
00309 void test_lptimer_time_measurement()
00310 {
00311     LowPowerTimer lp_timer;
00312 
00313     /* Start the timer. */
00314     lp_timer.start();
00315 
00316     /* Wait <wait_val_us> us. */
00317     wait_us(wait_val_us);
00318 
00319     /* Stop the timer. */
00320     lp_timer.stop();
00321 
00322     /* Check results - wait_val_us us have elapsed. */
00323     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), (float )wait_val_us / 1000000, lp_timer.read());
00324     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), wait_val_us / 1000, lp_timer.read_ms());
00325     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), wait_val_us, lp_timer.read_us());
00326     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), wait_val_us, lp_timer.read_high_resolution_us());
00327 }
00328 
00329 utest::v1::status_t test_setup(const size_t number_of_cases)
00330 {
00331     GREENTEA_SETUP(15, "default_auto");
00332     return verbose_test_setup_handler(number_of_cases);
00333 }
00334 
00335 Case cases[] = {
00336     Case("Test: LowPowerTimer - stopped after creation.", test_lptimer_creation),
00337     Case("Test: LowPowerTimer - measure time accumulation.", test_lptimer_time_accumulation),
00338     Case("Test: LowPowerTimer - reset.", test_lptimer_reset),
00339     Case("Test: LowPowerTimer - start started timer.", test_lptimer_start_started_timer),
00340     Case("Test: LowPowerTimer - float operator.", test_lptimer_float_operator),
00341     Case("Test: LowPowerTimer - time measurement 1 ms.", test_lptimer_time_measurement<1000>),
00342     Case("Test: LowPowerTimer - time measurement 10 ms.", test_lptimer_time_measurement<10000>),
00343     Case("Test: LowPowerTimer - time measurement 100 ms.", test_lptimer_time_measurement<100000>),
00344     Case("Test: LowPowerTimer - time measurement 1 s.", test_lptimer_time_measurement<1000000>)
00345 };
00346 
00347 Specification specification(test_setup, cases);
00348 
00349 int main()
00350 {
00351     return !Harness::run(specification);
00352 }