IBL LoRaWAN implementation

Dependents:   Simple-LoRaWAN

Fork of LMiC by Semtech

Committer:
sillevl
Date:
Thu Jun 30 17:31:55 2016 +0000
Revision:
6:59bd35cd865a
Parent:
1:d3b7bde3995c
add os_loop_once() function

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:62d1edcc13d1 1 /*******************************************************************************
mluis 1:d3b7bde3995c 2 * Copyright (c) 2014-2015 IBM Corporation.
mluis 0:62d1edcc13d1 3 * All rights reserved. This program and the accompanying materials
mluis 0:62d1edcc13d1 4 * are made available under the terms of the Eclipse Public License v1.0
mluis 0:62d1edcc13d1 5 * which accompanies this distribution, and is available at
mluis 0:62d1edcc13d1 6 * http://www.eclipse.org/legal/epl-v10.html
mluis 0:62d1edcc13d1 7 *
mluis 0:62d1edcc13d1 8 * Contributors:
mluis 0:62d1edcc13d1 9 * IBM Zurich Research Lab - initial API, implementation and documentation
mluis 0:62d1edcc13d1 10 *******************************************************************************/
mluis 0:62d1edcc13d1 11
mluis 0:62d1edcc13d1 12 #include "lmic.h"
mluis 0:62d1edcc13d1 13
mluis 0:62d1edcc13d1 14 // RUNTIME STATE
mluis 0:62d1edcc13d1 15 static struct {
mluis 0:62d1edcc13d1 16 osjob_t* scheduledjobs;
mluis 0:62d1edcc13d1 17 osjob_t* runnablejobs;
mluis 0:62d1edcc13d1 18 } OS;
mluis 0:62d1edcc13d1 19
mluis 1:d3b7bde3995c 20 void os_init () {
mluis 0:62d1edcc13d1 21 memset(&OS, 0x00, sizeof(OS));
mluis 0:62d1edcc13d1 22 hal_init();
mluis 0:62d1edcc13d1 23 radio_init();
mluis 0:62d1edcc13d1 24 LMIC_init();
mluis 0:62d1edcc13d1 25 }
mluis 0:62d1edcc13d1 26
mluis 1:d3b7bde3995c 27 ostime_t os_getTime () {
mluis 0:62d1edcc13d1 28 return hal_ticks();
mluis 0:62d1edcc13d1 29 }
mluis 0:62d1edcc13d1 30
mluis 0:62d1edcc13d1 31 static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) {
mluis 0:62d1edcc13d1 32 for( ; *pnext; pnext = &((*pnext)->next)) {
mluis 0:62d1edcc13d1 33 if(*pnext == job) { // unlink
mluis 0:62d1edcc13d1 34 *pnext = job->next;
mluis 0:62d1edcc13d1 35 return 1;
mluis 0:62d1edcc13d1 36 }
mluis 0:62d1edcc13d1 37 }
mluis 0:62d1edcc13d1 38 return 0;
mluis 0:62d1edcc13d1 39 }
mluis 0:62d1edcc13d1 40
mluis 0:62d1edcc13d1 41 // clear scheduled job
mluis 0:62d1edcc13d1 42 void os_clearCallback (osjob_t* job) {
mluis 0:62d1edcc13d1 43 hal_disableIRQs();
mluis 0:62d1edcc13d1 44 unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
mluis 0:62d1edcc13d1 45 hal_enableIRQs();
mluis 0:62d1edcc13d1 46 }
mluis 0:62d1edcc13d1 47
mluis 0:62d1edcc13d1 48 // schedule immediately runnable job
mluis 0:62d1edcc13d1 49 void os_setCallback (osjob_t* job, osjobcb_t cb) {
mluis 0:62d1edcc13d1 50 osjob_t** pnext;
mluis 0:62d1edcc13d1 51 hal_disableIRQs();
mluis 0:62d1edcc13d1 52 // remove if job was already queued
mluis 0:62d1edcc13d1 53 os_clearCallback(job);
mluis 0:62d1edcc13d1 54 // fill-in job
mluis 0:62d1edcc13d1 55 job->func = cb;
mluis 0:62d1edcc13d1 56 job->next = NULL;
mluis 0:62d1edcc13d1 57 // add to end of run queue
mluis 0:62d1edcc13d1 58 for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
mluis 0:62d1edcc13d1 59 *pnext = job;
mluis 0:62d1edcc13d1 60 hal_enableIRQs();
mluis 0:62d1edcc13d1 61 }
mluis 0:62d1edcc13d1 62
mluis 0:62d1edcc13d1 63 // schedule timed job
mluis 0:62d1edcc13d1 64 void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
mluis 0:62d1edcc13d1 65 osjob_t** pnext;
mluis 0:62d1edcc13d1 66 hal_disableIRQs();
mluis 0:62d1edcc13d1 67 // remove if job was already queued
mluis 0:62d1edcc13d1 68 os_clearCallback(job);
mluis 0:62d1edcc13d1 69 // fill-in job
mluis 0:62d1edcc13d1 70 job->deadline = time;
mluis 0:62d1edcc13d1 71 job->func = cb;
mluis 0:62d1edcc13d1 72 job->next = NULL;
mluis 0:62d1edcc13d1 73 // insert into schedule
mluis 0:62d1edcc13d1 74 for(pnext=&OS.scheduledjobs; *pnext; pnext=&((*pnext)->next)) {
mluis 1:d3b7bde3995c 75 if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!)
mluis 0:62d1edcc13d1 76 // enqueue before next element and stop
mluis 0:62d1edcc13d1 77 job->next = *pnext;
mluis 0:62d1edcc13d1 78 break;
mluis 0:62d1edcc13d1 79 }
mluis 0:62d1edcc13d1 80 }
mluis 0:62d1edcc13d1 81 *pnext = job;
mluis 0:62d1edcc13d1 82 hal_enableIRQs();
mluis 0:62d1edcc13d1 83 }
mluis 0:62d1edcc13d1 84
mluis 0:62d1edcc13d1 85 // execute jobs from timer and from run queue
mluis 1:d3b7bde3995c 86 void os_runloop () {
mluis 0:62d1edcc13d1 87 while(1) {
sillevl 6:59bd35cd865a 88 os_runloop_once();
mluis 0:62d1edcc13d1 89 }
mluis 0:62d1edcc13d1 90 }
sillevl 6:59bd35cd865a 91
sillevl 6:59bd35cd865a 92 void os_runloop_once() {
sillevl 6:59bd35cd865a 93 osjob_t* j = NULL;
sillevl 6:59bd35cd865a 94 hal_disableIRQs();
sillevl 6:59bd35cd865a 95 // check for runnable jobs
sillevl 6:59bd35cd865a 96 if(OS.runnablejobs) {
sillevl 6:59bd35cd865a 97 j = OS.runnablejobs;
sillevl 6:59bd35cd865a 98 OS.runnablejobs = j->next;
sillevl 6:59bd35cd865a 99 } else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs
sillevl 6:59bd35cd865a 100 j = OS.scheduledjobs;
sillevl 6:59bd35cd865a 101 OS.scheduledjobs = j->next;
sillevl 6:59bd35cd865a 102 } else { // nothing pending
sillevl 6:59bd35cd865a 103 hal_sleep(); // wake by irq (timer already restarted)
sillevl 6:59bd35cd865a 104 }
sillevl 6:59bd35cd865a 105 hal_enableIRQs();
sillevl 6:59bd35cd865a 106 if(j) { // run job callback
sillevl 6:59bd35cd865a 107 j->func(j);
sillevl 6:59bd35cd865a 108 }
sillevl 6:59bd35cd865a 109 }