Version of personalized IMPACT LoRa

Fork of LMiC-10secs by Alcatel-Lucent IoT Development

oslmic.cpp

Committer:
pnysten
Date:
2016-02-23
Revision:
9:c5820ce68bd6
Parent:
7:758e1719910c

File content as of revision 9:c5820ce68bd6:

/*******************************************************************************
 * 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"
#include "x_nucleo_iks01a1.h"
#include "debug.h"

/* Instantiate the expansion board */
static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15);

/* Retrieve the composing elements of the expansion board */
static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
static MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
static PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
static TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;

// 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)) {
        //debug_str(".");
        if((*pnext)->deadline - time > 0) { // (cmp diff, not abs!)
            // enqueue before next element and stop
            //debug_str("Stop To Wait...\r\n");
            job->next = *pnext;
            break;
        }
    }
    *pnext = job;
    hal_enableIRQs();
}

/* Helper function for printing floats & doubles */
static char *printDouble(char* str, double v, int decimalDigits=2)
{
  int i = 1;
  int intPart, fractPart;
  int len;
  char *ptr;

  /* prepare decimal digits multiplicator */
  for (;decimalDigits!=0; i*=10, decimalDigits--);

  /* calculate integer & fractinal parts */
  intPart = (int)v;
  fractPart = (int)((v-(double)(int)v)*i);

  /* fill in integer part */
  sprintf(str, "%i.", intPart);

  /* prepare fill in of fractional part */
  len = strlen(str);
  ptr = &str[len];

  /* fill in leading fractional zeros */
  for (i/=10;i>1; i/=10, ptr++) {
    if(fractPart >= i) break;
    *ptr = '0';
  }

  /* fill in (rest of) fractional part */
  sprintf(ptr, "%i", fractPart);

  return str;
}

// execute jobs from timer and from run queue
void os_runloop () {
/*      uint8_t id;
      float value1, value2;
      char buffer1[32], buffer2[32];
      int32_t axes[3];
      
      debug_str("--- Starting new run ---\r\n");
    
      humidity_sensor->ReadID(&id);
      debug_str("HTS221  humidity & temperature    = ");
      debug_uint(id);
      debug_str("\r\n");
      pressure_sensor->ReadID(&id);
      debug_str("LPS25H  pressure & temperature    = ");
      debug_uint(id);
      debug_str("\r\n");
      magnetometer->ReadID(&id);
      debug_str("LIS3MDL magnetometer              = ");
      debug_uint(id);
      debug_str("\r\n");
      gyroscope->ReadID(&id);
      debug_str("LSM6DS0 accelerometer & gyroscope = ");
      debug_uint(id);
      debug_str("\r\n");*/
      
//      wait(3);

      while(1) {
/*            debug_str("\r\n");
        
            temp_sensor1->GetTemperature(&value1);
            humidity_sensor->GetHumidity(&value2);
            debug_str("HTS221: [temp] ");
            debug_str(printDouble(buffer1, value1));
            debug_str("°C,   [hum] ");
            debug_str(printDouble(buffer2, value2));
            debug_str("%\r\n");
            //pc.printf("HTS221: [temp] %7s°C,   [hum] %s%%\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2));
            
            temp_sensor2->GetFahrenheit(&value1);
            pressure_sensor->GetPressure(&value2);
            debug_str("LPS25H: [temp] ");
            debug_str(printDouble(buffer1, value1));
            debug_str("°F, [press] ");
            debug_str(printDouble(buffer2, value2));
            debug_str("mbar\r\n");
            //pc.printf("LPS25H: [temp] %7s°F, [press] %smbar\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2));
        
            debug_str("---\r\n");
        
            magnetometer->Get_M_Axes(axes);
            debug_str("LIS3MDL [mag/mgauss]:  ");
            debug_uint(axes[0]);
            debug_str(", ");
            debug_uint(axes[1]);
            debug_str(", ");
            debug_uint(axes[2]);
            debug_str("\r\n");
            //pc.printf("LIS3MDL [mag/mgauss]:  %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
        
            accelerometer->Get_X_Axes(axes);
            debug_str("LSM6DS0 [acc/mg]:      ");
            debug_uint(axes[0]);
            debug_str(", ");
            debug_uint(axes[1]);
            debug_str(", ");
            debug_uint(axes[2]);
            debug_str("\r\n");
            //pc.printf("LSM6DS0 [acc/mg]:      %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
        
            gyroscope->Get_G_Axes(axes);
            debug_str("LSM6DS0 [gyro/mdps]:   ");
            debug_uint(axes[0]);
            debug_str(", ");
            debug_uint(axes[1]);
            debug_str(", ");
            debug_uint(axes[2]);
            debug_str("\r\n");
            //pc.printf("LSM6DS0 [gyro/mdps]:   %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);*/

            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);
            }
      }
}