takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /* mbed Microcontroller Library
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2013-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 "utest/utest.h"
kadonotakashi 0:8fdf9a60065b 19 #include "unity/unity.h"
kadonotakashi 0:8fdf9a60065b 20
kadonotakashi 0:8fdf9a60065b 21
kadonotakashi 0:8fdf9a60065b 22 #if !DEVICE_LPTICKER
kadonotakashi 0:8fdf9a60065b 23 #error [NOT_SUPPORTED] Low power ticker not supported for this target
kadonotakashi 0:8fdf9a60065b 24 #endif
kadonotakashi 0:8fdf9a60065b 25
kadonotakashi 0:8fdf9a60065b 26 using utest::v1::Case;
kadonotakashi 0:8fdf9a60065b 27
kadonotakashi 0:8fdf9a60065b 28 static const int test_timeout = 10;
kadonotakashi 0:8fdf9a60065b 29
kadonotakashi 0:8fdf9a60065b 30 #define TICKER_COUNT 16
kadonotakashi 0:8fdf9a60065b 31 #define MULTI_TICKER_TIME_MS 100
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 /* Due to poor accuracy of LowPowerTicker on many platforms
kadonotakashi 0:8fdf9a60065b 34 there is no sense to tune tolerance value as it was in Ticker tests.
kadonotakashi 0:8fdf9a60065b 35
kadonotakashi 0:8fdf9a60065b 36 Tolerance value is set to 600us for measurement inaccuracy + 5% tolerance
kadonotakashi 0:8fdf9a60065b 37 for LowPowerTicker. */
kadonotakashi 0:8fdf9a60065b 38 #define TOLERANCE_US(DELAY) (600 + DELAY / 20)
kadonotakashi 0:8fdf9a60065b 39
kadonotakashi 0:8fdf9a60065b 40
kadonotakashi 0:8fdf9a60065b 41 volatile uint32_t ticker_callback_flag;
kadonotakashi 0:8fdf9a60065b 42 volatile uint32_t multi_counter;
kadonotakashi 0:8fdf9a60065b 43 Timer gtimer;
kadonotakashi 0:8fdf9a60065b 44
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46
kadonotakashi 0:8fdf9a60065b 47 void sem_release(Semaphore *sem)
kadonotakashi 0:8fdf9a60065b 48 {
kadonotakashi 0:8fdf9a60065b 49 sem->release();
kadonotakashi 0:8fdf9a60065b 50 }
kadonotakashi 0:8fdf9a60065b 51
kadonotakashi 0:8fdf9a60065b 52
kadonotakashi 0:8fdf9a60065b 53 void stop_gtimer_set_flag(void)
kadonotakashi 0:8fdf9a60065b 54 {
kadonotakashi 0:8fdf9a60065b 55 gtimer.stop();
kadonotakashi 0:8fdf9a60065b 56 core_util_atomic_incr_u32((uint32_t *)&ticker_callback_flag, 1);
kadonotakashi 0:8fdf9a60065b 57 }
kadonotakashi 0:8fdf9a60065b 58
kadonotakashi 0:8fdf9a60065b 59 void increment_multi_counter(void)
kadonotakashi 0:8fdf9a60065b 60 {
kadonotakashi 0:8fdf9a60065b 61 core_util_atomic_incr_u32((uint32_t *)&multi_counter, 1);;
kadonotakashi 0:8fdf9a60065b 62 }
kadonotakashi 0:8fdf9a60065b 63
kadonotakashi 0:8fdf9a60065b 64 /** Test many tickers run one after the other
kadonotakashi 0:8fdf9a60065b 65
kadonotakashi 0:8fdf9a60065b 66 Given many Tickers
kadonotakashi 0:8fdf9a60065b 67 When schedule them one after the other with the same time intervals
kadonotakashi 0:8fdf9a60065b 68 Then tickers properly execute callbacks
kadonotakashi 0:8fdf9a60065b 69 When schedule them one after the other with the different time intervals
kadonotakashi 0:8fdf9a60065b 70 Then tickers properly execute callbacks
kadonotakashi 0:8fdf9a60065b 71 */
kadonotakashi 0:8fdf9a60065b 72 void test_multi_ticker(void)
kadonotakashi 0:8fdf9a60065b 73 {
kadonotakashi 0:8fdf9a60065b 74 LowPowerTicker ticker[TICKER_COUNT];
kadonotakashi 0:8fdf9a60065b 75 const uint32_t extra_wait = 10; // extra 10ms wait time
kadonotakashi 0:8fdf9a60065b 76
kadonotakashi 0:8fdf9a60065b 77 multi_counter = 0;
kadonotakashi 0:8fdf9a60065b 78 for (int i = 0; i < TICKER_COUNT; i++) {
kadonotakashi 0:8fdf9a60065b 79 ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000);
kadonotakashi 0:8fdf9a60065b 80 }
kadonotakashi 0:8fdf9a60065b 81
kadonotakashi 0:8fdf9a60065b 82 Thread::wait(MULTI_TICKER_TIME_MS + extra_wait);
kadonotakashi 0:8fdf9a60065b 83 TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
kadonotakashi 0:8fdf9a60065b 84
kadonotakashi 0:8fdf9a60065b 85 for (int i = 0; i < TICKER_COUNT; i++) {
kadonotakashi 0:8fdf9a60065b 86 ticker[i].detach();
kadonotakashi 0:8fdf9a60065b 87 }
kadonotakashi 0:8fdf9a60065b 88 // Because detach calls schedule_interrupt in some circumstances
kadonotakashi 0:8fdf9a60065b 89 // (e.g. when head event is removed), it's good to check if
kadonotakashi 0:8fdf9a60065b 90 // no more callbacks were triggered during detaching.
kadonotakashi 0:8fdf9a60065b 91 TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
kadonotakashi 0:8fdf9a60065b 92
kadonotakashi 0:8fdf9a60065b 93 multi_counter = 0;
kadonotakashi 0:8fdf9a60065b 94 for (int i = 0; i < TICKER_COUNT; i++) {
kadonotakashi 0:8fdf9a60065b 95 ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000);
kadonotakashi 0:8fdf9a60065b 96 }
kadonotakashi 0:8fdf9a60065b 97
kadonotakashi 0:8fdf9a60065b 98 Thread::wait(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
kadonotakashi 0:8fdf9a60065b 99 TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
kadonotakashi 0:8fdf9a60065b 100
kadonotakashi 0:8fdf9a60065b 101 for (int i = 0; i < TICKER_COUNT; i++) {
kadonotakashi 0:8fdf9a60065b 102 ticker[i].detach();
kadonotakashi 0:8fdf9a60065b 103 }
kadonotakashi 0:8fdf9a60065b 104 // Because detach calls schedule_interrupt in some circumstances
kadonotakashi 0:8fdf9a60065b 105 // (e.g. when head event is removed), it's good to check if
kadonotakashi 0:8fdf9a60065b 106 // no more callbacks were triggered during detaching.
kadonotakashi 0:8fdf9a60065b 107 TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
kadonotakashi 0:8fdf9a60065b 108 }
kadonotakashi 0:8fdf9a60065b 109
kadonotakashi 0:8fdf9a60065b 110 /** Test multi callback time
kadonotakashi 0:8fdf9a60065b 111
kadonotakashi 0:8fdf9a60065b 112 Given a Ticker
kadonotakashi 0:8fdf9a60065b 113 When the callback is attached multiple times
kadonotakashi 0:8fdf9a60065b 114 Then ticker properly execute callback multiple times
kadonotakashi 0:8fdf9a60065b 115 */
kadonotakashi 0:8fdf9a60065b 116 void test_multi_call_time(void)
kadonotakashi 0:8fdf9a60065b 117 {
kadonotakashi 0:8fdf9a60065b 118 LowPowerTicker ticker;
kadonotakashi 0:8fdf9a60065b 119 int time_diff;
kadonotakashi 0:8fdf9a60065b 120 const int attach_count = 10;
kadonotakashi 0:8fdf9a60065b 121
kadonotakashi 0:8fdf9a60065b 122 for (int i = 0; i < attach_count; i++) {
kadonotakashi 0:8fdf9a60065b 123 ticker_callback_flag = 0;
kadonotakashi 0:8fdf9a60065b 124 gtimer.reset();
kadonotakashi 0:8fdf9a60065b 125
kadonotakashi 0:8fdf9a60065b 126 gtimer.start();
kadonotakashi 0:8fdf9a60065b 127 ticker.attach_us(callback(stop_gtimer_set_flag), MULTI_TICKER_TIME_MS * 1000);
kadonotakashi 0:8fdf9a60065b 128 while (!ticker_callback_flag);
kadonotakashi 0:8fdf9a60065b 129 time_diff = gtimer.read_us();
kadonotakashi 0:8fdf9a60065b 130
kadonotakashi 0:8fdf9a60065b 131 TEST_ASSERT_UINT32_WITHIN(TOLERANCE_US(MULTI_TICKER_TIME_MS * 1000), MULTI_TICKER_TIME_MS * 1000, time_diff);
kadonotakashi 0:8fdf9a60065b 132 }
kadonotakashi 0:8fdf9a60065b 133 }
kadonotakashi 0:8fdf9a60065b 134
kadonotakashi 0:8fdf9a60065b 135 /** Test if detach cancel scheduled callback event
kadonotakashi 0:8fdf9a60065b 136
kadonotakashi 0:8fdf9a60065b 137 Given a Ticker with callback attached
kadonotakashi 0:8fdf9a60065b 138 When the callback is detached
kadonotakashi 0:8fdf9a60065b 139 Then the callback is not being called
kadonotakashi 0:8fdf9a60065b 140 */
kadonotakashi 0:8fdf9a60065b 141 void test_detach(void)
kadonotakashi 0:8fdf9a60065b 142 {
kadonotakashi 0:8fdf9a60065b 143 LowPowerTicker ticker;
kadonotakashi 0:8fdf9a60065b 144 int32_t ret;
kadonotakashi 0:8fdf9a60065b 145 const float ticker_time_s = 0.1f;
kadonotakashi 0:8fdf9a60065b 146 const uint32_t wait_time_ms = 500;
kadonotakashi 0:8fdf9a60065b 147 Semaphore sem(0, 1);
kadonotakashi 0:8fdf9a60065b 148
kadonotakashi 0:8fdf9a60065b 149 ticker.attach(callback(sem_release, &sem), ticker_time_s);
kadonotakashi 0:8fdf9a60065b 150
kadonotakashi 0:8fdf9a60065b 151 ret = sem.wait();
kadonotakashi 0:8fdf9a60065b 152 TEST_ASSERT_TRUE(ret > 0);
kadonotakashi 0:8fdf9a60065b 153
kadonotakashi 0:8fdf9a60065b 154 ret = sem.wait();
kadonotakashi 0:8fdf9a60065b 155 ticker.detach(); /* cancel */
kadonotakashi 0:8fdf9a60065b 156 TEST_ASSERT_TRUE(ret > 0);
kadonotakashi 0:8fdf9a60065b 157
kadonotakashi 0:8fdf9a60065b 158 ret = sem.wait(wait_time_ms);
kadonotakashi 0:8fdf9a60065b 159 TEST_ASSERT_EQUAL(0, ret);
kadonotakashi 0:8fdf9a60065b 160 }
kadonotakashi 0:8fdf9a60065b 161
kadonotakashi 0:8fdf9a60065b 162 /** Test single callback time via attach
kadonotakashi 0:8fdf9a60065b 163
kadonotakashi 0:8fdf9a60065b 164 Given a Ticker
kadonotakashi 0:8fdf9a60065b 165 When callback attached with time interval specified
kadonotakashi 0:8fdf9a60065b 166 Then ticker properly executes callback within a specified time interval
kadonotakashi 0:8fdf9a60065b 167 */
kadonotakashi 0:8fdf9a60065b 168 template<us_timestamp_t DELAY_US>
kadonotakashi 0:8fdf9a60065b 169 void test_attach_time(void)
kadonotakashi 0:8fdf9a60065b 170 {
kadonotakashi 0:8fdf9a60065b 171 LowPowerTicker ticker;
kadonotakashi 0:8fdf9a60065b 172 ticker_callback_flag = 0;
kadonotakashi 0:8fdf9a60065b 173
kadonotakashi 0:8fdf9a60065b 174 gtimer.reset();
kadonotakashi 0:8fdf9a60065b 175 gtimer.start();
kadonotakashi 0:8fdf9a60065b 176 ticker.attach(callback(stop_gtimer_set_flag), ((float)DELAY_US) / 1000000.0f);
kadonotakashi 0:8fdf9a60065b 177 while (!ticker_callback_flag);
kadonotakashi 0:8fdf9a60065b 178 ticker.detach();
kadonotakashi 0:8fdf9a60065b 179 const int time_diff = gtimer.read_us();
kadonotakashi 0:8fdf9a60065b 180
kadonotakashi 0:8fdf9a60065b 181 TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US(DELAY_US), DELAY_US, time_diff);
kadonotakashi 0:8fdf9a60065b 182 }
kadonotakashi 0:8fdf9a60065b 183
kadonotakashi 0:8fdf9a60065b 184 /** Test single callback time via attach_us
kadonotakashi 0:8fdf9a60065b 185
kadonotakashi 0:8fdf9a60065b 186 Given a Ticker
kadonotakashi 0:8fdf9a60065b 187 When callback attached with time interval specified
kadonotakashi 0:8fdf9a60065b 188 Then ticker properly executes callback within a specified time interval
kadonotakashi 0:8fdf9a60065b 189 */
kadonotakashi 0:8fdf9a60065b 190 template<us_timestamp_t DELAY_US>
kadonotakashi 0:8fdf9a60065b 191 void test_attach_us_time(void)
kadonotakashi 0:8fdf9a60065b 192 {
kadonotakashi 0:8fdf9a60065b 193 LowPowerTicker ticker;
kadonotakashi 0:8fdf9a60065b 194 ticker_callback_flag = 0;
kadonotakashi 0:8fdf9a60065b 195
kadonotakashi 0:8fdf9a60065b 196 gtimer.reset();
kadonotakashi 0:8fdf9a60065b 197 gtimer.start();
kadonotakashi 0:8fdf9a60065b 198 ticker.attach_us(callback(stop_gtimer_set_flag), DELAY_US);
kadonotakashi 0:8fdf9a60065b 199 while (!ticker_callback_flag);
kadonotakashi 0:8fdf9a60065b 200 ticker.detach();
kadonotakashi 0:8fdf9a60065b 201 const int time_diff = gtimer.read_us();
kadonotakashi 0:8fdf9a60065b 202
kadonotakashi 0:8fdf9a60065b 203 TEST_ASSERT_UINT64_WITHIN(TOLERANCE_US(DELAY_US), DELAY_US, time_diff);
kadonotakashi 0:8fdf9a60065b 204 }
kadonotakashi 0:8fdf9a60065b 205
kadonotakashi 0:8fdf9a60065b 206 // Test cases
kadonotakashi 0:8fdf9a60065b 207 Case cases[] = {
kadonotakashi 0:8fdf9a60065b 208 Case("Test attach for 0.001s and time measure", test_attach_time<1000>),
kadonotakashi 0:8fdf9a60065b 209 Case("Test attach_us for 1ms and time measure", test_attach_us_time<1000>),
kadonotakashi 0:8fdf9a60065b 210 Case("Test attach for 0.01s and time measure", test_attach_time<10000>),
kadonotakashi 0:8fdf9a60065b 211 Case("Test attach_us for 10ms and time measure", test_attach_us_time<10000>),
kadonotakashi 0:8fdf9a60065b 212 Case("Test attach for 0.1s and time measure", test_attach_time<100000>),
kadonotakashi 0:8fdf9a60065b 213 Case("Test attach_us for 100ms and time measure", test_attach_us_time<100000>),
kadonotakashi 0:8fdf9a60065b 214 Case("Test attach for 0.5s and time measure", test_attach_time<500000>),
kadonotakashi 0:8fdf9a60065b 215 Case("Test attach_us for 500ms and time measure", test_attach_us_time<500000>),
kadonotakashi 0:8fdf9a60065b 216 Case("Test detach", test_detach),
kadonotakashi 0:8fdf9a60065b 217 Case("Test multi call and time measure", test_multi_call_time),
kadonotakashi 0:8fdf9a60065b 218 Case("Test multi ticker", test_multi_ticker),
kadonotakashi 0:8fdf9a60065b 219 };
kadonotakashi 0:8fdf9a60065b 220
kadonotakashi 0:8fdf9a60065b 221 utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
kadonotakashi 0:8fdf9a60065b 222 {
kadonotakashi 0:8fdf9a60065b 223 GREENTEA_SETUP(test_timeout, "timing_drift_auto");
kadonotakashi 0:8fdf9a60065b 224 return utest::v1::greentea_test_setup_handler(number_of_cases);
kadonotakashi 0:8fdf9a60065b 225 }
kadonotakashi 0:8fdf9a60065b 226
kadonotakashi 0:8fdf9a60065b 227 utest::v1::Specification specification(greentea_test_setup, cases, utest::v1::greentea_test_teardown_handler);
kadonotakashi 0:8fdf9a60065b 228
kadonotakashi 0:8fdf9a60065b 229 int main()
kadonotakashi 0:8fdf9a60065b 230 {
kadonotakashi 0:8fdf9a60065b 231 utest::v1::Harness::run(specification);
kadonotakashi 0:8fdf9a60065b 232 }