Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

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