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_hal/common_tickers/main.cpp@0:8fdf9a60065b, 2018-10-10 (annotated)
- Committer:
- kadonotakashi
- Date:
- Wed Oct 10 00:33:53 2018 +0000
- Revision:
- 0:8fdf9a60065b
how to make mbed librry
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| kadonotakashi | 0:8fdf9a60065b | 1 | /* mbed Microcontroller Library |
| kadonotakashi | 0:8fdf9a60065b | 2 | * Copyright (c) 2017 ARM Limited |
| kadonotakashi | 0:8fdf9a60065b | 3 | * |
| kadonotakashi | 0:8fdf9a60065b | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| kadonotakashi | 0:8fdf9a60065b | 5 | * you may not use this file except in compliance with the License. |
| kadonotakashi | 0:8fdf9a60065b | 6 | * You may obtain a copy of the License at |
| kadonotakashi | 0:8fdf9a60065b | 7 | * |
| kadonotakashi | 0:8fdf9a60065b | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| kadonotakashi | 0:8fdf9a60065b | 9 | * |
| kadonotakashi | 0:8fdf9a60065b | 10 | * Unless required by applicable law or agreed to in writing, software |
| kadonotakashi | 0:8fdf9a60065b | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| kadonotakashi | 0:8fdf9a60065b | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| kadonotakashi | 0:8fdf9a60065b | 13 | * See the License for the specific language governing permissions and |
| kadonotakashi | 0:8fdf9a60065b | 14 | * limitations under the License. |
| kadonotakashi | 0:8fdf9a60065b | 15 | */ |
| kadonotakashi | 0:8fdf9a60065b | 16 | #include "mbed.h" |
| kadonotakashi | 0:8fdf9a60065b | 17 | #include "greentea-client/test_env.h" |
| kadonotakashi | 0:8fdf9a60065b | 18 | #include "unity.h" |
| kadonotakashi | 0:8fdf9a60065b | 19 | #include "utest.h" |
| kadonotakashi | 0:8fdf9a60065b | 20 | #include "ticker_api_tests.h" |
| kadonotakashi | 0:8fdf9a60065b | 21 | #include "hal/us_ticker_api.h" |
| kadonotakashi | 0:8fdf9a60065b | 22 | #include "hal/lp_ticker_api.h" |
| kadonotakashi | 0:8fdf9a60065b | 23 | #include "hal/mbed_lp_ticker_wrapper.h" |
| kadonotakashi | 0:8fdf9a60065b | 24 | |
| kadonotakashi | 0:8fdf9a60065b | 25 | #ifdef __cplusplus |
| kadonotakashi | 0:8fdf9a60065b | 26 | extern "C" { |
| kadonotakashi | 0:8fdf9a60065b | 27 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 28 | #include "os_tick.h" |
| kadonotakashi | 0:8fdf9a60065b | 29 | #ifdef __cplusplus |
| kadonotakashi | 0:8fdf9a60065b | 30 | } |
| kadonotakashi | 0:8fdf9a60065b | 31 | #endif // __cplusplus |
| kadonotakashi | 0:8fdf9a60065b | 32 | |
| kadonotakashi | 0:8fdf9a60065b | 33 | #if !DEVICE_USTICKER |
| kadonotakashi | 0:8fdf9a60065b | 34 | #error [NOT_SUPPORTED] test not supported |
| kadonotakashi | 0:8fdf9a60065b | 35 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 36 | |
| kadonotakashi | 0:8fdf9a60065b | 37 | #define US_PER_S 1000000 |
| kadonotakashi | 0:8fdf9a60065b | 38 | |
| kadonotakashi | 0:8fdf9a60065b | 39 | #define FORCE_OVERFLOW_TEST (false) |
| kadonotakashi | 0:8fdf9a60065b | 40 | #define TICKER_INT_VAL 500 |
| kadonotakashi | 0:8fdf9a60065b | 41 | #define TICKER_DELTA 10 |
| kadonotakashi | 0:8fdf9a60065b | 42 | |
| kadonotakashi | 0:8fdf9a60065b | 43 | #define LP_TICKER_OVERFLOW_DELTA1 0 // this will allow to detect that ticker counter rollovers to 0 |
| kadonotakashi | 0:8fdf9a60065b | 44 | #define LP_TICKER_OVERFLOW_DELTA2 0 |
| kadonotakashi | 0:8fdf9a60065b | 45 | #define US_TICKER_OVERFLOW_DELTA1 50 |
| kadonotakashi | 0:8fdf9a60065b | 46 | #define US_TICKER_OVERFLOW_DELTA2 60 |
| kadonotakashi | 0:8fdf9a60065b | 47 | |
| kadonotakashi | 0:8fdf9a60065b | 48 | #define TICKER_100_TICKS 100 |
| kadonotakashi | 0:8fdf9a60065b | 49 | #define TICKER_500_TICKS 500 |
| kadonotakashi | 0:8fdf9a60065b | 50 | |
| kadonotakashi | 0:8fdf9a60065b | 51 | #define MAX_FUNC_EXEC_TIME_US 30 |
| kadonotakashi | 0:8fdf9a60065b | 52 | #define DELTA_FUNC_EXEC_TIME_US 5 |
| kadonotakashi | 0:8fdf9a60065b | 53 | #define NUM_OF_CALLS 100 |
| kadonotakashi | 0:8fdf9a60065b | 54 | |
| kadonotakashi | 0:8fdf9a60065b | 55 | #define NUM_OF_CYCLES 100000 |
| kadonotakashi | 0:8fdf9a60065b | 56 | |
| kadonotakashi | 0:8fdf9a60065b | 57 | #define US_TICKER_OV_LIMIT 35000 |
| kadonotakashi | 0:8fdf9a60065b | 58 | #define LP_TICKER_OV_LIMIT 4000 |
| kadonotakashi | 0:8fdf9a60065b | 59 | |
| kadonotakashi | 0:8fdf9a60065b | 60 | using namespace utest::v1; |
| kadonotakashi | 0:8fdf9a60065b | 61 | |
| kadonotakashi | 0:8fdf9a60065b | 62 | volatile int intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 63 | const ticker_interface_t *intf; |
| kadonotakashi | 0:8fdf9a60065b | 64 | ticker_irq_handler_type prev_irq_handler; |
| kadonotakashi | 0:8fdf9a60065b | 65 | /* Some targets might fail overflow test uncertainly due to getting trapped in busy |
| kadonotakashi | 0:8fdf9a60065b | 66 | * intf->read() loop. In the loop, some ticker values wouldn't get caught in time |
| kadonotakashi | 0:8fdf9a60065b | 67 | * because of: |
| kadonotakashi | 0:8fdf9a60065b | 68 | * 1. Lower CPU clock |
| kadonotakashi | 0:8fdf9a60065b | 69 | * 2. Compiled code with worse performance |
| kadonotakashi | 0:8fdf9a60065b | 70 | * 3. Interrupt at that time |
| kadonotakashi | 0:8fdf9a60065b | 71 | * |
| kadonotakashi | 0:8fdf9a60065b | 72 | * We fix it by checking small ticker value range rather than one exact ticker point |
| kadonotakashi | 0:8fdf9a60065b | 73 | * in near overflow check. |
| kadonotakashi | 0:8fdf9a60065b | 74 | */ |
| kadonotakashi | 0:8fdf9a60065b | 75 | unsigned int ticker_overflow_delta1; |
| kadonotakashi | 0:8fdf9a60065b | 76 | unsigned int ticker_overflow_delta2; |
| kadonotakashi | 0:8fdf9a60065b | 77 | |
| kadonotakashi | 0:8fdf9a60065b | 78 | /* Auxiliary function to count ticker ticks elapsed during execution of N cycles of empty while loop. |
| kadonotakashi | 0:8fdf9a60065b | 79 | * Parameter <step> is used to disable compiler optimisation. */ |
| kadonotakashi | 0:8fdf9a60065b | 80 | MBED_NOINLINE |
| kadonotakashi | 0:8fdf9a60065b | 81 | uint32_t count_ticks(uint32_t cycles, uint32_t step) |
| kadonotakashi | 0:8fdf9a60065b | 82 | { |
| kadonotakashi | 0:8fdf9a60065b | 83 | register uint32_t reg_cycles = cycles; |
| kadonotakashi | 0:8fdf9a60065b | 84 | |
| kadonotakashi | 0:8fdf9a60065b | 85 | const ticker_info_t *p_ticker_info = intf->get_info(); |
| kadonotakashi | 0:8fdf9a60065b | 86 | const uint32_t max_count = ((1 << p_ticker_info->bits) - 1); |
| kadonotakashi | 0:8fdf9a60065b | 87 | |
| kadonotakashi | 0:8fdf9a60065b | 88 | core_util_critical_section_enter(); |
| kadonotakashi | 0:8fdf9a60065b | 89 | |
| kadonotakashi | 0:8fdf9a60065b | 90 | const uint32_t start = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 91 | |
| kadonotakashi | 0:8fdf9a60065b | 92 | while (reg_cycles -= step) { |
| kadonotakashi | 0:8fdf9a60065b | 93 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 94 | } |
| kadonotakashi | 0:8fdf9a60065b | 95 | |
| kadonotakashi | 0:8fdf9a60065b | 96 | const uint32_t stop = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 97 | |
| kadonotakashi | 0:8fdf9a60065b | 98 | core_util_critical_section_exit(); |
| kadonotakashi | 0:8fdf9a60065b | 99 | |
| kadonotakashi | 0:8fdf9a60065b | 100 | /* Handle overflow - overflow protection may not work in this case. */ |
| kadonotakashi | 0:8fdf9a60065b | 101 | uint32_t diff = (start <= stop) ? (stop - start) : (uint32_t)(max_count - start + stop + 1); |
| kadonotakashi | 0:8fdf9a60065b | 102 | |
| kadonotakashi | 0:8fdf9a60065b | 103 | return (diff); |
| kadonotakashi | 0:8fdf9a60065b | 104 | } |
| kadonotakashi | 0:8fdf9a60065b | 105 | |
| kadonotakashi | 0:8fdf9a60065b | 106 | /* Since according to the ticker requirements min acceptable counter size is |
| kadonotakashi | 0:8fdf9a60065b | 107 | * - 12 bits for low power timer - max count = 4095, |
| kadonotakashi | 0:8fdf9a60065b | 108 | * - 16 bits for high frequency timer - max count = 65535 |
| kadonotakashi | 0:8fdf9a60065b | 109 | * then all test cases must be executed in this time windows. |
| kadonotakashi | 0:8fdf9a60065b | 110 | * HAL ticker layer handles counter overflow and it is not handled in the target |
| kadonotakashi | 0:8fdf9a60065b | 111 | * ticker drivers. Ensure we have enough time to execute test case without overflow. |
| kadonotakashi | 0:8fdf9a60065b | 112 | */ |
| kadonotakashi | 0:8fdf9a60065b | 113 | void overflow_protect() |
| kadonotakashi | 0:8fdf9a60065b | 114 | { |
| kadonotakashi | 0:8fdf9a60065b | 115 | uint32_t time_window; |
| kadonotakashi | 0:8fdf9a60065b | 116 | |
| kadonotakashi | 0:8fdf9a60065b | 117 | if (intf == get_us_ticker_data()->interface) { |
| kadonotakashi | 0:8fdf9a60065b | 118 | time_window = US_TICKER_OV_LIMIT; |
| kadonotakashi | 0:8fdf9a60065b | 119 | } else { |
| kadonotakashi | 0:8fdf9a60065b | 120 | time_window = LP_TICKER_OV_LIMIT; |
| kadonotakashi | 0:8fdf9a60065b | 121 | } |
| kadonotakashi | 0:8fdf9a60065b | 122 | |
| kadonotakashi | 0:8fdf9a60065b | 123 | const uint32_t ticks_now = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 124 | const ticker_info_t *p_ticker_info = intf->get_info(); |
| kadonotakashi | 0:8fdf9a60065b | 125 | |
| kadonotakashi | 0:8fdf9a60065b | 126 | const uint32_t max_count = ((1 << p_ticker_info->bits) - 1); |
| kadonotakashi | 0:8fdf9a60065b | 127 | |
| kadonotakashi | 0:8fdf9a60065b | 128 | if ((max_count - ticks_now) > time_window) { |
| kadonotakashi | 0:8fdf9a60065b | 129 | return; |
| kadonotakashi | 0:8fdf9a60065b | 130 | } |
| kadonotakashi | 0:8fdf9a60065b | 131 | |
| kadonotakashi | 0:8fdf9a60065b | 132 | while (intf->read() > ticks_now); |
| kadonotakashi | 0:8fdf9a60065b | 133 | } |
| kadonotakashi | 0:8fdf9a60065b | 134 | |
| kadonotakashi | 0:8fdf9a60065b | 135 | void ticker_event_handler_stub(const ticker_data_t *const ticker) |
| kadonotakashi | 0:8fdf9a60065b | 136 | { |
| kadonotakashi | 0:8fdf9a60065b | 137 | if (ticker == get_us_ticker_data()) { |
| kadonotakashi | 0:8fdf9a60065b | 138 | us_ticker_clear_interrupt(); |
| kadonotakashi | 0:8fdf9a60065b | 139 | } else { |
| kadonotakashi | 0:8fdf9a60065b | 140 | #if DEVICE_LPTICKER |
| kadonotakashi | 0:8fdf9a60065b | 141 | lp_ticker_clear_interrupt(); |
| kadonotakashi | 0:8fdf9a60065b | 142 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 143 | } |
| kadonotakashi | 0:8fdf9a60065b | 144 | |
| kadonotakashi | 0:8fdf9a60065b | 145 | /* Indicate that ISR has been executed in interrupt context. */ |
| kadonotakashi | 0:8fdf9a60065b | 146 | if (core_util_is_isr_active()) { |
| kadonotakashi | 0:8fdf9a60065b | 147 | intFlag++; |
| kadonotakashi | 0:8fdf9a60065b | 148 | } |
| kadonotakashi | 0:8fdf9a60065b | 149 | } |
| kadonotakashi | 0:8fdf9a60065b | 150 | |
| kadonotakashi | 0:8fdf9a60065b | 151 | void wait_cycles(volatile unsigned int cycles) |
| kadonotakashi | 0:8fdf9a60065b | 152 | { |
| kadonotakashi | 0:8fdf9a60065b | 153 | while (cycles--); |
| kadonotakashi | 0:8fdf9a60065b | 154 | } |
| kadonotakashi | 0:8fdf9a60065b | 155 | |
| kadonotakashi | 0:8fdf9a60065b | 156 | /* Auxiliary function to determine how long ticker function are executed. |
| kadonotakashi | 0:8fdf9a60065b | 157 | * This function returns number of us between <start_ticks> and <stop_ticks> |
| kadonotakashi | 0:8fdf9a60065b | 158 | * taking into account counter roll-over, counter size and frequency. |
| kadonotakashi | 0:8fdf9a60065b | 159 | */ |
| kadonotakashi | 0:8fdf9a60065b | 160 | uint32_t diff_us(uint32_t start_ticks, uint32_t stop_ticks, const ticker_info_t *info) |
| kadonotakashi | 0:8fdf9a60065b | 161 | { |
| kadonotakashi | 0:8fdf9a60065b | 162 | uint32_t counter_mask = ((1 << info->bits) - 1); |
| kadonotakashi | 0:8fdf9a60065b | 163 | |
| kadonotakashi | 0:8fdf9a60065b | 164 | uint32_t diff_ticks = ((stop_ticks - start_ticks) & counter_mask); |
| kadonotakashi | 0:8fdf9a60065b | 165 | |
| kadonotakashi | 0:8fdf9a60065b | 166 | return (uint32_t)((uint64_t) diff_ticks * US_PER_S / info->frequency); |
| kadonotakashi | 0:8fdf9a60065b | 167 | } |
| kadonotakashi | 0:8fdf9a60065b | 168 | |
| kadonotakashi | 0:8fdf9a60065b | 169 | /* Test that ticker_init can be called multiple times and |
| kadonotakashi | 0:8fdf9a60065b | 170 | * ticker_init allows the ticker to keep counting and disables the ticker interrupt. |
| kadonotakashi | 0:8fdf9a60065b | 171 | */ |
| kadonotakashi | 0:8fdf9a60065b | 172 | void ticker_init_test() |
| kadonotakashi | 0:8fdf9a60065b | 173 | { |
| kadonotakashi | 0:8fdf9a60065b | 174 | overflow_protect(); |
| kadonotakashi | 0:8fdf9a60065b | 175 | |
| kadonotakashi | 0:8fdf9a60065b | 176 | intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 177 | |
| kadonotakashi | 0:8fdf9a60065b | 178 | intf->init(); |
| kadonotakashi | 0:8fdf9a60065b | 179 | |
| kadonotakashi | 0:8fdf9a60065b | 180 | /* Wait a while - let the ticker to count. */ |
| kadonotakashi | 0:8fdf9a60065b | 181 | wait_cycles(10000); |
| kadonotakashi | 0:8fdf9a60065b | 182 | |
| kadonotakashi | 0:8fdf9a60065b | 183 | const uint32_t ticks_start = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 184 | |
| kadonotakashi | 0:8fdf9a60065b | 185 | intf->set_interrupt(ticks_start + TICKER_INT_VAL); |
| kadonotakashi | 0:8fdf9a60065b | 186 | |
| kadonotakashi | 0:8fdf9a60065b | 187 | /* Re-initialise the ticker. */ |
| kadonotakashi | 0:8fdf9a60065b | 188 | intf->init(); |
| kadonotakashi | 0:8fdf9a60065b | 189 | |
| kadonotakashi | 0:8fdf9a60065b | 190 | const uint32_t ticks_after_reinit = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 191 | |
| kadonotakashi | 0:8fdf9a60065b | 192 | /* Wait long enough to fire ticker interrupt (should not be fired). */ |
| kadonotakashi | 0:8fdf9a60065b | 193 | while (intf->read() < (ticks_start + 2 * TICKER_INT_VAL)) { |
| kadonotakashi | 0:8fdf9a60065b | 194 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 195 | } |
| kadonotakashi | 0:8fdf9a60065b | 196 | |
| kadonotakashi | 0:8fdf9a60065b | 197 | TEST_ASSERT(intf->read() >= (ticks_start + 2 * TICKER_INT_VAL)); |
| kadonotakashi | 0:8fdf9a60065b | 198 | TEST_ASSERT(ticks_start <= ticks_after_reinit); |
| kadonotakashi | 0:8fdf9a60065b | 199 | TEST_ASSERT_EQUAL(0, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 200 | } |
| kadonotakashi | 0:8fdf9a60065b | 201 | |
| kadonotakashi | 0:8fdf9a60065b | 202 | /* Test that ticker frequency is non-zero and counter is at least 8 bits */ |
| kadonotakashi | 0:8fdf9a60065b | 203 | void ticker_info_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 204 | { |
| kadonotakashi | 0:8fdf9a60065b | 205 | const ticker_info_t *p_ticker_info = intf->get_info(); |
| kadonotakashi | 0:8fdf9a60065b | 206 | |
| kadonotakashi | 0:8fdf9a60065b | 207 | TEST_ASSERT(p_ticker_info->frequency != 0); |
| kadonotakashi | 0:8fdf9a60065b | 208 | TEST_ASSERT(p_ticker_info->bits >= 8); |
| kadonotakashi | 0:8fdf9a60065b | 209 | } |
| kadonotakashi | 0:8fdf9a60065b | 210 | |
| kadonotakashi | 0:8fdf9a60065b | 211 | /* Test that ticker interrupt fires only when the ticker counter increments to the value set by ticker_set_interrupt. */ |
| kadonotakashi | 0:8fdf9a60065b | 212 | void ticker_interrupt_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 213 | { |
| kadonotakashi | 0:8fdf9a60065b | 214 | uint32_t ticker_timeout[] = { 100, 200, 300, 500 }; |
| kadonotakashi | 0:8fdf9a60065b | 215 | |
| kadonotakashi | 0:8fdf9a60065b | 216 | overflow_protect(); |
| kadonotakashi | 0:8fdf9a60065b | 217 | |
| kadonotakashi | 0:8fdf9a60065b | 218 | for (uint32_t i = 0; i < (sizeof(ticker_timeout) / sizeof(uint32_t)); i++) { |
| kadonotakashi | 0:8fdf9a60065b | 219 | intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 220 | const uint32_t tick_count = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 221 | |
| kadonotakashi | 0:8fdf9a60065b | 222 | /* Set interrupt. Interrupt should be fired when tick count is equal to: |
| kadonotakashi | 0:8fdf9a60065b | 223 | * tick_count + ticker_timeout[i]. */ |
| kadonotakashi | 0:8fdf9a60065b | 224 | intf->set_interrupt(tick_count + ticker_timeout[i]); |
| kadonotakashi | 0:8fdf9a60065b | 225 | |
| kadonotakashi | 0:8fdf9a60065b | 226 | /* Wait until ticker count reach value: tick_count + ticker_timeout[i] - TICKER_DELTA. |
| kadonotakashi | 0:8fdf9a60065b | 227 | * Interrupt should not be fired. */ |
| kadonotakashi | 0:8fdf9a60065b | 228 | while (intf->read() < (tick_count + ticker_timeout[i] - TICKER_DELTA)) { |
| kadonotakashi | 0:8fdf9a60065b | 229 | /* Indicate failure if interrupt has fired earlier. */ |
| kadonotakashi | 0:8fdf9a60065b | 230 | TEST_ASSERT_EQUAL_INT_MESSAGE(0, intFlag, "Interrupt fired too early"); |
| kadonotakashi | 0:8fdf9a60065b | 231 | } |
| kadonotakashi | 0:8fdf9a60065b | 232 | |
| kadonotakashi | 0:8fdf9a60065b | 233 | /* Wait until ticker count reach value: tick_count + ticker_timeout[i] + TICKER_DELTA. |
| kadonotakashi | 0:8fdf9a60065b | 234 | * Interrupt should be fired after this time. */ |
| kadonotakashi | 0:8fdf9a60065b | 235 | while (intf->read() < (tick_count + ticker_timeout[i] + TICKER_DELTA)) { |
| kadonotakashi | 0:8fdf9a60065b | 236 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 237 | } |
| kadonotakashi | 0:8fdf9a60065b | 238 | |
| kadonotakashi | 0:8fdf9a60065b | 239 | TEST_ASSERT_EQUAL(1, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 240 | |
| kadonotakashi | 0:8fdf9a60065b | 241 | /* Wait until ticker count reach value: tick_count + 2 * ticker_timeout[i] + TICKER_DELTA. |
| kadonotakashi | 0:8fdf9a60065b | 242 | * Interrupt should not be triggered again. */ |
| kadonotakashi | 0:8fdf9a60065b | 243 | while (intf->read() < (tick_count + 2 * ticker_timeout[i] + TICKER_DELTA)) { |
| kadonotakashi | 0:8fdf9a60065b | 244 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 245 | } |
| kadonotakashi | 0:8fdf9a60065b | 246 | |
| kadonotakashi | 0:8fdf9a60065b | 247 | TEST_ASSERT_EQUAL(1, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 248 | } |
| kadonotakashi | 0:8fdf9a60065b | 249 | } |
| kadonotakashi | 0:8fdf9a60065b | 250 | |
| kadonotakashi | 0:8fdf9a60065b | 251 | /* Test that ticker interrupt is not triggered when ticker_set_interrupt */ |
| kadonotakashi | 0:8fdf9a60065b | 252 | void ticker_past_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 253 | { |
| kadonotakashi | 0:8fdf9a60065b | 254 | intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 255 | |
| kadonotakashi | 0:8fdf9a60065b | 256 | const uint32_t tick_count = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 257 | |
| kadonotakashi | 0:8fdf9a60065b | 258 | /* Set interrupt tick count to value in the past. |
| kadonotakashi | 0:8fdf9a60065b | 259 | * Interrupt should not be fired. */ |
| kadonotakashi | 0:8fdf9a60065b | 260 | intf->set_interrupt(tick_count - TICKER_DELTA); |
| kadonotakashi | 0:8fdf9a60065b | 261 | |
| kadonotakashi | 0:8fdf9a60065b | 262 | wait_cycles(1000); |
| kadonotakashi | 0:8fdf9a60065b | 263 | |
| kadonotakashi | 0:8fdf9a60065b | 264 | TEST_ASSERT_EQUAL(0, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 265 | } |
| kadonotakashi | 0:8fdf9a60065b | 266 | |
| kadonotakashi | 0:8fdf9a60065b | 267 | /* Test that ticker can be rescheduled repeatedly before the handler has been called. */ |
| kadonotakashi | 0:8fdf9a60065b | 268 | void ticker_repeat_reschedule_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 269 | { |
| kadonotakashi | 0:8fdf9a60065b | 270 | overflow_protect(); |
| kadonotakashi | 0:8fdf9a60065b | 271 | |
| kadonotakashi | 0:8fdf9a60065b | 272 | intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 273 | |
| kadonotakashi | 0:8fdf9a60065b | 274 | const uint32_t tick_count = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 275 | |
| kadonotakashi | 0:8fdf9a60065b | 276 | /* Set interrupt. Interrupt should be fired when tick count is equal to: |
| kadonotakashi | 0:8fdf9a60065b | 277 | * tick_count + TICKER_INT_VAL. */ |
| kadonotakashi | 0:8fdf9a60065b | 278 | intf->set_interrupt(tick_count + TICKER_INT_VAL); |
| kadonotakashi | 0:8fdf9a60065b | 279 | |
| kadonotakashi | 0:8fdf9a60065b | 280 | /* Reschedule interrupt - it should not be fired yet. |
| kadonotakashi | 0:8fdf9a60065b | 281 | * Re-schedule interrupt. */ |
| kadonotakashi | 0:8fdf9a60065b | 282 | intf->set_interrupt(tick_count + (2 * TICKER_INT_VAL)); |
| kadonotakashi | 0:8fdf9a60065b | 283 | intf->set_interrupt(tick_count + (3 * TICKER_INT_VAL)); |
| kadonotakashi | 0:8fdf9a60065b | 284 | |
| kadonotakashi | 0:8fdf9a60065b | 285 | /* Wait until ticker count reach value: tick_count + 3*TICKER_INT_VAL - TICKER_DELTA. |
| kadonotakashi | 0:8fdf9a60065b | 286 | * Interrupt should not be fired. */ |
| kadonotakashi | 0:8fdf9a60065b | 287 | while (intf->read() < (tick_count + 3 * TICKER_INT_VAL - TICKER_DELTA)) { |
| kadonotakashi | 0:8fdf9a60065b | 288 | /* Indicate failure if interrupt has fired earlier. */ |
| kadonotakashi | 0:8fdf9a60065b | 289 | TEST_ASSERT_EQUAL_INT_MESSAGE(0, intFlag, "Interrupt fired too early"); |
| kadonotakashi | 0:8fdf9a60065b | 290 | } |
| kadonotakashi | 0:8fdf9a60065b | 291 | |
| kadonotakashi | 0:8fdf9a60065b | 292 | /* Wait until ticker count reach value: tick_count + 3*TICKER_INT_VAL + TICKER_DELTA. |
| kadonotakashi | 0:8fdf9a60065b | 293 | * Interrupt should be fired after this time. */ |
| kadonotakashi | 0:8fdf9a60065b | 294 | while (intf->read() < (tick_count + 3 * TICKER_INT_VAL + TICKER_DELTA)) { |
| kadonotakashi | 0:8fdf9a60065b | 295 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 296 | } |
| kadonotakashi | 0:8fdf9a60065b | 297 | |
| kadonotakashi | 0:8fdf9a60065b | 298 | TEST_ASSERT_EQUAL(1, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 299 | } |
| kadonotakashi | 0:8fdf9a60065b | 300 | |
| kadonotakashi | 0:8fdf9a60065b | 301 | /* Test that ticker_fire_interrupt causes and interrupt to get fired immediately. */ |
| kadonotakashi | 0:8fdf9a60065b | 302 | void ticker_fire_now_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 303 | { |
| kadonotakashi | 0:8fdf9a60065b | 304 | intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 305 | |
| kadonotakashi | 0:8fdf9a60065b | 306 | intf->fire_interrupt(); |
| kadonotakashi | 0:8fdf9a60065b | 307 | |
| kadonotakashi | 0:8fdf9a60065b | 308 | /* On some platforms set_interrupt function sets interrupt in the nearest feature. */ |
| kadonotakashi | 0:8fdf9a60065b | 309 | wait_cycles(1000); |
| kadonotakashi | 0:8fdf9a60065b | 310 | |
| kadonotakashi | 0:8fdf9a60065b | 311 | TEST_ASSERT_EQUAL(1, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 312 | } |
| kadonotakashi | 0:8fdf9a60065b | 313 | |
| kadonotakashi | 0:8fdf9a60065b | 314 | /* Test that the ticker correctly handles overflow. */ |
| kadonotakashi | 0:8fdf9a60065b | 315 | void ticker_overflow_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 316 | { |
| kadonotakashi | 0:8fdf9a60065b | 317 | const ticker_info_t *p_ticker_info = intf->get_info(); |
| kadonotakashi | 0:8fdf9a60065b | 318 | |
| kadonotakashi | 0:8fdf9a60065b | 319 | /* We need to check how long it will take to overflow. |
| kadonotakashi | 0:8fdf9a60065b | 320 | * We will perform this test only if this time is no longer than 30 sec. |
| kadonotakashi | 0:8fdf9a60065b | 321 | */ |
| kadonotakashi | 0:8fdf9a60065b | 322 | const uint32_t max_count = (1 << p_ticker_info->bits) - 1; |
| kadonotakashi | 0:8fdf9a60065b | 323 | const uint32_t required_time_sec = (max_count / p_ticker_info->frequency); |
| kadonotakashi | 0:8fdf9a60065b | 324 | |
| kadonotakashi | 0:8fdf9a60065b | 325 | if (required_time_sec > 30 && !FORCE_OVERFLOW_TEST) { |
| kadonotakashi | 0:8fdf9a60065b | 326 | TEST_ASSERT_TRUE(true); |
| kadonotakashi | 0:8fdf9a60065b | 327 | printf("Test has been skipped.\n"); |
| kadonotakashi | 0:8fdf9a60065b | 328 | return; |
| kadonotakashi | 0:8fdf9a60065b | 329 | } |
| kadonotakashi | 0:8fdf9a60065b | 330 | |
| kadonotakashi | 0:8fdf9a60065b | 331 | intFlag = 0; |
| kadonotakashi | 0:8fdf9a60065b | 332 | |
| kadonotakashi | 0:8fdf9a60065b | 333 | /* Wait for max count. */ |
| kadonotakashi | 0:8fdf9a60065b | 334 | while (intf->read() >= (max_count - ticker_overflow_delta2) && |
| kadonotakashi | 0:8fdf9a60065b | 335 | intf->read() <= (max_count - ticker_overflow_delta1)) { |
| kadonotakashi | 0:8fdf9a60065b | 336 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 337 | } |
| kadonotakashi | 0:8fdf9a60065b | 338 | |
| kadonotakashi | 0:8fdf9a60065b | 339 | /* Now we are near/at the overflow point. Detect rollover. */ |
| kadonotakashi | 0:8fdf9a60065b | 340 | while (intf->read() > ticker_overflow_delta1); |
| kadonotakashi | 0:8fdf9a60065b | 341 | |
| kadonotakashi | 0:8fdf9a60065b | 342 | const uint32_t after_overflow = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 343 | |
| kadonotakashi | 0:8fdf9a60065b | 344 | /* Now we are just after overflow. Wait a while assuming that ticker still counts. */ |
| kadonotakashi | 0:8fdf9a60065b | 345 | while (intf->read() < TICKER_100_TICKS) { |
| kadonotakashi | 0:8fdf9a60065b | 346 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 347 | } |
| kadonotakashi | 0:8fdf9a60065b | 348 | |
| kadonotakashi | 0:8fdf9a60065b | 349 | const uint32_t next_after_overflow = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 350 | |
| kadonotakashi | 0:8fdf9a60065b | 351 | /* Check that after the overflow ticker continue count. */ |
| kadonotakashi | 0:8fdf9a60065b | 352 | TEST_ASSERT(after_overflow <= ticker_overflow_delta1); |
| kadonotakashi | 0:8fdf9a60065b | 353 | TEST_ASSERT(next_after_overflow >= TICKER_100_TICKS); |
| kadonotakashi | 0:8fdf9a60065b | 354 | TEST_ASSERT_EQUAL(0, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 355 | |
| kadonotakashi | 0:8fdf9a60065b | 356 | const uint32_t tick_count = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 357 | |
| kadonotakashi | 0:8fdf9a60065b | 358 | /* Check if interrupt scheduling still works. */ |
| kadonotakashi | 0:8fdf9a60065b | 359 | intf->set_interrupt(tick_count + TICKER_INT_VAL); |
| kadonotakashi | 0:8fdf9a60065b | 360 | |
| kadonotakashi | 0:8fdf9a60065b | 361 | /* Wait for the interrupt. */ |
| kadonotakashi | 0:8fdf9a60065b | 362 | while (intf->read() < (tick_count + TICKER_INT_VAL + TICKER_DELTA)) { |
| kadonotakashi | 0:8fdf9a60065b | 363 | /* Just wait. */ |
| kadonotakashi | 0:8fdf9a60065b | 364 | } |
| kadonotakashi | 0:8fdf9a60065b | 365 | |
| kadonotakashi | 0:8fdf9a60065b | 366 | TEST_ASSERT_EQUAL(1, intFlag); |
| kadonotakashi | 0:8fdf9a60065b | 367 | } |
| kadonotakashi | 0:8fdf9a60065b | 368 | |
| kadonotakashi | 0:8fdf9a60065b | 369 | /* Test that the ticker increments by one on each tick. */ |
| kadonotakashi | 0:8fdf9a60065b | 370 | void ticker_increment_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 371 | { |
| kadonotakashi | 0:8fdf9a60065b | 372 | const ticker_info_t *p_ticker_info = intf->get_info(); |
| kadonotakashi | 0:8fdf9a60065b | 373 | |
| kadonotakashi | 0:8fdf9a60065b | 374 | /* Perform test based on ticker speed. */ |
| kadonotakashi | 0:8fdf9a60065b | 375 | if (p_ticker_info->frequency <= 250000) { // low frequency tickers |
| kadonotakashi | 0:8fdf9a60065b | 376 | const uint32_t base_tick_count = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 377 | uint32_t next_tick_count = base_tick_count; |
| kadonotakashi | 0:8fdf9a60065b | 378 | |
| kadonotakashi | 0:8fdf9a60065b | 379 | while (next_tick_count == base_tick_count) { |
| kadonotakashi | 0:8fdf9a60065b | 380 | next_tick_count = intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 381 | } |
| kadonotakashi | 0:8fdf9a60065b | 382 | |
| kadonotakashi | 0:8fdf9a60065b | 383 | TEST_ASSERT_UINT32_WITHIN(1, next_tick_count, base_tick_count); |
| kadonotakashi | 0:8fdf9a60065b | 384 | } else { // high frequency tickers |
| kadonotakashi | 0:8fdf9a60065b | 385 | |
| kadonotakashi | 0:8fdf9a60065b | 386 | uint32_t num_of_cycles = NUM_OF_CYCLES; |
| kadonotakashi | 0:8fdf9a60065b | 387 | const uint32_t repeat_count = 20; |
| kadonotakashi | 0:8fdf9a60065b | 388 | const uint32_t max_inc_val = 100; |
| kadonotakashi | 0:8fdf9a60065b | 389 | |
| kadonotakashi | 0:8fdf9a60065b | 390 | uint32_t base_tick_count = count_ticks(num_of_cycles, 1); |
| kadonotakashi | 0:8fdf9a60065b | 391 | uint32_t next_tick_count = base_tick_count; |
| kadonotakashi | 0:8fdf9a60065b | 392 | uint32_t inc_val = 0; |
| kadonotakashi | 0:8fdf9a60065b | 393 | uint32_t repeat_cnt = 0; |
| kadonotakashi | 0:8fdf9a60065b | 394 | |
| kadonotakashi | 0:8fdf9a60065b | 395 | while (inc_val < max_inc_val) { |
| kadonotakashi | 0:8fdf9a60065b | 396 | next_tick_count = count_ticks(num_of_cycles + inc_val, 1); |
| kadonotakashi | 0:8fdf9a60065b | 397 | |
| kadonotakashi | 0:8fdf9a60065b | 398 | if (next_tick_count == base_tick_count) { |
| kadonotakashi | 0:8fdf9a60065b | 399 | |
| kadonotakashi | 0:8fdf9a60065b | 400 | /* Same tick count, so repeat 20 times and than |
| kadonotakashi | 0:8fdf9a60065b | 401 | * increase num of cycles by 1. |
| kadonotakashi | 0:8fdf9a60065b | 402 | */ |
| kadonotakashi | 0:8fdf9a60065b | 403 | if (repeat_cnt == repeat_count) { |
| kadonotakashi | 0:8fdf9a60065b | 404 | inc_val++; |
| kadonotakashi | 0:8fdf9a60065b | 405 | repeat_cnt = 0; |
| kadonotakashi | 0:8fdf9a60065b | 406 | } |
| kadonotakashi | 0:8fdf9a60065b | 407 | |
| kadonotakashi | 0:8fdf9a60065b | 408 | repeat_cnt++; |
| kadonotakashi | 0:8fdf9a60065b | 409 | } else { |
| kadonotakashi | 0:8fdf9a60065b | 410 | /* Check if we got 1 tick diff. */ |
| kadonotakashi | 0:8fdf9a60065b | 411 | if (next_tick_count - base_tick_count == 1 || |
| kadonotakashi | 0:8fdf9a60065b | 412 | base_tick_count - next_tick_count == 1) { |
| kadonotakashi | 0:8fdf9a60065b | 413 | break; |
| kadonotakashi | 0:8fdf9a60065b | 414 | } |
| kadonotakashi | 0:8fdf9a60065b | 415 | |
| kadonotakashi | 0:8fdf9a60065b | 416 | /* It is possible that the difference between base and next |
| kadonotakashi | 0:8fdf9a60065b | 417 | * tick count on some platforms is greater that 1, in this case we need |
| kadonotakashi | 0:8fdf9a60065b | 418 | * to repeat counting with the reduced number of cycles (for slower boards). |
| kadonotakashi | 0:8fdf9a60065b | 419 | * In cases if difference is exactly 1 we can exit the loop. |
| kadonotakashi | 0:8fdf9a60065b | 420 | */ |
| kadonotakashi | 0:8fdf9a60065b | 421 | num_of_cycles /= 2; |
| kadonotakashi | 0:8fdf9a60065b | 422 | inc_val = 0; |
| kadonotakashi | 0:8fdf9a60065b | 423 | repeat_cnt = 0; |
| kadonotakashi | 0:8fdf9a60065b | 424 | base_tick_count = count_ticks(num_of_cycles, 1); |
| kadonotakashi | 0:8fdf9a60065b | 425 | } |
| kadonotakashi | 0:8fdf9a60065b | 426 | } |
| kadonotakashi | 0:8fdf9a60065b | 427 | |
| kadonotakashi | 0:8fdf9a60065b | 428 | /* Since we are here we know that next_tick_count != base_tick_count. |
| kadonotakashi | 0:8fdf9a60065b | 429 | * The accuracy of our measurement method is +/- 1 tick, so it is possible that |
| kadonotakashi | 0:8fdf9a60065b | 430 | * next_tick_count == base_tick_count - 1. This is also valid result. |
| kadonotakashi | 0:8fdf9a60065b | 431 | */ |
| kadonotakashi | 0:8fdf9a60065b | 432 | TEST_ASSERT_UINT32_WITHIN(1, next_tick_count, base_tick_count); |
| kadonotakashi | 0:8fdf9a60065b | 433 | } |
| kadonotakashi | 0:8fdf9a60065b | 434 | } |
| kadonotakashi | 0:8fdf9a60065b | 435 | |
| kadonotakashi | 0:8fdf9a60065b | 436 | /* Test that common ticker functions complete with the required amount of time. */ |
| kadonotakashi | 0:8fdf9a60065b | 437 | void ticker_speed_test(void) |
| kadonotakashi | 0:8fdf9a60065b | 438 | { |
| kadonotakashi | 0:8fdf9a60065b | 439 | int counter = NUM_OF_CALLS; |
| kadonotakashi | 0:8fdf9a60065b | 440 | uint32_t start; |
| kadonotakashi | 0:8fdf9a60065b | 441 | uint32_t stop; |
| kadonotakashi | 0:8fdf9a60065b | 442 | |
| kadonotakashi | 0:8fdf9a60065b | 443 | const ticker_info_t *us_ticker_info = get_us_ticker_data()->interface->get_info(); |
| kadonotakashi | 0:8fdf9a60065b | 444 | |
| kadonotakashi | 0:8fdf9a60065b | 445 | /* ---- Test ticker_read function. ---- */ |
| kadonotakashi | 0:8fdf9a60065b | 446 | start = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 447 | while (counter--) { |
| kadonotakashi | 0:8fdf9a60065b | 448 | intf->read(); |
| kadonotakashi | 0:8fdf9a60065b | 449 | } |
| kadonotakashi | 0:8fdf9a60065b | 450 | stop = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 451 | |
| kadonotakashi | 0:8fdf9a60065b | 452 | TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); |
| kadonotakashi | 0:8fdf9a60065b | 453 | |
| kadonotakashi | 0:8fdf9a60065b | 454 | /* ---- Test ticker_clear_interrupt function. ---- */ |
| kadonotakashi | 0:8fdf9a60065b | 455 | counter = NUM_OF_CALLS; |
| kadonotakashi | 0:8fdf9a60065b | 456 | start = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 457 | while (counter--) { |
| kadonotakashi | 0:8fdf9a60065b | 458 | intf->clear_interrupt(); |
| kadonotakashi | 0:8fdf9a60065b | 459 | } |
| kadonotakashi | 0:8fdf9a60065b | 460 | stop = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 461 | |
| kadonotakashi | 0:8fdf9a60065b | 462 | TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); |
| kadonotakashi | 0:8fdf9a60065b | 463 | |
| kadonotakashi | 0:8fdf9a60065b | 464 | /* ---- Test ticker_set_interrupt function. ---- */ |
| kadonotakashi | 0:8fdf9a60065b | 465 | counter = NUM_OF_CALLS; |
| kadonotakashi | 0:8fdf9a60065b | 466 | start = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 467 | while (counter--) { |
| kadonotakashi | 0:8fdf9a60065b | 468 | intf->set_interrupt(0); |
| kadonotakashi | 0:8fdf9a60065b | 469 | } |
| kadonotakashi | 0:8fdf9a60065b | 470 | stop = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 471 | |
| kadonotakashi | 0:8fdf9a60065b | 472 | TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); |
| kadonotakashi | 0:8fdf9a60065b | 473 | |
| kadonotakashi | 0:8fdf9a60065b | 474 | /* ---- Test fire_interrupt function. ---- */ |
| kadonotakashi | 0:8fdf9a60065b | 475 | counter = NUM_OF_CALLS; |
| kadonotakashi | 0:8fdf9a60065b | 476 | /* Disable ticker interrupt which would interfere with speed test */ |
| kadonotakashi | 0:8fdf9a60065b | 477 | core_util_critical_section_enter(); |
| kadonotakashi | 0:8fdf9a60065b | 478 | start = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 479 | while (counter--) { |
| kadonotakashi | 0:8fdf9a60065b | 480 | intf->fire_interrupt(); |
| kadonotakashi | 0:8fdf9a60065b | 481 | } |
| kadonotakashi | 0:8fdf9a60065b | 482 | stop = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 483 | core_util_critical_section_exit(); |
| kadonotakashi | 0:8fdf9a60065b | 484 | |
| kadonotakashi | 0:8fdf9a60065b | 485 | TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); |
| kadonotakashi | 0:8fdf9a60065b | 486 | |
| kadonotakashi | 0:8fdf9a60065b | 487 | /* ---- Test disable_interrupt function. ---- */ |
| kadonotakashi | 0:8fdf9a60065b | 488 | counter = NUM_OF_CALLS; |
| kadonotakashi | 0:8fdf9a60065b | 489 | start = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 490 | while (counter--) { |
| kadonotakashi | 0:8fdf9a60065b | 491 | intf->disable_interrupt(); |
| kadonotakashi | 0:8fdf9a60065b | 492 | } |
| kadonotakashi | 0:8fdf9a60065b | 493 | stop = us_ticker_read(); |
| kadonotakashi | 0:8fdf9a60065b | 494 | |
| kadonotakashi | 0:8fdf9a60065b | 495 | TEST_ASSERT(diff_us(start, stop, us_ticker_info) < (NUM_OF_CALLS * (MAX_FUNC_EXEC_TIME_US + DELTA_FUNC_EXEC_TIME_US))); |
| kadonotakashi | 0:8fdf9a60065b | 496 | |
| kadonotakashi | 0:8fdf9a60065b | 497 | } |
| kadonotakashi | 0:8fdf9a60065b | 498 | |
| kadonotakashi | 0:8fdf9a60065b | 499 | utest::v1::status_t us_ticker_setup(const Case *const source, const size_t index_of_case) |
| kadonotakashi | 0:8fdf9a60065b | 500 | { |
| kadonotakashi | 0:8fdf9a60065b | 501 | intf = get_us_ticker_data()->interface; |
| kadonotakashi | 0:8fdf9a60065b | 502 | |
| kadonotakashi | 0:8fdf9a60065b | 503 | /* OS, common ticker and low power ticker wrapper |
| kadonotakashi | 0:8fdf9a60065b | 504 | * may make use of us ticker so suspend them for this test */ |
| kadonotakashi | 0:8fdf9a60065b | 505 | osKernelSuspend(); |
| kadonotakashi | 0:8fdf9a60065b | 506 | #if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) |
| kadonotakashi | 0:8fdf9a60065b | 507 | /* Suspend the lp ticker wrapper since it makes use of the us ticker */ |
| kadonotakashi | 0:8fdf9a60065b | 508 | ticker_suspend(get_lp_ticker_data()); |
| kadonotakashi | 0:8fdf9a60065b | 509 | lp_ticker_wrapper_suspend(); |
| kadonotakashi | 0:8fdf9a60065b | 510 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 511 | ticker_suspend(get_us_ticker_data()); |
| kadonotakashi | 0:8fdf9a60065b | 512 | |
| kadonotakashi | 0:8fdf9a60065b | 513 | intf->init(); |
| kadonotakashi | 0:8fdf9a60065b | 514 | |
| kadonotakashi | 0:8fdf9a60065b | 515 | prev_irq_handler = set_us_ticker_irq_handler(ticker_event_handler_stub); |
| kadonotakashi | 0:8fdf9a60065b | 516 | |
| kadonotakashi | 0:8fdf9a60065b | 517 | ticker_overflow_delta1 = US_TICKER_OVERFLOW_DELTA1; |
| kadonotakashi | 0:8fdf9a60065b | 518 | ticker_overflow_delta2 = US_TICKER_OVERFLOW_DELTA2; |
| kadonotakashi | 0:8fdf9a60065b | 519 | |
| kadonotakashi | 0:8fdf9a60065b | 520 | return greentea_case_setup_handler(source, index_of_case); |
| kadonotakashi | 0:8fdf9a60065b | 521 | } |
| kadonotakashi | 0:8fdf9a60065b | 522 | |
| kadonotakashi | 0:8fdf9a60065b | 523 | utest::v1::status_t us_ticker_teardown(const Case *const source, const size_t passed, const size_t failed, |
| kadonotakashi | 0:8fdf9a60065b | 524 | const failure_t reason) |
| kadonotakashi | 0:8fdf9a60065b | 525 | { |
| kadonotakashi | 0:8fdf9a60065b | 526 | set_us_ticker_irq_handler(prev_irq_handler); |
| kadonotakashi | 0:8fdf9a60065b | 527 | |
| kadonotakashi | 0:8fdf9a60065b | 528 | prev_irq_handler = NULL; |
| kadonotakashi | 0:8fdf9a60065b | 529 | |
| kadonotakashi | 0:8fdf9a60065b | 530 | ticker_resume(get_us_ticker_data()); |
| kadonotakashi | 0:8fdf9a60065b | 531 | #if DEVICE_LPTICKER && (LPTICKER_DELAY_TICKS > 0) |
| kadonotakashi | 0:8fdf9a60065b | 532 | lp_ticker_wrapper_resume(); |
| kadonotakashi | 0:8fdf9a60065b | 533 | ticker_resume(get_lp_ticker_data()); |
| kadonotakashi | 0:8fdf9a60065b | 534 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 535 | osKernelResume(0); |
| kadonotakashi | 0:8fdf9a60065b | 536 | |
| kadonotakashi | 0:8fdf9a60065b | 537 | return greentea_case_teardown_handler(source, passed, failed, reason); |
| kadonotakashi | 0:8fdf9a60065b | 538 | } |
| kadonotakashi | 0:8fdf9a60065b | 539 | |
| kadonotakashi | 0:8fdf9a60065b | 540 | #if DEVICE_LPTICKER |
| kadonotakashi | 0:8fdf9a60065b | 541 | utest::v1::status_t lp_ticker_setup(const Case *const source, const size_t index_of_case) |
| kadonotakashi | 0:8fdf9a60065b | 542 | { |
| kadonotakashi | 0:8fdf9a60065b | 543 | intf = get_lp_ticker_data()->interface; |
| kadonotakashi | 0:8fdf9a60065b | 544 | |
| kadonotakashi | 0:8fdf9a60065b | 545 | /* OS and common ticker may make use of lp ticker so suspend them for this test */ |
| kadonotakashi | 0:8fdf9a60065b | 546 | osKernelSuspend(); |
| kadonotakashi | 0:8fdf9a60065b | 547 | ticker_suspend(get_lp_ticker_data()); |
| kadonotakashi | 0:8fdf9a60065b | 548 | |
| kadonotakashi | 0:8fdf9a60065b | 549 | intf->init(); |
| kadonotakashi | 0:8fdf9a60065b | 550 | |
| kadonotakashi | 0:8fdf9a60065b | 551 | prev_irq_handler = set_lp_ticker_irq_handler(ticker_event_handler_stub); |
| kadonotakashi | 0:8fdf9a60065b | 552 | |
| kadonotakashi | 0:8fdf9a60065b | 553 | ticker_overflow_delta1 = LP_TICKER_OVERFLOW_DELTA1; |
| kadonotakashi | 0:8fdf9a60065b | 554 | ticker_overflow_delta2 = LP_TICKER_OVERFLOW_DELTA2; |
| kadonotakashi | 0:8fdf9a60065b | 555 | |
| kadonotakashi | 0:8fdf9a60065b | 556 | return greentea_case_setup_handler(source, index_of_case); |
| kadonotakashi | 0:8fdf9a60065b | 557 | } |
| kadonotakashi | 0:8fdf9a60065b | 558 | |
| kadonotakashi | 0:8fdf9a60065b | 559 | utest::v1::status_t lp_ticker_teardown(const Case *const source, const size_t passed, const size_t failed, |
| kadonotakashi | 0:8fdf9a60065b | 560 | const failure_t reason) |
| kadonotakashi | 0:8fdf9a60065b | 561 | { |
| kadonotakashi | 0:8fdf9a60065b | 562 | set_lp_ticker_irq_handler(prev_irq_handler); |
| kadonotakashi | 0:8fdf9a60065b | 563 | |
| kadonotakashi | 0:8fdf9a60065b | 564 | prev_irq_handler = NULL; |
| kadonotakashi | 0:8fdf9a60065b | 565 | |
| kadonotakashi | 0:8fdf9a60065b | 566 | ticker_resume(get_lp_ticker_data()); |
| kadonotakashi | 0:8fdf9a60065b | 567 | osKernelResume(0); |
| kadonotakashi | 0:8fdf9a60065b | 568 | |
| kadonotakashi | 0:8fdf9a60065b | 569 | return greentea_case_teardown_handler(source, passed, failed, reason); |
| kadonotakashi | 0:8fdf9a60065b | 570 | } |
| kadonotakashi | 0:8fdf9a60065b | 571 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 572 | |
| kadonotakashi | 0:8fdf9a60065b | 573 | utest::v1::status_t test_setup(const size_t number_of_cases) |
| kadonotakashi | 0:8fdf9a60065b | 574 | { |
| kadonotakashi | 0:8fdf9a60065b | 575 | GREENTEA_SETUP(80, "default_auto"); |
| kadonotakashi | 0:8fdf9a60065b | 576 | return verbose_test_setup_handler(number_of_cases); |
| kadonotakashi | 0:8fdf9a60065b | 577 | } |
| kadonotakashi | 0:8fdf9a60065b | 578 | |
| kadonotakashi | 0:8fdf9a60065b | 579 | Case cases[] = { |
| kadonotakashi | 0:8fdf9a60065b | 580 | Case("Microsecond ticker init is safe to call repeatedly", us_ticker_setup, ticker_init_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 581 | Case("Microsecond ticker info test", us_ticker_setup, ticker_info_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 582 | Case("Microsecond ticker interrupt test", us_ticker_setup, ticker_interrupt_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 583 | Case("Microsecond ticker past interrupt test", us_ticker_setup, ticker_past_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 584 | Case("Microsecond ticker reschedule test", us_ticker_setup, ticker_repeat_reschedule_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 585 | Case("Microsecond ticker fire interrupt", us_ticker_setup, ticker_fire_now_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 586 | Case("Microsecond ticker overflow test", us_ticker_setup, ticker_overflow_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 587 | Case("Microsecond ticker increment test", us_ticker_setup, ticker_increment_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 588 | Case("Microsecond ticker speed test", us_ticker_setup, ticker_speed_test, us_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 589 | #if DEVICE_LPTICKER |
| kadonotakashi | 0:8fdf9a60065b | 590 | Case("lp ticker init is safe to call repeatedly", lp_ticker_setup, ticker_init_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 591 | Case("lp ticker info test", lp_ticker_setup, ticker_info_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 592 | Case("lp ticker interrupt test", lp_ticker_setup, ticker_interrupt_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 593 | Case("lp ticker past interrupt test", lp_ticker_setup, ticker_past_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 594 | Case("lp ticker reschedule test", lp_ticker_setup, ticker_repeat_reschedule_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 595 | Case("lp ticker fire interrupt", lp_ticker_setup, ticker_fire_now_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 596 | Case("lp ticker overflow test", lp_ticker_setup, ticker_overflow_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 597 | Case("lp ticker increment test", lp_ticker_setup, ticker_increment_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 598 | Case("lp ticker speed test", lp_ticker_setup, ticker_speed_test, lp_ticker_teardown), |
| kadonotakashi | 0:8fdf9a60065b | 599 | #endif |
| kadonotakashi | 0:8fdf9a60065b | 600 | }; |
| kadonotakashi | 0:8fdf9a60065b | 601 | |
| kadonotakashi | 0:8fdf9a60065b | 602 | Specification specification(test_setup, cases); |
| kadonotakashi | 0:8fdf9a60065b | 603 | |
| kadonotakashi | 0:8fdf9a60065b | 604 | int main() |
| kadonotakashi | 0:8fdf9a60065b | 605 | { |
| kadonotakashi | 0:8fdf9a60065b | 606 | return !Harness::run(specification); |
| kadonotakashi | 0:8fdf9a60065b | 607 | } |