mbed library sources

Dependents:   bare

Fork of mbed-src by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers us_ticker_api.c Source File

us_ticker_api.c

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include <stddef.h>
00017 #include "us_ticker_api.h"
00018 #include "cmsis.h"
00019 
00020 static ticker_event_handler event_handler;
00021 static ticker_event_t *head = NULL;
00022 
00023 void us_ticker_set_handler(ticker_event_handler handler) {
00024     us_ticker_init();
00025     
00026     event_handler = handler;
00027 }
00028 
00029 void us_ticker_irq_handler(void) {
00030     us_ticker_clear_interrupt();
00031     
00032     /* Go through all the pending TimerEvents */
00033     while (1) {
00034         if (head == NULL) {
00035             // There are no more TimerEvents left, so disable matches.
00036             us_ticker_disable_interrupt();
00037             return;
00038         }
00039         
00040         if ((int)(head->timestamp - us_ticker_read()) <= 0) {
00041             // This event was in the past:
00042             //      point to the following one and execute its handler
00043             ticker_event_t *p = head;
00044             head = head->next;
00045             if (event_handler != NULL) {
00046                 event_handler(p->id); // NOTE: the handler can set new events
00047             }
00048         } else {
00049             // This event and the following ones in the list are in the future:
00050             //      set it as next interrupt and return
00051             us_ticker_set_interrupt(head->timestamp);
00052             return;
00053         }
00054     }
00055 }
00056 
00057 void us_ticker_insert_event(ticker_event_t *obj, unsigned int timestamp, uint32_t id) {
00058     /* disable interrupts for the duration of the function */
00059     __disable_irq();
00060     
00061     // initialise our data
00062     obj->timestamp = timestamp;
00063     obj->id = id;
00064     
00065     /* Go through the list until we either reach the end, or find
00066        an element this should come before (which is possibly the
00067        head). */
00068     ticker_event_t *prev = NULL, *p = head;
00069     while (p != NULL) {
00070         /* check if we come before p */
00071         if ((int)(timestamp - p->timestamp) <= 0) {
00072             break;
00073         }
00074         /* go to the next element */
00075         prev = p;
00076         p = p->next;
00077     }
00078     /* if prev is NULL we're at the head */
00079     if (prev == NULL) {
00080         head = obj;
00081         us_ticker_set_interrupt(timestamp);
00082     } else {
00083         prev->next = obj;
00084     }
00085     /* if we're at the end p will be NULL, which is correct */
00086     obj->next = p;
00087     
00088     __enable_irq();
00089 }
00090 
00091 void us_ticker_remove_event(ticker_event_t *obj) {
00092     __disable_irq();
00093     
00094     // remove this object from the list
00095     if (head == obj) {
00096         // first in the list, so just drop me
00097         head = obj->next;
00098         if (obj->next != NULL) {
00099             us_ticker_set_interrupt(head->timestamp);
00100         }
00101     } else {
00102         // find the object before me, then drop me
00103         ticker_event_t* p = head;
00104         while (p != NULL) {
00105             if (p->next == obj) {
00106                 p->next = obj->next;
00107                 break;
00108             }
00109             p = p->next;
00110         }
00111     }
00112     
00113     __enable_irq();
00114 }