Fix ADR channel mask handling
Fork of lmic_MOTE_L152RC by
Diff: oslmic.cpp
- Revision:
- 0:f2716e543d97
- Child:
- 9:83ae7f34e88c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oslmic.cpp Tue Jun 02 19:04:29 2015 +0000 @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2014-2015 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 () { + memset(&OS, 0x00, sizeof(OS)); + hal_init(); + radio_init(); + LMIC_init(); +} + +ostime_t os_getTime () { + 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((*pnext)->deadline - time > 0) { // (cmp diff, not abs!) + // 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 () { + 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 + j->func(j); + } + } +}