first test

Dependents:   LoRaWAN-lmic-app_tjm

Fork of LMiC by Semtech

Revision:
0:62d1edcc13d1
Child:
1:d3b7bde3995c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/oslmic.cpp	Thu Jan 22 12:50:49 2015 +0000
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Zurich Research Lab - initial API, implementation and documentation
+ *******************************************************************************/
+
+#include "lmic.h"
+
+// RUNTIME STATE
+static struct {
+    osjob_t* scheduledjobs;
+    osjob_t* runnablejobs;
+} OS;
+
+void os_init (void) {
+    memset(&OS, 0x00, sizeof(OS));
+    hal_init();
+    radio_init();
+    LMIC_init();
+}
+
+ostime_t os_getTime (void) {
+    return hal_ticks();
+}
+
+static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) {
+    for( ; *pnext; pnext = &((*pnext)->next)) {
+        if(*pnext == job) { // unlink
+            *pnext = job->next;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+// clear scheduled job
+void os_clearCallback (osjob_t* job) {
+    hal_disableIRQs();
+    unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
+    hal_enableIRQs();
+}
+
+// schedule immediately runnable job
+void os_setCallback (osjob_t* job, osjobcb_t cb) {
+    osjob_t** pnext;
+    hal_disableIRQs();
+    // remove if job was already queued
+    os_clearCallback(job);
+    // fill-in job
+    job->func = cb;
+    job->next = NULL;
+    // add to end of run queue
+    for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
+    *pnext = job;
+    hal_enableIRQs();
+}
+
+// schedule timed job
+void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
+    osjob_t** pnext;
+    hal_disableIRQs();
+    // remove if job was already queued
+    os_clearCallback(job);
+    // fill-in job
+    job->deadline = time;
+    job->func = cb;
+    job->next = NULL;
+    // insert into schedule
+    for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) {
+        if(time < (*pnext)->deadline) {
+            // enqueue before next element and stop
+            job->next = *pnext;
+            break;
+        }
+    }
+    *pnext = job;
+    hal_enableIRQs();
+}
+
+// execute jobs from timer and from run queue
+void os_runloop (void) {
+    while(1) {
+        osjob_t* j = NULL;
+        hal_disableIRQs();
+	// check for runnable jobs
+	if(OS.runnablejobs) {
+            j = OS.runnablejobs;
+            OS.runnablejobs = j->next;
+	} else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs
+            j = OS.scheduledjobs;
+            OS.scheduledjobs = j->next;
+        } else { // nothing pending
+            hal_sleep(); // wake by irq (timer already restarted)
+        }
+        hal_enableIRQs();
+        if(j) { // run job callback
+            if(j->func) {
+                j->func(j);
+            }
+        }
+    }
+}