joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers timeout.c Source File

timeout.c

00001 /*
00002  * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * 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, WITHOUT
00012  * 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 "eventOS_event.h"
00017 #include "eventOS_event_timer.h"
00018 #include "nsdynmemLIB.h"
00019 #include "ns_list.h"
00020 
00021 #define STARTUP_EVENT 0
00022 #define TIMER_EVENT 1
00023 
00024 // Timeout structure, already typedefed to timeout_t
00025 struct timeout_entry_t {
00026     void (*callback)(void *);
00027     void *arg;
00028     uint8_t event_id;
00029     ns_list_link_t link;
00030 };
00031 
00032 static NS_LIST_HEAD(timeout_t, link) timeout_list = NS_LIST_INIT(timeout_list);
00033 static int8_t timeout_tasklet_id = -1;
00034 
00035 static void timeout_tasklet(arm_event_s *event)
00036 {
00037     if (TIMER_EVENT != event->event_type) {
00038         return;
00039     }
00040 
00041     timeout_t *found = NULL;
00042     ns_list_foreach_safe(timeout_t, cur, &timeout_list) {
00043         if (cur->event_id == event->event_id) {
00044             found = cur;
00045             ns_list_remove(&timeout_list, cur);
00046             break;
00047         }
00048     }
00049 
00050     if (found) {
00051         found->callback(found->arg);
00052         ns_dyn_mem_free(found);
00053     }
00054 }
00055 
00056 timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg)
00057 {
00058     uint16_t count;
00059     uint8_t index;
00060     timeout_t *e = ns_dyn_mem_alloc(sizeof(timeout_t));
00061     if (!e) {
00062         return NULL;
00063     }
00064     e->callback = callback;
00065     e->arg = arg;
00066 
00067     // Start timeout taskled if it is not running
00068     if (-1 == timeout_tasklet_id) {
00069         timeout_tasklet_id = eventOS_event_handler_create(timeout_tasklet, STARTUP_EVENT);
00070         if (timeout_tasklet_id < 0) {
00071             timeout_tasklet_id = -1;
00072             goto FAIL;
00073         }
00074     }
00075 
00076     // Check that we still have indexes left. We have only 8bit timer id.
00077     count = ns_list_count(&timeout_list);
00078     if (count >= UINT8_MAX) { // Too big list, timer_id is uint8_t
00079         goto FAIL;
00080     }
00081 
00082     // Find next free index
00083     index = 0;
00084 AGAIN:
00085     ns_list_foreach(timeout_t, cur, &timeout_list) {
00086         if (cur->event_id == index) { // This index was used
00087             index++; // Check next one.
00088             goto AGAIN; // Start checking from begining of the list, indexes are not in order
00089         }
00090     }
00091     e->event_id = index;
00092     ns_list_add_to_end(&timeout_list, e);
00093     eventOS_event_timer_request(index, TIMER_EVENT, timeout_tasklet_id, ms);
00094     return e;
00095 FAIL:
00096     ns_dyn_mem_free(e);
00097     return NULL;
00098 }
00099 
00100 void eventOS_timeout_cancel(timeout_t *t)
00101 {
00102     ns_list_foreach_safe(timeout_t, cur, &timeout_list) {
00103         if (t == cur) {
00104             ns_list_remove(&timeout_list, cur);
00105             eventOS_event_timer_cancel(cur->event_id, timeout_tasklet_id);
00106             ns_dyn_mem_free(cur);
00107         }
00108     }
00109 }