Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mbed-os/TESTS/mbed_drivers/ticker/main.cpp@0:fbdae7e6d805, 2018-05-14 (annotated)
- Committer:
- borlanic
- Date:
- Mon May 14 11:29:06 2018 +0000
- Revision:
- 0:fbdae7e6d805
BBR
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| borlanic | 0:fbdae7e6d805 | 1 | /* mbed Microcontroller Library | 
| borlanic | 0:fbdae7e6d805 | 2 | * Copyright (c) 2013-2017 ARM Limited | 
| borlanic | 0:fbdae7e6d805 | 3 | * | 
| borlanic | 0:fbdae7e6d805 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
| borlanic | 0:fbdae7e6d805 | 5 | * you may not use this file except in compliance with the License. | 
| borlanic | 0:fbdae7e6d805 | 6 | * You may obtain a copy of the License at | 
| borlanic | 0:fbdae7e6d805 | 7 | * | 
| borlanic | 0:fbdae7e6d805 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | 
| borlanic | 0:fbdae7e6d805 | 9 | * | 
| borlanic | 0:fbdae7e6d805 | 10 | * Unless required by applicable law or agreed to in writing, software | 
| borlanic | 0:fbdae7e6d805 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
| borlanic | 0:fbdae7e6d805 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
| borlanic | 0:fbdae7e6d805 | 13 | * See the License for the specific language governing permissions and | 
| borlanic | 0:fbdae7e6d805 | 14 | * limitations under the License. | 
| borlanic | 0:fbdae7e6d805 | 15 | */ | 
| borlanic | 0:fbdae7e6d805 | 16 | #include "mbed.h" | 
| borlanic | 0:fbdae7e6d805 | 17 | #include "greentea-client/test_env.h" | 
| borlanic | 0:fbdae7e6d805 | 18 | #include "utest/utest.h" | 
| borlanic | 0:fbdae7e6d805 | 19 | #include "unity/unity.h" | 
| borlanic | 0:fbdae7e6d805 | 20 | |
| borlanic | 0:fbdae7e6d805 | 21 | |
| borlanic | 0:fbdae7e6d805 | 22 | using utest::v1::Case; | 
| borlanic | 0:fbdae7e6d805 | 23 | |
| borlanic | 0:fbdae7e6d805 | 24 | #define ONE_MILLI_SEC 1000 | 
| borlanic | 0:fbdae7e6d805 | 25 | #define TICKER_COUNT 16 | 
| borlanic | 0:fbdae7e6d805 | 26 | #define MULTI_TICKER_TIME_MS 100 | 
| borlanic | 0:fbdae7e6d805 | 27 | volatile uint32_t callback_trigger_count = 0; | 
| borlanic | 0:fbdae7e6d805 | 28 | static const int test_timeout = 240; | 
| borlanic | 0:fbdae7e6d805 | 29 | static const int total_ticks = 10; | 
| borlanic | 0:fbdae7e6d805 | 30 | |
| borlanic | 0:fbdae7e6d805 | 31 | |
| borlanic | 0:fbdae7e6d805 | 32 | /* Tolerance is quite arbitrary due to large number of boards with varying level of accuracy */ | 
| borlanic | 0:fbdae7e6d805 | 33 | #define TOLERANCE_US 1000 | 
| borlanic | 0:fbdae7e6d805 | 34 | |
| borlanic | 0:fbdae7e6d805 | 35 | volatile uint32_t ticker_callback_flag; | 
| borlanic | 0:fbdae7e6d805 | 36 | volatile uint32_t multi_counter; | 
| borlanic | 0:fbdae7e6d805 | 37 | |
| borlanic | 0:fbdae7e6d805 | 38 | DigitalOut led1(LED1); | 
| borlanic | 0:fbdae7e6d805 | 39 | DigitalOut led2(LED2); | 
| borlanic | 0:fbdae7e6d805 | 40 | |
| borlanic | 0:fbdae7e6d805 | 41 | Timer gtimer; | 
| borlanic | 0:fbdae7e6d805 | 42 | volatile int ticker_count = 0; | 
| borlanic | 0:fbdae7e6d805 | 43 | |
| borlanic | 0:fbdae7e6d805 | 44 | |
| borlanic | 0:fbdae7e6d805 | 45 | void switch_led1_state(void) | 
| borlanic | 0:fbdae7e6d805 | 46 | { | 
| borlanic | 0:fbdae7e6d805 | 47 | // blink 3 times per second | 
| borlanic | 0:fbdae7e6d805 | 48 | if((callback_trigger_count % 333) == 0) { | 
| borlanic | 0:fbdae7e6d805 | 49 | led1 = !led1; | 
| borlanic | 0:fbdae7e6d805 | 50 | } | 
| borlanic | 0:fbdae7e6d805 | 51 | } | 
| borlanic | 0:fbdae7e6d805 | 52 | |
| borlanic | 0:fbdae7e6d805 | 53 | void switch_led2_state(void) | 
| borlanic | 0:fbdae7e6d805 | 54 | { | 
| borlanic | 0:fbdae7e6d805 | 55 | // blink 3 times per second | 
| borlanic | 0:fbdae7e6d805 | 56 | // make led2 blink at the same callback_trigger_count value as led1 | 
| borlanic | 0:fbdae7e6d805 | 57 | if(((callback_trigger_count - 1) % 333) == 0) { | 
| borlanic | 0:fbdae7e6d805 | 58 | led2 = !led2; | 
| borlanic | 0:fbdae7e6d805 | 59 | } | 
| borlanic | 0:fbdae7e6d805 | 60 | } | 
| borlanic | 0:fbdae7e6d805 | 61 | |
| borlanic | 0:fbdae7e6d805 | 62 | void ticker_callback_1(void) | 
| borlanic | 0:fbdae7e6d805 | 63 | { | 
| borlanic | 0:fbdae7e6d805 | 64 | ++callback_trigger_count; | 
| borlanic | 0:fbdae7e6d805 | 65 | switch_led1_state(); | 
| borlanic | 0:fbdae7e6d805 | 66 | } | 
| borlanic | 0:fbdae7e6d805 | 67 | |
| borlanic | 0:fbdae7e6d805 | 68 | void ticker_callback_2(void) | 
| borlanic | 0:fbdae7e6d805 | 69 | { | 
| borlanic | 0:fbdae7e6d805 | 70 | ++callback_trigger_count; | 
| borlanic | 0:fbdae7e6d805 | 71 | switch_led2_state(); | 
| borlanic | 0:fbdae7e6d805 | 72 | } | 
| borlanic | 0:fbdae7e6d805 | 73 | |
| borlanic | 0:fbdae7e6d805 | 74 | |
| borlanic | 0:fbdae7e6d805 | 75 | void sem_release(Semaphore *sem) | 
| borlanic | 0:fbdae7e6d805 | 76 | { | 
| borlanic | 0:fbdae7e6d805 | 77 | sem->release(); | 
| borlanic | 0:fbdae7e6d805 | 78 | } | 
| borlanic | 0:fbdae7e6d805 | 79 | |
| borlanic | 0:fbdae7e6d805 | 80 | |
| borlanic | 0:fbdae7e6d805 | 81 | void stop_gtimer_set_flag(void) | 
| borlanic | 0:fbdae7e6d805 | 82 | { | 
| borlanic | 0:fbdae7e6d805 | 83 | gtimer.stop(); | 
| borlanic | 0:fbdae7e6d805 | 84 | core_util_atomic_incr_u32((uint32_t*)&ticker_callback_flag, 1); | 
| borlanic | 0:fbdae7e6d805 | 85 | } | 
| borlanic | 0:fbdae7e6d805 | 86 | |
| borlanic | 0:fbdae7e6d805 | 87 | void increment_multi_counter(void) | 
| borlanic | 0:fbdae7e6d805 | 88 | { | 
| borlanic | 0:fbdae7e6d805 | 89 | core_util_atomic_incr_u32((uint32_t*)&multi_counter, 1); | 
| borlanic | 0:fbdae7e6d805 | 90 | } | 
| borlanic | 0:fbdae7e6d805 | 91 | |
| borlanic | 0:fbdae7e6d805 | 92 | |
| borlanic | 0:fbdae7e6d805 | 93 | /* Tests is to measure the accuracy of Ticker over a period of time | 
| borlanic | 0:fbdae7e6d805 | 94 | * | 
| borlanic | 0:fbdae7e6d805 | 95 | * 1) DUT would start to update callback_trigger_count every milli sec | 
| borlanic | 0:fbdae7e6d805 | 96 | * 2) Host would query what is current count base_time, Device responds by the callback_trigger_count. | 
| borlanic | 0:fbdae7e6d805 | 97 | * 3) Host after waiting for measurement stretch. It will query for device time again final_time. | 
| borlanic | 0:fbdae7e6d805 | 98 | * 4) Host computes the drift considering base_time, final_time, transport delay and measurement stretch | 
| borlanic | 0:fbdae7e6d805 | 99 | * 5) Finally host send the results back to device pass/fail based on tolerance. | 
| borlanic | 0:fbdae7e6d805 | 100 | * 6) More details on tests can be found in timing_drift_auto.py | 
| borlanic | 0:fbdae7e6d805 | 101 | */ | 
| borlanic | 0:fbdae7e6d805 | 102 | void test_case_1x_ticker() | 
| borlanic | 0:fbdae7e6d805 | 103 | { | 
| borlanic | 0:fbdae7e6d805 | 104 | char _key[11] = { }; | 
| borlanic | 0:fbdae7e6d805 | 105 | char _value[128] = { }; | 
| borlanic | 0:fbdae7e6d805 | 106 | int expected_key = 1; | 
| borlanic | 0:fbdae7e6d805 | 107 | Ticker ticker; | 
| borlanic | 0:fbdae7e6d805 | 108 | |
| borlanic | 0:fbdae7e6d805 | 109 | led1 = 1; | 
| borlanic | 0:fbdae7e6d805 | 110 | led2 = 1; | 
| borlanic | 0:fbdae7e6d805 | 111 | callback_trigger_count = 0; | 
| borlanic | 0:fbdae7e6d805 | 112 | |
| borlanic | 0:fbdae7e6d805 | 113 | greentea_send_kv("timing_drift_check_start", 0); | 
| borlanic | 0:fbdae7e6d805 | 114 | ticker.attach_us(&ticker_callback_1, ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 115 | |
| borlanic | 0:fbdae7e6d805 | 116 | // wait for 1st signal from host | 
| borlanic | 0:fbdae7e6d805 | 117 | do { | 
| borlanic | 0:fbdae7e6d805 | 118 | greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); | 
| borlanic | 0:fbdae7e6d805 | 119 | expected_key = strcmp(_key, "base_time"); | 
| borlanic | 0:fbdae7e6d805 | 120 | } while (expected_key); | 
| borlanic | 0:fbdae7e6d805 | 121 | greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 122 | |
| borlanic | 0:fbdae7e6d805 | 123 | // wait for 2nd signal from host | 
| borlanic | 0:fbdae7e6d805 | 124 | greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); | 
| borlanic | 0:fbdae7e6d805 | 125 | greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 126 | |
| borlanic | 0:fbdae7e6d805 | 127 | //get the results from host | 
| borlanic | 0:fbdae7e6d805 | 128 | greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); | 
| borlanic | 0:fbdae7e6d805 | 129 | |
| borlanic | 0:fbdae7e6d805 | 130 | TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail..."); | 
| borlanic | 0:fbdae7e6d805 | 131 | } | 
| borlanic | 0:fbdae7e6d805 | 132 | |
| borlanic | 0:fbdae7e6d805 | 133 | /* Tests is to measure the accuracy of Ticker over a period of time | 
| borlanic | 0:fbdae7e6d805 | 134 | * | 
| borlanic | 0:fbdae7e6d805 | 135 | * 1) DUT would start to update callback_trigger_count every milli sec, we use 2 tickers | 
| borlanic | 0:fbdae7e6d805 | 136 | * to update the count alternatively. | 
| borlanic | 0:fbdae7e6d805 | 137 | * 2) Host would query what is current count base_time, Device responds by the callback_trigger_count | 
| borlanic | 0:fbdae7e6d805 | 138 | * 3) Host after waiting for measurement stretch. It will query for device time again final_time. | 
| borlanic | 0:fbdae7e6d805 | 139 | * 4) Host computes the drift considering base_time, final_time, transport delay and measurement stretch | 
| borlanic | 0:fbdae7e6d805 | 140 | * 5) Finally host send the results back to device pass/fail based on tolerance. | 
| borlanic | 0:fbdae7e6d805 | 141 | * 6) More details on tests can be found in timing_drift_auto.py | 
| borlanic | 0:fbdae7e6d805 | 142 | */ | 
| borlanic | 0:fbdae7e6d805 | 143 | void test_case_2x_ticker() | 
| borlanic | 0:fbdae7e6d805 | 144 | { | 
| borlanic | 0:fbdae7e6d805 | 145 | char _key[11] = { }; | 
| borlanic | 0:fbdae7e6d805 | 146 | char _value[128] = { }; | 
| borlanic | 0:fbdae7e6d805 | 147 | int expected_key = 1; | 
| borlanic | 0:fbdae7e6d805 | 148 | Ticker ticker1, ticker2; | 
| borlanic | 0:fbdae7e6d805 | 149 | |
| borlanic | 0:fbdae7e6d805 | 150 | led1 = 0; | 
| borlanic | 0:fbdae7e6d805 | 151 | led2 = 1; | 
| borlanic | 0:fbdae7e6d805 | 152 | callback_trigger_count = 0; | 
| borlanic | 0:fbdae7e6d805 | 153 | |
| borlanic | 0:fbdae7e6d805 | 154 | ticker1.attach_us(ticker_callback_1, 2 * ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 155 | // delay second ticker to have a pair of tickers tick every one millisecond | 
| borlanic | 0:fbdae7e6d805 | 156 | wait_us(ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 157 | greentea_send_kv("timing_drift_check_start", 0); | 
| borlanic | 0:fbdae7e6d805 | 158 | ticker2.attach_us(ticker_callback_2, 2 * ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 159 | |
| borlanic | 0:fbdae7e6d805 | 160 | // wait for 1st signal from host | 
| borlanic | 0:fbdae7e6d805 | 161 | do { | 
| borlanic | 0:fbdae7e6d805 | 162 | greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); | 
| borlanic | 0:fbdae7e6d805 | 163 | expected_key = strcmp(_key, "base_time"); | 
| borlanic | 0:fbdae7e6d805 | 164 | } while (expected_key); | 
| borlanic | 0:fbdae7e6d805 | 165 | greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 166 | |
| borlanic | 0:fbdae7e6d805 | 167 | // wait for 2nd signal from host | 
| borlanic | 0:fbdae7e6d805 | 168 | greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); | 
| borlanic | 0:fbdae7e6d805 | 169 | greentea_send_kv(_key, callback_trigger_count * ONE_MILLI_SEC); | 
| borlanic | 0:fbdae7e6d805 | 170 | |
| borlanic | 0:fbdae7e6d805 | 171 | //get the results from host | 
| borlanic | 0:fbdae7e6d805 | 172 | greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); | 
| borlanic | 0:fbdae7e6d805 | 173 | |
| borlanic | 0:fbdae7e6d805 | 174 | TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail..."); | 
| borlanic | 0:fbdae7e6d805 | 175 | } | 
| borlanic | 0:fbdae7e6d805 | 176 | |
| borlanic | 0:fbdae7e6d805 | 177 | /** Test many tickers run one after the other | 
| borlanic | 0:fbdae7e6d805 | 178 | |
| borlanic | 0:fbdae7e6d805 | 179 | Given many Tickers | 
| borlanic | 0:fbdae7e6d805 | 180 | When schedule them one after the other with the same time intervals | 
| borlanic | 0:fbdae7e6d805 | 181 | Then tickers properly execute callbacks | 
| borlanic | 0:fbdae7e6d805 | 182 | When schedule them one after the other with the different time intervals | 
| borlanic | 0:fbdae7e6d805 | 183 | Then tickers properly execute callbacks | 
| borlanic | 0:fbdae7e6d805 | 184 | */ | 
| borlanic | 0:fbdae7e6d805 | 185 | void test_multi_ticker(void) | 
| borlanic | 0:fbdae7e6d805 | 186 | { | 
| borlanic | 0:fbdae7e6d805 | 187 | Ticker ticker[TICKER_COUNT]; | 
| borlanic | 0:fbdae7e6d805 | 188 | const uint32_t extra_wait = 5; // extra 5ms wait time | 
| borlanic | 0:fbdae7e6d805 | 189 | |
| borlanic | 0:fbdae7e6d805 | 190 | multi_counter = 0; | 
| borlanic | 0:fbdae7e6d805 | 191 | for (int i = 0; i < TICKER_COUNT; i++) { | 
| borlanic | 0:fbdae7e6d805 | 192 | ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000); | 
| borlanic | 0:fbdae7e6d805 | 193 | } | 
| borlanic | 0:fbdae7e6d805 | 194 | |
| borlanic | 0:fbdae7e6d805 | 195 | Thread::wait(MULTI_TICKER_TIME_MS + extra_wait); | 
| borlanic | 0:fbdae7e6d805 | 196 | for (int i = 0; i < TICKER_COUNT; i++) { | 
| borlanic | 0:fbdae7e6d805 | 197 | ticker[i].detach(); | 
| borlanic | 0:fbdae7e6d805 | 198 | } | 
| borlanic | 0:fbdae7e6d805 | 199 | TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); | 
| borlanic | 0:fbdae7e6d805 | 200 | |
| borlanic | 0:fbdae7e6d805 | 201 | multi_counter = 0; | 
| borlanic | 0:fbdae7e6d805 | 202 | for (int i = 0; i < TICKER_COUNT; i++) { | 
| borlanic | 0:fbdae7e6d805 | 203 | ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000); | 
| borlanic | 0:fbdae7e6d805 | 204 | } | 
| borlanic | 0:fbdae7e6d805 | 205 | |
| borlanic | 0:fbdae7e6d805 | 206 | Thread::wait(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait); | 
| borlanic | 0:fbdae7e6d805 | 207 | for (int i = 0; i < TICKER_COUNT; i++) { | 
| borlanic | 0:fbdae7e6d805 | 208 | ticker[i].detach(); | 
| borlanic | 0:fbdae7e6d805 | 209 | } | 
| borlanic | 0:fbdae7e6d805 | 210 | TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter); | 
| borlanic | 0:fbdae7e6d805 | 211 | } | 
| borlanic | 0:fbdae7e6d805 | 212 | |
| borlanic | 0:fbdae7e6d805 | 213 | /** Test multi callback time | 
| borlanic | 0:fbdae7e6d805 | 214 | |
| borlanic | 0:fbdae7e6d805 | 215 | Given a Ticker | 
| borlanic | 0:fbdae7e6d805 | 216 | When the callback is attached multiple times | 
| borlanic | 0:fbdae7e6d805 | 217 | Then ticker properly execute callback multiple times | 
| borlanic | 0:fbdae7e6d805 | 218 | */ | 
| borlanic | 0:fbdae7e6d805 | 219 | void test_multi_call_time(void) | 
| borlanic | 0:fbdae7e6d805 | 220 | { | 
| borlanic | 0:fbdae7e6d805 | 221 | Ticker ticker; | 
| borlanic | 0:fbdae7e6d805 | 222 | int time_diff; | 
| borlanic | 0:fbdae7e6d805 | 223 | const int attach_count = 10; | 
| borlanic | 0:fbdae7e6d805 | 224 | |
| borlanic | 0:fbdae7e6d805 | 225 | for (int i = 0; i < attach_count; i++) { | 
| borlanic | 0:fbdae7e6d805 | 226 | ticker_callback_flag = 0; | 
| borlanic | 0:fbdae7e6d805 | 227 | gtimer.reset(); | 
| borlanic | 0:fbdae7e6d805 | 228 | |
| borlanic | 0:fbdae7e6d805 | 229 | gtimer.start(); | 
| borlanic | 0:fbdae7e6d805 | 230 | ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000); | 
| borlanic | 0:fbdae7e6d805 | 231 | while(!ticker_callback_flag); | 
| borlanic | 0:fbdae7e6d805 | 232 | time_diff = gtimer.read_us(); | 
| borlanic | 0:fbdae7e6d805 | 233 | |
| borlanic | 0:fbdae7e6d805 | 234 | TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US, MULTI_TICKER_TIME_MS * 1000, time_diff); | 
| borlanic | 0:fbdae7e6d805 | 235 | } | 
| borlanic | 0:fbdae7e6d805 | 236 | } | 
| borlanic | 0:fbdae7e6d805 | 237 | |
| borlanic | 0:fbdae7e6d805 | 238 | /** Test if detach cancel scheduled callback event | 
| borlanic | 0:fbdae7e6d805 | 239 | |
| borlanic | 0:fbdae7e6d805 | 240 | Given a Ticker with callback attached | 
| borlanic | 0:fbdae7e6d805 | 241 | When the callback is detached | 
| borlanic | 0:fbdae7e6d805 | 242 | Then the callback is not being called | 
| borlanic | 0:fbdae7e6d805 | 243 | */ | 
| borlanic | 0:fbdae7e6d805 | 244 | void test_detach(void) | 
| borlanic | 0:fbdae7e6d805 | 245 | { | 
| borlanic | 0:fbdae7e6d805 | 246 | Ticker ticker; | 
| borlanic | 0:fbdae7e6d805 | 247 | int32_t ret; | 
| borlanic | 0:fbdae7e6d805 | 248 | const float ticker_time_s = 0.1f; | 
| borlanic | 0:fbdae7e6d805 | 249 | const uint32_t wait_time_ms = 500; | 
| borlanic | 0:fbdae7e6d805 | 250 | Semaphore sem(0, 1); | 
| borlanic | 0:fbdae7e6d805 | 251 | |
| borlanic | 0:fbdae7e6d805 | 252 | ticker.attach(callback(sem_release, &sem), ticker_time_s); | 
| borlanic | 0:fbdae7e6d805 | 253 | |
| borlanic | 0:fbdae7e6d805 | 254 | ret = sem.wait(); | 
| borlanic | 0:fbdae7e6d805 | 255 | TEST_ASSERT_TRUE(ret > 0); | 
| borlanic | 0:fbdae7e6d805 | 256 | |
| borlanic | 0:fbdae7e6d805 | 257 | ret = sem.wait(); | 
| borlanic | 0:fbdae7e6d805 | 258 | ticker.detach(); /* cancel */ | 
| borlanic | 0:fbdae7e6d805 | 259 | TEST_ASSERT_TRUE(ret > 0); | 
| borlanic | 0:fbdae7e6d805 | 260 | |
| borlanic | 0:fbdae7e6d805 | 261 | ret = sem.wait(wait_time_ms); | 
| borlanic | 0:fbdae7e6d805 | 262 | TEST_ASSERT_EQUAL(0, ret); | 
| borlanic | 0:fbdae7e6d805 | 263 | } | 
| borlanic | 0:fbdae7e6d805 | 264 | |
| borlanic | 0:fbdae7e6d805 | 265 | /** Test single callback time via attach | 
| borlanic | 0:fbdae7e6d805 | 266 | |
| borlanic | 0:fbdae7e6d805 | 267 | Given a Ticker | 
| borlanic | 0:fbdae7e6d805 | 268 | When callback attached with time interval specified | 
| borlanic | 0:fbdae7e6d805 | 269 | Then ticker properly executes callback within a specified time interval | 
| borlanic | 0:fbdae7e6d805 | 270 | */ | 
| borlanic | 0:fbdae7e6d805 | 271 | template<us_timestamp_t DELAY_US> | 
| borlanic | 0:fbdae7e6d805 | 272 | void test_attach_time(void) | 
| borlanic | 0:fbdae7e6d805 | 273 | { | 
| borlanic | 0:fbdae7e6d805 | 274 | Ticker ticker; | 
| borlanic | 0:fbdae7e6d805 | 275 | ticker_callback_flag = 0; | 
| borlanic | 0:fbdae7e6d805 | 276 | |
| borlanic | 0:fbdae7e6d805 | 277 | gtimer.reset(); | 
| borlanic | 0:fbdae7e6d805 | 278 | gtimer.start(); | 
| borlanic | 0:fbdae7e6d805 | 279 | ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f); | 
| borlanic | 0:fbdae7e6d805 | 280 | while(!ticker_callback_flag); | 
| borlanic | 0:fbdae7e6d805 | 281 | ticker.detach(); | 
| borlanic | 0:fbdae7e6d805 | 282 | const int time_diff = gtimer.read_us(); | 
| borlanic | 0:fbdae7e6d805 | 283 | |
| borlanic | 0:fbdae7e6d805 | 284 | TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US, DELAY_US, time_diff); | 
| borlanic | 0:fbdae7e6d805 | 285 | } | 
| borlanic | 0:fbdae7e6d805 | 286 | |
| borlanic | 0:fbdae7e6d805 | 287 | /** Test single callback time via attach_us | 
| borlanic | 0:fbdae7e6d805 | 288 | |
| borlanic | 0:fbdae7e6d805 | 289 | Given a Ticker | 
| borlanic | 0:fbdae7e6d805 | 290 | When callback attached with time interval specified | 
| borlanic | 0:fbdae7e6d805 | 291 | Then ticker properly executes callback within a specified time interval | 
| borlanic | 0:fbdae7e6d805 | 292 | */ | 
| borlanic | 0:fbdae7e6d805 | 293 | template<us_timestamp_t DELAY_US> | 
| borlanic | 0:fbdae7e6d805 | 294 | void test_attach_us_time(void) | 
| borlanic | 0:fbdae7e6d805 | 295 | { | 
| borlanic | 0:fbdae7e6d805 | 296 | Ticker ticker; | 
| borlanic | 0:fbdae7e6d805 | 297 | ticker_callback_flag = 0; | 
| borlanic | 0:fbdae7e6d805 | 298 | |
| borlanic | 0:fbdae7e6d805 | 299 | gtimer.reset(); | 
| borlanic | 0:fbdae7e6d805 | 300 | gtimer.start(); | 
| borlanic | 0:fbdae7e6d805 | 301 | ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US); | 
| borlanic | 0:fbdae7e6d805 | 302 | while(!ticker_callback_flag); | 
| borlanic | 0:fbdae7e6d805 | 303 | ticker.detach(); | 
| borlanic | 0:fbdae7e6d805 | 304 | const int time_diff = gtimer.read_us(); | 
| borlanic | 0:fbdae7e6d805 | 305 | |
| borlanic | 0:fbdae7e6d805 | 306 | TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US, DELAY_US, time_diff); | 
| borlanic | 0:fbdae7e6d805 | 307 | } | 
| borlanic | 0:fbdae7e6d805 | 308 | |
| borlanic | 0:fbdae7e6d805 | 309 | |
| borlanic | 0:fbdae7e6d805 | 310 | // Test cases | 
| borlanic | 0:fbdae7e6d805 | 311 | Case cases[] = { | 
| borlanic | 0:fbdae7e6d805 | 312 | Case("Test attach for 0.01s and time measure", test_attach_time<10000>), | 
| borlanic | 0:fbdae7e6d805 | 313 | Case("Test attach_us for 10ms and time measure", test_attach_us_time<10000>), | 
| borlanic | 0:fbdae7e6d805 | 314 | Case("Test attach for 0.1s and time measure", test_attach_time<100000>), | 
| borlanic | 0:fbdae7e6d805 | 315 | Case("Test attach_us for 100ms and time measure", test_attach_us_time<100000>), | 
| borlanic | 0:fbdae7e6d805 | 316 | Case("Test attach for 0.5s and time measure", test_attach_time<500000>), | 
| borlanic | 0:fbdae7e6d805 | 317 | Case("Test attach_us for 500ms and time measure", test_attach_us_time<500000>), | 
| borlanic | 0:fbdae7e6d805 | 318 | Case("Test detach", test_detach), | 
| borlanic | 0:fbdae7e6d805 | 319 | Case("Test multi call and time measure", test_multi_call_time), | 
| borlanic | 0:fbdae7e6d805 | 320 | Case("Test multi ticker", test_multi_ticker), | 
| borlanic | 0:fbdae7e6d805 | 321 | Case("Test timers: 1x ticker", test_case_1x_ticker), | 
| borlanic | 0:fbdae7e6d805 | 322 | Case("Test timers: 2x ticker", test_case_2x_ticker) | 
| borlanic | 0:fbdae7e6d805 | 323 | }; | 
| borlanic | 0:fbdae7e6d805 | 324 | |
| borlanic | 0:fbdae7e6d805 | 325 | utest::v1::status_t greentea_test_setup(const size_t number_of_cases) | 
| borlanic | 0:fbdae7e6d805 | 326 | { | 
| borlanic | 0:fbdae7e6d805 | 327 | GREENTEA_SETUP(test_timeout, "timing_drift_auto"); | 
| borlanic | 0:fbdae7e6d805 | 328 | return utest::v1::greentea_test_setup_handler(number_of_cases); | 
| borlanic | 0:fbdae7e6d805 | 329 | } | 
| borlanic | 0:fbdae7e6d805 | 330 | |
| borlanic | 0:fbdae7e6d805 | 331 | utest::v1::Specification specification(greentea_test_setup, cases, utest::v1::greentea_test_teardown_handler); | 
| borlanic | 0:fbdae7e6d805 | 332 | |
| borlanic | 0:fbdae7e6d805 | 333 | int main() | 
| borlanic | 0:fbdae7e6d805 | 334 | { | 
| borlanic | 0:fbdae7e6d805 | 335 | utest::v1::Harness::run(specification); | 
| borlanic | 0:fbdae7e6d805 | 336 | } |