PES4 / Mbed OS Queue_02
Committer:
demayer
Date:
Sat Apr 11 08:15:48 2020 +0000
Revision:
1:b36bbc1c6d27
Parent:
0:6bf0743ece18
IMU-library in .h und .cpp file aufgeteilt

Who changed what in which revision?

UserRevisionLine numberNew contents of line
demayer 0:6bf0743ece18 1 /* mbed Microcontroller Library
demayer 0:6bf0743ece18 2 * Copyright (c) 2017 ARM Limited
demayer 0:6bf0743ece18 3 *
demayer 0:6bf0743ece18 4 * Licensed under the Apache License, Version 2.0 (the "License");
demayer 0:6bf0743ece18 5 * you may not use this file except in compliance with the License.
demayer 0:6bf0743ece18 6 * You may obtain a copy of the License at
demayer 0:6bf0743ece18 7 *
demayer 0:6bf0743ece18 8 * http://www.apache.org/licenses/LICENSE-2.0
demayer 0:6bf0743ece18 9 *
demayer 0:6bf0743ece18 10 * Unless required by applicable law or agreed to in writing, software
demayer 0:6bf0743ece18 11 * distributed under the License is distributed on an "AS IS" BASIS,
demayer 0:6bf0743ece18 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
demayer 0:6bf0743ece18 13 * See the License for the specific language governing permissions and
demayer 0:6bf0743ece18 14 * limitations under the License.
demayer 0:6bf0743ece18 15 */
demayer 0:6bf0743ece18 16
demayer 0:6bf0743ece18 17 #define __STDC_LIMIT_MACROS
demayer 0:6bf0743ece18 18 #include <stdint.h>
demayer 0:6bf0743ece18 19 #include <algorithm>
demayer 0:6bf0743ece18 20
demayer 0:6bf0743ece18 21 #include "utest/utest.h"
demayer 0:6bf0743ece18 22 #include "unity/unity.h"
demayer 0:6bf0743ece18 23 #include "greentea-client/test_env.h"
demayer 0:6bf0743ece18 24
demayer 0:6bf0743ece18 25 #include "mbed.h"
demayer 0:6bf0743ece18 26 #include "ticker_api.h"
demayer 0:6bf0743ece18 27
demayer 0:6bf0743ece18 28 using namespace utest::v1;
demayer 0:6bf0743ece18 29
demayer 0:6bf0743ece18 30 #define MBED_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
demayer 0:6bf0743ece18 31
demayer 0:6bf0743ece18 32 #define TIMESTAMP_MAX_DELTA_BITS(bits) ((uint64_t)(0x7 << ((bits) - 4)))
demayer 0:6bf0743ece18 33 #define TIMESTAMP_MAX_DELTA TIMESTAMP_MAX_DELTA_BITS(32)
demayer 0:6bf0743ece18 34
demayer 0:6bf0743ece18 35 struct ticker_interface_stub_t {
demayer 0:6bf0743ece18 36 ticker_interface_t interface;
demayer 0:6bf0743ece18 37 bool initialized;
demayer 0:6bf0743ece18 38 bool interrupt_flag;
demayer 0:6bf0743ece18 39 timestamp_t timestamp ;
demayer 0:6bf0743ece18 40 timestamp_t interrupt_timestamp;
demayer 0:6bf0743ece18 41 unsigned int init_call;
demayer 0:6bf0743ece18 42 unsigned int read_call;
demayer 0:6bf0743ece18 43 unsigned int disable_interrupt_call;
demayer 0:6bf0743ece18 44 unsigned int clear_interrupt_call;
demayer 0:6bf0743ece18 45 unsigned int set_interrupt_call;
demayer 0:6bf0743ece18 46 unsigned int fire_interrupt_call;
demayer 0:6bf0743ece18 47 unsigned int get_info_call;
demayer 0:6bf0743ece18 48 };
demayer 0:6bf0743ece18 49
demayer 0:6bf0743ece18 50 static ticker_interface_stub_t interface_stub = { 0 };
demayer 0:6bf0743ece18 51 static ticker_info_t interface_info_stub = { 0 };
demayer 0:6bf0743ece18 52
demayer 0:6bf0743ece18 53 static void ticker_interface_stub_init()
demayer 0:6bf0743ece18 54 {
demayer 0:6bf0743ece18 55 ++interface_stub.init_call;
demayer 0:6bf0743ece18 56 interface_stub.initialized = true;
demayer 0:6bf0743ece18 57 }
demayer 0:6bf0743ece18 58
demayer 0:6bf0743ece18 59 static uint32_t ticker_interface_stub_read()
demayer 0:6bf0743ece18 60 {
demayer 0:6bf0743ece18 61 ++interface_stub.read_call;
demayer 0:6bf0743ece18 62 return interface_stub.timestamp;
demayer 0:6bf0743ece18 63 }
demayer 0:6bf0743ece18 64
demayer 0:6bf0743ece18 65 static void ticker_interface_stub_disable_interrupt()
demayer 0:6bf0743ece18 66 {
demayer 0:6bf0743ece18 67 ++interface_stub.disable_interrupt_call;
demayer 0:6bf0743ece18 68 }
demayer 0:6bf0743ece18 69
demayer 0:6bf0743ece18 70 static void ticker_interface_stub_clear_interrupt()
demayer 0:6bf0743ece18 71 {
demayer 0:6bf0743ece18 72 ++interface_stub.clear_interrupt_call;
demayer 0:6bf0743ece18 73 interface_stub.interrupt_flag = false;
demayer 0:6bf0743ece18 74 }
demayer 0:6bf0743ece18 75
demayer 0:6bf0743ece18 76 static void ticker_interface_stub_set_interrupt(timestamp_t timestamp)
demayer 0:6bf0743ece18 77 {
demayer 0:6bf0743ece18 78 ++interface_stub.set_interrupt_call;
demayer 0:6bf0743ece18 79 interface_stub.interrupt_timestamp = timestamp;
demayer 0:6bf0743ece18 80 }
demayer 0:6bf0743ece18 81
demayer 0:6bf0743ece18 82 static void ticker_interface_stub_fire_interrupt()
demayer 0:6bf0743ece18 83 {
demayer 0:6bf0743ece18 84 ++interface_stub.fire_interrupt_call;
demayer 0:6bf0743ece18 85 }
demayer 0:6bf0743ece18 86
demayer 0:6bf0743ece18 87 static const ticker_info_t *ticker_interface_stub_get_info()
demayer 0:6bf0743ece18 88 {
demayer 0:6bf0743ece18 89 ++interface_stub.get_info_call;
demayer 0:6bf0743ece18 90 return &interface_info_stub;
demayer 0:6bf0743ece18 91 }
demayer 0:6bf0743ece18 92
demayer 0:6bf0743ece18 93 static void reset_ticker_interface_stub()
demayer 0:6bf0743ece18 94 {
demayer 0:6bf0743ece18 95 interface_stub.interface.init = ticker_interface_stub_init;
demayer 0:6bf0743ece18 96 interface_stub.interface.read = ticker_interface_stub_read;
demayer 0:6bf0743ece18 97 interface_stub.interface.disable_interrupt =
demayer 0:6bf0743ece18 98 ticker_interface_stub_disable_interrupt;
demayer 0:6bf0743ece18 99 interface_stub.interface.clear_interrupt =
demayer 0:6bf0743ece18 100 ticker_interface_stub_clear_interrupt;
demayer 0:6bf0743ece18 101 interface_stub.interface.set_interrupt =ticker_interface_stub_set_interrupt;
demayer 0:6bf0743ece18 102 interface_stub.interface.fire_interrupt = ticker_interface_stub_fire_interrupt;
demayer 0:6bf0743ece18 103 interface_stub.interface.get_info = ticker_interface_stub_get_info;
demayer 0:6bf0743ece18 104 interface_stub.initialized = false;
demayer 0:6bf0743ece18 105 interface_stub.interrupt_flag = false;
demayer 0:6bf0743ece18 106 interface_stub.timestamp = 0;
demayer 0:6bf0743ece18 107 interface_stub.interrupt_timestamp = 0;
demayer 0:6bf0743ece18 108 interface_stub.init_call = 0;
demayer 0:6bf0743ece18 109 interface_stub.read_call = 0;
demayer 0:6bf0743ece18 110 interface_stub.disable_interrupt_call = 0;
demayer 0:6bf0743ece18 111 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 112 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 113 interface_stub.fire_interrupt_call = 0;
demayer 0:6bf0743ece18 114
demayer 0:6bf0743ece18 115 interface_info_stub.frequency = 1000000;
demayer 0:6bf0743ece18 116 interface_info_stub.bits = 32;
demayer 0:6bf0743ece18 117 }
demayer 0:6bf0743ece18 118
demayer 0:6bf0743ece18 119 // stub of the event queue
demayer 0:6bf0743ece18 120 static ticker_event_queue_t queue_stub = {
demayer 0:6bf0743ece18 121 /* event handler */ NULL,
demayer 0:6bf0743ece18 122 /* head */ NULL,
demayer 0:6bf0743ece18 123 /* timestamp */ 0,
demayer 0:6bf0743ece18 124 /* initialized */ false
demayer 0:6bf0743ece18 125 };
demayer 0:6bf0743ece18 126
demayer 0:6bf0743ece18 127 static void reset_queue_stub()
demayer 0:6bf0743ece18 128 {
demayer 0:6bf0743ece18 129 queue_stub.event_handler = NULL;
demayer 0:6bf0743ece18 130 queue_stub.head = NULL,
demayer 0:6bf0743ece18 131 queue_stub.tick_last_read = 0;
demayer 0:6bf0743ece18 132 queue_stub.tick_remainder = 0;
demayer 0:6bf0743ece18 133 queue_stub.frequency = 0;
demayer 0:6bf0743ece18 134 queue_stub.bitmask = 0;
demayer 0:6bf0743ece18 135 queue_stub.max_delta = 0;
demayer 0:6bf0743ece18 136 queue_stub.max_delta_us = 0;
demayer 0:6bf0743ece18 137 queue_stub.present_time = 0;
demayer 0:6bf0743ece18 138 queue_stub.initialized = false;
demayer 0:6bf0743ece18 139 }
demayer 0:6bf0743ece18 140
demayer 0:6bf0743ece18 141 // stub of the ticker
demayer 0:6bf0743ece18 142 static ticker_data_t ticker_stub = {
demayer 0:6bf0743ece18 143 /* interface */ &interface_stub.interface,
demayer 0:6bf0743ece18 144 /* queue */ &queue_stub
demayer 0:6bf0743ece18 145 };
demayer 0:6bf0743ece18 146
demayer 0:6bf0743ece18 147 static void reset_ticker_stub()
demayer 0:6bf0743ece18 148 {
demayer 0:6bf0743ece18 149 reset_queue_stub();
demayer 0:6bf0743ece18 150 reset_ticker_interface_stub();
demayer 0:6bf0743ece18 151 }
demayer 0:6bf0743ece18 152
demayer 0:6bf0743ece18 153 const uint32_t test_frequencies[] = {
demayer 0:6bf0743ece18 154 1,
demayer 0:6bf0743ece18 155 32768, // 2^15
demayer 0:6bf0743ece18 156 1000000,
demayer 0:6bf0743ece18 157 0xFFFFFFFF // 2^32 - 1
demayer 0:6bf0743ece18 158 };
demayer 0:6bf0743ece18 159
demayer 0:6bf0743ece18 160 const uint32_t test_bitwidths[] = {
demayer 0:6bf0743ece18 161 32,
demayer 0:6bf0743ece18 162 31,
demayer 0:6bf0743ece18 163 16,
demayer 0:6bf0743ece18 164 8
demayer 0:6bf0743ece18 165 };
demayer 0:6bf0743ece18 166
demayer 0:6bf0743ece18 167 template < void (F)(uint32_t a, uint32_t b)>
demayer 0:6bf0743ece18 168 static void test_over_frequency_and_width(void)
demayer 0:6bf0743ece18 169 {
demayer 0:6bf0743ece18 170 for (unsigned int i = 0; i < MBED_ARRAY_SIZE(test_frequencies); i++) {
demayer 0:6bf0743ece18 171 for (unsigned int j = 0; j < MBED_ARRAY_SIZE(test_bitwidths); j++) {
demayer 0:6bf0743ece18 172 reset_ticker_stub();
demayer 0:6bf0743ece18 173 interface_info_stub.frequency = test_frequencies[i];
demayer 0:6bf0743ece18 174 interface_info_stub.bits = test_bitwidths[j];
demayer 0:6bf0743ece18 175
demayer 0:6bf0743ece18 176 F(test_frequencies[i], test_bitwidths[j]);
demayer 0:6bf0743ece18 177 }
demayer 0:6bf0743ece18 178 }
demayer 0:6bf0743ece18 179 }
demayer 0:6bf0743ece18 180
demayer 0:6bf0743ece18 181 static utest::v1::status_t case_setup_handler(
demayer 0:6bf0743ece18 182 const Case *const source, const size_t index_of_case
demayer 0:6bf0743ece18 183 ) {
demayer 0:6bf0743ece18 184 utest::v1::status_t status = greentea_case_setup_handler(source, index_of_case);
demayer 0:6bf0743ece18 185 reset_ticker_stub();
demayer 0:6bf0743ece18 186 return status;
demayer 0:6bf0743ece18 187 }
demayer 0:6bf0743ece18 188
demayer 0:6bf0743ece18 189 static utest::v1::status_t case_teardown_handler(
demayer 0:6bf0743ece18 190 const Case *const source, const size_t passed, const size_t failed, const failure_t reason
demayer 0:6bf0743ece18 191 ) {
demayer 0:6bf0743ece18 192 reset_ticker_stub();
demayer 0:6bf0743ece18 193 utest::v1::status_t status = greentea_case_teardown_handler(
demayer 0:6bf0743ece18 194 source, passed, failed, reason
demayer 0:6bf0743ece18 195 );
demayer 0:6bf0743ece18 196 return status;
demayer 0:6bf0743ece18 197 }
demayer 0:6bf0743ece18 198
demayer 0:6bf0743ece18 199 static utest::v1::status_t greentea_failure_handler(
demayer 0:6bf0743ece18 200 const Case *const source, const failure_t reason
demayer 0:6bf0743ece18 201 ) {
demayer 0:6bf0743ece18 202 utest::v1::status_t status = greentea_case_failure_abort_handler(
demayer 0:6bf0743ece18 203 source, reason
demayer 0:6bf0743ece18 204 );
demayer 0:6bf0743ece18 205 return status;
demayer 0:6bf0743ece18 206 }
demayer 0:6bf0743ece18 207
demayer 0:6bf0743ece18 208 #define MAKE_TEST_CASE(description, handler) \
demayer 0:6bf0743ece18 209 { \
demayer 0:6bf0743ece18 210 description, \
demayer 0:6bf0743ece18 211 handler, \
demayer 0:6bf0743ece18 212 NULL, \
demayer 0:6bf0743ece18 213 NULL, \
demayer 0:6bf0743ece18 214 case_setup_handler, \
demayer 0:6bf0743ece18 215 case_teardown_handler, \
demayer 0:6bf0743ece18 216 greentea_failure_handler \
demayer 0:6bf0743ece18 217 }
demayer 0:6bf0743ece18 218
demayer 0:6bf0743ece18 219 /**
demayer 0:6bf0743ece18 220 * Given an unitialized ticker_data instance.
demayer 0:6bf0743ece18 221 * When the ticker is initialized
demayer 0:6bf0743ece18 222 * Then:
demayer 0:6bf0743ece18 223 * - The ticker interface should be initialized
demayer 0:6bf0743ece18 224 * - The queue handler should be set to the handler provided in parameter
demayer 0:6bf0743ece18 225 * - The internal ticker timestamp should be zero
demayer 0:6bf0743ece18 226 * - interrupt should be scheduled in current timestamp +
demayer 0:6bf0743ece18 227 * TIMESTAMP_MAX_DELTA
demayer 0:6bf0743ece18 228 * - The queue should not contains any event
demayer 0:6bf0743ece18 229 */
demayer 0:6bf0743ece18 230 static void test_ticker_initialization()
demayer 0:6bf0743ece18 231 {
demayer 0:6bf0743ece18 232 ticker_event_handler dummy_handler = (ticker_event_handler)0xDEADBEEF;
demayer 0:6bf0743ece18 233
demayer 0:6bf0743ece18 234 // setup of the stub
demayer 0:6bf0743ece18 235 interface_stub.timestamp = 0xFEEDBABE;
demayer 0:6bf0743ece18 236
demayer 0:6bf0743ece18 237 ticker_set_handler(&ticker_stub, dummy_handler);
demayer 0:6bf0743ece18 238
demayer 0:6bf0743ece18 239 TEST_ASSERT_TRUE(interface_stub.initialized);
demayer 0:6bf0743ece18 240 TEST_ASSERT_EQUAL_PTR(dummy_handler, queue_stub.event_handler);
demayer 0:6bf0743ece18 241 TEST_ASSERT_EQUAL_UINT64(0, queue_stub.present_time);
demayer 0:6bf0743ece18 242 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 243 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 244 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 245 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 246 );
demayer 0:6bf0743ece18 247 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head);
demayer 0:6bf0743ece18 248 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 249 }
demayer 0:6bf0743ece18 250
demayer 0:6bf0743ece18 251 /**
demayer 0:6bf0743ece18 252 * Given an initialized ticker_data instance.
demayer 0:6bf0743ece18 253 * When the ticker handler is set to a new value
demayer 0:6bf0743ece18 254 * Then:
demayer 0:6bf0743ece18 255 * - The ticker interface initialization function should not be called.
demayer 0:6bf0743ece18 256 * - The queue handler should be set to the new handler.
demayer 0:6bf0743ece18 257 * - The events in the queue should remains the same.
demayer 0:6bf0743ece18 258 */
demayer 0:6bf0743ece18 259 static void test_ticker_re_initialization()
demayer 0:6bf0743ece18 260 {
demayer 0:6bf0743ece18 261 ticker_event_handler dummy_handler = (ticker_event_handler) 0xDEADBEEF;
demayer 0:6bf0743ece18 262 ticker_event_handler expected_handler = (ticker_event_handler) 0xFEEDDEAF;
demayer 0:6bf0743ece18 263
demayer 0:6bf0743ece18 264 ticker_event_t first_event = { 0 };
demayer 0:6bf0743ece18 265 ticker_event_t second_event = { 0 };
demayer 0:6bf0743ece18 266 ticker_event_t third_event = { 0 };
demayer 0:6bf0743ece18 267
demayer 0:6bf0743ece18 268 first_event.next = &second_event;
demayer 0:6bf0743ece18 269 second_event.next = &third_event;
demayer 0:6bf0743ece18 270
demayer 0:6bf0743ece18 271 // initialize the ticker and put few events in the queue.
demayer 0:6bf0743ece18 272 ticker_set_handler(&ticker_stub, dummy_handler);
demayer 0:6bf0743ece18 273 // simulate insertion, it shouldn't affect the queue behaviour for this test
demayer 0:6bf0743ece18 274 queue_stub.head = &first_event;
demayer 0:6bf0743ece18 275 interface_stub.init_call = 0;
demayer 0:6bf0743ece18 276
demayer 0:6bf0743ece18 277 ticker_set_handler(&ticker_stub, expected_handler);
demayer 0:6bf0743ece18 278
demayer 0:6bf0743ece18 279 TEST_ASSERT_TRUE(interface_stub.initialized);
demayer 0:6bf0743ece18 280 TEST_ASSERT_EQUAL(0, interface_stub.init_call);
demayer 0:6bf0743ece18 281 TEST_ASSERT_EQUAL(expected_handler, queue_stub.event_handler);
demayer 0:6bf0743ece18 282 TEST_ASSERT_EQUAL(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 283 TEST_ASSERT_EQUAL(&second_event, queue_stub.head->next);
demayer 0:6bf0743ece18 284 TEST_ASSERT_EQUAL(&third_event, queue_stub.head->next->next);
demayer 0:6bf0743ece18 285 TEST_ASSERT_EQUAL(NULL, queue_stub.head->next->next->next);
demayer 0:6bf0743ece18 286 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 287 }
demayer 0:6bf0743ece18 288
demayer 0:6bf0743ece18 289 /**
demayer 0:6bf0743ece18 290 * Given an initialized ticker_data instance.
demayer 0:6bf0743ece18 291 * When the ticker is read
demayer 0:6bf0743ece18 292 * Then it should return the value present in the ticker interface
demayer 0:6bf0743ece18 293 */
demayer 0:6bf0743ece18 294 static void test_ticker_read()
demayer 0:6bf0743ece18 295 {
demayer 0:6bf0743ece18 296 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 297
demayer 0:6bf0743ece18 298 timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 299 0xA,
demayer 0:6bf0743ece18 300 0xAA,
demayer 0:6bf0743ece18 301 0xAAA,
demayer 0:6bf0743ece18 302 0xAAAA,
demayer 0:6bf0743ece18 303 0xAAAAA,
demayer 0:6bf0743ece18 304 0xAAAAAA,
demayer 0:6bf0743ece18 305 0xAAAAAAA,
demayer 0:6bf0743ece18 306 0xAAAAAAAA
demayer 0:6bf0743ece18 307 };
demayer 0:6bf0743ece18 308
demayer 0:6bf0743ece18 309 for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) {
demayer 0:6bf0743ece18 310 interface_stub.timestamp = timestamps[i];
demayer 0:6bf0743ece18 311 TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub));
demayer 0:6bf0743ece18 312 TEST_ASSERT_EQUAL_UINT64(timestamps[i], ticker_read_us(&ticker_stub));
demayer 0:6bf0743ece18 313 }
demayer 0:6bf0743ece18 314
demayer 0:6bf0743ece18 315 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 316 }
demayer 0:6bf0743ece18 317
demayer 0:6bf0743ece18 318 /**
demayer 0:6bf0743ece18 319 * Given an initialized ticker_data instance.
demayer 0:6bf0743ece18 320 * When the ticker is read and the value read is less than the previous
demayer 0:6bf0743ece18 321 * value read.
demayer 0:6bf0743ece18 322 * Then:
demayer 0:6bf0743ece18 323 * - ticker_read should return the value read in the ticker interface
demayer 0:6bf0743ece18 324 * - ticker_read_us should return a value where:
demayer 0:6bf0743ece18 325 * + lower 8 bytes should be equal to the value in the ticker interface
demayer 0:6bf0743ece18 326 * + upper 8 bytes should be equal to the previous value of upper 8 bytes
demayer 0:6bf0743ece18 327 * plus one.
demayer 0:6bf0743ece18 328 */
demayer 0:6bf0743ece18 329 static void test_ticker_read_overflow()
demayer 0:6bf0743ece18 330 {
demayer 0:6bf0743ece18 331 const timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 332 0xAAAAAAAA,
demayer 0:6bf0743ece18 333 0xAAAAAAA,
demayer 0:6bf0743ece18 334 0xAAAAAA,
demayer 0:6bf0743ece18 335 0xAAAAA,
demayer 0:6bf0743ece18 336 0xAAAA,
demayer 0:6bf0743ece18 337 0xAAA,
demayer 0:6bf0743ece18 338 0xAA,
demayer 0:6bf0743ece18 339 0xA
demayer 0:6bf0743ece18 340 };
demayer 0:6bf0743ece18 341
demayer 0:6bf0743ece18 342 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 343
demayer 0:6bf0743ece18 344 uint32_t upper_bytes_begin = ticker_read_us(&ticker_stub) >> 32;
demayer 0:6bf0743ece18 345
demayer 0:6bf0743ece18 346 for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) {
demayer 0:6bf0743ece18 347 interface_stub.timestamp = timestamps[i];
demayer 0:6bf0743ece18 348 TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub));
demayer 0:6bf0743ece18 349 TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read_us(&ticker_stub));
demayer 0:6bf0743ece18 350 TEST_ASSERT_EQUAL_UINT64(
demayer 0:6bf0743ece18 351 upper_bytes_begin + i, ticker_read_us(&ticker_stub) >> 32
demayer 0:6bf0743ece18 352 );
demayer 0:6bf0743ece18 353 }
demayer 0:6bf0743ece18 354
demayer 0:6bf0743ece18 355 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 356 }
demayer 0:6bf0743ece18 357
demayer 0:6bf0743ece18 358 /**
demayer 0:6bf0743ece18 359 * Given an initialized ticker without user registered events.
demayer 0:6bf0743ece18 360 * When an event is inserted with ticker_insert_event and the timestamp passed
demayer 0:6bf0743ece18 361 * in parameter is in range [ticker_timestamp : ticker_timestamp +
demayer 0:6bf0743ece18 362 * TIMESTAMP_MAX_DELTA[.
demayer 0:6bf0743ece18 363 * Then
demayer 0:6bf0743ece18 364 * - The event should be in the queue
demayer 0:6bf0743ece18 365 * - The interrupt timestamp should be equal to the timestamp of the event
demayer 0:6bf0743ece18 366 * - The timestamp of the event should reflect the timestamp requested.
demayer 0:6bf0743ece18 367 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 368 */
demayer 0:6bf0743ece18 369 static void test_legacy_insert_event_outside_overflow_range()
demayer 0:6bf0743ece18 370 {
demayer 0:6bf0743ece18 371 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 372 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 373
demayer 0:6bf0743ece18 374 // test the end of the range
demayer 0:6bf0743ece18 375 ticker_event_t last_event = { 0 };
demayer 0:6bf0743ece18 376 const timestamp_t timestamp_last_event =
demayer 0:6bf0743ece18 377 interface_stub.timestamp + TIMESTAMP_MAX_DELTA;
demayer 0:6bf0743ece18 378 const uint32_t id_last_event = 0xDEADDEAF;
demayer 0:6bf0743ece18 379
demayer 0:6bf0743ece18 380 ticker_insert_event(
demayer 0:6bf0743ece18 381 &ticker_stub,
demayer 0:6bf0743ece18 382 &last_event, timestamp_last_event, id_last_event
demayer 0:6bf0743ece18 383 );
demayer 0:6bf0743ece18 384
demayer 0:6bf0743ece18 385 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
demayer 0:6bf0743ece18 386 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 387 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 388 timestamp_last_event, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 389 );
demayer 0:6bf0743ece18 390 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
demayer 0:6bf0743ece18 391 TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp);
demayer 0:6bf0743ece18 392 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);
demayer 0:6bf0743ece18 393
demayer 0:6bf0743ece18 394 // test the beginning of the range
demayer 0:6bf0743ece18 395 ticker_event_t first_event = { 0 };
demayer 0:6bf0743ece18 396 const timestamp_t timestamp_first_event = interface_stub.timestamp + 1;
demayer 0:6bf0743ece18 397 const uint32_t id_first_event = 0xAAAAAAAA;
demayer 0:6bf0743ece18 398
demayer 0:6bf0743ece18 399 ticker_insert_event(
demayer 0:6bf0743ece18 400 &ticker_stub,
demayer 0:6bf0743ece18 401 &first_event, timestamp_first_event, id_first_event
demayer 0:6bf0743ece18 402 );
demayer 0:6bf0743ece18 403
demayer 0:6bf0743ece18 404 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 405 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 406 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 407 timestamp_first_event, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 408 );
demayer 0:6bf0743ece18 409 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
demayer 0:6bf0743ece18 410 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 411 timestamp_first_event, first_event.timestamp
demayer 0:6bf0743ece18 412 );
demayer 0:6bf0743ece18 413 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);
demayer 0:6bf0743ece18 414
demayer 0:6bf0743ece18 415 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 416 }
demayer 0:6bf0743ece18 417
demayer 0:6bf0743ece18 418 /**
demayer 0:6bf0743ece18 419 * Given an initialized ticker without user registered events.
demayer 0:6bf0743ece18 420 * When an event is inserted with ticker_insert_event and a timestamp in the
demayer 0:6bf0743ece18 421 * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 :
demayer 0:6bf0743ece18 422 * ticker_timestamp + UINT32MAX [
demayer 0:6bf0743ece18 423 * Then
demayer 0:6bf0743ece18 424 * - The event should be in the queue
demayer 0:6bf0743ece18 425 * - The interrupt timestamp should be equal to
demayer 0:6bf0743ece18 426 * TIMESTAMP_MAX_DELTA
demayer 0:6bf0743ece18 427 * - The timestamp of the event should reflect the timestamp requested.
demayer 0:6bf0743ece18 428 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 429 */
demayer 0:6bf0743ece18 430 static void test_legacy_insert_event_in_overflow_range()
demayer 0:6bf0743ece18 431 {
demayer 0:6bf0743ece18 432 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 433 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 434
demayer 0:6bf0743ece18 435 // test the end of the range
demayer 0:6bf0743ece18 436 ticker_event_t last_event = { 0 };
demayer 0:6bf0743ece18 437 const timestamp_t timestamp_last_event =
demayer 0:6bf0743ece18 438 interface_stub.timestamp + UINT32_MAX;
demayer 0:6bf0743ece18 439 const uint32_t id_last_event = 0xDEADDEAF;
demayer 0:6bf0743ece18 440
demayer 0:6bf0743ece18 441 ticker_insert_event(
demayer 0:6bf0743ece18 442 &ticker_stub,
demayer 0:6bf0743ece18 443 &last_event, timestamp_last_event, id_last_event
demayer 0:6bf0743ece18 444 );
demayer 0:6bf0743ece18 445
demayer 0:6bf0743ece18 446 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
demayer 0:6bf0743ece18 447 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 448 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 449 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 450 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 451 );
demayer 0:6bf0743ece18 452 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
demayer 0:6bf0743ece18 453 TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp);
demayer 0:6bf0743ece18 454 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);
demayer 0:6bf0743ece18 455
demayer 0:6bf0743ece18 456 // test the beginning of the range
demayer 0:6bf0743ece18 457 ++interface_stub.timestamp;
demayer 0:6bf0743ece18 458
demayer 0:6bf0743ece18 459 ticker_event_t first_event = { 0 };
demayer 0:6bf0743ece18 460 const timestamp_t timestamp_first_event =
demayer 0:6bf0743ece18 461 interface_stub.timestamp + TIMESTAMP_MAX_DELTA + 1;
demayer 0:6bf0743ece18 462 const uint32_t id_first_event = 0xAAAAAAAA;
demayer 0:6bf0743ece18 463
demayer 0:6bf0743ece18 464 ticker_insert_event(
demayer 0:6bf0743ece18 465 &ticker_stub,
demayer 0:6bf0743ece18 466 &first_event, timestamp_first_event, id_first_event
demayer 0:6bf0743ece18 467 );
demayer 0:6bf0743ece18 468
demayer 0:6bf0743ece18 469 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 470 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 471 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 472 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 473 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 474 );
demayer 0:6bf0743ece18 475 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
demayer 0:6bf0743ece18 476 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 477 timestamp_first_event, first_event.timestamp
demayer 0:6bf0743ece18 478 );
demayer 0:6bf0743ece18 479 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);
demayer 0:6bf0743ece18 480
demayer 0:6bf0743ece18 481 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 482 }
demayer 0:6bf0743ece18 483
demayer 0:6bf0743ece18 484 /**
demayer 0:6bf0743ece18 485 * Given an initialized ticker without user registered events.
demayer 0:6bf0743ece18 486 * When an event is inserted with ticker_insert_event and the timestamp in
demayer 0:6bf0743ece18 487 * parameter is less than the current timestamp value.
demayer 0:6bf0743ece18 488 * Then
demayer 0:6bf0743ece18 489 * - The event should be in the queue
demayer 0:6bf0743ece18 490 * - The timestamp of the event should reflect the timestamp requested:
demayer 0:6bf0743ece18 491 * + lower 8 bytes should be equal to the timestamp in input.
demayer 0:6bf0743ece18 492 * + upper 8 bytes should be equal to the upper of the upper 8 bytes of the
demayer 0:6bf0743ece18 493 * timestamp state stored in the queue plus one.
demayer 0:6bf0743ece18 494 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 495 */
demayer 0:6bf0743ece18 496 static void test_legacy_insert_event_overflow(){
demayer 0:6bf0743ece18 497 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 498 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 499
demayer 0:6bf0743ece18 500 interface_stub.timestamp = 0x20000000;
demayer 0:6bf0743ece18 501 ticker_read(&ticker_stub);
demayer 0:6bf0743ece18 502
demayer 0:6bf0743ece18 503 ticker_event_t event = { 0 };
demayer 0:6bf0743ece18 504 const timestamp_t expected_timestamp =
demayer 0:6bf0743ece18 505 interface_stub.timestamp +
demayer 0:6bf0743ece18 506 TIMESTAMP_MAX_DELTA +
demayer 0:6bf0743ece18 507 1;
demayer 0:6bf0743ece18 508 const us_timestamp_t expected_us_timestamp =
demayer 0:6bf0743ece18 509 (((queue_stub.present_time >> 32) + 1) << 32) | expected_timestamp;
demayer 0:6bf0743ece18 510 const uint32_t expected_id = 0xDEADDEAF;
demayer 0:6bf0743ece18 511
demayer 0:6bf0743ece18 512 ticker_insert_event(
demayer 0:6bf0743ece18 513 &ticker_stub,
demayer 0:6bf0743ece18 514 &event, expected_timestamp, expected_id
demayer 0:6bf0743ece18 515 );
demayer 0:6bf0743ece18 516
demayer 0:6bf0743ece18 517 TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head);
demayer 0:6bf0743ece18 518 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 519 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 520 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 521 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 522 );
demayer 0:6bf0743ece18 523 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
demayer 0:6bf0743ece18 524 TEST_ASSERT_EQUAL_UINT32(expected_us_timestamp, event.timestamp);
demayer 0:6bf0743ece18 525 TEST_ASSERT_EQUAL_UINT32(expected_id, event.id);
demayer 0:6bf0743ece18 526
demayer 0:6bf0743ece18 527 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 528 }
demayer 0:6bf0743ece18 529
demayer 0:6bf0743ece18 530 /**
demayer 0:6bf0743ece18 531 * Given an initialized ticker.
demayer 0:6bf0743ece18 532 * When an event is inserted with ticker_insert_event and a timestamp less than
demayer 0:6bf0743ece18 533 * the one for the next scheduled timestamp.
demayer 0:6bf0743ece18 534 * Then
demayer 0:6bf0743ece18 535 * - The event inserted should be the first in the queue
demayer 0:6bf0743ece18 536 * - The interrupt timestamp should be equal to the timestamp of the event or
demayer 0:6bf0743ece18 537 * TIMESTAMP_MAX_DELTA if in the overflow range.
demayer 0:6bf0743ece18 538 * - The timestamp of the event should reflect the timestamp requested.
demayer 0:6bf0743ece18 539 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 540 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 541 */
demayer 0:6bf0743ece18 542 static void test_legacy_insert_event_head()
demayer 0:6bf0743ece18 543 {
demayer 0:6bf0743ece18 544 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 545 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 546
demayer 0:6bf0743ece18 547 const timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 548 UINT32_MAX,
demayer 0:6bf0743ece18 549 TIMESTAMP_MAX_DELTA + 1,
demayer 0:6bf0743ece18 550 TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 551 TIMESTAMP_MAX_DELTA / 2,
demayer 0:6bf0743ece18 552 TIMESTAMP_MAX_DELTA / 4,
demayer 0:6bf0743ece18 553 TIMESTAMP_MAX_DELTA / 8,
demayer 0:6bf0743ece18 554 TIMESTAMP_MAX_DELTA / 16,
demayer 0:6bf0743ece18 555 };
demayer 0:6bf0743ece18 556 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 557
demayer 0:6bf0743ece18 558 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 559 ticker_insert_event(
demayer 0:6bf0743ece18 560 &ticker_stub,
demayer 0:6bf0743ece18 561 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 562 );
demayer 0:6bf0743ece18 563
demayer 0:6bf0743ece18 564 TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head);
demayer 0:6bf0743ece18 565 TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 566 if (timestamps[i] < TIMESTAMP_MAX_DELTA) {
demayer 0:6bf0743ece18 567 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 568 timestamps[i],
demayer 0:6bf0743ece18 569 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 570 );
demayer 0:6bf0743ece18 571 } else {
demayer 0:6bf0743ece18 572 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 573 TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 574 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 575 );
demayer 0:6bf0743ece18 576 }
demayer 0:6bf0743ece18 577
demayer 0:6bf0743ece18 578 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 579 timestamps[i], events[i].timestamp
demayer 0:6bf0743ece18 580 );
demayer 0:6bf0743ece18 581 TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
demayer 0:6bf0743ece18 582
demayer 0:6bf0743ece18 583 ticker_event_t* e = &events[i];
demayer 0:6bf0743ece18 584 while (e) {
demayer 0:6bf0743ece18 585 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
demayer 0:6bf0743ece18 586 if (e->next) {
demayer 0:6bf0743ece18 587 TEST_ASSERT_TRUE(e->id > e->next->id);
demayer 0:6bf0743ece18 588 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
demayer 0:6bf0743ece18 589 } else {
demayer 0:6bf0743ece18 590 TEST_ASSERT_EQUAL_UINT32(0, e->id);
demayer 0:6bf0743ece18 591 }
demayer 0:6bf0743ece18 592 e = e->next;
demayer 0:6bf0743ece18 593 }
demayer 0:6bf0743ece18 594 }
demayer 0:6bf0743ece18 595
demayer 0:6bf0743ece18 596 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 597 }
demayer 0:6bf0743ece18 598
demayer 0:6bf0743ece18 599 /**
demayer 0:6bf0743ece18 600 * Given an initialized ticker.
demayer 0:6bf0743ece18 601 * When an event is inserted with ticker_insert_event and its timestamp is bigger
demayer 0:6bf0743ece18 602 * than the one of the last event in the queue.
demayer 0:6bf0743ece18 603 * Then
demayer 0:6bf0743ece18 604 * - The event inserted should be the last in the queue
demayer 0:6bf0743ece18 605 * - The interrupt timestamp should remains equal to the interrupt timestamp
demayer 0:6bf0743ece18 606 * of the head event .
demayer 0:6bf0743ece18 607 * - The timestamp of the event should reflect the timestamp requested.
demayer 0:6bf0743ece18 608 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 609 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 610 */
demayer 0:6bf0743ece18 611 static void test_legacy_insert_event_tail()
demayer 0:6bf0743ece18 612 {
demayer 0:6bf0743ece18 613 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 614 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 615
demayer 0:6bf0743ece18 616 const timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 617 0xA,
demayer 0:6bf0743ece18 618 0xAA,
demayer 0:6bf0743ece18 619 0xAAA,
demayer 0:6bf0743ece18 620 0xAAAA,
demayer 0:6bf0743ece18 621 0xAAAAA,
demayer 0:6bf0743ece18 622 0xAAAAAA,
demayer 0:6bf0743ece18 623 0xAAAAAAA,
demayer 0:6bf0743ece18 624 0xAAAAAAAA,
demayer 0:6bf0743ece18 625 };
demayer 0:6bf0743ece18 626 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 627
demayer 0:6bf0743ece18 628 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 629 ticker_insert_event(
demayer 0:6bf0743ece18 630 &ticker_stub,
demayer 0:6bf0743ece18 631 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 632 );
demayer 0:6bf0743ece18 633
demayer 0:6bf0743ece18 634 TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head);
demayer 0:6bf0743ece18 635 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 636 timestamps[0], interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 637 );
demayer 0:6bf0743ece18 638
demayer 0:6bf0743ece18 639 TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp);
demayer 0:6bf0743ece18 640 TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
demayer 0:6bf0743ece18 641
demayer 0:6bf0743ece18 642 ticker_event_t* e = queue_stub.head;
demayer 0:6bf0743ece18 643 while (e) {
demayer 0:6bf0743ece18 644 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
demayer 0:6bf0743ece18 645 if (e->next) {
demayer 0:6bf0743ece18 646 TEST_ASSERT_TRUE(e->id < e->next->id);
demayer 0:6bf0743ece18 647 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
demayer 0:6bf0743ece18 648 } else {
demayer 0:6bf0743ece18 649 TEST_ASSERT_EQUAL_UINT32(&events[i], e);
demayer 0:6bf0743ece18 650 }
demayer 0:6bf0743ece18 651 e = e->next;
demayer 0:6bf0743ece18 652 }
demayer 0:6bf0743ece18 653 }
demayer 0:6bf0743ece18 654
demayer 0:6bf0743ece18 655 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 656 }
demayer 0:6bf0743ece18 657
demayer 0:6bf0743ece18 658 /**
demayer 0:6bf0743ece18 659 * Given an initialized ticker.
demayer 0:6bf0743ece18 660 * When an event is inserted with ticker_insert_event and a timestamp less
demayer 0:6bf0743ece18 661 * than the current timestamp in the interface and less than the relative
demayer 0:6bf0743ece18 662 * timestamp of the next event to execute.
demayer 0:6bf0743ece18 663 * Then
demayer 0:6bf0743ece18 664 * - The event inserted should be after the head
demayer 0:6bf0743ece18 665 * - The interrupt timestamp should remains equal to the interrupt timestamp
demayer 0:6bf0743ece18 666 * of the head event .
demayer 0:6bf0743ece18 667 * - The timestamp of the event should reflect the timestamp requested (overflow)
demayer 0:6bf0743ece18 668 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 669 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 670 */
demayer 0:6bf0743ece18 671 static void test_legacy_insert_event_multiple_overflow()
demayer 0:6bf0743ece18 672 {
demayer 0:6bf0743ece18 673 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 674 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 675
demayer 0:6bf0743ece18 676 const timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 677 0xA,
demayer 0:6bf0743ece18 678 0xAA,
demayer 0:6bf0743ece18 679 0xAAA,
demayer 0:6bf0743ece18 680 0xAAAA,
demayer 0:6bf0743ece18 681 0xAAAAA,
demayer 0:6bf0743ece18 682 0xAAAAAA,
demayer 0:6bf0743ece18 683 0xAAAAAAA,
demayer 0:6bf0743ece18 684 0xAAAAAAAA
demayer 0:6bf0743ece18 685 };
demayer 0:6bf0743ece18 686 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 687
demayer 0:6bf0743ece18 688 ticker_event_t ref_event;
demayer 0:6bf0743ece18 689 timestamp_t ref_event_timestamp = 0xCCCCCCCC;
demayer 0:6bf0743ece18 690 ticker_insert_event(
demayer 0:6bf0743ece18 691 &ticker_stub,
demayer 0:6bf0743ece18 692 &ref_event, ref_event_timestamp, 0xDEADBEEF
demayer 0:6bf0743ece18 693 );
demayer 0:6bf0743ece18 694
demayer 0:6bf0743ece18 695 timestamp_t last_timestamp_to_insert =
demayer 0:6bf0743ece18 696 timestamps[MBED_ARRAY_SIZE(timestamps) - 1];
demayer 0:6bf0743ece18 697 interface_stub.timestamp =
demayer 0:6bf0743ece18 698 last_timestamp_to_insert +
demayer 0:6bf0743ece18 699 ((ref_event_timestamp - last_timestamp_to_insert) / 2);
demayer 0:6bf0743ece18 700
demayer 0:6bf0743ece18 701 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 702 ticker_insert_event(
demayer 0:6bf0743ece18 703 &ticker_stub,
demayer 0:6bf0743ece18 704 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 705 );
demayer 0:6bf0743ece18 706
demayer 0:6bf0743ece18 707 TEST_ASSERT_EQUAL_PTR(&ref_event, queue_stub.head);
demayer 0:6bf0743ece18 708 TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head->next);
demayer 0:6bf0743ece18 709 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 710 ref_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 711 );
demayer 0:6bf0743ece18 712
demayer 0:6bf0743ece18 713 TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp);
demayer 0:6bf0743ece18 714 TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
demayer 0:6bf0743ece18 715
demayer 0:6bf0743ece18 716 ticker_event_t* e = queue_stub.head->next;
demayer 0:6bf0743ece18 717 while (e) {
demayer 0:6bf0743ece18 718 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
demayer 0:6bf0743ece18 719 if (e->next) {
demayer 0:6bf0743ece18 720 TEST_ASSERT_TRUE(e->id < e->next->id);
demayer 0:6bf0743ece18 721 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
demayer 0:6bf0743ece18 722 } else {
demayer 0:6bf0743ece18 723 TEST_ASSERT_EQUAL_UINT32(&events[i], e);
demayer 0:6bf0743ece18 724 }
demayer 0:6bf0743ece18 725 e = e->next;
demayer 0:6bf0743ece18 726 }
demayer 0:6bf0743ece18 727 }
demayer 0:6bf0743ece18 728
demayer 0:6bf0743ece18 729 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 730 }
demayer 0:6bf0743ece18 731
demayer 0:6bf0743ece18 732 /**
demayer 0:6bf0743ece18 733 * Given an initialized ticker.
demayer 0:6bf0743ece18 734 * When an event is inserted with ticker_insert_event.
demayer 0:6bf0743ece18 735 * Then
demayer 0:6bf0743ece18 736 * - The event inserted should be at the correct position in the queue
demayer 0:6bf0743ece18 737 * - The event queue should remain ordered by timestamp
demayer 0:6bf0743ece18 738 * - The interrupt timestamp should be equal to the interrupt timestamp
demayer 0:6bf0743ece18 739 * of the head event or TIMESTAMP_MAX_DELTA if the
demayer 0:6bf0743ece18 740 * timestamp is in the overflow range.
demayer 0:6bf0743ece18 741 * - The timestamp of the event should reflect the timestamp requested (overflow)
demayer 0:6bf0743ece18 742 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 743 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 744 */
demayer 0:6bf0743ece18 745 static void test_legacy_insert_event_multiple_random()
demayer 0:6bf0743ece18 746 {
demayer 0:6bf0743ece18 747 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 748 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 749
demayer 0:6bf0743ece18 750 const timestamp_t ref_timestamp = UINT32_MAX / 2;
demayer 0:6bf0743ece18 751 interface_stub.timestamp = ref_timestamp;
demayer 0:6bf0743ece18 752
demayer 0:6bf0743ece18 753 // insert first event at the head of the queue
demayer 0:6bf0743ece18 754 ticker_event_t first_event;
demayer 0:6bf0743ece18 755 const timestamp_t first_event_timestamp =
demayer 0:6bf0743ece18 756 ref_timestamp + TIMESTAMP_MAX_DELTA + 100;
demayer 0:6bf0743ece18 757
demayer 0:6bf0743ece18 758 ticker_insert_event(
demayer 0:6bf0743ece18 759 &ticker_stub,
demayer 0:6bf0743ece18 760 &first_event, first_event_timestamp, (uint32_t) &first_event
demayer 0:6bf0743ece18 761 );
demayer 0:6bf0743ece18 762
demayer 0:6bf0743ece18 763 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 764 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next);
demayer 0:6bf0743ece18 765 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 766 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 767 );
demayer 0:6bf0743ece18 768 TEST_ASSERT_EQUAL_UINT32(first_event_timestamp, first_event.timestamp);
demayer 0:6bf0743ece18 769 TEST_ASSERT_EQUAL_UINT64(
demayer 0:6bf0743ece18 770 first_event.timestamp,
demayer 0:6bf0743ece18 771 first_event_timestamp +
demayer 0:6bf0743ece18 772 ((first_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
demayer 0:6bf0743ece18 773 );
demayer 0:6bf0743ece18 774 TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id);
demayer 0:6bf0743ece18 775
demayer 0:6bf0743ece18 776 // insert second event at the tail of the queue
demayer 0:6bf0743ece18 777 ticker_event_t second_event;
demayer 0:6bf0743ece18 778 const timestamp_t second_event_timestamp = first_event_timestamp + 1;
demayer 0:6bf0743ece18 779
demayer 0:6bf0743ece18 780 ticker_insert_event(
demayer 0:6bf0743ece18 781 &ticker_stub,
demayer 0:6bf0743ece18 782 &second_event, second_event_timestamp, (uint32_t) &second_event
demayer 0:6bf0743ece18 783 );
demayer 0:6bf0743ece18 784
demayer 0:6bf0743ece18 785 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 786 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 787 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 788 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 789 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 790 );
demayer 0:6bf0743ece18 791 TEST_ASSERT_EQUAL_UINT32(second_event_timestamp, second_event.timestamp);
demayer 0:6bf0743ece18 792 TEST_ASSERT_EQUAL_UINT64(
demayer 0:6bf0743ece18 793 second_event.timestamp,
demayer 0:6bf0743ece18 794 second_event_timestamp +
demayer 0:6bf0743ece18 795 ((second_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
demayer 0:6bf0743ece18 796 );
demayer 0:6bf0743ece18 797 TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id);
demayer 0:6bf0743ece18 798
demayer 0:6bf0743ece18 799
demayer 0:6bf0743ece18 800 // insert third event at the head of the queue out the overflow zone
demayer 0:6bf0743ece18 801 ticker_event_t third_event;
demayer 0:6bf0743ece18 802 const timestamp_t third_event_timestamp =
demayer 0:6bf0743ece18 803 ref_timestamp + TIMESTAMP_MAX_DELTA - 100;
demayer 0:6bf0743ece18 804
demayer 0:6bf0743ece18 805 ticker_insert_event(
demayer 0:6bf0743ece18 806 &ticker_stub,
demayer 0:6bf0743ece18 807 &third_event, third_event_timestamp, (uint32_t) &third_event
demayer 0:6bf0743ece18 808 );
demayer 0:6bf0743ece18 809
demayer 0:6bf0743ece18 810 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head);
demayer 0:6bf0743ece18 811 TEST_ASSERT_EQUAL_PTR(&first_event, third_event.next);
demayer 0:6bf0743ece18 812 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 813 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 814 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 815 third_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 816 );
demayer 0:6bf0743ece18 817 TEST_ASSERT_EQUAL_UINT32(third_event_timestamp, third_event.timestamp);
demayer 0:6bf0743ece18 818 TEST_ASSERT_EQUAL_UINT64(
demayer 0:6bf0743ece18 819 third_event.timestamp,
demayer 0:6bf0743ece18 820 third_event_timestamp +
demayer 0:6bf0743ece18 821 ((third_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
demayer 0:6bf0743ece18 822 );
demayer 0:6bf0743ece18 823 TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id);
demayer 0:6bf0743ece18 824
demayer 0:6bf0743ece18 825 // insert fourth event right after the third event
demayer 0:6bf0743ece18 826 ticker_event_t fourth_event;
demayer 0:6bf0743ece18 827 const timestamp_t fourth_event_timestamp = third_event_timestamp + 50;
demayer 0:6bf0743ece18 828
demayer 0:6bf0743ece18 829 ticker_insert_event(
demayer 0:6bf0743ece18 830 &ticker_stub,
demayer 0:6bf0743ece18 831 &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event
demayer 0:6bf0743ece18 832 );
demayer 0:6bf0743ece18 833
demayer 0:6bf0743ece18 834 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head);
demayer 0:6bf0743ece18 835 TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next);
demayer 0:6bf0743ece18 836 TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next);
demayer 0:6bf0743ece18 837 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 838 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 839 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 840 third_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 841 );
demayer 0:6bf0743ece18 842 TEST_ASSERT_EQUAL_UINT32(fourth_event_timestamp, fourth_event.timestamp);
demayer 0:6bf0743ece18 843 TEST_ASSERT_EQUAL_UINT64(
demayer 0:6bf0743ece18 844 fourth_event.timestamp,
demayer 0:6bf0743ece18 845 fourth_event_timestamp +
demayer 0:6bf0743ece18 846 ((fourth_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
demayer 0:6bf0743ece18 847 );
demayer 0:6bf0743ece18 848 TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id);
demayer 0:6bf0743ece18 849
demayer 0:6bf0743ece18 850 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 851 }
demayer 0:6bf0743ece18 852
demayer 0:6bf0743ece18 853 /**
demayer 0:6bf0743ece18 854 * Given an initialized ticker without user registered events.
demayer 0:6bf0743ece18 855 * When an event is inserted with ticker_insert_event_us and the timestamp passed
demayer 0:6bf0743ece18 856 * in parameter is in range [ticker_timestamp : ticker_timestamp +
demayer 0:6bf0743ece18 857 * TIMESTAMP_MAX_DELTA[.
demayer 0:6bf0743ece18 858 * Then
demayer 0:6bf0743ece18 859 * - The event should be in the queue
demayer 0:6bf0743ece18 860 * - The interrupt timestamp should be equal to the lower 8 bytes of the event.
demayer 0:6bf0743ece18 861 * - The timestamp of the event should be equal to the timestamp requested.
demayer 0:6bf0743ece18 862 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 863 */
demayer 0:6bf0743ece18 864 static void test_insert_event_us_outside_overflow_range()
demayer 0:6bf0743ece18 865 {
demayer 0:6bf0743ece18 866 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 867 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 868 interface_stub.timestamp = 0xAAAAAAAA;
demayer 0:6bf0743ece18 869 queue_stub.tick_last_read = interface_stub.timestamp;
demayer 0:6bf0743ece18 870 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp;
demayer 0:6bf0743ece18 871
demayer 0:6bf0743ece18 872 // test the end of the range
demayer 0:6bf0743ece18 873 ticker_event_t last_event = { 0 };
demayer 0:6bf0743ece18 874 const us_timestamp_t timestamp_last_event =
demayer 0:6bf0743ece18 875 queue_stub.present_time + TIMESTAMP_MAX_DELTA;
demayer 0:6bf0743ece18 876 const uint32_t id_last_event = 0xDEADDEAF;
demayer 0:6bf0743ece18 877
demayer 0:6bf0743ece18 878 ticker_insert_event_us(
demayer 0:6bf0743ece18 879 &ticker_stub,
demayer 0:6bf0743ece18 880 &last_event, timestamp_last_event, id_last_event
demayer 0:6bf0743ece18 881 );
demayer 0:6bf0743ece18 882
demayer 0:6bf0743ece18 883 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
demayer 0:6bf0743ece18 884 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 885 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 886 timestamp_last_event, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 887 );
demayer 0:6bf0743ece18 888 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
demayer 0:6bf0743ece18 889 TEST_ASSERT_EQUAL_UINT64(timestamp_last_event, last_event.timestamp);
demayer 0:6bf0743ece18 890 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);
demayer 0:6bf0743ece18 891
demayer 0:6bf0743ece18 892 // test the beginning of the range
demayer 0:6bf0743ece18 893 ticker_event_t first_event = { 0 };
demayer 0:6bf0743ece18 894 const us_timestamp_t timestamp_first_event = queue_stub.present_time + 1;
demayer 0:6bf0743ece18 895 const uint32_t id_first_event = 0xAAAAAAAA;
demayer 0:6bf0743ece18 896
demayer 0:6bf0743ece18 897 ticker_insert_event_us(
demayer 0:6bf0743ece18 898 &ticker_stub,
demayer 0:6bf0743ece18 899 &first_event, timestamp_first_event, id_first_event
demayer 0:6bf0743ece18 900 );
demayer 0:6bf0743ece18 901
demayer 0:6bf0743ece18 902 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 903 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 904 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 905 timestamp_first_event, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 906 );
demayer 0:6bf0743ece18 907 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
demayer 0:6bf0743ece18 908 TEST_ASSERT_EQUAL_UINT64(
demayer 0:6bf0743ece18 909 timestamp_first_event, first_event.timestamp
demayer 0:6bf0743ece18 910 );
demayer 0:6bf0743ece18 911 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);
demayer 0:6bf0743ece18 912
demayer 0:6bf0743ece18 913 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 914 }
demayer 0:6bf0743ece18 915
demayer 0:6bf0743ece18 916 /**
demayer 0:6bf0743ece18 917 * Given an initialized ticker without user registered events.
demayer 0:6bf0743ece18 918 * When an event is inserted with ticker_insert_event_us and a timestamp in the
demayer 0:6bf0743ece18 919 * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : UINT64_MAX [
demayer 0:6bf0743ece18 920 * Then
demayer 0:6bf0743ece18 921 * - The event should be in the queue
demayer 0:6bf0743ece18 922 * - The interrupt timestamp should be equal to TIMESTAMP_MAX_DELTA
demayer 0:6bf0743ece18 923 * - The timestamp of the event should be equal to the timestamp in parameter.
demayer 0:6bf0743ece18 924 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 925 */
demayer 0:6bf0743ece18 926 static void test_insert_event_us_in_overflow_range()
demayer 0:6bf0743ece18 927 {
demayer 0:6bf0743ece18 928 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 929 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 930 interface_stub.timestamp = 0xAAAAAAAA;
demayer 0:6bf0743ece18 931 queue_stub.tick_last_read = interface_stub.timestamp;
demayer 0:6bf0743ece18 932 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp;
demayer 0:6bf0743ece18 933
demayer 0:6bf0743ece18 934 // test the end of the range
demayer 0:6bf0743ece18 935 ticker_event_t last_event = { 0 };
demayer 0:6bf0743ece18 936 const us_timestamp_t timestamp_last_event = UINT64_MAX;
demayer 0:6bf0743ece18 937 const uint32_t id_last_event = 0xDEADDEAF;
demayer 0:6bf0743ece18 938
demayer 0:6bf0743ece18 939 ticker_insert_event_us(
demayer 0:6bf0743ece18 940 &ticker_stub,
demayer 0:6bf0743ece18 941 &last_event, timestamp_last_event, id_last_event
demayer 0:6bf0743ece18 942 );
demayer 0:6bf0743ece18 943
demayer 0:6bf0743ece18 944 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
demayer 0:6bf0743ece18 945 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 946 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 947 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 948 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 949 );
demayer 0:6bf0743ece18 950 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
demayer 0:6bf0743ece18 951 TEST_ASSERT_EQUAL_UINT64(timestamp_last_event, last_event.timestamp);
demayer 0:6bf0743ece18 952 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);
demayer 0:6bf0743ece18 953
demayer 0:6bf0743ece18 954 // test the beginning of the range
demayer 0:6bf0743ece18 955 ++interface_stub.timestamp;
demayer 0:6bf0743ece18 956 ++queue_stub.present_time;
demayer 0:6bf0743ece18 957
demayer 0:6bf0743ece18 958 ticker_event_t first_event = { 0 };
demayer 0:6bf0743ece18 959 const us_timestamp_t timestamp_first_event =
demayer 0:6bf0743ece18 960 queue_stub.present_time + TIMESTAMP_MAX_DELTA + 1;
demayer 0:6bf0743ece18 961 uint32_t id_first_event = 0xAAAAAAAA;
demayer 0:6bf0743ece18 962
demayer 0:6bf0743ece18 963 ticker_insert_event_us(&ticker_stub,
demayer 0:6bf0743ece18 964 &first_event, timestamp_first_event, id_first_event
demayer 0:6bf0743ece18 965 );
demayer 0:6bf0743ece18 966
demayer 0:6bf0743ece18 967 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 968 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 969 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 970 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 971 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 972 );
demayer 0:6bf0743ece18 973 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
demayer 0:6bf0743ece18 974 TEST_ASSERT_EQUAL_UINT64(timestamp_first_event, first_event.timestamp);
demayer 0:6bf0743ece18 975 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);
demayer 0:6bf0743ece18 976
demayer 0:6bf0743ece18 977 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 978 }
demayer 0:6bf0743ece18 979
demayer 0:6bf0743ece18 980 /**
demayer 0:6bf0743ece18 981 * Given an initialized ticker without user registered events.
demayer 0:6bf0743ece18 982 * When an event is inserted with ticker_insert_event_us and a timestamp less
demayer 0:6bf0743ece18 983 * than timestamp value in the ticker interface.
demayer 0:6bf0743ece18 984 * Then
demayer 0:6bf0743ece18 985 * - The event should be in the queue
demayer 0:6bf0743ece18 986 * - The interrupt timestamp should be set to interface_stub.timestamp so it
demayer 0:6bf0743ece18 987 * is scheduled immediately.
demayer 0:6bf0743ece18 988 */
demayer 0:6bf0743ece18 989 static void test_insert_event_us_underflow()
demayer 0:6bf0743ece18 990 {
demayer 0:6bf0743ece18 991 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 992 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 993
demayer 0:6bf0743ece18 994 interface_stub.timestamp = 0xAAAAAAAA;
demayer 0:6bf0743ece18 995 queue_stub.tick_last_read = interface_stub.timestamp;
demayer 0:6bf0743ece18 996 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp;
demayer 0:6bf0743ece18 997
demayer 0:6bf0743ece18 998 // test the end of the range
demayer 0:6bf0743ece18 999 ticker_event_t event = { 0 };
demayer 0:6bf0743ece18 1000 const timestamp_t expected_timestamp = queue_stub.present_time - 1;
demayer 0:6bf0743ece18 1001 const uint32_t expected_id = 0xDEADDEAF;
demayer 0:6bf0743ece18 1002
demayer 0:6bf0743ece18 1003 ticker_insert_event_us(
demayer 0:6bf0743ece18 1004 &ticker_stub,
demayer 0:6bf0743ece18 1005 &event, expected_timestamp, expected_id
demayer 0:6bf0743ece18 1006 );
demayer 0:6bf0743ece18 1007
demayer 0:6bf0743ece18 1008 TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head);
demayer 0:6bf0743ece18 1009 TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call);
demayer 0:6bf0743ece18 1010
demayer 0:6bf0743ece18 1011 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1012 }
demayer 0:6bf0743ece18 1013
demayer 0:6bf0743ece18 1014 /**
demayer 0:6bf0743ece18 1015 * Given an initialized ticker.
demayer 0:6bf0743ece18 1016 * When an event is inserted with ticker_insert_event_us and a timestamp less
demayer 0:6bf0743ece18 1017 * than the one for the next scheduled timestamp.
demayer 0:6bf0743ece18 1018 * Then
demayer 0:6bf0743ece18 1019 * - The event inserted should be the first in the queue
demayer 0:6bf0743ece18 1020 * - The interrupt timestamp should be equal to the timestamp of the event or
demayer 0:6bf0743ece18 1021 * TIMESTAMP_MAX_DELTA if in the overflow range.
demayer 0:6bf0743ece18 1022 * - The timestamp of the event should be equal to the timestamp in parameter.
demayer 0:6bf0743ece18 1023 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 1024 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 1025 */
demayer 0:6bf0743ece18 1026 static void test_insert_event_us_head()
demayer 0:6bf0743ece18 1027 {
demayer 0:6bf0743ece18 1028 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1029 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1030 interface_stub.timestamp = 0xAAAAAAAA;
demayer 0:6bf0743ece18 1031 queue_stub.tick_last_read = interface_stub.timestamp;
demayer 0:6bf0743ece18 1032 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp;
demayer 0:6bf0743ece18 1033
demayer 0:6bf0743ece18 1034 const us_timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 1035 UINT64_MAX,
demayer 0:6bf0743ece18 1036 queue_stub.present_time + TIMESTAMP_MAX_DELTA + 1,
demayer 0:6bf0743ece18 1037 queue_stub.present_time + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1038 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 2),
demayer 0:6bf0743ece18 1039 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 4),
demayer 0:6bf0743ece18 1040 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 8),
demayer 0:6bf0743ece18 1041 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 16),
demayer 0:6bf0743ece18 1042 };
demayer 0:6bf0743ece18 1043 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1044
demayer 0:6bf0743ece18 1045 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1046 ticker_insert_event_us(
demayer 0:6bf0743ece18 1047 &ticker_stub,
demayer 0:6bf0743ece18 1048 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 1049 );
demayer 0:6bf0743ece18 1050
demayer 0:6bf0743ece18 1051 TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head);
demayer 0:6bf0743ece18 1052 if ((timestamps[i] - queue_stub.present_time) < TIMESTAMP_MAX_DELTA) {
demayer 0:6bf0743ece18 1053 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1054 timestamps[i],
demayer 0:6bf0743ece18 1055 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1056 );
demayer 0:6bf0743ece18 1057 } else {
demayer 0:6bf0743ece18 1058 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1059 queue_stub.present_time + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1060 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1061 );
demayer 0:6bf0743ece18 1062 }
demayer 0:6bf0743ece18 1063
demayer 0:6bf0743ece18 1064 TEST_ASSERT_EQUAL_UINT64(timestamps[i], events[i].timestamp);
demayer 0:6bf0743ece18 1065 TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
demayer 0:6bf0743ece18 1066
demayer 0:6bf0743ece18 1067 ticker_event_t* e = &events[i];
demayer 0:6bf0743ece18 1068 while (e) {
demayer 0:6bf0743ece18 1069 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
demayer 0:6bf0743ece18 1070 if (e->next) {
demayer 0:6bf0743ece18 1071 TEST_ASSERT_TRUE(e->id > e->next->id);
demayer 0:6bf0743ece18 1072 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
demayer 0:6bf0743ece18 1073 } else {
demayer 0:6bf0743ece18 1074 TEST_ASSERT_EQUAL_UINT32(0, e->id);
demayer 0:6bf0743ece18 1075 }
demayer 0:6bf0743ece18 1076 e = e->next;
demayer 0:6bf0743ece18 1077 }
demayer 0:6bf0743ece18 1078 }
demayer 0:6bf0743ece18 1079
demayer 0:6bf0743ece18 1080 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1081 }
demayer 0:6bf0743ece18 1082
demayer 0:6bf0743ece18 1083 /**
demayer 0:6bf0743ece18 1084 * Given an initialized ticker.
demayer 0:6bf0743ece18 1085 * When an event is inserted with ticker_insert_event_us and its timestamp is
demayer 0:6bf0743ece18 1086 * bigger than the one of the last event in the queue.
demayer 0:6bf0743ece18 1087 * Then
demayer 0:6bf0743ece18 1088 * - The event inserted should be the last in the queue
demayer 0:6bf0743ece18 1089 * - The interrupt timestamp should remains equal to the interrupt timestamp
demayer 0:6bf0743ece18 1090 * of the head event .
demayer 0:6bf0743ece18 1091 * - The timestamp of the event should reflect the timestamp requested.
demayer 0:6bf0743ece18 1092 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 1093 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 1094 */
demayer 0:6bf0743ece18 1095 static void test_insert_event_us_tail()
demayer 0:6bf0743ece18 1096 {
demayer 0:6bf0743ece18 1097 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1098 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1099
demayer 0:6bf0743ece18 1100 const us_timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 1101 0xA,
demayer 0:6bf0743ece18 1102 (1ULL << 32),
demayer 0:6bf0743ece18 1103 (2ULL << 32),
demayer 0:6bf0743ece18 1104 (4ULL << 32),
demayer 0:6bf0743ece18 1105 (8ULL << 32),
demayer 0:6bf0743ece18 1106 (16ULL << 32),
demayer 0:6bf0743ece18 1107 (32ULL << 32),
demayer 0:6bf0743ece18 1108 (64ULL << 32),
demayer 0:6bf0743ece18 1109 };
demayer 0:6bf0743ece18 1110 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1111
demayer 0:6bf0743ece18 1112 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1113 ticker_insert_event_us(
demayer 0:6bf0743ece18 1114 &ticker_stub,
demayer 0:6bf0743ece18 1115 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 1116 );
demayer 0:6bf0743ece18 1117
demayer 0:6bf0743ece18 1118 TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head);
demayer 0:6bf0743ece18 1119 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1120 timestamps[0], interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1121 );
demayer 0:6bf0743ece18 1122 TEST_ASSERT_EQUAL_UINT64(timestamps[i], events[i].timestamp);
demayer 0:6bf0743ece18 1123 TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
demayer 0:6bf0743ece18 1124
demayer 0:6bf0743ece18 1125 ticker_event_t* e = queue_stub.head;
demayer 0:6bf0743ece18 1126 while (e) {
demayer 0:6bf0743ece18 1127 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
demayer 0:6bf0743ece18 1128 if (e->next) {
demayer 0:6bf0743ece18 1129 TEST_ASSERT_TRUE(e->id < e->next->id);
demayer 0:6bf0743ece18 1130 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
demayer 0:6bf0743ece18 1131 } else {
demayer 0:6bf0743ece18 1132 TEST_ASSERT_EQUAL_UINT32(&events[i], e);
demayer 0:6bf0743ece18 1133 }
demayer 0:6bf0743ece18 1134 e = e->next;
demayer 0:6bf0743ece18 1135 }
demayer 0:6bf0743ece18 1136 }
demayer 0:6bf0743ece18 1137
demayer 0:6bf0743ece18 1138 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1139 }
demayer 0:6bf0743ece18 1140
demayer 0:6bf0743ece18 1141 /**
demayer 0:6bf0743ece18 1142 * Given an initialized ticker.
demayer 0:6bf0743ece18 1143 * When an event is inserted with ticker_insert_event_us.
demayer 0:6bf0743ece18 1144 * Then
demayer 0:6bf0743ece18 1145 * - The event inserted should be at the correct position in the queue
demayer 0:6bf0743ece18 1146 * - The event queue should remain ordered by timestamp
demayer 0:6bf0743ece18 1147 * - The interrupt timestamp should be equal to the interrupt timestamp
demayer 0:6bf0743ece18 1148 * of the head event or TIMESTAMP_MAX_DELTA if the
demayer 0:6bf0743ece18 1149 * timestamp is in the overflow range.
demayer 0:6bf0743ece18 1150 * - The timestamp of the event should be equal to the timestamp parameter.
demayer 0:6bf0743ece18 1151 * - The id of the event should be equal to the id passed in parameter.
demayer 0:6bf0743ece18 1152 * - Events in the queue should remained ordered by timestamp.
demayer 0:6bf0743ece18 1153 */
demayer 0:6bf0743ece18 1154 static void test_insert_event_us_multiple_random()
demayer 0:6bf0743ece18 1155 {
demayer 0:6bf0743ece18 1156 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1157 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1158
demayer 0:6bf0743ece18 1159 const timestamp_t ref_timestamp = UINT32_MAX / 2;
demayer 0:6bf0743ece18 1160 interface_stub.timestamp = ref_timestamp;
demayer 0:6bf0743ece18 1161
demayer 0:6bf0743ece18 1162 // insert first event at the head of the queue
demayer 0:6bf0743ece18 1163 ticker_event_t first_event;
demayer 0:6bf0743ece18 1164 const us_timestamp_t first_event_timestamp =
demayer 0:6bf0743ece18 1165 ref_timestamp + TIMESTAMP_MAX_DELTA + 100;
demayer 0:6bf0743ece18 1166
demayer 0:6bf0743ece18 1167 ticker_insert_event_us(
demayer 0:6bf0743ece18 1168 &ticker_stub,
demayer 0:6bf0743ece18 1169 &first_event, first_event_timestamp, (uint32_t) &first_event
demayer 0:6bf0743ece18 1170 );
demayer 0:6bf0743ece18 1171
demayer 0:6bf0743ece18 1172 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 1173 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next);
demayer 0:6bf0743ece18 1174 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1175 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1176 );
demayer 0:6bf0743ece18 1177 TEST_ASSERT_EQUAL_UINT64(first_event.timestamp, first_event_timestamp);
demayer 0:6bf0743ece18 1178 TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id);
demayer 0:6bf0743ece18 1179
demayer 0:6bf0743ece18 1180 // insert second event at the tail of the queue
demayer 0:6bf0743ece18 1181 ticker_event_t second_event;
demayer 0:6bf0743ece18 1182 const us_timestamp_t second_event_timestamp = first_event_timestamp + 1;
demayer 0:6bf0743ece18 1183
demayer 0:6bf0743ece18 1184 ticker_insert_event_us(
demayer 0:6bf0743ece18 1185 &ticker_stub,
demayer 0:6bf0743ece18 1186 &second_event, second_event_timestamp, (uint32_t) &second_event
demayer 0:6bf0743ece18 1187 );
demayer 0:6bf0743ece18 1188
demayer 0:6bf0743ece18 1189 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 1190 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 1191 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 1192 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1193 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1194 );
demayer 0:6bf0743ece18 1195 TEST_ASSERT_EQUAL_UINT64(second_event_timestamp, second_event.timestamp);
demayer 0:6bf0743ece18 1196 TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id);
demayer 0:6bf0743ece18 1197
demayer 0:6bf0743ece18 1198
demayer 0:6bf0743ece18 1199 // insert third event at the head of the queue out the overflow zone
demayer 0:6bf0743ece18 1200 ticker_event_t third_event;
demayer 0:6bf0743ece18 1201 const us_timestamp_t third_event_timestamp =
demayer 0:6bf0743ece18 1202 ref_timestamp + TIMESTAMP_MAX_DELTA - 100;
demayer 0:6bf0743ece18 1203
demayer 0:6bf0743ece18 1204 ticker_insert_event_us(
demayer 0:6bf0743ece18 1205 &ticker_stub,
demayer 0:6bf0743ece18 1206 &third_event, third_event_timestamp, (uint32_t) &third_event
demayer 0:6bf0743ece18 1207 );
demayer 0:6bf0743ece18 1208
demayer 0:6bf0743ece18 1209 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head);
demayer 0:6bf0743ece18 1210 TEST_ASSERT_EQUAL_PTR(&first_event, third_event.next);
demayer 0:6bf0743ece18 1211 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 1212 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 1213 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1214 third_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1215 );
demayer 0:6bf0743ece18 1216 TEST_ASSERT_EQUAL_UINT64(third_event_timestamp, third_event.timestamp);
demayer 0:6bf0743ece18 1217 TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id);
demayer 0:6bf0743ece18 1218
demayer 0:6bf0743ece18 1219 // insert fourth event right after the third event
demayer 0:6bf0743ece18 1220 ticker_event_t fourth_event;
demayer 0:6bf0743ece18 1221 const us_timestamp_t fourth_event_timestamp = third_event_timestamp + 50;
demayer 0:6bf0743ece18 1222
demayer 0:6bf0743ece18 1223 ticker_insert_event_us(
demayer 0:6bf0743ece18 1224 &ticker_stub,
demayer 0:6bf0743ece18 1225 &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event
demayer 0:6bf0743ece18 1226 );
demayer 0:6bf0743ece18 1227
demayer 0:6bf0743ece18 1228 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head);
demayer 0:6bf0743ece18 1229 TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next);
demayer 0:6bf0743ece18 1230 TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next);
demayer 0:6bf0743ece18 1231 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 1232 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 1233 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1234 third_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1235 );
demayer 0:6bf0743ece18 1236 TEST_ASSERT_EQUAL_UINT64(fourth_event_timestamp, fourth_event.timestamp);
demayer 0:6bf0743ece18 1237 TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id);
demayer 0:6bf0743ece18 1238
demayer 0:6bf0743ece18 1239 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1240 }
demayer 0:6bf0743ece18 1241
demayer 0:6bf0743ece18 1242 /**
demayer 0:6bf0743ece18 1243 * Given an initialized ticker with multiple events registered.
demayer 0:6bf0743ece18 1244 * When the event at the tail of the queue is removed from the queue.
demayer 0:6bf0743ece18 1245 * Then:
demayer 0:6bf0743ece18 1246 * - The event should not be in the queue.
demayer 0:6bf0743ece18 1247 * - The events in the queue should remain ordered
demayer 0:6bf0743ece18 1248 * - The interrupt timestamp should be unchanged.
demayer 0:6bf0743ece18 1249 */
demayer 0:6bf0743ece18 1250 static void test_remove_event_tail()
demayer 0:6bf0743ece18 1251 {
demayer 0:6bf0743ece18 1252 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1253 const us_timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 1254 0xA,
demayer 0:6bf0743ece18 1255 (1ULL << 32),
demayer 0:6bf0743ece18 1256 (2ULL << 32),
demayer 0:6bf0743ece18 1257 (4ULL << 32),
demayer 0:6bf0743ece18 1258 (8ULL << 32),
demayer 0:6bf0743ece18 1259 (16ULL << 32),
demayer 0:6bf0743ece18 1260 (32ULL << 32),
demayer 0:6bf0743ece18 1261 (64ULL << 32),
demayer 0:6bf0743ece18 1262 };
demayer 0:6bf0743ece18 1263 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1264
demayer 0:6bf0743ece18 1265 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1266 ticker_insert_event_us(
demayer 0:6bf0743ece18 1267 &ticker_stub,
demayer 0:6bf0743ece18 1268 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 1269 );
demayer 0:6bf0743ece18 1270 }
demayer 0:6bf0743ece18 1271
demayer 0:6bf0743ece18 1272 for (ssize_t i = MBED_ARRAY_SIZE(events) - 1; i >= 0; --i) {
demayer 0:6bf0743ece18 1273 ticker_remove_event(&ticker_stub, &events[i]);
demayer 0:6bf0743ece18 1274
demayer 0:6bf0743ece18 1275 ticker_event_t* e = queue_stub.head;
demayer 0:6bf0743ece18 1276 size_t event_count = 0;
demayer 0:6bf0743ece18 1277 while (e) {
demayer 0:6bf0743ece18 1278 TEST_ASSERT_NOT_EQUAL(e, &events[i]);
demayer 0:6bf0743ece18 1279 if (e->next) {
demayer 0:6bf0743ece18 1280 TEST_ASSERT_TRUE(e->timestamp <= e->next->timestamp);
demayer 0:6bf0743ece18 1281 }
demayer 0:6bf0743ece18 1282 e = e->next;
demayer 0:6bf0743ece18 1283 ++event_count;
demayer 0:6bf0743ece18 1284 }
demayer 0:6bf0743ece18 1285
demayer 0:6bf0743ece18 1286 TEST_ASSERT_EQUAL(i, event_count);
demayer 0:6bf0743ece18 1287
demayer 0:6bf0743ece18 1288 if (i != 0 ) {
demayer 0:6bf0743ece18 1289 TEST_ASSERT_EQUAL(
demayer 0:6bf0743ece18 1290 timestamps[0],
demayer 0:6bf0743ece18 1291 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1292 );
demayer 0:6bf0743ece18 1293 } else {
demayer 0:6bf0743ece18 1294 TEST_ASSERT_EQUAL(
demayer 0:6bf0743ece18 1295 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1296 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1297 );
demayer 0:6bf0743ece18 1298 }
demayer 0:6bf0743ece18 1299 }
demayer 0:6bf0743ece18 1300
demayer 0:6bf0743ece18 1301 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1302 }
demayer 0:6bf0743ece18 1303
demayer 0:6bf0743ece18 1304 /**
demayer 0:6bf0743ece18 1305 * Given an initialized ticker with multiple events registered.
demayer 0:6bf0743ece18 1306 * When the event at the head of the queue is removed from the queue.
demayer 0:6bf0743ece18 1307 * Then:
demayer 0:6bf0743ece18 1308 * - The event should not be in the queue.
demayer 0:6bf0743ece18 1309 * - The event at the head of the queue should be the equal to the one
demayer 0:6bf0743ece18 1310 * after the event removed.
demayer 0:6bf0743ece18 1311 * - The interrupt timestamp should be equal to the interrupt timestamp
demayer 0:6bf0743ece18 1312 * of the head event or TIMESTAMP_MAX_DELTA if the
demayer 0:6bf0743ece18 1313 * timestamp is in the overflow range.
demayer 0:6bf0743ece18 1314 */
demayer 0:6bf0743ece18 1315 static void test_remove_event_head()
demayer 0:6bf0743ece18 1316 {
demayer 0:6bf0743ece18 1317 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1318 const us_timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 1319 TIMESTAMP_MAX_DELTA / 8,
demayer 0:6bf0743ece18 1320 TIMESTAMP_MAX_DELTA / 4,
demayer 0:6bf0743ece18 1321 TIMESTAMP_MAX_DELTA / 2,
demayer 0:6bf0743ece18 1322 TIMESTAMP_MAX_DELTA - 1,
demayer 0:6bf0743ece18 1323 TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1324 TIMESTAMP_MAX_DELTA + 1,
demayer 0:6bf0743ece18 1325 (1ULL << 32) | TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1326 UINT64_MAX
demayer 0:6bf0743ece18 1327 };
demayer 0:6bf0743ece18 1328 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1329
demayer 0:6bf0743ece18 1330 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1331 ticker_insert_event_us(&ticker_stub,
demayer 0:6bf0743ece18 1332 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 1333 );
demayer 0:6bf0743ece18 1334 }
demayer 0:6bf0743ece18 1335
demayer 0:6bf0743ece18 1336 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1337 ticker_remove_event(&ticker_stub, &events[i]);
demayer 0:6bf0743ece18 1338
demayer 0:6bf0743ece18 1339 ticker_event_t* e = queue_stub.head;
demayer 0:6bf0743ece18 1340 size_t event_count = 0;
demayer 0:6bf0743ece18 1341 while (e) {
demayer 0:6bf0743ece18 1342 TEST_ASSERT_NOT_EQUAL(e, &events[i]);
demayer 0:6bf0743ece18 1343 if (e->next) {
demayer 0:6bf0743ece18 1344 TEST_ASSERT_TRUE(e->timestamp <= e->next->timestamp);
demayer 0:6bf0743ece18 1345 }
demayer 0:6bf0743ece18 1346 e = e->next;
demayer 0:6bf0743ece18 1347 ++event_count;
demayer 0:6bf0743ece18 1348 }
demayer 0:6bf0743ece18 1349
demayer 0:6bf0743ece18 1350 TEST_ASSERT_EQUAL(MBED_ARRAY_SIZE(events) - i - 1, event_count);
demayer 0:6bf0743ece18 1351
demayer 0:6bf0743ece18 1352 if (event_count) {
demayer 0:6bf0743ece18 1353 TEST_ASSERT_EQUAL(
demayer 0:6bf0743ece18 1354 std::min(
demayer 0:6bf0743ece18 1355 timestamps[i + 1],
demayer 0:6bf0743ece18 1356 interface_stub.timestamp + TIMESTAMP_MAX_DELTA
demayer 0:6bf0743ece18 1357 ),
demayer 0:6bf0743ece18 1358 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1359 );
demayer 0:6bf0743ece18 1360 } else {
demayer 0:6bf0743ece18 1361 TEST_ASSERT_EQUAL(
demayer 0:6bf0743ece18 1362 interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1363 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1364 );
demayer 0:6bf0743ece18 1365 }
demayer 0:6bf0743ece18 1366
demayer 0:6bf0743ece18 1367 }
demayer 0:6bf0743ece18 1368
demayer 0:6bf0743ece18 1369 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1370 }
demayer 0:6bf0743ece18 1371
demayer 0:6bf0743ece18 1372 /**
demayer 0:6bf0743ece18 1373 * Given an initialized ticker with multiple events registered.
demayer 0:6bf0743ece18 1374 * When an event not in the queue is attempted to be removed.
demayer 0:6bf0743ece18 1375 * Then the queue should remains identical as before.
demayer 0:6bf0743ece18 1376 */
demayer 0:6bf0743ece18 1377 static void test_remove_event_invalid()
demayer 0:6bf0743ece18 1378 {
demayer 0:6bf0743ece18 1379 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1380 const us_timestamp_t timestamps[] = {
demayer 0:6bf0743ece18 1381 TIMESTAMP_MAX_DELTA / 8,
demayer 0:6bf0743ece18 1382 TIMESTAMP_MAX_DELTA / 4,
demayer 0:6bf0743ece18 1383 TIMESTAMP_MAX_DELTA / 2,
demayer 0:6bf0743ece18 1384 TIMESTAMP_MAX_DELTA - 1,
demayer 0:6bf0743ece18 1385 TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1386 TIMESTAMP_MAX_DELTA + 1,
demayer 0:6bf0743ece18 1387 (1ULL << 32) | TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1388 UINT64_MAX
demayer 0:6bf0743ece18 1389 };
demayer 0:6bf0743ece18 1390 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1391
demayer 0:6bf0743ece18 1392 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1393 ticker_insert_event_us(
demayer 0:6bf0743ece18 1394 &ticker_stub,
demayer 0:6bf0743ece18 1395 &events[i], timestamps[i], i
demayer 0:6bf0743ece18 1396 );
demayer 0:6bf0743ece18 1397 }
demayer 0:6bf0743ece18 1398
demayer 0:6bf0743ece18 1399 ticker_event_t invalid_event;
demayer 0:6bf0743ece18 1400 ticker_remove_event(&ticker_stub, &invalid_event);
demayer 0:6bf0743ece18 1401
demayer 0:6bf0743ece18 1402 TEST_ASSERT_EQUAL(&events[0], queue_stub.head);
demayer 0:6bf0743ece18 1403
demayer 0:6bf0743ece18 1404 ticker_event_t* e = queue_stub.head;
demayer 0:6bf0743ece18 1405 size_t event_count = 0;
demayer 0:6bf0743ece18 1406 while (e) {
demayer 0:6bf0743ece18 1407 TEST_ASSERT_EQUAL(e, &events[event_count]);
demayer 0:6bf0743ece18 1408 e = e->next;
demayer 0:6bf0743ece18 1409 ++event_count;
demayer 0:6bf0743ece18 1410 }
demayer 0:6bf0743ece18 1411 TEST_ASSERT_EQUAL(MBED_ARRAY_SIZE(events), event_count);
demayer 0:6bf0743ece18 1412 }
demayer 0:6bf0743ece18 1413
demayer 0:6bf0743ece18 1414 /**
demayer 0:6bf0743ece18 1415 * Given an initialized ticker with multiple events inserted.
demayer 0:6bf0743ece18 1416 * When an event is remoced
demayer 0:6bf0743ece18 1417 * Then:
demayer 0:6bf0743ece18 1418 * - the event should not be in the queue
demayer 0:6bf0743ece18 1419 * - the queue should remain ordered
demayer 0:6bf0743ece18 1420 * - the interrupt timestamp should be set to either head->timestamp or
demayer 0:6bf0743ece18 1421 * TIMESTAMP_MAX_DELTA depending on the distance between the current time
demayer 0:6bf0743ece18 1422 * ans the timestamp of the event at the head of the queue.
demayer 0:6bf0743ece18 1423 */
demayer 0:6bf0743ece18 1424 static void test_remove_random()
demayer 0:6bf0743ece18 1425 {
demayer 0:6bf0743ece18 1426 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 1427 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1428
demayer 0:6bf0743ece18 1429 const timestamp_t ref_timestamp = UINT32_MAX / 2;
demayer 0:6bf0743ece18 1430 interface_stub.timestamp = ref_timestamp;
demayer 0:6bf0743ece18 1431
demayer 0:6bf0743ece18 1432 // insert all events
demayer 0:6bf0743ece18 1433 ticker_event_t first_event;
demayer 0:6bf0743ece18 1434 const us_timestamp_t first_event_timestamp =
demayer 0:6bf0743ece18 1435 ref_timestamp + TIMESTAMP_MAX_DELTA + 100;
demayer 0:6bf0743ece18 1436
demayer 0:6bf0743ece18 1437 ticker_insert_event_us(
demayer 0:6bf0743ece18 1438 &ticker_stub,
demayer 0:6bf0743ece18 1439 &first_event, first_event_timestamp, (uint32_t) &first_event
demayer 0:6bf0743ece18 1440 );
demayer 0:6bf0743ece18 1441
demayer 0:6bf0743ece18 1442
demayer 0:6bf0743ece18 1443 ticker_event_t second_event;
demayer 0:6bf0743ece18 1444 const us_timestamp_t second_event_timestamp = first_event_timestamp + 1;
demayer 0:6bf0743ece18 1445
demayer 0:6bf0743ece18 1446 ticker_insert_event_us(
demayer 0:6bf0743ece18 1447 &ticker_stub,
demayer 0:6bf0743ece18 1448 &second_event, second_event_timestamp, (uint32_t) &second_event
demayer 0:6bf0743ece18 1449 );
demayer 0:6bf0743ece18 1450
demayer 0:6bf0743ece18 1451 ticker_event_t third_event;
demayer 0:6bf0743ece18 1452 const us_timestamp_t third_event_timestamp =
demayer 0:6bf0743ece18 1453 ref_timestamp + TIMESTAMP_MAX_DELTA - 100;
demayer 0:6bf0743ece18 1454
demayer 0:6bf0743ece18 1455 ticker_insert_event_us(
demayer 0:6bf0743ece18 1456 &ticker_stub,
demayer 0:6bf0743ece18 1457 &third_event, third_event_timestamp, (uint32_t) &third_event
demayer 0:6bf0743ece18 1458 );
demayer 0:6bf0743ece18 1459
demayer 0:6bf0743ece18 1460 ticker_event_t fourth_event;
demayer 0:6bf0743ece18 1461 const us_timestamp_t fourth_event_timestamp = third_event_timestamp + 50;
demayer 0:6bf0743ece18 1462
demayer 0:6bf0743ece18 1463 ticker_insert_event_us(
demayer 0:6bf0743ece18 1464 &ticker_stub,
demayer 0:6bf0743ece18 1465 &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event
demayer 0:6bf0743ece18 1466 );
demayer 0:6bf0743ece18 1467
demayer 0:6bf0743ece18 1468 // test that the queue is in the correct state
demayer 0:6bf0743ece18 1469 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head);
demayer 0:6bf0743ece18 1470 TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next);
demayer 0:6bf0743ece18 1471 TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next);
demayer 0:6bf0743ece18 1472 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 1473 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 1474 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1475 third_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1476 );
demayer 0:6bf0743ece18 1477 TEST_ASSERT_EQUAL_UINT64(fourth_event_timestamp, fourth_event.timestamp);
demayer 0:6bf0743ece18 1478 TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id);
demayer 0:6bf0743ece18 1479
demayer 0:6bf0743ece18 1480 // remove fourth event
demayer 0:6bf0743ece18 1481 ticker_remove_event(&ticker_stub, &fourth_event);
demayer 0:6bf0743ece18 1482
demayer 0:6bf0743ece18 1483 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head);
demayer 0:6bf0743ece18 1484 TEST_ASSERT_EQUAL_PTR(&first_event, third_event.next);
demayer 0:6bf0743ece18 1485 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 1486 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 1487 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1488 third_event_timestamp, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1489 );
demayer 0:6bf0743ece18 1490 TEST_ASSERT_EQUAL_UINT64(third_event_timestamp, third_event.timestamp);
demayer 0:6bf0743ece18 1491 TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id);
demayer 0:6bf0743ece18 1492
demayer 0:6bf0743ece18 1493 // remove third event
demayer 0:6bf0743ece18 1494 ticker_remove_event(&ticker_stub, &third_event);
demayer 0:6bf0743ece18 1495
demayer 0:6bf0743ece18 1496 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 1497 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
demayer 0:6bf0743ece18 1498 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
demayer 0:6bf0743ece18 1499 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1500 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1501 );
demayer 0:6bf0743ece18 1502 TEST_ASSERT_EQUAL_UINT64(second_event_timestamp, second_event.timestamp);
demayer 0:6bf0743ece18 1503 TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id);
demayer 0:6bf0743ece18 1504
demayer 0:6bf0743ece18 1505 // remove second event
demayer 0:6bf0743ece18 1506 ticker_remove_event(&ticker_stub, &second_event);
demayer 0:6bf0743ece18 1507
demayer 0:6bf0743ece18 1508 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
demayer 0:6bf0743ece18 1509 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next);
demayer 0:6bf0743ece18 1510 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1511 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1512 );
demayer 0:6bf0743ece18 1513 TEST_ASSERT_EQUAL_UINT64(first_event.timestamp, first_event_timestamp);
demayer 0:6bf0743ece18 1514 TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id);
demayer 0:6bf0743ece18 1515
demayer 0:6bf0743ece18 1516 // remove first event
demayer 0:6bf0743ece18 1517 ticker_remove_event(&ticker_stub, &first_event);
demayer 0:6bf0743ece18 1518
demayer 0:6bf0743ece18 1519 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head);
demayer 0:6bf0743ece18 1520 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next);
demayer 0:6bf0743ece18 1521 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1522 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1523 );
demayer 0:6bf0743ece18 1524
demayer 0:6bf0743ece18 1525 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1526 }
demayer 0:6bf0743ece18 1527
demayer 0:6bf0743ece18 1528 /**
demayer 0:6bf0743ece18 1529 * Given an initialized ticker without user registered events and a ticker
demayer 0:6bf0743ece18 1530 * interface timestamp equal or bigger than the one registered by the overflow
demayer 0:6bf0743ece18 1531 * event.
demayer 0:6bf0743ece18 1532 * When the interrupt handler is called.
demayer 0:6bf0743ece18 1533 * Then:
demayer 0:6bf0743ece18 1534 * - The interrupt timestamp should be updated to the timestamp of the ticker
demayer 0:6bf0743ece18 1535 * interface plus TIMESTAMP_MAX_DELTA.
demayer 0:6bf0743ece18 1536 * - The irq handler registered should not be called.
demayer 0:6bf0743ece18 1537 */
demayer 0:6bf0743ece18 1538 static void test_overflow_event_update()
demayer 0:6bf0743ece18 1539 {
demayer 0:6bf0743ece18 1540 static uint32_t handler_call = 0;
demayer 0:6bf0743ece18 1541 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1542 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1543 ++handler_call;
demayer 0:6bf0743ece18 1544 }
demayer 0:6bf0743ece18 1545 };
demayer 0:6bf0743ece18 1546 handler_call = 0;
demayer 0:6bf0743ece18 1547
demayer 0:6bf0743ece18 1548 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1549 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1550
demayer 0:6bf0743ece18 1551 for (size_t i = 0; i < 8; ++i) {
demayer 0:6bf0743ece18 1552 us_timestamp_t previous_timestamp = queue_stub.present_time;
demayer 0:6bf0743ece18 1553 timestamp_t interface_timestamp =
demayer 0:6bf0743ece18 1554 previous_timestamp + (TIMESTAMP_MAX_DELTA + i * 100);
demayer 0:6bf0743ece18 1555 interface_stub.timestamp = interface_timestamp;
demayer 0:6bf0743ece18 1556
demayer 0:6bf0743ece18 1557 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1558 TEST_ASSERT_EQUAL(i + 1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1559
demayer 0:6bf0743ece18 1560 TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1561 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1562 interface_timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1563 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1564 );
demayer 0:6bf0743ece18 1565 TEST_ASSERT_EQUAL(0, handler_call);
demayer 0:6bf0743ece18 1566 }
demayer 0:6bf0743ece18 1567
demayer 0:6bf0743ece18 1568 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1569 }
demayer 0:6bf0743ece18 1570
demayer 0:6bf0743ece18 1571 /**
demayer 0:6bf0743ece18 1572 * Given an initialized ticker without user registered events and a ticker
demayer 0:6bf0743ece18 1573 * interface timestamp less than the one registered to handle overflow.
demayer 0:6bf0743ece18 1574 * When the interrupt handler is called.
demayer 0:6bf0743ece18 1575 * Then:
demayer 0:6bf0743ece18 1576 * - The interrupt timestamp should be updated to the timestamp of the ticker
demayer 0:6bf0743ece18 1577 * interface plus TIMESTAMP_MAX_DELTA.
demayer 0:6bf0743ece18 1578 * - The irq handler registered should not be called.
demayer 0:6bf0743ece18 1579 */
demayer 0:6bf0743ece18 1580 static void test_overflow_event_update_when_spurious_interrupt()
demayer 0:6bf0743ece18 1581 {
demayer 0:6bf0743ece18 1582 static uint32_t handler_call = 0;
demayer 0:6bf0743ece18 1583 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1584 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1585 ++handler_call;
demayer 0:6bf0743ece18 1586 }
demayer 0:6bf0743ece18 1587 };
demayer 0:6bf0743ece18 1588 handler_call = 0;
demayer 0:6bf0743ece18 1589
demayer 0:6bf0743ece18 1590 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1591 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1592
demayer 0:6bf0743ece18 1593 for (size_t i = 0; i < 8; ++i) {
demayer 0:6bf0743ece18 1594 us_timestamp_t previous_timestamp = queue_stub.present_time;
demayer 0:6bf0743ece18 1595 timestamp_t interface_timestamp =
demayer 0:6bf0743ece18 1596 previous_timestamp + (TIMESTAMP_MAX_DELTA / (2 + i));
demayer 0:6bf0743ece18 1597 interface_stub.timestamp = interface_timestamp;
demayer 0:6bf0743ece18 1598
demayer 0:6bf0743ece18 1599 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1600
demayer 0:6bf0743ece18 1601 TEST_ASSERT_EQUAL(i + 1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1602 TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1603 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1604 interface_timestamp + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1605 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1606 );
demayer 0:6bf0743ece18 1607 TEST_ASSERT_EQUAL(0, handler_call);
demayer 0:6bf0743ece18 1608 }
demayer 0:6bf0743ece18 1609
demayer 0:6bf0743ece18 1610 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1611 }
demayer 0:6bf0743ece18 1612
demayer 0:6bf0743ece18 1613 /**
demayer 0:6bf0743ece18 1614 * Given an initialized ticker with a single ticker event inserted and a ticker
demayer 0:6bf0743ece18 1615 * interface timestamp bigger than the one set for interrupt.
demayer 0:6bf0743ece18 1616 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1617 * Then:
demayer 0:6bf0743ece18 1618 * - The IRQ handler should be called with the id of the event at the head of
demayer 0:6bf0743ece18 1619 * the queue.
demayer 0:6bf0743ece18 1620 * - The event at the head of the queue should be replaced by the next event.
demayer 0:6bf0743ece18 1621 * - The interrupt timestamp in the ticker interface should be set to the
demayer 0:6bf0743ece18 1622 * value of the interface timestamp + TIMESTAMP_MAX_DELTA
demayer 0:6bf0743ece18 1623 */
demayer 0:6bf0743ece18 1624 static void test_irq_handler_single_event()
demayer 0:6bf0743ece18 1625 {
demayer 0:6bf0743ece18 1626 static const timestamp_t event_timestamp = 0xAAAAAAAA;
demayer 0:6bf0743ece18 1627 static const timestamp_t interface_timestamp_after_irq = event_timestamp + 100;
demayer 0:6bf0743ece18 1628
demayer 0:6bf0743ece18 1629 uint32_t handler_call = 0;
demayer 0:6bf0743ece18 1630 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1631 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1632 ++ (*((uint32_t*) id));
demayer 0:6bf0743ece18 1633 interface_stub.timestamp = interface_timestamp_after_irq;
demayer 0:6bf0743ece18 1634 }
demayer 0:6bf0743ece18 1635 };
demayer 0:6bf0743ece18 1636
demayer 0:6bf0743ece18 1637 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1638 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1639
demayer 0:6bf0743ece18 1640 ticker_event_t e;
demayer 0:6bf0743ece18 1641 ticker_insert_event(&ticker_stub, &e, event_timestamp, (uint32_t) &handler_call);
demayer 0:6bf0743ece18 1642
demayer 0:6bf0743ece18 1643 interface_stub.timestamp = event_timestamp;
demayer 0:6bf0743ece18 1644 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1645
demayer 0:6bf0743ece18 1646 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1647
demayer 0:6bf0743ece18 1648 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1649 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1650 TEST_ASSERT_EQUAL(1, handler_call);
demayer 0:6bf0743ece18 1651 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1652 interface_timestamp_after_irq + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1653 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1654 );
demayer 0:6bf0743ece18 1655
demayer 0:6bf0743ece18 1656 TEST_ASSERT_NULL(queue_stub.head);
demayer 0:6bf0743ece18 1657
demayer 0:6bf0743ece18 1658 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1659 }
demayer 0:6bf0743ece18 1660
demayer 0:6bf0743ece18 1661 /**
demayer 0:6bf0743ece18 1662 * Given an initialized ticker with at least a ticker event inserted and a ticker
demayer 0:6bf0743ece18 1663 * interface timestamp less than the one set for interrupt.
demayer 0:6bf0743ece18 1664 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1665 * Then:
demayer 0:6bf0743ece18 1666 * - The IRQ handler should not be called.
demayer 0:6bf0743ece18 1667 * - The event at the head of the queue should remains the same.
demayer 0:6bf0743ece18 1668 * - The interrupt timestamp in the ticker interface should be set to the
demayer 0:6bf0743ece18 1669 * value of the event timestamp
demayer 0:6bf0743ece18 1670 */
demayer 0:6bf0743ece18 1671 static void test_irq_handler_single_event_spurious()
demayer 0:6bf0743ece18 1672 {
demayer 0:6bf0743ece18 1673 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1674 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1675 TEST_FAIL();
demayer 0:6bf0743ece18 1676 }
demayer 0:6bf0743ece18 1677 };
demayer 0:6bf0743ece18 1678
demayer 0:6bf0743ece18 1679 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1680 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1681
demayer 0:6bf0743ece18 1682 const us_timestamp_t timestamps [] = {
demayer 0:6bf0743ece18 1683 UINT32_MAX,
demayer 0:6bf0743ece18 1684 TIMESTAMP_MAX_DELTA + 1,
demayer 0:6bf0743ece18 1685 TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1686 TIMESTAMP_MAX_DELTA - 1
demayer 0:6bf0743ece18 1687 };
demayer 0:6bf0743ece18 1688
demayer 0:6bf0743ece18 1689 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1690
demayer 0:6bf0743ece18 1691 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1692 ticker_insert_event_us(
demayer 0:6bf0743ece18 1693 &ticker_stub,
demayer 0:6bf0743ece18 1694 &events[i], timestamps[i], timestamps[i]
demayer 0:6bf0743ece18 1695 );
demayer 0:6bf0743ece18 1696 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1697 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 1698
demayer 0:6bf0743ece18 1699 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1700
demayer 0:6bf0743ece18 1701 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1702 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1703 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1704 std::min(timestamps[i], TIMESTAMP_MAX_DELTA),
demayer 0:6bf0743ece18 1705 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1706 );
demayer 0:6bf0743ece18 1707 }
demayer 0:6bf0743ece18 1708
demayer 0:6bf0743ece18 1709 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1710 }
demayer 0:6bf0743ece18 1711
demayer 0:6bf0743ece18 1712 /**
demayer 0:6bf0743ece18 1713 * Given an initialized ticker with multiple ticker event inserted, its
demayer 0:6bf0743ece18 1714 * interface timestamp at greater than the timestamp of the next schedule event
demayer 0:6bf0743ece18 1715 * and all event execution time taking at least the time befor ethe next event.
demayer 0:6bf0743ece18 1716 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1717 * Then:
demayer 0:6bf0743ece18 1718 * - The IRQ handler should have been called for every event.
demayer 0:6bf0743ece18 1719 * - The head of the queue should be set to NULL.
demayer 0:6bf0743ece18 1720 * - The interrupt timestamp in the ticker interface should be scheduled in
demayer 0:6bf0743ece18 1721 * TIMESTAMP_MAX_DELTAs
demayer 0:6bf0743ece18 1722 */
demayer 0:6bf0743ece18 1723 static void test_irq_handler_multiple_event_multiple_dequeue()
demayer 0:6bf0743ece18 1724 {
demayer 0:6bf0743ece18 1725 const us_timestamp_t timestamps [] = {
demayer 0:6bf0743ece18 1726 10,
demayer 0:6bf0743ece18 1727 10 + TIMESTAMP_MAX_DELTA - 1,
demayer 0:6bf0743ece18 1728 10 + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1729 10 + TIMESTAMP_MAX_DELTA + 1,
demayer 0:6bf0743ece18 1730 UINT32_MAX
demayer 0:6bf0743ece18 1731 };
demayer 0:6bf0743ece18 1732
demayer 0:6bf0743ece18 1733 static size_t handler_called = 0;
demayer 0:6bf0743ece18 1734 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1735 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1736 ++handler_called;
demayer 0:6bf0743ece18 1737 ticker_event_t* e = (ticker_event_t*) id;
demayer 0:6bf0743ece18 1738 if (e->next) {
demayer 0:6bf0743ece18 1739 interface_stub.timestamp = e->next->timestamp;
demayer 0:6bf0743ece18 1740 }
demayer 0:6bf0743ece18 1741 }
demayer 0:6bf0743ece18 1742 };
demayer 0:6bf0743ece18 1743 handler_called = 0;
demayer 0:6bf0743ece18 1744
demayer 0:6bf0743ece18 1745 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1746 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1747
demayer 0:6bf0743ece18 1748 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1749
demayer 0:6bf0743ece18 1750 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1751 ticker_insert_event_us(
demayer 0:6bf0743ece18 1752 &ticker_stub,
demayer 0:6bf0743ece18 1753 &events[i], timestamps[i], (uint32_t) &events[i]
demayer 0:6bf0743ece18 1754 );
demayer 0:6bf0743ece18 1755 }
demayer 0:6bf0743ece18 1756
demayer 0:6bf0743ece18 1757 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1758 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 1759 interface_stub.timestamp = timestamps[0];
demayer 0:6bf0743ece18 1760
demayer 0:6bf0743ece18 1761 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1762
demayer 0:6bf0743ece18 1763 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1764 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1765 TEST_ASSERT_EQUAL_UINT32(MBED_ARRAY_SIZE(timestamps), handler_called);
demayer 0:6bf0743ece18 1766 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1767 timestamps[MBED_ARRAY_SIZE(timestamps) - 1] + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1768 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1769 );
demayer 0:6bf0743ece18 1770 TEST_ASSERT_NULL(queue_stub.head);
demayer 0:6bf0743ece18 1771
demayer 0:6bf0743ece18 1772 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1773 }
demayer 0:6bf0743ece18 1774
demayer 0:6bf0743ece18 1775 /**
demayer 0:6bf0743ece18 1776 * Given an initialized ticker with two ticker event inserted scheduled from more
demayer 0:6bf0743ece18 1777 * than TIMESTAMP_MAX_DELTA from one another. The interface
demayer 0:6bf0743ece18 1778 * timestamp is equal to the timestamp of the first event.
demayer 0:6bf0743ece18 1779 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1780 * Then:
demayer 0:6bf0743ece18 1781 * - The IRQ handler should have been called for the first event.
demayer 0:6bf0743ece18 1782 * - The head of the queue should be set to the event after the first event.
demayer 0:6bf0743ece18 1783 * - The interrupt timestamp in the ticker interface should be scheduled in
demayer 0:6bf0743ece18 1784 * TIMESTAMP_MAX_DELTA.
demayer 0:6bf0743ece18 1785 */
demayer 0:6bf0743ece18 1786 static void test_irq_handler_multiple_event_single_dequeue_overflow()
demayer 0:6bf0743ece18 1787 {
demayer 0:6bf0743ece18 1788 const us_timestamp_t timestamps [] = {
demayer 0:6bf0743ece18 1789 10,
demayer 0:6bf0743ece18 1790 10 + TIMESTAMP_MAX_DELTA + 1
demayer 0:6bf0743ece18 1791 };
demayer 0:6bf0743ece18 1792
demayer 0:6bf0743ece18 1793 size_t handler_called = 0;
demayer 0:6bf0743ece18 1794 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1795 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1796 ++ (*((size_t*) id));
demayer 0:6bf0743ece18 1797 }
demayer 0:6bf0743ece18 1798 };
demayer 0:6bf0743ece18 1799
demayer 0:6bf0743ece18 1800 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1801 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1802
demayer 0:6bf0743ece18 1803 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1804
demayer 0:6bf0743ece18 1805 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1806 ticker_insert_event_us(
demayer 0:6bf0743ece18 1807 &ticker_stub,
demayer 0:6bf0743ece18 1808 &events[i], timestamps[i], (uint32_t) &handler_called
demayer 0:6bf0743ece18 1809 );
demayer 0:6bf0743ece18 1810 }
demayer 0:6bf0743ece18 1811
demayer 0:6bf0743ece18 1812 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1813 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 1814 interface_stub.timestamp = timestamps[0];
demayer 0:6bf0743ece18 1815
demayer 0:6bf0743ece18 1816 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1817
demayer 0:6bf0743ece18 1818 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1819 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1820 TEST_ASSERT_EQUAL_UINT32(1, handler_called);
demayer 0:6bf0743ece18 1821 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1822 timestamps[0] + TIMESTAMP_MAX_DELTA,
demayer 0:6bf0743ece18 1823 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1824 );
demayer 0:6bf0743ece18 1825 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head);
demayer 0:6bf0743ece18 1826
demayer 0:6bf0743ece18 1827 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1828 }
demayer 0:6bf0743ece18 1829
demayer 0:6bf0743ece18 1830 /**
demayer 0:6bf0743ece18 1831 * Given an initialized ticker with two ticker event inserted scheduled from less
demayer 0:6bf0743ece18 1832 * than TIMESTAMP_MAX_DELTA from one another. The interface
demayer 0:6bf0743ece18 1833 * timestamp is equal to the timestamp of the first event.
demayer 0:6bf0743ece18 1834 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1835 * Then:
demayer 0:6bf0743ece18 1836 * - The IRQ handler should have been called for the first event.
demayer 0:6bf0743ece18 1837 * - The head of the queue should be set to second event.
demayer 0:6bf0743ece18 1838 * - The interrupt timestamp in the ticker interface should be equal to the
demayer 0:6bf0743ece18 1839 * timestamp of the second event.
demayer 0:6bf0743ece18 1840 */
demayer 0:6bf0743ece18 1841 static void test_irq_handler_multiple_event_single_dequeue()
demayer 0:6bf0743ece18 1842 {
demayer 0:6bf0743ece18 1843 const us_timestamp_t timestamps [] = {
demayer 0:6bf0743ece18 1844 10,
demayer 0:6bf0743ece18 1845 10 + TIMESTAMP_MAX_DELTA - 1
demayer 0:6bf0743ece18 1846 };
demayer 0:6bf0743ece18 1847
demayer 0:6bf0743ece18 1848 size_t handler_called = 0;
demayer 0:6bf0743ece18 1849 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1850 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1851 ++ (*((size_t*) id));
demayer 0:6bf0743ece18 1852 }
demayer 0:6bf0743ece18 1853 };
demayer 0:6bf0743ece18 1854
demayer 0:6bf0743ece18 1855 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1856 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1857
demayer 0:6bf0743ece18 1858 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1859
demayer 0:6bf0743ece18 1860 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1861 ticker_insert_event_us(
demayer 0:6bf0743ece18 1862 &ticker_stub,
demayer 0:6bf0743ece18 1863 &events[i], timestamps[i], (uint32_t) &handler_called
demayer 0:6bf0743ece18 1864 );
demayer 0:6bf0743ece18 1865 }
demayer 0:6bf0743ece18 1866
demayer 0:6bf0743ece18 1867 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1868 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 1869 interface_stub.timestamp = timestamps[0];
demayer 0:6bf0743ece18 1870
demayer 0:6bf0743ece18 1871 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1872
demayer 0:6bf0743ece18 1873 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1874 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 1875 TEST_ASSERT_EQUAL_UINT32(1, handler_called);
demayer 0:6bf0743ece18 1876 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1877 timestamps[1],
demayer 0:6bf0743ece18 1878 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1879 );
demayer 0:6bf0743ece18 1880 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head);
demayer 0:6bf0743ece18 1881
demayer 0:6bf0743ece18 1882 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1883 }
demayer 0:6bf0743ece18 1884
demayer 0:6bf0743ece18 1885 /**
demayer 0:6bf0743ece18 1886 * Given an initialized ticker with multiple ticker event inserted and the
demayer 0:6bf0743ece18 1887 * interface timestamp is equal to the timestamp of the first event. The first
demayer 0:6bf0743ece18 1888 * event to execute will insert an events in the ticker which have to be executed
demayer 0:6bf0743ece18 1889 * immediately.
demayer 0:6bf0743ece18 1890 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1891 * Then:
demayer 0:6bf0743ece18 1892 * - The IRQ handler should have been called for the first event and the event
demayer 0:6bf0743ece18 1893 * inserted during irq.
demayer 0:6bf0743ece18 1894 * - The head of the queue should be set correctly.
demayer 0:6bf0743ece18 1895 * - The interrupt timestamp in the ticker interface should be equal to
demayer 0:6bf0743ece18 1896 * timestamp of the head event.
demayer 0:6bf0743ece18 1897 */
demayer 0:6bf0743ece18 1898 static void test_irq_handler_insert_immediate_in_irq()
demayer 0:6bf0743ece18 1899 {
demayer 0:6bf0743ece18 1900 static const us_timestamp_t timestamps [] = {
demayer 0:6bf0743ece18 1901 10,
demayer 0:6bf0743ece18 1902 10 + TIMESTAMP_MAX_DELTA - 1
demayer 0:6bf0743ece18 1903 };
demayer 0:6bf0743ece18 1904
demayer 0:6bf0743ece18 1905 static const us_timestamp_t expected_timestamp =
demayer 0:6bf0743ece18 1906 ((timestamps[1] - timestamps[0]) / 2) + timestamps[0];
demayer 0:6bf0743ece18 1907
demayer 0:6bf0743ece18 1908 struct ctrl_block_t {
demayer 0:6bf0743ece18 1909 bool irq_event_called;
demayer 0:6bf0743ece18 1910 ticker_event_t immediate_event;
demayer 0:6bf0743ece18 1911 size_t handler_called;
demayer 0:6bf0743ece18 1912 };
demayer 0:6bf0743ece18 1913
demayer 0:6bf0743ece18 1914 ctrl_block_t ctrl_block = { 0 };
demayer 0:6bf0743ece18 1915
demayer 0:6bf0743ece18 1916 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1917 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1918 ctrl_block_t* ctrl_block = (ctrl_block_t*) id;
demayer 0:6bf0743ece18 1919
demayer 0:6bf0743ece18 1920 if (ctrl_block->handler_called == 0) {
demayer 0:6bf0743ece18 1921 ticker_insert_event(
demayer 0:6bf0743ece18 1922 &ticker_stub,
demayer 0:6bf0743ece18 1923 &ctrl_block->immediate_event, expected_timestamp, id
demayer 0:6bf0743ece18 1924 );
demayer 0:6bf0743ece18 1925 interface_stub.timestamp = expected_timestamp;
demayer 0:6bf0743ece18 1926 } else if (ctrl_block->handler_called > 1) {
demayer 0:6bf0743ece18 1927 TEST_FAIL();
demayer 0:6bf0743ece18 1928 }
demayer 0:6bf0743ece18 1929 ++ctrl_block->handler_called;
demayer 0:6bf0743ece18 1930 }
demayer 0:6bf0743ece18 1931 };
demayer 0:6bf0743ece18 1932
demayer 0:6bf0743ece18 1933 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 1934 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1935
demayer 0:6bf0743ece18 1936 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 1937
demayer 0:6bf0743ece18 1938 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 1939 ticker_insert_event_us(
demayer 0:6bf0743ece18 1940 &ticker_stub,
demayer 0:6bf0743ece18 1941 &events[i], timestamps[i], (uint32_t) &ctrl_block
demayer 0:6bf0743ece18 1942 );
demayer 0:6bf0743ece18 1943 }
demayer 0:6bf0743ece18 1944
demayer 0:6bf0743ece18 1945 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 1946 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 1947 interface_stub.timestamp = timestamps[0];
demayer 0:6bf0743ece18 1948
demayer 0:6bf0743ece18 1949 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 1950
demayer 0:6bf0743ece18 1951 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 1952 TEST_ASSERT_EQUAL_UINT32(2, ctrl_block.handler_called);
demayer 0:6bf0743ece18 1953 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 1954 timestamps[1],
demayer 0:6bf0743ece18 1955 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 1956 );
demayer 0:6bf0743ece18 1957 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head);
demayer 0:6bf0743ece18 1958
demayer 0:6bf0743ece18 1959 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 1960 }
demayer 0:6bf0743ece18 1961
demayer 0:6bf0743ece18 1962 /**
demayer 0:6bf0743ece18 1963 * Given an initialized ticker with multiple ticker event inserted and the
demayer 0:6bf0743ece18 1964 * interface timestamp is equal to the timestamp of the first event. The first
demayer 0:6bf0743ece18 1965 * event to execute will insert an events in the ticker which does not have to
demayer 0:6bf0743ece18 1966 * be executed immediately.
demayer 0:6bf0743ece18 1967 * When ticker_irq_handler is called.
demayer 0:6bf0743ece18 1968 * Then:
demayer 0:6bf0743ece18 1969 * - The IRQ handler should have been called for the first event.
demayer 0:6bf0743ece18 1970 * - The head of the queue should be set to the event inserted in IRQ.
demayer 0:6bf0743ece18 1971 * - The interrupt timestamp in the ticker interface should be equal to
demayer 0:6bf0743ece18 1972 * timestamp of the head event.
demayer 0:6bf0743ece18 1973 */
demayer 0:6bf0743ece18 1974 static void test_irq_handler_insert_non_immediate_in_irq()
demayer 0:6bf0743ece18 1975 {
demayer 0:6bf0743ece18 1976 static const us_timestamp_t timestamps [] = {
demayer 0:6bf0743ece18 1977 10,
demayer 0:6bf0743ece18 1978 10 + TIMESTAMP_MAX_DELTA - 1
demayer 0:6bf0743ece18 1979 };
demayer 0:6bf0743ece18 1980
demayer 0:6bf0743ece18 1981 static const us_timestamp_t expected_timestamp =
demayer 0:6bf0743ece18 1982 ((timestamps[1] - timestamps[0]) / 2) + timestamps[0];
demayer 0:6bf0743ece18 1983
demayer 0:6bf0743ece18 1984 struct ctrl_block_t {
demayer 0:6bf0743ece18 1985 bool irq_event_called;
demayer 0:6bf0743ece18 1986 ticker_event_t non_immediate_event;
demayer 0:6bf0743ece18 1987 size_t handler_called;
demayer 0:6bf0743ece18 1988 };
demayer 0:6bf0743ece18 1989
demayer 0:6bf0743ece18 1990 ctrl_block_t ctrl_block = { 0 };
demayer 0:6bf0743ece18 1991
demayer 0:6bf0743ece18 1992 struct irq_handler_stub_t {
demayer 0:6bf0743ece18 1993 static void event_handler(uint32_t id) {
demayer 0:6bf0743ece18 1994 ctrl_block_t* ctrl_block = (ctrl_block_t*) id;
demayer 0:6bf0743ece18 1995
demayer 0:6bf0743ece18 1996 if (ctrl_block->handler_called == 0) {
demayer 0:6bf0743ece18 1997 ticker_insert_event(
demayer 0:6bf0743ece18 1998 &ticker_stub,
demayer 0:6bf0743ece18 1999 &ctrl_block->non_immediate_event, expected_timestamp, id
demayer 0:6bf0743ece18 2000 );
demayer 0:6bf0743ece18 2001 } else {
demayer 0:6bf0743ece18 2002 TEST_FAIL();
demayer 0:6bf0743ece18 2003 }
demayer 0:6bf0743ece18 2004 ++ctrl_block->handler_called;
demayer 0:6bf0743ece18 2005 }
demayer 0:6bf0743ece18 2006 };
demayer 0:6bf0743ece18 2007
demayer 0:6bf0743ece18 2008
demayer 0:6bf0743ece18 2009 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler);
demayer 0:6bf0743ece18 2010 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 2011
demayer 0:6bf0743ece18 2012 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
demayer 0:6bf0743ece18 2013
demayer 0:6bf0743ece18 2014 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
demayer 0:6bf0743ece18 2015 ticker_insert_event_us(
demayer 0:6bf0743ece18 2016 &ticker_stub,
demayer 0:6bf0743ece18 2017 &events[i], timestamps[i], (uint32_t) &ctrl_block
demayer 0:6bf0743ece18 2018 );
demayer 0:6bf0743ece18 2019 }
demayer 0:6bf0743ece18 2020
demayer 0:6bf0743ece18 2021 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 2022 interface_stub.clear_interrupt_call = 0;
demayer 0:6bf0743ece18 2023 interface_stub.timestamp = timestamps[0];
demayer 0:6bf0743ece18 2024
demayer 0:6bf0743ece18 2025 ticker_irq_handler(&ticker_stub);
demayer 0:6bf0743ece18 2026
demayer 0:6bf0743ece18 2027 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call);
demayer 0:6bf0743ece18 2028 TEST_ASSERT_EQUAL_UINT32(1, ctrl_block.handler_called);
demayer 0:6bf0743ece18 2029 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 2030 expected_timestamp,
demayer 0:6bf0743ece18 2031 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 2032 );
demayer 0:6bf0743ece18 2033 TEST_ASSERT_EQUAL_PTR(&ctrl_block.non_immediate_event, queue_stub.head);
demayer 0:6bf0743ece18 2034 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head->next);
demayer 0:6bf0743ece18 2035
demayer 0:6bf0743ece18 2036 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 2037 }
demayer 0:6bf0743ece18 2038
demayer 0:6bf0743ece18 2039 static uint32_t ticker_interface_stub_read_interrupt_time()
demayer 0:6bf0743ece18 2040 {
demayer 0:6bf0743ece18 2041 ++interface_stub.read_call;
demayer 0:6bf0743ece18 2042 // only if set interrupt call, to test the condition afterwards
demayer 0:6bf0743ece18 2043 if (interface_stub.set_interrupt_call) {
demayer 0:6bf0743ece18 2044 return interface_stub.interrupt_timestamp;
demayer 0:6bf0743ece18 2045 } else {
demayer 0:6bf0743ece18 2046 return interface_stub.timestamp;
demayer 0:6bf0743ece18 2047 }
demayer 0:6bf0743ece18 2048 }
demayer 0:6bf0743ece18 2049
demayer 0:6bf0743ece18 2050 /**
demayer 0:6bf0743ece18 2051 * Test to insert an event that is already in the past, the fire_interrupt should
demayer 0:6bf0743ece18 2052 * be invoked, instead of set_interrupt
demayer 0:6bf0743ece18 2053 */
demayer 0:6bf0743ece18 2054 static void test_set_interrupt_past_time()
demayer 0:6bf0743ece18 2055 {
demayer 0:6bf0743ece18 2056 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 2057
demayer 0:6bf0743ece18 2058 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 2059 interface_stub.fire_interrupt_call = 0;
demayer 0:6bf0743ece18 2060 interface_stub.timestamp = 0xFF;
demayer 0:6bf0743ece18 2061
demayer 0:6bf0743ece18 2062
demayer 0:6bf0743ece18 2063 // This tests fire now functinality when next_event_timestamp <= present
demayer 0:6bf0743ece18 2064 ticker_event_t event = { 0 };
demayer 0:6bf0743ece18 2065 const timestamp_t event_timestamp = interface_stub.timestamp;
demayer 0:6bf0743ece18 2066 const uint32_t id_last_event = 0xDEADDEAF;
demayer 0:6bf0743ece18 2067
demayer 0:6bf0743ece18 2068 ticker_insert_event(&ticker_stub, &event, event_timestamp, id_last_event);
demayer 0:6bf0743ece18 2069 TEST_ASSERT_EQUAL(0, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 2070 TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call);
demayer 0:6bf0743ece18 2071 }
demayer 0:6bf0743ece18 2072 /**
demayer 0:6bf0743ece18 2073 * Test to insert an event that is being delayed, set_interrupt is set
demayer 0:6bf0743ece18 2074 * but then event is already in the past, thus fire_interrupt should be invoked right-away
demayer 0:6bf0743ece18 2075 */
demayer 0:6bf0743ece18 2076 static void test_set_interrupt_past_time_with_delay()
demayer 0:6bf0743ece18 2077 {
demayer 0:6bf0743ece18 2078 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 2079
demayer 0:6bf0743ece18 2080 interface_stub.set_interrupt_call = 0;
demayer 0:6bf0743ece18 2081 interface_stub.fire_interrupt_call = 0;
demayer 0:6bf0743ece18 2082 interface_stub.timestamp = 0xFF;
demayer 0:6bf0743ece18 2083
demayer 0:6bf0743ece18 2084 // This tests fire now functionality when present time >= new_match_time
demayer 0:6bf0743ece18 2085 interface_stub.interface.read = ticker_interface_stub_read_interrupt_time;
demayer 0:6bf0743ece18 2086 ticker_event_t event = { 0 };
demayer 0:6bf0743ece18 2087 const timestamp_t event_timestamp = interface_stub.timestamp + 5;
demayer 0:6bf0743ece18 2088 const uint32_t id_last_event = 0xDEADDEAF;
demayer 0:6bf0743ece18 2089
demayer 0:6bf0743ece18 2090 ticker_insert_event(&ticker_stub, &event, event_timestamp, id_last_event);
demayer 0:6bf0743ece18 2091 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 2092 TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call);
demayer 0:6bf0743ece18 2093 }
demayer 0:6bf0743ece18 2094
demayer 0:6bf0743ece18 2095 /**
demayer 0:6bf0743ece18 2096 * Convert ticks at a given frequency to time in microseconds
demayer 0:6bf0743ece18 2097 *
demayer 0:6bf0743ece18 2098 * Assert if there is a 64-bit overflow
demayer 0:6bf0743ece18 2099 */
demayer 0:6bf0743ece18 2100 static uint64_t convert_to_us(uint64_t ticks, uint32_t frequency)
demayer 0:6bf0743ece18 2101 {
demayer 0:6bf0743ece18 2102 uint64_t scaled_ticks = ticks * 1000000;
demayer 0:6bf0743ece18 2103 // Assert that there was not an overflow
demayer 0:6bf0743ece18 2104 TEST_ASSERT_EQUAL(ticks, scaled_ticks / 1000000);
demayer 0:6bf0743ece18 2105 return scaled_ticks / frequency;
demayer 0:6bf0743ece18 2106 }
demayer 0:6bf0743ece18 2107
demayer 0:6bf0743ece18 2108 /**
demayer 0:6bf0743ece18 2109 * Given an uninitialized ticker instance and an interface of a
demayer 0:6bf0743ece18 2110 * certain frequency and bit width.
demayer 0:6bf0743ece18 2111 * Then the time returned the ticker should match the cumulative time.
demayer 0:6bf0743ece18 2112 */
demayer 0:6bf0743ece18 2113 void test_frequencies_and_masks(uint32_t frequency, uint32_t bits)
demayer 0:6bf0743ece18 2114 {
demayer 0:6bf0743ece18 2115 const uint32_t bitmask = ((uint64_t)1 << bits) - 1;
demayer 0:6bf0743ece18 2116
demayer 0:6bf0743ece18 2117 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 2118 uint64_t ticks = 0;
demayer 0:6bf0743ece18 2119
demayer 0:6bf0743ece18 2120 // Single tick
demayer 0:6bf0743ece18 2121 ticks += 1;
demayer 0:6bf0743ece18 2122 interface_stub.timestamp = ticks & bitmask;
demayer 0:6bf0743ece18 2123 TEST_ASSERT_EQUAL_UINT32(convert_to_us(ticks, frequency), ticker_read(&ticker_stub));
demayer 0:6bf0743ece18 2124 TEST_ASSERT_EQUAL_UINT64(convert_to_us(ticks, frequency), ticker_read_us(&ticker_stub));
demayer 0:6bf0743ece18 2125
demayer 0:6bf0743ece18 2126 // Run until the loop before 64-bit overflow (worst case with frequency=1hz, bits=32)
demayer 0:6bf0743ece18 2127 for (unsigned int k = 0; k < 4294; k++) {
demayer 0:6bf0743ece18 2128
demayer 0:6bf0743ece18 2129 // Largest value possible tick
demayer 0:6bf0743ece18 2130 ticks += ((uint64_t)1 << bits) - 1;
demayer 0:6bf0743ece18 2131 interface_stub.timestamp = ticks & bitmask;
demayer 0:6bf0743ece18 2132 TEST_ASSERT_EQUAL_UINT32(convert_to_us(ticks, frequency), ticker_read(&ticker_stub));
demayer 0:6bf0743ece18 2133 TEST_ASSERT_EQUAL_UINT64(convert_to_us(ticks, frequency), ticker_read_us(&ticker_stub));
demayer 0:6bf0743ece18 2134 }
demayer 0:6bf0743ece18 2135 }
demayer 0:6bf0743ece18 2136
demayer 0:6bf0743ece18 2137 /**
demayer 0:6bf0743ece18 2138 * Given an uninitialized ticker_data instance.
demayer 0:6bf0743ece18 2139 * When the ticker is initialized
demayer 0:6bf0743ece18 2140 * Then:
demayer 0:6bf0743ece18 2141 * - The internal ticker timestamp should be zero
demayer 0:6bf0743ece18 2142 * - interrupt should be scheduled in current (timestamp +
demayer 0:6bf0743ece18 2143 * TIMESTAMP_MAX_DELTA_BITS(bitwidth)) % modval
demayer 0:6bf0743ece18 2144 * - The queue should not contains any event
demayer 0:6bf0743ece18 2145 */
demayer 0:6bf0743ece18 2146 static void test_ticker_max_value()
demayer 0:6bf0743ece18 2147 {
demayer 0:6bf0743ece18 2148 for (int bitwidth = 8; bitwidth <= 32; bitwidth++) {
demayer 0:6bf0743ece18 2149 const uint64_t modval = 1ULL << bitwidth;
demayer 0:6bf0743ece18 2150
demayer 0:6bf0743ece18 2151 // setup of the stub
demayer 0:6bf0743ece18 2152 reset_ticker_stub();
demayer 0:6bf0743ece18 2153 interface_info_stub.bits = bitwidth;
demayer 0:6bf0743ece18 2154 interface_stub.timestamp = 0xBA;
demayer 0:6bf0743ece18 2155
demayer 0:6bf0743ece18 2156 ticker_set_handler(&ticker_stub, NULL);
demayer 0:6bf0743ece18 2157
demayer 0:6bf0743ece18 2158 TEST_ASSERT_EQUAL_UINT64(0, queue_stub.present_time);
demayer 0:6bf0743ece18 2159 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
demayer 0:6bf0743ece18 2160 TEST_ASSERT_EQUAL_UINT32(
demayer 0:6bf0743ece18 2161 (interface_stub.timestamp + TIMESTAMP_MAX_DELTA_BITS(bitwidth)) % modval,
demayer 0:6bf0743ece18 2162 interface_stub.interrupt_timestamp
demayer 0:6bf0743ece18 2163 );
demayer 0:6bf0743ece18 2164 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head);
demayer 0:6bf0743ece18 2165 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
demayer 0:6bf0743ece18 2166 }
demayer 0:6bf0743ece18 2167 }
demayer 0:6bf0743ece18 2168
demayer 0:6bf0743ece18 2169 /**
demayer 0:6bf0743ece18 2170 * Check that _ticker_match_interval_passed correctly detects matches
demayer 0:6bf0743ece18 2171 *
demayer 0:6bf0743ece18 2172 * Brute force test that _ticker_match_interval_passed returns the correct match value
demayer 0:6bf0743ece18 2173 * for all cominations of values within a small range.
demayer 0:6bf0743ece18 2174 */
demayer 0:6bf0743ece18 2175 static void test_match_interval_passed()
demayer 0:6bf0743ece18 2176 {
demayer 0:6bf0743ece18 2177
demayer 0:6bf0743ece18 2178 for (int modval = 1; modval <= 5; modval++) {
demayer 0:6bf0743ece18 2179 for (int prev = 0; prev < modval; prev++) {
demayer 0:6bf0743ece18 2180 for (int cur = 0; cur < modval; cur++) {
demayer 0:6bf0743ece18 2181 for (int match = 0; match < modval; match++) {
demayer 0:6bf0743ece18 2182 uint32_t delta = (cur - prev) % modval;
demayer 0:6bf0743ece18 2183 uint32_t delta_to_match = (match - prev) % modval;
demayer 0:6bf0743ece18 2184 bool match_expected = false;
demayer 0:6bf0743ece18 2185 if (delta_to_match) {
demayer 0:6bf0743ece18 2186 match_expected = delta >= delta_to_match;
demayer 0:6bf0743ece18 2187 }
demayer 0:6bf0743ece18 2188
demayer 0:6bf0743ece18 2189 // Sanity checks
demayer 0:6bf0743ece18 2190 if (prev == cur) {
demayer 0:6bf0743ece18 2191 // No time has passed
demayer 0:6bf0743ece18 2192 TEST_ASSERT_EQUAL(false, match_expected);
demayer 0:6bf0743ece18 2193 } else if (match == prev) {
demayer 0:6bf0743ece18 2194 // Match can't occur without an overflow occurring
demayer 0:6bf0743ece18 2195 TEST_ASSERT_EQUAL(false, match_expected);
demayer 0:6bf0743ece18 2196 } else if (cur == match) {
demayer 0:6bf0743ece18 2197 // All other cases where cur == match a match should be expected
demayer 0:6bf0743ece18 2198 TEST_ASSERT_EQUAL(true, match_expected);
demayer 0:6bf0743ece18 2199 }
demayer 0:6bf0743ece18 2200
demayer 0:6bf0743ece18 2201 // Actual test
demayer 0:6bf0743ece18 2202 TEST_ASSERT_EQUAL(match_expected, _ticker_match_interval_passed(prev, cur, match));
demayer 0:6bf0743ece18 2203 }
demayer 0:6bf0743ece18 2204 }
demayer 0:6bf0743ece18 2205 }
demayer 0:6bf0743ece18 2206 }
demayer 0:6bf0743ece18 2207 }
demayer 0:6bf0743ece18 2208
demayer 0:6bf0743ece18 2209 typedef struct {
demayer 0:6bf0743ece18 2210 timestamp_t prev;
demayer 0:6bf0743ece18 2211 timestamp_t cur;
demayer 0:6bf0743ece18 2212 timestamp_t match;
demayer 0:6bf0743ece18 2213 bool result;
demayer 0:6bf0743ece18 2214 } match_interval_entry_t;
demayer 0:6bf0743ece18 2215
demayer 0:6bf0743ece18 2216 /**
demayer 0:6bf0743ece18 2217 * Check that _ticker_match_interval_passed correctly detects matches
demayer 0:6bf0743ece18 2218 *
demayer 0:6bf0743ece18 2219 * Use a table of pre-computed values to check that _ticker_match_interval_passed
demayer 0:6bf0743ece18 2220 * returns the correct match value.
demayer 0:6bf0743ece18 2221 */
demayer 0:6bf0743ece18 2222 static void test_match_interval_passed_table()
demayer 0:6bf0743ece18 2223 {
demayer 0:6bf0743ece18 2224 static const match_interval_entry_t test_values[] = {
demayer 0:6bf0743ece18 2225 /* prev, cur, match, result */
demayer 0:6bf0743ece18 2226 {0x00000000, 0x00000000, 0x00000000, false},
demayer 0:6bf0743ece18 2227 {0x00000000, 0x00000000, 0xffffffff, false},
demayer 0:6bf0743ece18 2228 {0x00000000, 0x00000000, 0x00000001, false},
demayer 0:6bf0743ece18 2229 {0x00000000, 0xffffffff, 0x00000000, false},
demayer 0:6bf0743ece18 2230 {0x00000000, 0x00000001, 0x00000000, false},
demayer 0:6bf0743ece18 2231 {0xffffffff, 0x00000000, 0x00000000, true},
demayer 0:6bf0743ece18 2232 {0x00000001, 0x00000000, 0x00000000, true},
demayer 0:6bf0743ece18 2233 {0x00005555, 0x00005555, 0x00005555, false},
demayer 0:6bf0743ece18 2234 {0x00005555, 0x00005555, 0x00005554, false},
demayer 0:6bf0743ece18 2235 {0x00005555, 0x00005555, 0x00005556, false},
demayer 0:6bf0743ece18 2236 {0x00005555, 0x00005554, 0x00005555, false},
demayer 0:6bf0743ece18 2237 {0x00005555, 0x00005556, 0x00005555, false},
demayer 0:6bf0743ece18 2238 {0x00005554, 0x00005555, 0x00005555, true},
demayer 0:6bf0743ece18 2239 {0x00005556, 0x00005555, 0x00005555, true},
demayer 0:6bf0743ece18 2240 {0xffffffff, 0xffffffff, 0xffffffff, false},
demayer 0:6bf0743ece18 2241 {0xffffffff, 0xffffffff, 0xfffffffe, false},
demayer 0:6bf0743ece18 2242 {0xffffffff, 0xffffffff, 0x00000000, false},
demayer 0:6bf0743ece18 2243 {0xffffffff, 0xfffffffe, 0xffffffff, false},
demayer 0:6bf0743ece18 2244 {0xffffffff, 0x00000000, 0xffffffff, false},
demayer 0:6bf0743ece18 2245 {0xfffffffe, 0xffffffff, 0xffffffff, true},
demayer 0:6bf0743ece18 2246 {0x00000000, 0xffffffff, 0xffffffff, true},
demayer 0:6bf0743ece18 2247 };
demayer 0:6bf0743ece18 2248 for (int i = 0; i < MBED_ARRAY_SIZE(test_values); i++) {
demayer 0:6bf0743ece18 2249 const uint32_t prev = test_values[i].prev;
demayer 0:6bf0743ece18 2250 const uint32_t cur = test_values[i].cur;
demayer 0:6bf0743ece18 2251 const uint32_t match = test_values[i].match;
demayer 0:6bf0743ece18 2252 const uint32_t result = test_values[i].result;
demayer 0:6bf0743ece18 2253 TEST_ASSERT_EQUAL(result, _ticker_match_interval_passed(prev, cur, match));
demayer 0:6bf0743ece18 2254 }
demayer 0:6bf0743ece18 2255 }
demayer 0:6bf0743ece18 2256
demayer 0:6bf0743ece18 2257 static const case_t cases[] = {
demayer 0:6bf0743ece18 2258 MAKE_TEST_CASE("ticker initialization", test_ticker_initialization),
demayer 0:6bf0743ece18 2259 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2260 "ticker multiple initialization", test_ticker_re_initialization
demayer 0:6bf0743ece18 2261 ),
demayer 0:6bf0743ece18 2262 MAKE_TEST_CASE("ticker read", test_ticker_read),
demayer 0:6bf0743ece18 2263 MAKE_TEST_CASE("ticker read overflow", test_ticker_read_overflow),
demayer 0:6bf0743ece18 2264 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2265 "legacy insert event outside overflow range",
demayer 0:6bf0743ece18 2266 test_legacy_insert_event_outside_overflow_range
demayer 0:6bf0743ece18 2267 ),
demayer 0:6bf0743ece18 2268 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2269 "legacy insert event in overflow range",
demayer 0:6bf0743ece18 2270 test_legacy_insert_event_in_overflow_range
demayer 0:6bf0743ece18 2271 ),
demayer 0:6bf0743ece18 2272 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2273 "legacy insert event overflow", test_legacy_insert_event_overflow
demayer 0:6bf0743ece18 2274 ),
demayer 0:6bf0743ece18 2275 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2276 "legacy insert event head", test_legacy_insert_event_head
demayer 0:6bf0743ece18 2277 ),
demayer 0:6bf0743ece18 2278 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2279 "legacy insert event tail", test_legacy_insert_event_tail
demayer 0:6bf0743ece18 2280 ),
demayer 0:6bf0743ece18 2281 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2282 "legacy insert event multiple overflow",
demayer 0:6bf0743ece18 2283 test_legacy_insert_event_multiple_overflow
demayer 0:6bf0743ece18 2284 ),
demayer 0:6bf0743ece18 2285 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2286 "test_legacy_insert_event_multiple_random",
demayer 0:6bf0743ece18 2287 test_legacy_insert_event_multiple_random
demayer 0:6bf0743ece18 2288 ),
demayer 0:6bf0743ece18 2289 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2290 "test_insert_event_us_outside_overflow_range",
demayer 0:6bf0743ece18 2291 test_insert_event_us_outside_overflow_range
demayer 0:6bf0743ece18 2292 ),
demayer 0:6bf0743ece18 2293 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2294 "test_insert_event_us_in_overflow_range",
demayer 0:6bf0743ece18 2295 test_insert_event_us_in_overflow_range
demayer 0:6bf0743ece18 2296 ),
demayer 0:6bf0743ece18 2297 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2298 "test_insert_event_us_underflow", test_insert_event_us_underflow
demayer 0:6bf0743ece18 2299 ),
demayer 0:6bf0743ece18 2300 MAKE_TEST_CASE("test_insert_event_us_head", test_insert_event_us_head),
demayer 0:6bf0743ece18 2301 MAKE_TEST_CASE("test_insert_event_us_tail", test_insert_event_us_tail),
demayer 0:6bf0743ece18 2302 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2303 "test_insert_event_us_multiple_random",
demayer 0:6bf0743ece18 2304 test_insert_event_us_multiple_random
demayer 0:6bf0743ece18 2305 ),
demayer 0:6bf0743ece18 2306 MAKE_TEST_CASE("test_remove_event_tail", test_remove_event_tail),
demayer 0:6bf0743ece18 2307 MAKE_TEST_CASE("test_remove_event_head", test_remove_event_head),
demayer 0:6bf0743ece18 2308 MAKE_TEST_CASE("test_remove_event_invalid", test_remove_event_invalid),
demayer 0:6bf0743ece18 2309 MAKE_TEST_CASE("test_remove_random", test_remove_random),
demayer 0:6bf0743ece18 2310 MAKE_TEST_CASE("update overflow guard", test_overflow_event_update),
demayer 0:6bf0743ece18 2311 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2312 "update overflow guard in case of spurious interrupt",
demayer 0:6bf0743ece18 2313 test_overflow_event_update_when_spurious_interrupt
demayer 0:6bf0743ece18 2314 ),
demayer 0:6bf0743ece18 2315 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2316 "test_irq_handler_single_event", test_irq_handler_single_event
demayer 0:6bf0743ece18 2317 ),
demayer 0:6bf0743ece18 2318 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2319 "test_irq_handler_single_event_spurious",
demayer 0:6bf0743ece18 2320 test_irq_handler_single_event_spurious
demayer 0:6bf0743ece18 2321 ),
demayer 0:6bf0743ece18 2322 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2323 "test_irq_handler_multiple_event_multiple_dequeue",
demayer 0:6bf0743ece18 2324 test_irq_handler_multiple_event_multiple_dequeue
demayer 0:6bf0743ece18 2325 ),
demayer 0:6bf0743ece18 2326 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2327 "test_irq_handler_multiple_event_single_dequeue_overflow",
demayer 0:6bf0743ece18 2328 test_irq_handler_multiple_event_single_dequeue_overflow
demayer 0:6bf0743ece18 2329 ),
demayer 0:6bf0743ece18 2330 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2331 "test_irq_handler_multiple_event_single_dequeue",
demayer 0:6bf0743ece18 2332 test_irq_handler_multiple_event_single_dequeue
demayer 0:6bf0743ece18 2333 ),
demayer 0:6bf0743ece18 2334 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2335 "test_irq_handler_insert_immediate_in_irq",
demayer 0:6bf0743ece18 2336 test_irq_handler_insert_immediate_in_irq
demayer 0:6bf0743ece18 2337 ),
demayer 0:6bf0743ece18 2338 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2339 "test_irq_handler_insert_non_immediate_in_irq",
demayer 0:6bf0743ece18 2340 test_irq_handler_insert_non_immediate_in_irq
demayer 0:6bf0743ece18 2341 ),
demayer 0:6bf0743ece18 2342 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2343 "test_set_interrupt_past_time",
demayer 0:6bf0743ece18 2344 test_set_interrupt_past_time
demayer 0:6bf0743ece18 2345 ),
demayer 0:6bf0743ece18 2346 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2347 "test_set_interrupt_past_time_with_delay",
demayer 0:6bf0743ece18 2348 test_set_interrupt_past_time_with_delay
demayer 0:6bf0743ece18 2349 ),
demayer 0:6bf0743ece18 2350 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2351 "test_frequencies_and_masks",
demayer 0:6bf0743ece18 2352 test_over_frequency_and_width<test_frequencies_and_masks>
demayer 0:6bf0743ece18 2353 ),
demayer 0:6bf0743ece18 2354 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2355 "test_ticker_max_value",
demayer 0:6bf0743ece18 2356 test_ticker_max_value
demayer 0:6bf0743ece18 2357 ),
demayer 0:6bf0743ece18 2358 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2359 "test_match_interval_passed",
demayer 0:6bf0743ece18 2360 test_match_interval_passed
demayer 0:6bf0743ece18 2361 ),
demayer 0:6bf0743ece18 2362 MAKE_TEST_CASE(
demayer 0:6bf0743ece18 2363 "test_match_interval_passed_table",
demayer 0:6bf0743ece18 2364 test_match_interval_passed_table
demayer 0:6bf0743ece18 2365 )
demayer 0:6bf0743ece18 2366 };
demayer 0:6bf0743ece18 2367
demayer 0:6bf0743ece18 2368 static utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
demayer 0:6bf0743ece18 2369 {
demayer 0:6bf0743ece18 2370 GREENTEA_SETUP(60, "default_auto");
demayer 0:6bf0743ece18 2371 return verbose_test_setup_handler(number_of_cases);
demayer 0:6bf0743ece18 2372 }
demayer 0:6bf0743ece18 2373
demayer 0:6bf0743ece18 2374 int main()
demayer 0:6bf0743ece18 2375 {
demayer 0:6bf0743ece18 2376 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
demayer 0:6bf0743ece18 2377 return !Harness::run(specification);
demayer 0:6bf0743ece18 2378 }