mbed-dev-f303

Committer:
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4
Date:
Tue Jun 14 09:21:18 2022 +0000
Revision:
0:bdf663c61a82
lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 1 /* mbed Microcontroller Library
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 2 * Copyright (c) 2015 ARM Limited
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 3 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 4 * Licensed under the Apache License, Version 2.0 (the "License");
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 5 * you may not use this file except in compliance with the License.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 6 * You may obtain a copy of the License at
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 7 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 8 * http://www.apache.org/licenses/LICENSE-2.0
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 9 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 10 * Unless required by applicable law or agreed to in writing, software
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 11 * distributed under the License is distributed on an "AS IS" BASIS,
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 13 * See the License for the specific language governing permissions and
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 14 * limitations under the License.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 15 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 16 #include <stdio.h>
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 17 #include <stddef.h>
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 18 #include "hal/ticker_api.h"
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 19 #include "platform/mbed_critical.h"
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 20
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 21 static void schedule_interrupt(const ticker_data_t *const ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 22 static void update_present_time(const ticker_data_t *const ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 23
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 24 /*
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 25 * Initialize a ticker instance.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 26 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 27 static void initialize(const ticker_data_t *ticker)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 28 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 29 // return if the queue has already been initialized, in that case the
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 30 // interface used by the queue is already initialized.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 31 if (ticker->queue->initialized) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 32 return;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 33 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 34
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 35 ticker->interface->init();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 36
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 37 ticker->queue->event_handler = NULL;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 38 ticker->queue->head = NULL;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 39 ticker->queue->present_time = 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 40 ticker->queue->initialized = true;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 41
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 42 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 43 schedule_interrupt(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 44 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 45
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 46 /**
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 47 * Set the event handler function of a ticker instance.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 48 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 49 static void set_handler(const ticker_data_t *const ticker, ticker_event_handler handler)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 50 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 51 ticker->queue->event_handler = handler;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 52 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 53
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 54 /*
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 55 * Convert a 32 bit timestamp into a 64 bit timestamp.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 56 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 57 * A 64 bit timestamp is used as the point of time of reference while the
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 58 * timestamp to convert is relative to this point of time.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 59 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 60 * The lower 32 bits of the timestamp returned will be equal to the timestamp to
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 61 * convert.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 62 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 63 * If the timestamp to convert is less than the lower 32 bits of the time
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 64 * reference then the timestamp to convert is seen as an overflowed value and
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 65 * the upper 32 bit of the timestamp returned will be equal to the upper 32 bit
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 66 * of the reference point + 1.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 67 * Otherwise, the upper 32 bit returned will be equal to the upper 32 bit of the
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 68 * reference point.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 69 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 70 * @param ref: The 64 bit timestamp of reference.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 71 * @param timestamp: The timestamp to convert.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 72 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 73 static us_timestamp_t convert_timestamp(us_timestamp_t ref, timestamp_t timestamp)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 74 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 75 bool overflow = timestamp < ((timestamp_t) ref) ? true : false;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 76
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 77 us_timestamp_t result = (ref & ~((us_timestamp_t)UINT32_MAX)) | timestamp;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 78 if (overflow) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 79 result += (1ULL<<32);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 80 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 81
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 82 return result;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 83 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 84
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 85 /**
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 86 * Update the present timestamp value of a ticker.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 87 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 88 static void update_present_time(const ticker_data_t *const ticker)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 89 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 90 ticker->queue->present_time = convert_timestamp(
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 91 ticker->queue->present_time,
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 92 ticker->interface->read()
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 93 );
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 94 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 95
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 96 /**
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 97 * Compute the time when the interrupt has to be triggered and schedule it.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 98 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 99 * If there is no event in the queue or the next event to execute is in more
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 100 * than MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA us from now then the ticker
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 101 * irq will be scheduled in MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA us.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 102 * Otherwise the irq will be scheduled to happen when the running counter reach
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 103 * the timestamp of the first event in the queue.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 104 *
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 105 * @note If there is no event in the queue then the interrupt is scheduled to
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 106 * in MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA. This is necessary to keep track
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 107 * of the timer overflow.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 108 */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 109 static void schedule_interrupt(const ticker_data_t *const ticker)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 110 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 111 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 112 uint32_t relative_timeout = MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 113
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 114 if (ticker->queue->head) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 115 us_timestamp_t present = ticker->queue->present_time;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 116 us_timestamp_t next_event_timestamp = ticker->queue->head->timestamp;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 117
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 118 // if the event at the head of the queue is in the past then schedule
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 119 // it immediately.
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 120 if (next_event_timestamp <= present) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 121 ticker->interface->fire_interrupt();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 122 return;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 123 } else if ((next_event_timestamp - present) < MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 124 relative_timeout = next_event_timestamp - present;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 125 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 126 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 127
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 128 us_timestamp_t new_match_time = ticker->queue->present_time + relative_timeout;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 129 ticker->interface->set_interrupt(new_match_time);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 130 // there could be a delay, reread the time, check if it was set in the past
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 131 // As result, if it is already in the past, we fire it immediately
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 132 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 133 us_timestamp_t present = ticker->queue->present_time;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 134 if (present >= new_match_time) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 135 ticker->interface->fire_interrupt();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 136 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 137 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 138
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 139 void ticker_set_handler(const ticker_data_t *const ticker, ticker_event_handler handler)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 140 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 141 initialize(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 142 set_handler(ticker, handler);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 143 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 144
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 145 void ticker_irq_handler(const ticker_data_t *const ticker)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 146 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 147 ticker->interface->clear_interrupt();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 148
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 149 /* Go through all the pending TimerEvents */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 150 while (1) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 151 if (ticker->queue->head == NULL) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 152 break;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 153 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 154
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 155 // update the current timestamp used by the queue
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 156 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 157
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 158 if (ticker->queue->head->timestamp <= ticker->queue->present_time) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 159 // This event was in the past:
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 160 // point to the following one and execute its handler
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 161 ticker_event_t *p = ticker->queue->head;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 162 ticker->queue->head = ticker->queue->head->next;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 163 if (ticker->queue->event_handler != NULL) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 164 (*ticker->queue->event_handler)(p->id); // NOTE: the handler can set new events
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 165 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 166 /* Note: We continue back to examining the head because calling the
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 167 * event handler may have altered the chain of pending events. */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 168 } else {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 169 break;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 170 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 171 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 172
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 173 schedule_interrupt(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 174 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 175
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 176 void ticker_insert_event(const ticker_data_t *const ticker, ticker_event_t *obj, timestamp_t timestamp, uint32_t id)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 177 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 178 core_util_critical_section_enter();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 179
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 180 // update the current timestamp
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 181 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 182 us_timestamp_t absolute_timestamp = convert_timestamp(
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 183 ticker->queue->present_time,
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 184 timestamp
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 185 );
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 186 core_util_critical_section_exit();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 187
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 188 // defer to ticker_insert_event_us
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 189 ticker_insert_event_us(
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 190 ticker,
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 191 obj, absolute_timestamp, id
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 192 );
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 193 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 194
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 195 void ticker_insert_event_us(const ticker_data_t *const ticker, ticker_event_t *obj, us_timestamp_t timestamp, uint32_t id)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 196 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 197 core_util_critical_section_enter();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 198
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 199 // update the current timestamp
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 200 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 201
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 202 // initialise our data
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 203 obj->timestamp = timestamp;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 204 obj->id = id;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 205
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 206 /* Go through the list until we either reach the end, or find
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 207 an element this should come before (which is possibly the
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 208 head). */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 209 ticker_event_t *prev = NULL, *p = ticker->queue->head;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 210 while (p != NULL) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 211 /* check if we come before p */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 212 if (timestamp < p->timestamp) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 213 break;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 214 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 215 /* go to the next element */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 216 prev = p;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 217 p = p->next;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 218 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 219
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 220 /* if we're at the end p will be NULL, which is correct */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 221 obj->next = p;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 222
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 223 /* if prev is NULL we're at the head */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 224 if (prev == NULL) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 225 ticker->queue->head = obj;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 226 } else {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 227 prev->next = obj;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 228 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 229
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 230 schedule_interrupt(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 231
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 232 core_util_critical_section_exit();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 233 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 234
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 235 void ticker_remove_event(const ticker_data_t *const ticker, ticker_event_t *obj)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 236 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 237 core_util_critical_section_enter();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 238
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 239 // remove this object from the list
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 240 if (ticker->queue->head == obj) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 241 // first in the list, so just drop me
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 242 ticker->queue->head = obj->next;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 243 schedule_interrupt(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 244 } else {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 245 // find the object before me, then drop me
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 246 ticker_event_t* p = ticker->queue->head;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 247 while (p != NULL) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 248 if (p->next == obj) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 249 p->next = obj->next;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 250 break;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 251 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 252 p = p->next;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 253 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 254 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 255
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 256 core_util_critical_section_exit();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 257 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 258
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 259 timestamp_t ticker_read(const ticker_data_t *const ticker)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 260 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 261 return ticker_read_us(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 262 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 263
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 264 us_timestamp_t ticker_read_us(const ticker_data_t *const ticker)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 265 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 266 initialize(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 267 update_present_time(ticker);
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 268 return ticker->queue->present_time;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 269 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 270
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 271 int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp)
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 272 {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 273 int ret = 0;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 274
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 275 /* if head is NULL, there are no pending events */
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 276 core_util_critical_section_enter();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 277 if (data->queue->head != NULL) {
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 278 *timestamp = data->queue->head->timestamp;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 279 ret = 1;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 280 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 281 core_util_critical_section_exit();
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 282
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 283 return ret;
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 284 }
abe5b02d-a2d4-4fe9-818e-c4e57c809ea4 0:bdf663c61a82 285