diff options
Diffstat (limited to 'src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/oslmic.c')
-rw-r--r-- | src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/oslmic.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/oslmic.c b/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/oslmic.c new file mode 100644 index 0000000..fa205f4 --- /dev/null +++ b/src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/oslmic.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2014-2016 IBM Corporation. + * Copyright (c) 2016-2017, 2019 MCCI Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the <organization> nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LMIC_DR_LEGACY 0 + +#include "lmic.h" + +extern const struct lmic_pinmap lmic_pins; + +// RUNTIME STATE +static struct { + osjob_t* scheduledjobs; + osjob_t* runnablejobs; +} OS; + +int os_init_ex (const void *pintable) { + memset(&OS, 0x00, sizeof(OS)); + hal_init_ex(pintable); + if (! radio_init()) + return 0; + LMIC_init(); + return 1; +} + +void os_init() { + if (os_init_ex((const void *)&lmic_pins)) + return; + ASSERT(0); +} + +ostime_t os_getTime () { + return hal_ticks(); +} + +// unlink job from queue, return if removed +static int unlinkjob (osjob_t** pnext, osjob_t* job) { + for( ; *pnext; pnext = &((*pnext)->next)) { + if(*pnext == job) { // unlink + *pnext = job->next; + return 1; + } + } + return 0; +} + +static osjob_t** getJobQueue(osjob_t* job) { + return os_jobIsTimed(job) ? &OS.scheduledjobs : &OS.runnablejobs; +} + +// clear scheduled job +void os_clearCallback (osjob_t* job) { + hal_disableIRQs(); + + unlinkjob(getJobQueue(job), 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 + unlinkjob(getJobQueue(job), job); + + // fill-in job. Ascending memory order is write-queue friendly + job->next = NULL; + job->deadline = 0; + job->func = cb; + + // 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; + + // special case time 0 -- it will be one tick late. + if (time == 0) + time = 1; + + hal_disableIRQs(); + + // remove if job was already queued + unlinkjob(getJobQueue(job), job); + + // fill-in job + job->next = NULL; + job->deadline = time; + job->func = cb; + + // 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) { + os_runloop_once(); + } +} + +void os_runloop_once() { + osjob_t* j = NULL; + hal_processPendingIRQs(); + + 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); + } +} + +// return true if there are any jobs scheduled within time ticks from now. +// return false if any jobs scheduled are at least time ticks in the future. +bit_t os_queryTimeCriticalJobs(ostime_t time) { + if (OS.scheduledjobs && + OS.scheduledjobs->deadline - os_getTime() < time) + return 1; + else + return 0; +} |