Generic communication interface between the wireless board (mote) and the sensor board. Any kind of sensor board can be connected to the mote using this specification given it provides a SPI peripheral, one input pin with interrupt capability and one digital output. The sensor board must implement a special register set from which all required information can be retrieved. Protocol: http://is.gd/wuQorh Github: http://is.gd/ySj1L9

Dependencies:   mbed-src

Files at this revision

API Documentation at this revision

Comitter:
marcelobarrosalmeida
Date:
Tue Apr 08 16:34:20 2014 +0000
Parent:
0:01c4d4d8febf
Commit message:
Adding accel to sensor list

Changed in this revision

MMA8451Q/MMA8451Q.cpp Show annotated file Show diff for this revision Revisions of this file
MMA8451Q/MMA8451Q.h Show annotated file Show diff for this revision Revisions of this file
SLCD.lib Show diff for this revision Revisions of this file
SLCD/FRDM-s401.h Show annotated file Show diff for this revision Revisions of this file
SLCD/LCDconfig.h Show annotated file Show diff for this revision Revisions of this file
SLCD/SLCD.cpp Show annotated file Show diff for this revision Revisions of this file
SLCD/SLCD.h Show annotated file Show diff for this revision Revisions of this file
TSI.lib Show diff for this revision Revisions of this file
TSI/TSISensor.cpp Show annotated file Show diff for this revision Revisions of this file
TSI/TSISensor.h Show annotated file Show diff for this revision Revisions of this file
mbed-src.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
pt.lib Show diff for this revision Revisions of this file
pt/graham-pt.h Show annotated file Show diff for this revision Revisions of this file
pt/lc-addrlabels.h Show annotated file Show diff for this revision Revisions of this file
pt/lc-switch.h Show annotated file Show diff for this revision Revisions of this file
pt/lc.h Show annotated file Show diff for this revision Revisions of this file
pt/pt-sem.h Show annotated file Show diff for this revision Revisions of this file
pt/pt.h Show annotated file Show diff for this revision Revisions of this file
sens_itf.lib Show diff for this revision Revisions of this file
sens_itf/sens_itf.c Show annotated file Show diff for this revision Revisions of this file
sens_itf/sens_itf.h Show annotated file Show diff for this revision Revisions of this file
sens_itf/sens_itf_sensor.cpp Show annotated file Show diff for this revision Revisions of this file
sens_itf/sens_util.c Show annotated file Show diff for this revision Revisions of this file
sens_itf/sens_util.h Show annotated file Show diff for this revision Revisions of this file
util.lib Show diff for this revision Revisions of this file
util/buf_io.c Show annotated file Show diff for this revision Revisions of this file
util/buf_io.h Show annotated file Show diff for this revision Revisions of this file
util/crc16.c Show annotated file Show diff for this revision Revisions of this file
util/crc16.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA8451Q/MMA8451Q.cpp	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,81 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MMA8451Q.h"
+
+#define REG_WHO_AM_I      0x0D
+#define REG_CTRL_REG_1    0x2A
+#define REG_OUT_X_MSB     0x01
+#define REG_OUT_Y_MSB     0x03
+#define REG_OUT_Z_MSB     0x05
+
+#define UINT14_MAX        16383
+
+MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
+    // activate the peripheral
+    uint8_t data[2] = {REG_CTRL_REG_1, 0x01};
+    writeRegs(data, 2);
+}
+
+MMA8451Q::~MMA8451Q() { }
+
+uint8_t MMA8451Q::getWhoAmI() {
+    uint8_t who_am_i = 0;
+    readRegs(REG_WHO_AM_I, &who_am_i, 1);
+    return who_am_i;
+}
+
+float MMA8451Q::getAccX() {
+    return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
+}
+
+float MMA8451Q::getAccY() {
+    return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
+}
+
+float MMA8451Q::getAccZ() {
+    return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
+}
+
+void MMA8451Q::getAccAllAxis(float * res) {
+    res[0] = getAccX();
+    res[1] = getAccY();
+    res[2] = getAccZ();
+}
+
+int16_t MMA8451Q::getAccAxis(uint8_t addr) {
+    int16_t acc;
+    uint8_t res[2];
+    readRegs(addr, res, 2);
+
+    acc = (res[0] << 6) | (res[1] >> 2);
+    if (acc > UINT14_MAX/2)
+        acc -= UINT14_MAX;
+
+    return acc;
+}
+
+void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
+    char t[1] = {addr};
+    m_i2c.write(m_addr, t, 1, true);
+    m_i2c.read(m_addr, (char *)data, len);
+}
+
+void MMA8451Q::writeRegs(uint8_t * data, int len) {
+    m_i2c.write(m_addr, (char *)data, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA8451Q/MMA8451Q.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,110 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MMA8451Q_H
+#define MMA8451Q_H
+
+#include "mbed.h"
+
+/**
+* MMA8451Q accelerometer example
+*
+* @code
+* #include "mbed.h"
+* #include "MMA8451Q.h"
+* 
+* #define MMA8451_I2C_ADDRESS (0x1d<<1)
+* 
+* int main(void) {
+* 
+* MMA8451Q acc(P_E25, P_E24, MMA8451_I2C_ADDRESS);
+* PwmOut rled(LED_RED);
+* PwmOut gled(LED_GREEN);
+* PwmOut bled(LED_BLUE);
+* 
+*     while (true) {       
+*         rled = 1.0 - abs(acc.getAccX());
+*         gled = 1.0 - abs(acc.getAccY());
+*         bled = 1.0 - abs(acc.getAccZ());
+*         wait(0.1);
+*     }
+* }
+* @endcode
+*/
+class MMA8451Q
+{
+public:
+  /**
+  * MMA8451Q constructor
+  *
+  * @param sda SDA pin
+  * @param sdl SCL pin
+  * @param addr addr of the I2C peripheral
+  */
+  MMA8451Q(PinName sda, PinName scl, int addr);
+
+  /**
+  * MMA8451Q destructor
+  */
+  ~MMA8451Q();
+
+  /**
+   * Get the value of the WHO_AM_I register
+   *
+   * @returns WHO_AM_I value
+   */
+  uint8_t getWhoAmI();
+
+  /**
+   * Get X axis acceleration
+   *
+   * @returns X axis acceleration
+   */
+  float getAccX();
+
+  /**
+   * Get Y axis acceleration
+   *
+   * @returns Y axis acceleration
+   */
+  float getAccY();
+
+  /**
+   * Get Z axis acceleration
+   *
+   * @returns Z axis acceleration
+   */
+  float getAccZ();
+
+  /**
+   * Get XYZ axis acceleration
+   *
+   * @param res array where acceleration data will be stored
+   */
+  void getAccAllAxis(float * res);
+
+private:
+  I2C m_i2c;
+  int m_addr;
+  void readRegs(int addr, uint8_t * data, int len);
+  void writeRegs(uint8_t * data, int len);
+  int16_t getAccAxis(uint8_t addr);
+
+};
+
+#endif
--- a/SLCD.lib	Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/Sissors/code/SLCD/#dc8a41707598
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/FRDM-s401.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,96 @@
+/*^^^^^^^^^^^^^^^^      LCD HARDWARE CONECTION ^^^^^^^^^^^^^^^^^^^^^^^^*/
+#define  _LCDFRONTPLANES   (8)            // # of frontPlanes
+#define  _LCDBACKPLANES    (4)            // # of backplanes
+
+/*
+   LCD logical organization definition
+   This section indicates how the LCD is distributed  how many characteres of (7-seg, 14,seg, 16 seg, or colums in case of Dot Matrix) does it contain
+   First character is forced only one can be written
+
+*/
+// HARDWARE_CONFIG Changing LCD pins Allows to verify all LCD pins easily
+// if HARDWARE_CONFIG  == 0 FRDM-KL46 RevB 
+// if HARDWARE_CONFIG  == 1 FRDM-KL46 RevA
+#ifdef FRDM_REVA
+#define HARDWARE_CONFIG 1
+#else
+#define HARDWARE_CONFIG 0
+#endif
+
+#define _CHARNUM     (4)  //number of chars that can be written
+#define _CHAR_SIZE   (2)  // Used only when Dot Matrix is used
+#define _LCDTYPE     (2)  //indicate how many LCD_WF are required to write a single Character
+
+/*
+  Following definitions indicate how characters are associated to waveform
+*/
+/* Hardware configuration  */
+#if HARDWARE_CONFIG == 0
+
+// LCD PIN1 to LCDWF0  Rev B
+#define   CHAR1a    37      // LCD Pin 5
+#define   CHAR1b    17      // LCD Pin 6
+#define   CHAR2a    7       // LCD Pin 7
+#define   CHAR2b    8       // LCD Pin 8
+#define   CHAR3a    53      // LCD Pin 9
+#define   CHAR3b    38      // LCD Pin 10
+#define   CHAR4a    10      // LCD Pin 11
+#define   CHAR4b    11      // LCD Pin 12
+#define   CHARCOM0    40    // LCD Pin 1
+#define   CHARCOM1    52    // LCD Pin 2
+#define   CHARCOM2    19    // LCD Pin 3
+#define   CHARCOM3    18    // LCD Pin 4
+
+// LCD PIN1 to LCDWF2   for FRDM-KL46Z
+#elif HARDWARE_CONFIG == 1
+#define   CHAR1a    37      // LCD Pin 5
+#define   CHAR1b    17      // LCD Pin 6
+#define   CHAR2a    7       // LCD Pin 7
+#define   CHAR2b    8       // LCD Pin 8
+#define   CHAR3a    12      // LCD Pin 9
+#define   CHAR3b    26      // LCD Pin 10
+#define   CHAR4a    10      // LCD Pin 11
+#define   CHAR4b    11      // LCD Pin 12
+#define   CHARCOM0    51    // LCD Pin 1
+#define   CHARCOM1    52    // LCD Pin 2
+#define   CHARCOM2    19    // LCD Pin 3
+#define   CHARCOM3    16    // LCD Pin 4
+
+#endif
+
+
+/*Ascii Codification table information */
+#define ASCCI_TABLE_START '0'   // indicates which is the first Ascii character in the table
+#define ASCCI_TABLE_END   'Z'   // indicates which is the last Ascii character in the table
+#define BLANK_CHARACTER   '>'  // Indicate which ASCII character is a blank character (depends on ASCII table)
+
+#define _ALLON 0xFF     // Used for ALL_on function 
+
+#define SEGDP 0x01
+#define SEGC  0x02
+#define SEGB  0x04
+#define SEGA  0x08
+
+#define SEGD  0x01
+#define SEGE  0x02
+#define SEGG  0x04
+#define SEGF  0x08
+
+
+/* Fault detect initial limits */
+
+/* Fault detect initial parameters and limits */
+#define FAULTD_FP_FDPRS  FDPRS_32
+#define FAULTD_FP_FDSWW  FDSWW_128
+#define FAULTD_BP_FDPRS  FDPRS_64
+#define FAULTD_BP_FDSWW  FDSWW_128
+
+#define FAULTD_FP_HI  127
+#define FAULTD_FP_LO  110
+#define FAULTD_BP_HI  127
+#define FAULTD_BP_LO  110
+#define FAULTD_TIME   6
+
+extern const uint8_t  WF_ORDERING_TABLE[];   //   Logical Front plane N to LCD_WFx
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/LCDconfig.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,183 @@
+#include "FRDM-s401.h"                //  4x7 segdisplay
+
+
+#if 1  // VREF to VLL1
+/* Following configuration is used for LCD default initialization  */
+#define _LCDRVEN          (1)         //
+#define _LCDRVTRIM        (8)         // CPSEL = 1     0 -- 8000 pf 1 -- 6000 pf  2 -- 4000 pf  3 -- 2000 pf
+#define _LCDCPSEL         (1)         //  charge pump select 0 or 1 
+#define _LCDLOADADJUST    (3)         // CPSEL = 1     0 -- 8000 pf 1 -- 6000 pf  2 -- 4000 pf  3 -- 2000 pf
+#define _LCDALTDIV        (0)         // CPSEL = 1     0 -- 8000 pf 1 -- 6000 pf  2 -- 4000 pf  3 -- 2000 pf
+#define _LCDALRCLKSOURCE  (0)         // 0 -- External clock       1 --  Alternate clock
+
+#define _LCDCLKPSL        (0)         //  Clock divider to generate the LCD Waveforms 
+#define _LCDSUPPLY        (1) 
+#define _LCDHREF          (0)         // 0 or 1 
+#define _LCDCLKSOURCE     (1)         // 0 -- External clock       1 --  Alternate clock
+#define _LCDLCK           (1)         //Any number between 0 and 7 
+#define _LCDBLINKRATE     (3)         //Any number between 0 and 7 
+
+
+#else    //VLL3 to VDD internally
+/* Following configuration is used for LCD default initialization  */
+#define _LCDCLKSOURCE     (1)         // 0 -- External clock       1 --  Alternate clock
+#define _LCDALRCLKSOURCE  (0)         // 0 -- External clock       1 --  Alternate clock
+#define _LCDCLKPSL        (0)         // Clock divider to generate the LCD Waveforms 
+#define _LCDSUPPLY        (0) 
+#define _LCDLOADADJUST    (3)         // CPSEL = 1     0 -- 8000 pf 1 -- 6000 pf  2 -- 4000 pf  3 -- 2000 pf
+#define _LCDALTDIV        (0)         // CPSEL = 1     0 -- 8000 pf 1 -- 6000 pf  2 -- 4000 pf  3 -- 2000 pf
+#define _LCDRVTRIM        (0)         // CPSEL = 1     0 -- 8000 pf 1 -- 6000 pf  2 -- 4000 pf  3 -- 2000 pf
+#define _LCDHREF          (0)         // 0 or 1 
+#define _LCDCPSEL         (1)         // 0 or 1 
+#define _LCDRVEN          (0)         //
+#define _LCDBLINKRATE     (3)         // Any number between 0 and 7 
+#define _LCDLCK           (0)         // Any number between 0 and 7 
+
+#endif
+
+
+
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~  LCD  Control Register 0  ~|~|~|~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDINTENABLE          (1)    
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~  LCD  Control Register 1  ~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDFRAMEINTERRUPT     (0)     //0 Disable Frame Frequency Interrupt
+                                            //1 Enable an LCD interrupt that coincides with the LCD frame frequency
+#define _LCDFULLCPLDIRIVE      (0)     // 0 GPIO shared with the LCD. Inputs levels and internal pullup reference to VDD
+                                            // 1 If VSUPPLY=11and RVEN=0. Inputs levels and internal pullup reference to VLL3
+#define _LCDWAITMODE           (0)     // 0 Allows the LCD driver and charge pump to continue running during wait mode
+                                            //  1 Disable the LCD when the MCU goes into wait mode
+#define _LCDSTOPMODE           (0)     // 0 Allows the LCD driver and charge pump to continue running during stop2 or stop3
+                                            //  1 Disable the LCD when and charge pump when the MCU goes into stop2 or stop3                                                               
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~  LCD  Voltage Supply Register  ~|~|~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDHIGHREF             (0)    //0 Divide input VIREG=1.0v
+                                            //1 Do not divide the input VIREG=1.67v
+#define _LCDBBYPASS             (0)    //Determines whether the internal LCD op amp buffer is bypassed
+                                            //0 Buffered mode
+                                            //1 Unbuffered mode
+                            
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~  LCD  Regulated Voltage Control |~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDCONTRAST            (1)       //Contrast by software   0 -- Disable    1-- Enable
+#define _LVLCONTRAST            (0)       //Any number between 0  and 15, if the number is bigger the glass gets darker
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~  LCD  Blink Control Register ~|~|~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDBLINKCONTROL        (1)     //0 Disable blink mode
+                                            //1 Enable blink mode
+#define _LCDALTMODE             (0)     //0 Normal display 
+                                            //1 Alternate display for 4 backplanes or less the LCD backplane sequencer changes to otuput an alternate display
+#define _LCDBLANKDISP           (0)     //0 Do not blank display
+                                            //1 Blank display if you put it in 0 the text before blank is manteined     
+#define _LCDBLINKMODE           (0)     //0 Display blank during the blink period 
+                                            //1 Display alternate displat during blink period (Ignored if duty is 5 or greater)
+
+
+//Calculated values
+#define _LCDUSEDPINS   (_LCDFRONTPLANES + _LCDBACKPLANES)
+#define _LCDDUTY       (_LCDBACKPLANES-1)         //Any number between 0 and 7 
+#define  LCD_WF_BASE    LCD->WF8B[0]
+
+// General definitions used by the LCD library         
+#define  LCD_WF(x)              *((uint8 *)&LCD_WF_BASE + x) 
+
+/*LCD Fault Detections Consts*/
+#define  FP_TYPE  0x00         // pin is a Front Plane
+#define  BP_TYPE  0x80         // pin is Back Plane
+
+// Fault Detect Preescaler Options
+#define FDPRS_1      0
+#define FDPRS_2      1
+#define FDPRS_4      2
+#define FDPRS_8      3
+#define FDPRS_16     4 
+#define FDPRS_32     5
+#define FDPRS_64     6
+#define FDPRS_128    7
+
+// Fault Detect Sample Window Width Values  
+#define FDSWW_4           0
+#define FDSWW_8           1
+#define FDSWW_16          2
+#define FDSWW_32          3
+#define FDSWW_64          4
+#define FDSWW_128         5
+#define FDSWW_256         6
+#define FDSWW_512         7
+
+/*
+  Mask Bit definitions used f
+*/
+#define     mBIT0   1
+#define     mBIT1   2
+#define     mBIT2   4
+#define     mBIT3   8
+#define     mBIT4   16
+#define     mBIT5   32
+#define     mBIT6   64
+#define     mBIT7   128
+#define     mBIT8   256
+#define     mBIT9   512
+#define     mBIT10   1024
+#define     mBIT11   2048
+#define     mBIT12   4096
+#define     mBIT13   8192
+#define     mBIT14   16384
+#define     mBIT15   32768
+#define     mBIT16   65536
+#define     mBIT17   131072
+#define     mBIT18   262144
+#define     mBIT19   524288
+#define     mBIT20   1048576
+#define     mBIT21   2097152
+#define     mBIT22   4194304
+#define     mBIT23   8388608
+#define     mBIT24   16777216
+#define     mBIT25   33554432
+#define     mBIT26   67108864
+#define     mBIT27   134217728
+#define     mBIT28   268435456
+#define     mBIT29   536870912
+#define     mBIT30   1073741824
+#define     mBIT31   2147483648
+
+#define    mBIT32      1
+#define    mBIT33      2
+#define    mBIT34      4
+#define    mBIT35      8
+#define    mBIT36      16
+#define    mBIT37      32
+#define    mBIT38      64
+#define    mBIT39      128
+#define    mBIT40      256
+#define    mBIT41      512
+#define    mBIT42      1024
+#define    mBIT43      2048
+#define    mBIT44      4096
+#define    mBIT45      8192
+#define    mBIT46      16384
+#define    mBIT47      32768
+#define    mBIT48      65536
+#define    mBIT49      131072
+#define    mBIT50      262144
+#define    mBIT51      524288
+#define    mBIT52      1048576
+#define    mBIT53      2097152
+#define    mBIT54      4194304
+#define    mBIT55      8388608
+#define    mBIT56      16777216
+#define    mBIT57      33554432
+#define    mBIT58      67108864
+#define    mBIT59      134217728
+#define    mBIT60      268435456
+#define    mBIT61      536870912
+#define    mBIT62      1073741824
+#define    mBIT63      2147483648
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/SLCD.cpp	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,243 @@
+#include "SLCD.h"
+#include "LCDconfig.h"
+
+
+const uint8_t WF_ORDERING_TABLE[ ] =
+{
+   CHAR1a,   // LCD81 --- Pin:5  LCDnAddress=51
+   CHAR1b,   // LCD82 --- Pin:6  LCDnAddress=52
+   CHAR2a,   // LCD83 --- Pin:7  LCDnAddress=53
+   CHAR2b,   // LCD84 --- Pin:8  LCDnAddress=54
+   CHAR3a,   // LCD85 --- Pin:9  LCDnAddress=55
+   CHAR3b,   // LCD86 --- Pin:10 LCDnAddress=56
+   CHAR4a,   // LCD87 --- Pin:11 LCDnAddress=57
+   CHAR4b,   // LCD88 --- Pin:12 LCDnAddress=58
+   CHARCOM0, // LCD77 --- Pin:1  LCDnAddress=4D
+   CHARCOM1, // LCD78 --- Pin:2  LCDnAddress=4E
+   CHARCOM2, // LCD79 --- Pin:3  LCDnAddress=4F
+   CHARCOM3, // LCD80 --- Pin:4  LCDnAddress=50
+};
+
+const char ASCII_TO_WF_CODIFICATION_TABLE [ ] =
+{
+ 
+ /*
+                segA
+              ________  
+             |        | 
+        segF |        | segB
+             |        |
+              -segG--
+             |        |
+        segE |        | segC
+             |________|
+                segD
+ */   
+    
+( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 0,   offset=0
+(!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = 1,   offset=4
+( SEGD+ SEGE+!SEGF+ SEGG) , (!SEGC+ SEGB+ SEGA) ,//Char = 2,   offset=8
+( SEGD+!SEGE+!SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 3,   offset=12
+(!SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = 4,   offset=16
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = 5,   offset=20
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = 6,   offset=24
+(!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 7,   offset=28
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 8,   offset=32
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 9,   offset=36
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = :,   offset=40
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = ;,   offset=44
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = <,   offset=48
+( SEGD+!SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = =,   offset=52
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = >,   offset=56
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ?,   offset=60
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = @,   offset=64
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = A,   offset=68
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = B,   offset=72
+( SEGD+ SEGE+ SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = C,   offset=76
+( SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = D,   offset=80
+( SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = E,   offset=84
+(!SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = F,   offset=88
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = G,   offset=92
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = H,   offset=96
+(!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = I,   offset=100
+( SEGD+ SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = J,   offset=104
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = K,   offset=108
+( SEGD+ SEGE+ SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = L,   offset=112
+(!SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = M,   offset=116
+(!SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = N,   offset=120
+( SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = O,   offset=124
+(!SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+ SEGB+ SEGA) ,//Char = P,   offset=128
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = Q,   offset=132
+(!SEGD+ SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = R,   offset=136
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = S,   offset=140
+( SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = T,   offset=144
+( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = U,   offset=148
+( SEGD+ SEGE+!SEGF+!SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = V,   offset=152
+( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = W,   offset=156
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = X,   offset=160
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = Y,   offset=164
+( SEGD+!SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = Z,   offset=168
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = [,   offset=172
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = \,   offset=176
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ],   offset=180
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ^,   offset=184
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = _,   offset=188
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = `,   offset=192
+};
+
+SLCD::SLCD() {
+    init();
+    CharPosition = 0;    
+}
+
+void SLCD::init(){
+    SIM->SCGC5 |= SIM_SCGC5_SLCD_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
+     
+    // configure pins for LCD operation    
+  PORTC->PCR[20] = 0x00000000;     //VLL2
+  PORTC->PCR[21] = 0x00000000;     //VLL1
+  PORTC->PCR[22] = 0x00000000;     //VCAP2
+  PORTC->PCR[23] = 0x00000000;     //VCAP1     
+    // Enable IRCLK 
+     MCG->C1  = MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK;
+     MCG->C2 &= ~MCG_C2_IRCS_MASK ;  //0 32KHZ internal reference clock; 1= 4MHz irc     
+     LCD->GCR = 0x0;
+     LCD->AR  = 0x0;     
+    // LCD configurartion     
+      LCD->GCR =   ( LCD_GCR_RVEN_MASK*_LCDRVEN  
+                   | LCD_GCR_RVTRIM(_LCDRVTRIM)         //0-15
+                   | LCD_GCR_CPSEL_MASK*_LCDCPSEL 
+                   | LCD_GCR_LADJ(_LCDLOADADJUST)       //0-3
+                   | LCD_GCR_VSUPPLY_MASK*_LCDSUPPLY    //0-1
+                   |!LCD_GCR_FDCIEN_MASK
+                   | LCD_GCR_ALTDIV(_LCDALTDIV)         //0-3
+                   |!LCD_GCR_LCDDOZE_MASK  
+                   |!LCD_GCR_LCDSTP_MASK
+                   |!LCD_GCR_LCDEN_MASK                 //WILL BE ENABLE ON SUBSEQUENT STEP
+                   | LCD_GCR_SOURCE_MASK*_LCDCLKSOURCE
+                   | LCD_GCR_ALTSOURCE_MASK*_LCDALRCLKSOURCE  
+                   | LCD_GCR_LCLK(_LCDLCK)    //0-7
+                   | LCD_GCR_DUTY(_LCDDUTY)   //0-7
+                 );    
+   uint8_t i;
+   uint32_t *p_pen;
+   uint8_t pen_offset;   // 0 or 1   
+   uint8_t pen_bit;      // 0 to 31
+   LCD->PEN[0] = 0x0;
+   LCD->PEN[1] = 0x0;
+   LCD->BPEN[0] = 0x0;
+   LCD->BPEN[1] = 0x0;   
+   p_pen = (uint32_t *)&LCD->PEN[0];
+    for (i=0;i<_LCDUSEDPINS;i++) 
+    {
+      pen_offset = WF_ORDERING_TABLE[i]/32;
+      pen_bit    = WF_ORDERING_TABLE[i]%32;
+      p_pen[pen_offset] |= 1 << pen_bit;
+      if (i>= _LCDFRONTPLANES)    // Pin is a backplane
+      {
+        p_pen[pen_offset+2] |= 1 << pen_bit;  // Enable  BPEN 
+        LCD->WF8B[(uint8_t)WF_ORDERING_TABLE[i]] = 1 << (i - _LCDFRONTPLANES);   // fill with 0x01, 0x02, etc 
+      } 
+    }    
+      LCD->GCR |= LCD_GCR_LCDEN_MASK;
+}
+
+int SLCD::_putc(int c) {
+    Write_Char(c);
+    return 0;
+}
+
+void SLCD::Write_Char (char lbValue) {
+  uint8_t char_val;
+  uint8_t temp;
+  uint8_t *lbpLCDWF;
+  uint8_t lbCounter;
+  uint16_t arrayOffset;
+  uint8_t position;
+  
+  if (CharPosition >= _CHARNUM)
+    CharPosition = 0;  
+  lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+  /* only ascii character if value not writeable write as @ */
+  if (lbValue>='a' && lbValue<='z') {
+    lbValue -= 32; // UpperCase
+  }
+  if (lbValue<ASCCI_TABLE_START || lbValue >ASCCI_TABLE_END) {
+    lbValue = BLANK_CHARACTER;  // default value as space
+  }
+  lbValue -=ASCCI_TABLE_START;        // Remove the offset to search in the ascci table
+  arrayOffset = (lbValue * _CHAR_SIZE); // Compensate matrix offset
+  // ensure bLCD position is in valid limit
+  lbCounter = 0;  //number of writings to complete one char
+  while (lbCounter<_CHAR_SIZE) {
+    position = (CharPosition) *_LCDTYPE + lbCounter; 
+    temp=0;
+    if (lbCounter==1) {
+      temp = lbpLCDWF[WF_ORDERING_TABLE[position]] & 0x01;//bit 0 has the special symbol information
+    } 
+    char_val = ASCII_TO_WF_CODIFICATION_TABLE[arrayOffset + lbCounter];
+    lbpLCDWF[WF_ORDERING_TABLE[position]] = char_val | temp;
+    //  if (char_val==0) lbCounter = _CHAR_SIZE; //end of this character
+    lbCounter++;
+  }  
+  CharPosition++;
+}
+
+void SLCD::Home (void)
+ {
+      CharPosition =  0;
+ }
+
+void SLCD::Contrast (uint8_t lbContrast)
+{ 
+       lbContrast &= 0x0F;              //Forced to the only values accepted 
+       LCD->GCR |= LCD_GCR_RVTRIM(lbContrast);
+}
+ 
+void SLCD::All_Segments (int mode)
+{
+ uint8_t lbTotalBytes = _CHARNUM * _LCDTYPE;              
+ uint8_t lbCounter=0;
+ uint8_t *lbpLCDWF;
+ 
+    lbpLCDWF = (uint8_t *)&LCD->WF8B[0];      
+        while (lbCounter < lbTotalBytes)
+          {
+              if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[lbCounter++]]=_ALLON;}
+                else {lbpLCDWF[WF_ORDERING_TABLE[lbCounter++]]=0;}
+          }         
+}
+
+void SLCD::DP1 (int mode)
+{
+  uint8_t *lbpLCDWF; 
+    lbpLCDWF = (uint8_t *)&LCD->WF8B[0];       
+        if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[1]]|=1;}
+            else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[1]]&=~1;}                
+}
+ 
+void SLCD::DP2 (int mode)
+{
+  uint8_t *lbpLCDWF; 
+    lbpLCDWF = (uint8_t *)&LCD->WF8B[0];       
+        if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[3]]|=1;}
+            else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[3]]&=~1;}               
+} 
+
+void SLCD::DP3 (int mode)
+{
+  uint8_t *lbpLCDWF; 
+    lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+        if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[5]]|=1;}
+            else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[5]]&=~1;}
+}
+ 
+void SLCD::Colon (int mode)
+{
+  uint8_t *lbpLCDWF; 
+    lbpLCDWF = (uint8_t *)&LCD->WF8B[0];     
+        if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[7]]|=1;}
+            else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[7]]&=~1;}                 
+}
+ 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/SLCD.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,44 @@
+#include "mbed.h"
+
+
+/*  ------ sample usage------
+
+    #include "mbed.h"
+    #include "SLCD.h"
+    
+    SLCD slcd;
+    
+    main()
+    {
+        slcd.printf("1234");    // standard printf function, only charaters in ASCII_TO_WF_CODIFICATION_TABLE will display
+        slcd.putc("A");         // prints a single character 
+        slcd.Write_Char('A');   // prints a single character
+        slcd.All_Segments(y);   // y=1 for ALL segments on, 0 for ALL segments off  
+        slcd.DPx(y);            // x=DP1 to DP3, y=1 for on 0 for off
+        slcd.Colon(y);          // y=1 for on, 0 for off
+        slcd.CharPosition=x;    // x=0 to 3, 0 is start position
+        slcd.Home();            // sets next charater to posistion 0 (start)
+        slcd.Contrast (x);      // set contrast x=0 - 15, 0 lightest, 15 darkest    
+    }   
+*/
+
+class SLCD : public Stream {
+    public:
+    SLCD();
+    
+    void init();
+    void Write_Char(char lbValue);
+    void Home (void);
+    void Contrast (uint8_t lbContrast);
+    void All_Segments (int);     
+    void DP1 (int);
+    void DP2 (int);
+    void DP3 (int);
+    void Colon (int);     
+    uint8_t CharPosition;
+         
+    virtual int _putc(int c);
+    virtual int _getc() {
+        return 0;
+    }  
+};
--- a/TSI.lib	Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/vsluiter/code/TSI/#4dc2f5a3a731
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TSI/TSISensor.cpp	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,254 @@
+/* Freescale Semiconductor Inc.
+ * (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
+ * (c) Copyright 2001-2004 Motorola, Inc. 
+ *
+ * mbed Microcontroller Library
+ * (c) Copyright 2009-2012 ARM Limited.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+#include "TSISensor.h"
+
+#define NO_TOUCH                 0
+#define SLIDER_LENGTH           40 //LENGTH in mm
+#define TOTAL_ELECTRODE          3
+
+#define TSI0a        0
+#define TSI1         1
+#define TSI2         2
+#define TSI3         3
+#define TSI4         4
+#define TSI5         5
+#define TSI6         6
+#define TSI7         7
+#define TSI8         8
+#define TSI9         9
+#define TSI10        10
+#define TSI11        11
+#define TSI12        12
+#define TSI13        13
+#define TSI14        14
+#define TSI15        15
+
+/*Chose the correct TSI channel for the electrode number*/
+#define ELECTRODE0   TSI9
+#define ELECTRODE1   TSI10
+#define ELECTRODE2   TSI0a
+#define ELECTRODE3   TSI1
+#define ELECTRODE4   TSI2
+#define ELECTRODE5   TSI3
+#define ELECTRODE6   TSI4
+#define ELECTRODE7   TSI5
+#define ELECTRODE8   TSI6
+#define ELECTRODE9   TSI7
+#define ELECTRODE10  TSI8
+#define ELECTRODE11  TSI11
+#define ELECTRODE12  TSI12
+#define ELECTRODE13  TSI13
+#define ELECTRODE14  TSI14
+#define ELECTRODE15  TSI15
+
+#define THRESHOLD0   100
+#define THRESHOLD1   100
+#define THRESHOLD2   100
+#define THRESHOLD3   100
+#define THRESHOLD4   100
+#define THRESHOLD5   100
+#define THRESHOLD6   100
+#define THRESHOLD7   100
+#define THRESHOLD8   100
+#define THRESHOLD9   100
+#define THRESHOLD10   100
+#define THRESHOLD11   100
+#define THRESHOLD12   100
+#define THRESHOLD13   100
+#define THRESHOLD14   100
+#define THRESHOLD15   100
+
+static uint8_t total_electrode = TOTAL_ELECTRODE;
+static uint8_t elec_array[16]={ELECTRODE0,ELECTRODE1,ELECTRODE2,ELECTRODE3,ELECTRODE4,ELECTRODE5,
+                               ELECTRODE6,ELECTRODE7,ELECTRODE8,ELECTRODE9,ELECTRODE10,ELECTRODE11,
+                               ELECTRODE12,ELECTRODE13,ELECTRODE14,ELECTRODE15};
+static uint16_t gu16TSICount[16];
+static uint16_t gu16Baseline[16];
+static uint16_t gu16Threshold[16]={THRESHOLD0,THRESHOLD1,THRESHOLD2,THRESHOLD3,THRESHOLD4,THRESHOLD5,
+                                   THRESHOLD6,THRESHOLD7,THRESHOLD8,THRESHOLD9,THRESHOLD10,THRESHOLD11,
+                                   THRESHOLD12,THRESHOLD13,THRESHOLD14,THRESHOLD15};
+static uint16_t gu16Delta[16];
+static uint8_t ongoing_elec;
+static uint8_t end_flag = 1;
+
+static uint8_t SliderPercentegePosition[2] = {NO_TOUCH,NO_TOUCH};
+static uint8_t SliderDistancePosition[2] = {NO_TOUCH,NO_TOUCH};
+static uint32_t AbsolutePercentegePosition = NO_TOUCH;
+static uint32_t AbsoluteDistancePosition = NO_TOUCH;
+
+static void tsi_irq();
+
+TSISensor::TSISensor() {
+    SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
+    SIM->SCGC5 |= SIM_SCGC5_TSI_MASK;
+
+    TSI0->GENCS |= (TSI_GENCS_ESOR_MASK
+                   | TSI_GENCS_MODE(0)
+                   | TSI_GENCS_REFCHRG(4)
+                   | TSI_GENCS_DVOLT(0)
+                   | TSI_GENCS_EXTCHRG(7)
+                   | TSI_GENCS_PS(4)
+                   | TSI_GENCS_NSCN(11)
+                   | TSI_GENCS_TSIIEN_MASK
+                   | TSI_GENCS_STPE_MASK
+                   );
+
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;
+
+    NVIC_SetVector(TSI0_IRQn, (uint32_t)&tsi_irq);
+    NVIC_EnableIRQ(TSI0_IRQn);
+
+    selfCalibration();
+}
+
+void TSISensor::TSISensor_reset(void) {
+    SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
+    SIM->SCGC5 |= SIM_SCGC5_TSI_MASK;
+
+    TSI0->GENCS |= (TSI_GENCS_ESOR_MASK
+                   | TSI_GENCS_MODE(0)
+                   | TSI_GENCS_REFCHRG(4)
+                   | TSI_GENCS_DVOLT(0)
+                   | TSI_GENCS_EXTCHRG(7)
+                   | TSI_GENCS_PS(4)
+                   | TSI_GENCS_NSCN(11)
+                   | TSI_GENCS_TSIIEN_MASK
+                   | TSI_GENCS_STPE_MASK
+                   );
+
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;
+
+    //NVIC_SetVector(TSI0_IRQn, (uint32_t)&tsi_irq);
+    //NVIC_EnableIRQ(TSI0_IRQn);
+
+    selfCalibration();
+}
+
+void TSISensor::selfCalibration(void)
+{
+    unsigned char cnt;
+    unsigned char trigger_backup;
+
+    TSI0->GENCS |= TSI_GENCS_EOSF_MASK;      // Clear End of Scan Flag
+    TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK;    // Disable TSI module
+
+    if(TSI0->GENCS & TSI_GENCS_STM_MASK)     // Back-up TSI Trigger mode from Application
+        trigger_backup = 1;
+    else
+        trigger_backup = 0;
+
+    TSI0->GENCS &= ~TSI_GENCS_STM_MASK;      // Use SW trigger
+    TSI0->GENCS &= ~TSI_GENCS_TSIIEN_MASK;    // Enable TSI interrupts
+
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;     // Enable TSI module
+
+    for(cnt=0; cnt < total_electrode; cnt++)  // Get Counts when Electrode not pressed
+    {
+        TSI0->DATA = ((elec_array[cnt] << TSI_DATA_TSICH_SHIFT) );
+        TSI0->DATA |= TSI_DATA_SWTS_MASK;
+        while(!(TSI0->GENCS & TSI_GENCS_EOSF_MASK));
+        TSI0->GENCS |= TSI_GENCS_EOSF_MASK;
+        gu16Baseline[cnt] = (TSI0->DATA & TSI_DATA_TSICNT_MASK);
+    }
+
+    TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK;    // Disable TSI module
+    TSI0->GENCS |= TSI_GENCS_TSIIEN_MASK;     // Enale TSI interrupt
+    if(trigger_backup)                      // Restore trigger mode
+        TSI0->GENCS |= TSI_GENCS_STM_MASK;
+    else
+        TSI0->GENCS &= ~TSI_GENCS_STM_MASK;
+
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;     // Enable TSI module
+
+    TSI0->DATA = ((elec_array[0]<<TSI_DATA_TSICH_SHIFT) );
+    TSI0->DATA |= TSI_DATA_SWTS_MASK;
+}
+
+void TSISensor::sliderRead(void ) {
+    if(end_flag) {
+        end_flag = 0;
+        if((gu16Delta[0] > gu16Threshold[0])||(gu16Delta[1] > gu16Threshold[1])) {
+            SliderPercentegePosition[0] = (gu16Delta[0]*100)/(gu16Delta[0]+gu16Delta[1]);
+            SliderPercentegePosition[1] = (gu16Delta[1]*100)/(gu16Delta[0]+gu16Delta[1]);
+            SliderDistancePosition[0] = (SliderPercentegePosition[0]* SLIDER_LENGTH)/100;
+            SliderDistancePosition[1] = (SliderPercentegePosition[1]* SLIDER_LENGTH)/100;
+            AbsolutePercentegePosition = ((100 - SliderPercentegePosition[0]) + SliderPercentegePosition[1])/2;
+            AbsoluteDistancePosition = ((SLIDER_LENGTH - SliderDistancePosition[0]) + SliderDistancePosition[1])/2;
+         } else {
+            SliderPercentegePosition[0] = NO_TOUCH;
+            SliderPercentegePosition[1] = NO_TOUCH;
+            SliderDistancePosition[0] = NO_TOUCH;
+            SliderDistancePosition[1] = NO_TOUCH;
+            AbsolutePercentegePosition = NO_TOUCH;
+            AbsoluteDistancePosition = NO_TOUCH;
+         }
+    }
+}
+
+float TSISensor::readPercentage() {
+    sliderRead();
+    return (float)AbsolutePercentegePosition/100.0;
+}
+
+uint8_t TSISensor::readDistance() {
+    sliderRead();
+    return AbsoluteDistancePosition;
+}
+
+uint16_t TSISensor::readValue(uint8_t index)
+{
+    return gu16TSICount[index];
+}
+
+static void changeElectrode(void)
+{
+    int16_t u16temp_delta;
+
+    gu16TSICount[ongoing_elec] = (TSI0->DATA & TSI_DATA_TSICNT_MASK);          // Save Counts for current electrode
+    u16temp_delta = gu16TSICount[ongoing_elec] - gu16Baseline[ongoing_elec];  // Obtains Counts Delta from callibration reference
+    if(u16temp_delta < 0)
+        gu16Delta[ongoing_elec] = 0;
+    else
+        gu16Delta[ongoing_elec] = u16temp_delta;
+
+    //Change Electrode to Scan
+    if(total_electrode > 1)  
+    {
+        if((total_electrode-1) > ongoing_elec)
+            ongoing_elec++;
+        else
+            ongoing_elec = 0;
+
+        TSI0->DATA = ((elec_array[ongoing_elec]<<TSI_DATA_TSICH_SHIFT) );
+        TSI0->DATA |= TSI_DATA_SWTS_MASK;
+    }
+}
+
+void tsi_irq(void)
+{
+    end_flag = 1;
+    TSI0->GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
+    changeElectrode();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TSI/TSISensor.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,73 @@
+/* Freescale Semiconductor Inc.
+ * (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
+ * (c) Copyright 2001-2004 Motorola, Inc. 
+ *
+ * mbed Microcontroller Library
+ * (c) Copyright 2009-2012 ARM Limited.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TSISENSOR_H
+#define TSISENSOR_H
+
+/**
+* TSISensor example
+*
+* @code
+* #include "mbed.h"
+* #include "TSISensor.h"
+* 
+* int main(void) {
+*     PwmOut led(LED_GREEN);
+*     TSISensor tsi;
+*     
+*     while (true) {
+*         led = 1.0 - tsi.readPercentage();
+*         wait(0.1);
+*     }
+* }
+* @endcode
+*/
+class TSISensor {
+public:
+    /**
+     *   Initialize the TSI Touch Sensor
+     */
+    TSISensor();
+
+    /**
+     * Read Touch Sensor percentage value
+     *
+     * @returns percentage value between [0 ... 1]
+     */
+    float readPercentage();
+
+    /**
+     * Read Touch Sensor distance
+     *
+     * @returns distance in mm. The value is between [0 ... 40]
+     */
+    uint8_t readDistance();
+    uint16_t readValue(uint8_t);
+    void TSISensor_reset(void);
+
+private:
+    void sliderRead(void);
+    void selfCalibration(void);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src.lib	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-src/#8435094ec241
--- a/mbed.bld	Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/7d30d6019079
\ No newline at end of file
--- a/pt.lib	Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-pt#738c912b9ca3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/graham-pt.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. 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. 
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 THE INSTITUTE OR CONTRIBUTORS 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. 
+ *
+ * This file is part of the Contiki operating system.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: graham-pt.h,v 1.1 2005/10/04 08:30:05 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+  lc_t lc;
+};
+
+/**
+ * Extended PT.
+ * This add's a flags field to the basic pt structure.
+ */
+struct ptx {
+  lc_t lc;
+  unsigned short flags;
+};
+
+#define PT_THREAD_WAITING 0
+#define PT_THREAD_EXITED  1
+
+/** Extended PT flag : thread is sleeping */
+#define PT_F_SLEEPING 1
+/** Extended PT flag : thread has been flagged to be killed (will exit on next block/wait/yield) */
+#define PT_F_KILL     2
+/** Extended PT flag : thread is waiting */
+#define PT_F_WAITING  4
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * Example:
+ \code
+ PT_THREAD(consumer(struct pt *p, int event)) {
+   PT_BEGIN(p);
+   while(1) {
+     PT_WAIT_UNTIL(p, event == AVAILABLE);
+     consume();
+     PT_WAIT_UNTIL(p, event == CONSUMED);
+     acknowledge_consumed();
+   }
+   PT_END(p);
+ }
+ \endcode
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * Example:
+ *
+ \code
+ void main(void) {
+   struct pt p;
+   int event;
+   
+   PT_INIT(&p);
+   while(PT_SCHEDULE(consumer(&p, event))) {
+     event = get_event();
+   }
+ }
+ \endcode
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt)   LC_INIT((pt)->lc)
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * Example:
+ *
+ \code
+ PT_THREAD(producer(struct pt *p, int event)) {
+   PT_BEGIN(p);
+   while(1) {
+     PT_WAIT_UNTIL(p, event == CONSUMED || event == DROPPED);
+     produce();
+     PT_WAIT_UNTIL(p, event == PRODUCED);
+   }
+   
+   PT_END(p);
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) LC_RESUME((pt)->lc)
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * Example:
+ \code
+ PT_THREAD(seconds(struct pt *p)) {
+   PT_BEGIN(p);
+
+   PT_WAIT_UNTIL(p, time >= 2 * SECOND);
+   printf("Two seconds have passed\n");
+   
+   PT_END(p);
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)	        \
+  do {						\
+    LC_SET((pt)->lc);				\
+    if(sizeof(*(pt))==sizeof(struct ptx)) \
+    { \
+      if(((struct ptx*)(pt))->flags&PT_F_KILL) \
+      { \
+        PT_INIT(pt);				\
+        return PT_THREAD_EXITED; \
+      } \
+      if(condition) \
+        ((struct ptx*)(pt))->flags&=PT_F_WAITING; \
+      else \
+        ((struct ptx*)(pt))->flags|=PT_F_WAITING; \
+      if(((struct ptx*)(pt))->flags&PT_F_WAITING) {				\
+        return PT_THREAD_WAITING;			\
+      }						\
+    }else{ \
+      if(!(condition)) {				\
+        return PT_THREAD_WAITING;			\
+      }						\
+    } \
+  } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * Example:
+ \code
+ PT_THREAD(child(struct pt *p, int event)) {
+   PT_BEGIN(p);
+
+   PT_WAIT_UNTIL(p, event == EVENT1);   
+   
+   PT_END(p);
+ }
+
+ PT_THREAD(parent(struct pt *p, struct pt *child_pt, int event)) {
+   PT_BEGIN(p);
+
+   PT_INIT(child_pt);
+   
+   PT_WAIT_THREAD(p, child(child_pt, event));
+   
+   PT_END(p);
+ }
+ \endcode
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer 
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * Example:
+ \code
+ static struct pt parent_pt, child_pt;
+ int should_spawn_flag;
+
+ PT_THREAD(child(struct pt *pt)) {
+   PT_BEGIN(pt);
+
+   while(all_items_processed()) {
+     process_item();
+     PT_WAIT_UNTIL(pt, item_processed());
+   }
+   
+   PT_END(pt);
+ }
+ 
+ PT_THREAD(parent(void)) {
+   PT_BEGIN(&parent_pt);
+
+   if(should_spawn_flag) {
+     PT_SPAWN(&parent_pt, &child_pt, child(&child_pt));
+   }
+   
+   PT_END(&parent_pt);
+ }
+ \endcode
+ *
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)		\
+  do {						\
+    PT_INIT((child));				\
+    PT_WAIT_THREAD((pt), (thread));		\
+  } while(0)
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)				\
+  do {						\
+    PT_INIT(pt);				\
+    return PT_THREAD_WAITING;			\
+  } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)				\
+  do {						\
+    PT_INIT(pt);				\
+    return PT_THREAD_EXITED;			\
+  } while(0)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It should
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_EXIT(pt)
+
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * Example
+ \code
+ void main(void) {
+   struct pt p;
+   int event;
+   
+   PT_INIT(&p);
+   while(PT_SCHEDULE(consumer(&p, event))) {
+     event = get_event();
+   }   
+ }
+ \endcode
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) (f == PT_THREAD_WAITING)
+
+/**
+ * Declarare that a protothread can yield.
+ *
+ * If a protothread should be able to yield with the PT_YIELD()
+ * statement, this flag must be placed first in the protothread's
+ * function body.
+ *
+ * Example:
+ \code
+ static
+ PT_THREAD(loop_thread(struct pt *pt))
+ {
+   PT_YIELDING();
+   static int i;
+
+   PT_BEGIN(pt);
+   
+   for(i = 0; i < 200; ++i) {
+     handle_item(i);
+     PT_YIELD(pt);
+   }
+   
+   PT_END(pt);
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define PT_YIELDING() char pt_yielded = 1
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \note The PT_YIELDING() flag must be placed first in the
+ * protothread's body if the PT_YIELD() function should be used.
+ *
+ * Example
+ \code
+static
+PT_THREAD(fade(struct pt *pt))
+{
+  PT_YIELDING();
+  static int delay;
+  
+  PT_BEGIN(pt);
+  
+  for(delay = 3980; delay > 20; delay -= 20) {
+    leds_red(LEDS_ON);
+    clock_delay(4000 - delay);
+    leds_red(LEDS_OFF);
+    clock_delay(delay);
+    PT_YIELD(pt);
+  }
+  
+  PT_END(pt);
+}
+ \endcode
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)				\
+  do {						\
+    pt_yielded = 0;				\
+    PT_WAIT_UNTIL(pt, pt_yielded);		\
+  } while(0)
+
+/*
+ * Extended Protothread API.
+ * The following functions require a struct ptx, rather than a plan struct pt.
+ */  
+  
+/**
+ * Put a protothread to sleep.
+ * Execution of the thread won't continue until another thread explicitly wakes the thread
+ * with PT_WAKE().
+ * Requires a ptx.
+ */
+#define PT_SLEEP(ptx)	\
+  do {						\
+    ptx->flags|=PT_F_SLEEPING; \
+    PT_WAIT_UNTIL(ptx, (((ptx)->flags&PT_F_SLEEPING)==0));		\
+  } while(0)
+
+/**
+ * Wake a protothread.
+ * Wake up a protothread if it is sleeping (ie. has called PT_SLEEP()) - if the thread isn't sleeping,
+ * then it has no effect.
+ * NOTE: Requires a ptx.
+ */
+#define PT_WAKE(ptx) (ptx)->flags&=~PT_F_SLEEPING
+
+/**
+ * Kill a protothread.
+ * The thread is marked with the kill flag and will exit next time the thread sleeps/waits/yields.
+ * NOTE: Requires a ptx.
+ */
+#define PT_KILL(ptx) (ptx)->flags&=~PT_F_KILL
+
+/**
+ * Is a protothread blocked?
+ * Returns non-zero is the thread is waiting.
+ * NOTE: Requires a ptx.
+ */
+#define PT_ISBLOCKED(ptx) ((ptx)->flags&PT_F_WAITING)
+  
+#endif /* __PT_H__ */
+
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/lc-addrlabels.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 THE INSTITUTE OR CONTRIBUTORS 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.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h,v 1.4 2006/06/03 11:29:43 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+#define LC_RESUME(s)				\
+  do {						\
+    if(s != NULL) {				\
+      goto *s;					\
+    }						\
+  } while(0)
+
+#define LC_CONCAT2(s1, s2) s1##s2
+#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
+
+#define LC_SET(s)				\
+  do {						\
+    LC_CONCAT(LC_LABEL, __LINE__):   	        \
+    (s) = &&LC_CONCAT(LC_LABEL, __LINE__);	\
+  } while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/lc-switch.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 THE INSTITUTE OR CONTRIBUTORS 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.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h,v 1.4 2006/06/03 11:29:43 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWITCH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+   LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/lc.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. 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. 
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 THE INSTITUTE OR CONTRIBUTORS 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. 
+ *
+ * This file is part of the protothreads library.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h,v 1.2 2005/02/24 10:36:59 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer 
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+
+#ifdef LC_INCLUDE
+#include LC_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/pt-sem.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. 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. 
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 THE INSTITUTE OR CONTRIBUTORS 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. 
+ *
+ * This file is part of the protothreads library.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt-sem.h,v 1.2 2005/02/24 10:36:59 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup ptsem Protothread semaphores
+ * @{
+ *
+ * This module implements counting semaphores on top of
+ * protothreads. Semaphores are a synchronization primitive that
+ * provide two operations: "wait" and "signal". The "wait" operation
+ * checks the semaphore counter and blocks the thread if the counter
+ * is zero. The "signal" operation increases the semaphore counter but
+ * does not block. If another thread has blocked waiting for the
+ * semaphore that is signalled, the blocked thread will become
+ * runnable again.
+ *
+ * Semaphores can be used to implement other, more structured,
+ * synchronization primitives such as monitors and message
+ * queues/bounded buffers (see below).
+ *
+ * The following example shows how the producer-consumer problem, also
+ * known as the bounded buffer problem, can be solved using
+ * protothreads and semaphores. Notes on the program follow after the
+ * example.
+ *
+ \code
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static struct pt_sem mutex, full, empty;
+
+PT_THREAD(producer(struct pt *pt))
+{
+  static int produced;
+  
+  PT_BEGIN(pt);
+  
+  for(produced = 0; produced < NUM_ITEMS; ++produced) {
+  
+    PT_SEM_WAIT(pt, &full);
+    
+    PT_SEM_WAIT(pt, &mutex);
+    add_to_buffer(produce_item());    
+    PT_SEM_SIGNAL(pt, &mutex);
+    
+    PT_SEM_SIGNAL(pt, &empty);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(consumer(struct pt *pt))
+{
+  static int consumed;
+  
+  PT_BEGIN(pt);
+
+  for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+    
+    PT_SEM_WAIT(pt, &empty);
+    
+    PT_SEM_WAIT(pt, &mutex);    
+    consume_item(get_from_buffer());    
+    PT_SEM_SIGNAL(pt, &mutex);
+    
+    PT_SEM_SIGNAL(pt, &full);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(driver_thread(struct pt *pt))
+{
+  static struct pt pt_producer, pt_consumer;
+
+  PT_BEGIN(pt);
+  
+  PT_SEM_INIT(&empty, 0);
+  PT_SEM_INIT(&full, BUFSIZE);
+  PT_SEM_INIT(&mutex, 1);
+
+  PT_INIT(&pt_producer);
+  PT_INIT(&pt_consumer);
+
+  PT_WAIT_THREAD(pt, producer(&pt_producer) &
+		     consumer(&pt_consumer));
+
+  PT_END(pt);
+}
+ \endcode
+ *
+ * The program uses three protothreads: one protothread that
+ * implements the consumer, one thread that implements the producer,
+ * and one protothread that drives the two other protothreads. The
+ * program uses three semaphores: "full", "empty" and "mutex". The
+ * "mutex" semaphore is used to provide mutual exclusion for the
+ * buffer, the "empty" semaphore is used to block the consumer is the
+ * buffer is empty, and the "full" semaphore is used to block the
+ * producer is the buffer is full.
+ *
+ * The "driver_thread" holds two protothread state variables,
+ * "pt_producer" and "pt_consumer". It is important to note that both
+ * these variables are declared as <i>static</i>. If the static
+ * keyword is not used, both variables are stored on the stack. Since
+ * protothreads do not store the stack, these variables may be
+ * overwritten during a protothread wait operation. Similarly, both
+ * the "consumer" and "producer" protothreads declare their local
+ * variables as static, to avoid them being stored on the stack.
+ * 
+ *
+ */
+   
+/**
+ * \file
+ * Couting semaphores implemented on protothreads
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_SEM_H__
+#define __PT_SEM_H__
+
+#include "pt.h"
+
+struct pt_sem {
+  unsigned int count;
+};
+
+/**
+ * Initialize a semaphore
+ *
+ * This macro initializes a semaphore with a value for the
+ * counter. Internally, the semaphores use an "unsigned int" to
+ * represent the counter, and therefore the "count" argument should be
+ * within range of an unsigned int.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \param c (unsigned int) The initial count of the semaphore.
+ * \hideinitializer
+ */
+#define PT_SEM_INIT(s, c) (s)->count = c
+
+/**
+ * Wait for a semaphore
+ *
+ * This macro carries out the "wait" operation on the semaphore. The
+ * wait operation causes the protothread to block while the counter is
+ * zero. When the counter reaches a value larger than zero, the
+ * protothread will continue.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_WAIT(pt, s)	\
+  do {						\
+    PT_WAIT_UNTIL(pt, (s)->count > 0);		\
+    --(s)->count;				\
+  } while(0)
+
+/**
+ * Signal a semaphore
+ *
+ * This macro carries out the "signal" operation on the semaphore. The
+ * signal operation increments the counter inside the semaphore, which
+ * eventually will cause waiting protothreads to continue executing.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_SIGNAL(pt, s) ++(s)->count
+
+#endif /* __PT_SEM_H__ */
+
+/** @} */
+/** @} */
+   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/pt.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 THE INSTITUTE OR CONTRIBUTORS 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.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h,v 1.7 2006/10/02 07:52:56 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+  lc_t lc;
+};
+
+#define PT_WAITING 0
+#define PT_YIELDED 1
+#define PT_EXITED  2
+#define PT_ENDED   3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt)   LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+                   PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)	        \
+  do {						\
+    LC_SET((pt)->lc);				\
+    if(!(condition)) {				\
+      return PT_WAITING;			\
+    }						\
+  } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)		\
+  do {						\
+    PT_INIT((child));				\
+    PT_WAIT_THREAD((pt), (thread));		\
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)				\
+  do {						\
+    PT_INIT(pt);				\
+    return PT_WAITING;			\
+  } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)				\
+  do {						\
+    PT_INIT(pt);				\
+    return PT_EXITED;			\
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)				\
+  do {						\
+    PT_YIELD_FLAG = 0;				\
+    LC_SET((pt)->lc);				\
+    if(PT_YIELD_FLAG == 0) {			\
+      return PT_YIELDED;			\
+    }						\
+  } while(0)
+
+/**
+ * \brief      Yield from the protothread until a condition occurs.
+ * \param pt   A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ *             This function will yield the protothread, until the
+ *             specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond)		\
+  do {						\
+    PT_YIELD_FLAG = 0;				\
+    LC_SET((pt)->lc);				\
+    if((PT_YIELD_FLAG == 0) || !(cond)) {	\
+      return PT_YIELDED;			\
+    }						\
+  } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */
--- a/sens_itf.lib	Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/marcelobarrosalmeida/code/sens_itf/#d3dffda90b26
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_itf.c	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,407 @@
+#include <string.h>
+#include <stdint.h>
+#include "sens_itf.h"
+#include "../util/buf_io.h"
+#include "../util/crc16.h"
+
+#define SENS_ITF_DBG_FRAME 1
+
+uint8_t sens_itf_unpack_point_value(sens_itf_cmd_point_t *point, uint8_t *buf)
+{
+    uint8_t size = 0;
+
+    switch (point->type)
+    {
+    case SENS_ITF_DT_U8:
+        point->value.u8 = buf_io_get8_fl(buf);
+        size = 1;
+        break;
+    case SENS_ITF_DT_S8:
+        point->value.s8 = buf_io_get8_fl(buf);
+        size = 1;
+        break;
+    case SENS_ITF_DT_U16:
+        point->value.u16 = buf_io_get16_fl(buf);
+        size = 2;
+        break;
+    case SENS_ITF_DT_S16:
+        point->value.s16 = buf_io_get16_fl(buf);
+        size = 2;
+        break;
+    case SENS_ITF_DT_U32:
+        point->value.u32 = buf_io_get32_fl(buf);
+        size = 4;
+        break;
+    case SENS_ITF_DT_S32:
+        point->value.s32 = buf_io_get32_fl(buf);
+        size = 4;
+        break;
+    case SENS_ITF_DT_U64:
+        point->value.u64 = buf_io_get64_fl(buf);
+        size = 8;
+        break;
+    case SENS_ITF_DT_S64:
+        point->value.s64 = buf_io_get64_fl(buf);
+        size = 8;
+        break;
+    case SENS_ITF_DT_FLOAT:
+        point->value.fp32 = buf_io_getf_fl(buf);
+        size = 4;
+        break;
+    case SENS_ITF_DT_DOUBLE:
+        point->value.fp64 = buf_io_getd_fl(buf);
+        size = 8;
+        break;
+    default:
+        break;
+    }
+
+    return size;
+}
+
+uint8_t sens_itf_pack_point_value(const sens_itf_cmd_point_t *point, uint8_t *buf)
+{
+    uint8_t size = 0;
+
+    switch (point->type)
+    {
+    case SENS_ITF_DT_U8:
+        buf_io_put8_tl(point->value.u8, buf);
+        size = 1;
+        break;
+    case SENS_ITF_DT_S8:
+        buf_io_put8_tl(point->value.s8, buf);
+        size = 1;
+        break;
+    case SENS_ITF_DT_U16:
+        buf_io_put16_tl(point->value.u16, buf);
+        size = 2;
+        break;
+    case SENS_ITF_DT_S16:
+        buf_io_put16_tl(point->value.s16, buf);
+        size = 2;
+        break;
+    case SENS_ITF_DT_U32:
+        buf_io_put32_tl(point->value.u32, buf);
+        size = 4;
+        break;
+    case SENS_ITF_DT_S32:
+        buf_io_put32_tl(point->value.s32, buf);
+        size = 4;
+        break;
+    case SENS_ITF_DT_U64:
+        buf_io_put64_tl(point->value.u64, buf);
+        size = 8;
+        break;
+    case SENS_ITF_DT_S64:
+        buf_io_put64_tl(point->value.s64, buf);
+        size = 8;
+        break;
+    case SENS_ITF_DT_FLOAT:
+        buf_io_putf_tl(point->value.fp32, buf);
+        size = 4;
+        break;
+    case SENS_ITF_DT_DOUBLE:
+        buf_io_putd_tl(point->value.fp64, buf);
+        size = 8;
+        break;
+    default:
+        break;
+    }
+
+    return size;
+}
+
+uint8_t sens_itf_unpack_cmd_req(sens_itf_cmd_req_t *cmd, uint8_t *frame, uint8_t frame_size)
+{
+    uint8_t *buf = frame;
+    uint16_t crc;
+    uint16_t frame_crc;
+    uint8_t size;
+
+    if (frame_size < 3)
+    {
+        //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Invalid frame size %d", frame_size));
+        return 0;
+    }
+    
+    // minimal header decoding
+    cmd->hdr.size = buf_io_get8_fl_ap(buf);
+    cmd->hdr.addr = buf_io_get8_fl_ap(buf);
+
+    frame_crc = buf_io_get16_fl(&frame[cmd->hdr.size]);
+    crc = crc16_calc(frame, cmd->hdr.size);
+    cmd->crc = frame_crc;
+
+    if (frame_crc != crc)
+    {
+        //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Invalid CRC %04X <> %04X", frame_crc, crc));
+        return 0;
+    }
+    
+    switch (cmd->hdr.addr)
+    {
+    case SENS_ITF_REGMAP_BRD_CMD:
+        cmd->payload.command_cmd.cmd = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_WRITE_BAT_STATUS:
+        cmd->payload.bat_status_cmd.status = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_WRITE_BAT_CHARGE:
+        cmd->payload.bat_charge_cmd.charge = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_DSP_WRITE:
+        cmd->payload.write_display_cmd.line = buf_io_get8_fl_ap(buf);
+        memcpy(cmd->payload.write_display_cmd.msg,buf,SENS_ITF_DSP_MSG_MAX_SIZE);
+        buf += SENS_ITF_DSP_MSG_MAX_SIZE;
+        break;
+    case SENS_ITF_REGMAP_WPAN_STATUS:
+        cmd->payload.wpan_status_cmd.status = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_WPAN_STRENGTH:
+        cmd->payload.wpan_strength_cmd.strenght = buf_io_get8_fl_ap(buf);
+        break;
+    default:
+        break;
+    }
+
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) && 
+        (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32))
+    {
+        //uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_WRITE_POINT_DATA_1;
+        cmd->payload.point_value_cmd.type =  buf_io_get8_fl_ap(buf);
+        buf += sens_itf_unpack_point_value(&cmd->payload.point_value_cmd, buf);
+    }
+
+    size = cmd->hdr.size + 2; // + crc 
+    return size;
+}
+
+uint8_t sens_itf_pack_cmd_res(sens_itf_cmd_res_t *cmd, uint8_t *frame)
+{
+    uint8_t *buf = &frame[1];
+    uint8_t size = 0;
+    uint16_t crc;
+
+    buf_io_put8_tl_ap(cmd->hdr.addr, buf);
+    buf_io_put8_tl_ap(cmd->hdr.status, buf);
+
+    // only fill command when status is OK, otherwise an error will be reported
+    if (cmd->hdr.status == SENS_ITF_ANS_OK)
+    {
+        switch (cmd->hdr.addr)
+        {
+        case SENS_ITF_REGMAP_ITF_VERSION:
+            buf_io_put8_tl_ap(cmd->payload.itf_version_cmd.version, buf);
+            break;
+        case SENS_ITF_REGMAP_BRD_ID:
+            memcpy(buf, cmd->payload.brd_id_cmd.model, SENS_ITF_MODEL_NAME_SIZE);
+            buf += SENS_ITF_MODEL_NAME_SIZE;
+            memcpy(buf, cmd->payload.brd_id_cmd.manufactor, SENS_ITF_MANUF_NAME_SIZE);
+            buf += SENS_ITF_MODEL_NAME_SIZE;
+            buf_io_put32_tl_ap(cmd->payload.brd_id_cmd.sensor_id, buf);
+            buf_io_put8_tl_ap(cmd->payload.brd_id_cmd.hardware_revision, buf);
+            buf_io_put8_tl_ap(cmd->payload.brd_id_cmd.num_of_points, buf);
+            buf_io_put8_tl_ap(cmd->payload.brd_id_cmd.cabalities, buf);
+            break;
+        case SENS_ITF_REGMAP_BRD_STATUS:
+            buf_io_put8_tl_ap(cmd->payload.brd_status_cmd.status, buf);
+            break;
+        case SENS_ITF_REGMAP_BRD_CMD:
+            buf_io_put8_tl_ap(cmd->payload.command_res_cmd.status, buf);
+            break;
+        case SENS_ITF_REGMAP_READ_BAT_STATUS:
+            buf_io_put8_tl_ap(cmd->payload.bat_status_cmd.status, buf);
+            break;
+        case SENS_ITF_REGMAP_READ_BAT_CHARGE:
+            buf_io_put8_tl_ap(cmd->payload.bat_charge_cmd.charge, buf);
+            break;
+        case SENS_ITF_REGMAP_SVR_MAIN_ADDR:
+        case SENS_ITF_REGMAP_SVR_SEC_ADDR:
+            memcpy(buf, cmd->payload.svr_addr_cmd.addr, SENS_ITF_SERVER_ADDR_SIZE);
+            buf += SENS_ITF_SERVER_ADDR_SIZE;
+            break;
+        default:
+            break;
+        }
+
+        if ((cmd->hdr.addr >= SENS_ITF_REGMAP_POINT_DESC_1) &&
+            (cmd->hdr.addr <= SENS_ITF_REGMAP_POINT_DESC_32))
+        {
+            //uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_POINT_DESC_1;
+            memcpy(buf, cmd->payload.point_desc_cmd.name, SENS_ITF_POINT_NAME_SIZE);
+            buf += SENS_ITF_POINT_NAME_SIZE;
+            buf_io_put8_tl_ap(cmd->payload.point_desc_cmd.type, buf);
+            buf_io_put8_tl_ap(cmd->payload.point_desc_cmd.unit, buf);
+            buf_io_put8_tl_ap(cmd->payload.point_desc_cmd.access_rights, buf);
+            buf_io_put32_tl_ap(cmd->payload.point_desc_cmd.sampling_time_x250ms, buf);
+        }
+
+        if ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+            (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32))
+        {
+            //uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_READ_POINT_DATA_1;
+            buf_io_put8_tl_ap(cmd->payload.point_value_cmd.type,buf);
+            buf += sens_itf_pack_point_value(&cmd->payload.point_value_cmd, buf);
+        }
+    }
+
+    size = buf - frame;
+    buf_io_put8_tl(size, frame);
+    crc = crc16_calc(frame, size);
+    cmd->crc = crc;
+    cmd->hdr.size = size;
+    buf_io_put16_tl(crc, buf);
+    
+    size += 2; // +crc 
+    return size;
+}
+
+
+uint8_t sens_itf_unpack_cmd_res(sens_itf_cmd_res_t * cmd, uint8_t *frame, uint8_t frame_size)
+{
+    uint8_t size;
+    uint8_t *buf = frame;
+    uint16_t crc;
+    uint16_t frame_crc;
+
+    if (frame_size < 3)
+    {
+        cmd->hdr.status = SENS_ITF_ANS_ERROR;
+        return 0;
+    }
+    
+    // minimal header decoding
+    cmd->hdr.size = buf_io_get8_fl_ap(buf);
+    cmd->hdr.addr = buf_io_get8_fl_ap(buf);
+    cmd->hdr.status = buf_io_get8_fl_ap(buf);
+
+    frame_crc = buf_io_get16_fl(&frame[cmd->hdr.size]);
+    crc = crc16_calc(frame, cmd->hdr.size);
+    cmd->crc = frame_crc;
+
+    if (frame_crc != crc)
+    {
+        //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Invalid CRC %04X <> %04X", frame_crc, crc));
+        cmd->hdr.status = SENS_ITF_ANS_CRC_ERROR;
+        return 0;
+    }
+
+    if (cmd->hdr.status != SENS_ITF_ANS_OK)
+    {
+        //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Response error %d", cmd->hdr.status));
+        return 0;
+    }
+
+    switch (cmd->hdr.addr)
+    {
+    case SENS_ITF_REGMAP_ITF_VERSION:
+        cmd->payload.itf_version_cmd.version = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_BRD_ID:
+        memcpy(cmd->payload.brd_id_cmd.model, buf, SENS_ITF_MODEL_NAME_SIZE);
+        buf += SENS_ITF_MODEL_NAME_SIZE;
+        memcpy(cmd->payload.brd_id_cmd.manufactor, buf, SENS_ITF_MANUF_NAME_SIZE);
+        buf += SENS_ITF_MODEL_NAME_SIZE;
+        cmd->payload.brd_id_cmd.sensor_id = buf_io_get32_fl_ap(buf);
+        cmd->payload.brd_id_cmd.hardware_revision = buf_io_get8_fl_ap(buf);
+        cmd->payload.brd_id_cmd.num_of_points = buf_io_get8_fl_ap(buf);
+        cmd->payload.brd_id_cmd.cabalities = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_BRD_STATUS:
+        cmd->payload.brd_status_cmd.status = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_BRD_CMD:
+        cmd->payload.command_res_cmd.status = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_READ_BAT_STATUS:
+        cmd->payload.bat_status_cmd.status = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_READ_BAT_CHARGE:
+        cmd->payload.bat_charge_cmd.charge = buf_io_get8_fl_ap(buf);
+        break;
+    case SENS_ITF_REGMAP_SVR_MAIN_ADDR:
+    case SENS_ITF_REGMAP_SVR_SEC_ADDR:
+        memcpy(cmd->payload.svr_addr_cmd.addr, buf, SENS_ITF_SERVER_ADDR_SIZE);
+        buf += SENS_ITF_SERVER_ADDR_SIZE;
+        break;
+    default:
+        break;
+    }
+
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_POINT_DESC_1) && 
+        (cmd->hdr.addr <= SENS_ITF_REGMAP_POINT_DESC_32))
+    {
+        memcpy(cmd->payload.point_desc_cmd.name, buf, SENS_ITF_POINT_NAME_SIZE);
+        buf += SENS_ITF_POINT_NAME_SIZE;
+        cmd->payload.point_desc_cmd.type = buf_io_get8_fl_ap(buf);
+        cmd->payload.point_desc_cmd.unit = buf_io_get8_fl_ap(buf);
+        cmd->payload.point_desc_cmd.access_rights = buf_io_get8_fl_ap(buf);
+        cmd->payload.point_desc_cmd.sampling_time_x250ms = buf_io_get32_fl_ap(buf);
+    }
+
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+        (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32))
+    {
+        cmd->payload.point_value_cmd.type = buf_io_get8_fl_ap(buf);
+        buf += sens_itf_unpack_point_value(&cmd->payload.point_value_cmd, buf);
+    }
+
+    size = cmd->hdr.size + 2; // crc 
+    return size;
+}
+
+uint8_t sens_itf_pack_cmd_req(sens_itf_cmd_req_t *cmd, uint8_t *frame)
+{
+    uint8_t *buf = &frame[1];
+    uint8_t size = 0;
+    uint16_t crc;
+
+    // address
+    // commands without arguments are handled only with this line
+    buf_io_put8_tl_ap(cmd->hdr.addr, buf);
+    
+    switch (cmd->hdr.addr)
+    {
+    case SENS_ITF_REGMAP_BRD_CMD:
+        buf_io_put8_tl_ap(cmd->payload.command_cmd.cmd, buf);
+        break;
+    case SENS_ITF_REGMAP_WRITE_BAT_STATUS:
+        buf_io_put8_tl_ap(cmd->payload.bat_status_cmd.status, buf);
+        break;
+    case SENS_ITF_REGMAP_WRITE_BAT_CHARGE:
+        buf_io_put8_tl_ap(cmd->payload.bat_charge_cmd.charge, buf);
+        break;
+    case SENS_ITF_REGMAP_DSP_WRITE:
+        buf_io_put8_tl_ap(cmd->payload.write_display_cmd.line, buf);
+        memcpy(buf, cmd->payload.write_display_cmd.msg, SENS_ITF_DSP_MSG_MAX_SIZE);
+        buf += SENS_ITF_DSP_MSG_MAX_SIZE;
+        break;
+    case SENS_ITF_REGMAP_WPAN_STATUS:
+        buf_io_put8_tl_ap(cmd->payload.wpan_status_cmd.status,buf);
+        break;
+    case SENS_ITF_REGMAP_WPAN_STRENGTH:
+        buf_io_put8_tl_ap(cmd->payload.wpan_strength_cmd.strenght,buf);
+        break;
+    default:
+        break;
+    }
+
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) && 
+        (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32))
+    {
+        buf_io_put8_tl_ap(cmd->payload.point_value_cmd.type, buf);
+        buf += sens_itf_pack_point_value(&cmd->payload.point_value_cmd, buf);
+    }
+
+    size = buf - frame;
+    buf_io_put8_tl(size, frame);
+    crc = crc16_calc(frame, size);
+    cmd->crc = crc;
+    cmd->hdr.size = size;
+    buf_io_put16_tl(crc, buf);
+
+    size += 2; // + crc
+
+    return size;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_itf.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,403 @@
+/** @file */
+
+#ifndef __SENS_ITF_H__
+#define __SENS_ITF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SENS_ITF_LATEST_VERSION     0
+#define SENS_ITF_MAX_FRAME_SIZE   128
+#define SENS_ITF_DSP_MSG_MAX_SIZE  24
+#define SENS_ITF_MAX_POINTS        32
+#define SENS_ITF_SERVER_ADDR_SIZE  16
+#define SENS_ITF_MODEL_NAME_SIZE    8
+#define SENS_ITF_MANUF_NAME_SIZE    8
+#define SENS_ITF_POINT_NAME_SIZE    8
+
+/** Sensor interface standard datatypes */
+enum sens_itf_datatypes_e
+{
+	SENS_ITF_DT_U8     = 0x00, /**< 8 bits unsigned */
+	SENS_ITF_DT_S8     = 0x01, /**< 8 bits signed */
+	SENS_ITF_DT_U16    = 0x02, /**< 16 bits unsigned */
+	SENS_ITF_DT_S16    = 0x03, /**< 16 bits signed */
+	SENS_ITF_DT_U32    = 0x04, /**< 32 bits unsigned */
+	SENS_ITF_DT_S32    = 0x05, /**< 32 bits signed */
+	SENS_ITF_DT_U64    = 0x06, /**< 64 bits unsigned */
+	SENS_ITF_DT_S64    = 0x07, /**< 64 bits signed */
+	SENS_ITF_DT_FLOAT  = 0x08, /**< IEEE 754 single precision */
+	SENS_ITF_DT_DOUBLE = 0x09, /**< IEEE 754 double precision */
+};
+
+/** Sensor interface register map */
+enum sens_itf_register_map_e 
+{
+	SENS_ITF_REGMAP_ITF_VERSION      = 0x00, /**< Sensor Board Interface Version */
+	SENS_ITF_REGMAP_BRD_ID           = 0x01, /**< Sensor Board Identification */
+	SENS_ITF_REGMAP_BRD_STATUS       = 0x02, /**< Sensor Board Status */
+	SENS_ITF_REGMAP_BRD_CMD          = 0x03, /**< Sensor Board Command */
+	SENS_ITF_REGMAP_READ_BAT_STATUS  = 0x04, /**< Read battery status */
+    SENS_ITF_REGMAP_WRITE_BAT_STATUS = 0x05, /**< Write battery status */
+	SENS_ITF_REGMAP_READ_BAT_CHARGE  = 0x06, /**< Read battery charge(0 - 100 % ) */
+    SENS_ITF_REGMAP_WRITE_BAT_CHARGE = 0x07, /**< Write Battery charge(0 - 100 % ) */
+	SENS_ITF_REGMAP_WPAN_STATUS      = 0x08, /**< Wireless network status */
+	SENS_ITF_REGMAP_WPAN_STRENGTH    = 0x09, /**< Wireless network strength(RSSI, 0 to 100 % ) */
+	SENS_ITF_REGMAP_DSP_WRITE        = 0x0A, /**< Write display (when display is available) */
+	SENS_ITF_REGMAP_SVR_MAIN_ADDR    = 0x0B, /**< Main server address(IPv6) */
+	SENS_ITF_REGMAP_SVR_SEC_ADDR     = 0x0C, /**< Secondary server address(IPv6) */
+
+	/*0x0D to 0x0F - Reserved(Should not be answered) */
+
+	SENS_ITF_REGMAP_POINT_DESC_1  = 0x10, /**< Sensor Point Description 1 */
+	SENS_ITF_REGMAP_POINT_DESC_2  = 0x11, /**< Sensor Point Description 2 */
+	SENS_ITF_REGMAP_POINT_DESC_3  = 0x12, /**< Sensor Point Description 3 */
+	SENS_ITF_REGMAP_POINT_DESC_4  = 0x13, /**< Sensor Point Description 4 */
+	SENS_ITF_REGMAP_POINT_DESC_5  = 0x14, /**< Sensor Point Description 5 */
+	SENS_ITF_REGMAP_POINT_DESC_6  = 0x15, /**< Sensor Point Description 6 */
+	SENS_ITF_REGMAP_POINT_DESC_7  = 0x16, /**< Sensor Point Description 7 */
+	SENS_ITF_REGMAP_POINT_DESC_8  = 0x17, /**< Sensor Point Description 8 */
+	SENS_ITF_REGMAP_POINT_DESC_9  = 0x18, /**< Sensor Point Description 9 */
+	SENS_ITF_REGMAP_POINT_DESC_10 = 0x19, /**< Sensor Point Description 10 */
+	SENS_ITF_REGMAP_POINT_DESC_11 = 0x1A, /**< Sensor Point Description 11 */
+	SENS_ITF_REGMAP_POINT_DESC_12 = 0x1B, /**< Sensor Point Description 12 */
+	SENS_ITF_REGMAP_POINT_DESC_13 = 0x1C, /**< Sensor Point Description 13 */
+	SENS_ITF_REGMAP_POINT_DESC_14 = 0x1D, /**< Sensor Point Description 14 */
+	SENS_ITF_REGMAP_POINT_DESC_15 = 0x1E, /**< Sensor Point Description 15 */
+	SENS_ITF_REGMAP_POINT_DESC_16 = 0x1F, /**< Sensor Point Description 16 */
+	SENS_ITF_REGMAP_POINT_DESC_17 = 0x20, /**< Sensor Point Description 17 */
+	SENS_ITF_REGMAP_POINT_DESC_18 = 0x21, /**< Sensor Point Description 18 */
+	SENS_ITF_REGMAP_POINT_DESC_19 = 0x22, /**< Sensor Point Description 19 */
+	SENS_ITF_REGMAP_POINT_DESC_20 = 0x23, /**< Sensor Point Description 20 */
+	SENS_ITF_REGMAP_POINT_DESC_21 = 0x24, /**< Sensor Point Description 21 */
+	SENS_ITF_REGMAP_POINT_DESC_22 = 0x25, /**< Sensor Point Description 22 */
+	SENS_ITF_REGMAP_POINT_DESC_23 = 0x26, /**< Sensor Point Description 23 */
+	SENS_ITF_REGMAP_POINT_DESC_24 = 0x27, /**< Sensor Point Description 24 */
+	SENS_ITF_REGMAP_POINT_DESC_25 = 0x28, /**< Sensor Point Description 25 */
+	SENS_ITF_REGMAP_POINT_DESC_26 = 0x29, /**< Sensor Point Description 26 */
+	SENS_ITF_REGMAP_POINT_DESC_27 = 0x2A, /**< Sensor Point Description 27 */
+	SENS_ITF_REGMAP_POINT_DESC_28 = 0x2B, /**< Sensor Point Description 28 */
+	SENS_ITF_REGMAP_POINT_DESC_29 = 0x2C, /**< Sensor Point Description 29 */
+	SENS_ITF_REGMAP_POINT_DESC_30 = 0x2D, /**< Sensor Point Description 30 */
+	SENS_ITF_REGMAP_POINT_DESC_31 = 0x2E, /**< Sensor Point Description 31 */
+	SENS_ITF_REGMAP_POINT_DESC_32 = 0x2F, /**< Sensor Point Description 32 */
+
+	SENS_ITF_REGMAP_READ_POINT_DATA_1 = 0x30, /**< Read Sensor Point Data 1 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_2 = 0x31, /**< Read Sensor Point Data 2 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_3 = 0x32, /**< Read Sensor Point Data 3 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_4 = 0x33, /**< Read Sensor Point Data 4 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_5 = 0x34, /**< Read Sensor Point Data 5 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_6 = 0x35, /**< Read Sensor Point Data 6 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_7 = 0x36, /**< Read Sensor Point Data 7 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_8 = 0x37, /**< Read Sensor Point Data 8 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_9 = 0x38, /**< Read Sensor Point Data 9 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_10 = 0x39, /**< Read Sensor Point Data 10 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_11 = 0x3A, /**< Read Sensor Point Data 11 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_12 = 0x3B, /**< Read Sensor Point Data 12 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_13 = 0x3C, /**< Read Sensor Point Data 13 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_14 = 0x3D, /**< Read Sensor Point Data 14 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_15 = 0x3E, /**< Read Sensor Point Data 15 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_16 = 0x3F, /**< Read Sensor Point Data 16 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_17 = 0x40, /**< Read Sensor Point Data 17 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_18 = 0x41, /**< Read Sensor Point Data 18 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_19 = 0x42, /**< Read Sensor Point Data 19 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_20 = 0x43, /**< Read Sensor Point Data 20 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_21 = 0x44, /**< Read Sensor Point Data 21 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_22 = 0x45, /**< Read Sensor Point Data 22 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_23 = 0x46, /**< Read Sensor Point Data 23 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_24 = 0x47, /**< Read Sensor Point Data 24 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_25 = 0x48, /**< Read Sensor Point Data 25 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_26 = 0x49, /**< Read Sensor Point Data 26 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_27 = 0x4A, /**< Read Sensor Point Data 27 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_28 = 0x4B, /**< Read Sensor Point Data 28 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_29 = 0x4C, /**< Read Sensor Point Data 29 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_30 = 0x4D, /**< Read Sensor Point Data 30 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_31 = 0x4E, /**< Read Sensor Point Data 31 */
+	SENS_ITF_REGMAP_READ_POINT_DATA_32 = 0x4F, /**< Read Sensor Point Data 32 */
+
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_1 = 0x50, /**< Write Sensor Point Data 1 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_2 = 0x51, /**< Write Sensor Point Data 2 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_3 = 0x52, /**< Write Sensor Point Data 3 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_4 = 0x53, /**< Write Sensor Point Data 4 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_5 = 0x54, /**< Write Sensor Point Data 5 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_6 = 0x55, /**< Write Sensor Point Data 6 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_7 = 0x56, /**< Write Sensor Point Data 7 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_8 = 0x57, /**< Write Sensor Point Data 8 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_9 = 0x58, /**< Write Sensor Point Data 9 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_10 = 0x59, /**< Write Sensor Point Data 10 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_11 = 0x5A, /**< Write Sensor Point Data 11 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_12 = 0x5B, /**< Write Sensor Point Data 12 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_13 = 0x5C, /**< Write Sensor Point Data 13 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_14 = 0x5D, /**< Write Sensor Point Data 14 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_15 = 0x5E, /**< Write Sensor Point Data 15 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_16 = 0x5F, /**< Write Sensor Point Data 16 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_17 = 0x60, /**< Write Sensor Point Data 17 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_18 = 0x61, /**< Write Sensor Point Data 18 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_19 = 0x62, /**< Write Sensor Point Data 19 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_20 = 0x63, /**< Write Sensor Point Data 20 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_21 = 0x64, /**< Write Sensor Point Data 21 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_22 = 0x65, /**< Write Sensor Point Data 22 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_23 = 0x66, /**< Write Sensor Point Data 23 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_24 = 0x67, /**< Write Sensor Point Data 24 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_25 = 0x68, /**< Write Sensor Point Data 25 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_26 = 0x69, /**< Write Sensor Point Data 26 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_27 = 0x6A, /**< Write Sensor Point Data 27 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_28 = 0x6B, /**< Write Sensor Point Data 28 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_29 = 0x6C, /**< Write Sensor Point Data 29 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_30 = 0x6D, /**< Write Sensor Point Data 30 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_31 = 0x6E, /**< Write Sensor Point Data 31 */
+	SENS_ITF_REGMAP_WRITE_POINT_DATA_32 = 0x6F, /**< Write Sensor Point Data 32 */
+
+	/* 0x70 to 0xFF - Reserved */
+};
+
+enum sens_itf_sensor_status_e
+{
+	SENS_ITF_SENSOR_STATUS_OK = 0,
+	SENS_ITF_SENSOR_STATUS_POINT_1 = 1,
+	SENS_ITF_SENSOR_STATUS_POINT_2 = 2,
+	SENS_ITF_SENSOR_STATUS_POINT_3 = 3,
+	SENS_ITF_SENSOR_STATUS_POINT_4 = 4,
+	SENS_ITF_SENSOR_STATUS_POINT_5 = 5,
+	SENS_ITF_SENSOR_STATUS_POINT_6 = 6,
+	SENS_ITF_SENSOR_STATUS_POINT_7 = 7,
+	SENS_ITF_SENSOR_STATUS_POINT_8 = 8,
+	SENS_ITF_SENSOR_STATUS_POINT_9 = 9,
+	SENS_ITF_SENSOR_STATUS_POINT_10 = 10,
+	SENS_ITF_SENSOR_STATUS_POINT_11 = 11,
+	SENS_ITF_SENSOR_STATUS_POINT_12 = 12,
+	SENS_ITF_SENSOR_STATUS_POINT_13 = 13,
+	SENS_ITF_SENSOR_STATUS_POINT_14 = 14,
+	SENS_ITF_SENSOR_STATUS_POINT_15 = 15,
+	SENS_ITF_SENSOR_STATUS_POINT_16 = 16,
+	SENS_ITF_SENSOR_STATUS_POINT_17 = 17,
+	SENS_ITF_SENSOR_STATUS_POINT_18 = 18,
+	SENS_ITF_SENSOR_STATUS_POINT_19 = 19,
+	SENS_ITF_SENSOR_STATUS_POINT_20 = 20,
+	SENS_ITF_SENSOR_STATUS_POINT_21 = 21,
+	SENS_ITF_SENSOR_STATUS_POINT_22 = 22,
+	SENS_ITF_SENSOR_STATUS_POINT_23 = 23,
+	SENS_ITF_SENSOR_STATUS_POINT_24 = 24,
+	SENS_ITF_SENSOR_STATUS_POINT_25 = 25,
+	SENS_ITF_SENSOR_STATUS_POINT_26 = 26,
+	SENS_ITF_SENSOR_STATUS_POINT_27 = 27,
+	SENS_ITF_SENSOR_STATUS_POINT_28 = 28,
+	SENS_ITF_SENSOR_STATUS_POINT_29 = 29,
+	SENS_ITF_SENSOR_STATUS_POINT_30 = 30,
+	SENS_ITF_SENSOR_STATUS_POINT_31 = 31,
+	SENS_ITF_SENSOR_STATUS_POINT_32 = 32,
+	/* 33 to 127 - reserved */
+	SENS_ITF_SENSOR_STATUS_GENERAL_SENSOR_FAILURE = 128,
+	/* 129 to 255 - reserved */
+};
+
+enum sens_itf_sensor_cmds_e
+{
+	SENS_ITF_SENSOR_CMD_RESET = 0,
+};
+
+enum sens_itf_ans_status_e
+{
+	SENS_ITF_ANS_OK = 0,
+	SENS_ITF_ANS_ERROR = 1,
+    SENS_ITF_ANS_CRC_ERROR = 2,
+	SENS_ITF_ANS_READY_ONLY = 3,
+	SENS_ITF_ANS_WRITE_ONLY = 4,
+    SENS_ITF_ANS_REGISTER_NOT_IMPLEMENTED = 5,
+};
+
+enum sens_itf_access_rights_e
+{
+	SENS_ITF_ACCESS_READ_ONLY = 0x01,
+	SENS_ITF_ACCESS_WRITE_ONLY = 0x02,
+	SENS_ITF_ACCESS_READ_WRITE = 0x03,
+};
+
+enum sens_itf_sensor_capabilities_e
+{
+	SENS_ITF_CAPABILITIES_BATTERY = 0x01,
+	SENS_ITF_CAPABILITIES_DISPLAY = 0x02,
+	SENS_ITF_CAPABILITIES_WPAN_STATUS = 0x04,
+	SENS_ITF_CAPABILITIES_BATTERY_STATUS = 0x08,
+};
+
+enum sens_itf_bat_status_e
+{
+	SENS_ITF_BAT_STATUS_CHARGED = 0x00,
+	SENS_ITF_BAT_STATUS_CHARGING = 0x01,
+	SENS_ITF_BAT_STATUS_DISCHARGING = 0x02,
+	SENS_ITF_BAT_STATUS_FAILURE = 0x03,
+};
+
+enum sens_itf_wpan_status_e
+{
+	SENS_ITF_WPAN_STATUS_CONNECTED = 0x00,
+	SENS_ITF_WPAN_STATUS_DISCONNECTED = 0x01,
+	SENS_ITF_WPAN_STATUS_CONNECTING = 0x02,
+};
+
+union sens_itf_point_data_u
+{
+	uint8_t  u8;
+	int8_t   s8;
+	uint16_t u16;
+	int16_t  s16;
+	uint32_t u32;
+	int32_t  s32;
+	uint64_t u64;
+	int64_t  s64;
+	float    fp32;
+	double   fp64;
+};
+
+typedef struct sens_itf_cmd_bat_status_s
+{
+	uint8_t status;
+} sens_itf_cmd_bat_status_t;
+
+typedef struct sens_itf_cmd_bat_charge_s
+{
+	uint8_t charge;
+} sens_itf_cmd_bat_charge_t;
+
+typedef struct sens_itf_cmd_command_s
+{
+	uint8_t cmd;
+} sens_itf_cmd_command_t;
+
+typedef struct sens_itf_cmd_command_res_s
+{
+	uint8_t status;
+} sens_itf_cmd_command_res_t;
+
+typedef struct sens_itf_cmd_wpan_status_s
+{
+	uint8_t status;
+} sens_itf_cmd_wpan_status_t;
+
+typedef struct sens_itf_cmd_wpan_strenght_s
+{
+	uint8_t strenght;
+} sens_itf_cmd_wpan_strenght_t;
+
+typedef struct sens_itf_cmd_write_display_s
+{
+	uint8_t line;
+	uint8_t msg[SENS_ITF_DSP_MSG_MAX_SIZE];
+} sens_itf_cmd_write_display_t;
+
+typedef struct sens_itf_cmd_svr_addr_s
+{
+	uint8_t addr[SENS_ITF_SERVER_ADDR_SIZE];
+} sens_itf_cmd_svr_addr_t;
+
+typedef struct sens_itf_cmd_itf_version_s
+{
+	uint8_t version;
+} sens_itf_cmd_itf_version_t;
+
+typedef struct sens_itf_cmd_brd_id_s
+{
+	uint8_t model[SENS_ITF_MODEL_NAME_SIZE];
+	uint8_t manufactor[SENS_ITF_MANUF_NAME_SIZE];
+	uint32_t sensor_id;
+	uint8_t hardware_revision;
+	uint8_t num_of_points;
+	uint8_t cabalities;
+} sens_itf_cmd_brd_id_t;
+
+typedef struct sens_itf_cmd_brd_status_s
+{
+	uint8_t status;
+} sens_itf_cmd_brd_status_t;
+
+typedef struct sens_itf_cmd_point_desc_s
+{
+	uint8_t name[SENS_ITF_POINT_NAME_SIZE];
+	uint8_t type;
+	uint8_t unit;
+	uint8_t access_rights;
+	uint32_t sampling_time_x250ms;
+} sens_itf_cmd_point_desc_t;
+
+typedef struct sens_itf_cmd_point_s
+{
+	union sens_itf_point_data_u value;
+    uint8_t type;
+} sens_itf_cmd_point_t;
+
+typedef struct sens_itf_point_ctrl_s
+{
+	uint8_t num_of_points;
+	struct {
+		sens_itf_cmd_point_desc_t desc;
+		sens_itf_cmd_point_t value;
+	} points[SENS_ITF_MAX_POINTS];
+} sens_itf_point_ctrl_t;
+
+union sens_itf_cmds_u
+{
+	sens_itf_cmd_bat_status_t bat_status_cmd;
+	sens_itf_cmd_bat_charge_t bat_charge_cmd;
+    sens_itf_cmd_command_t command_cmd;
+    sens_itf_cmd_command_res_t command_res_cmd;
+	sens_itf_cmd_wpan_status_t wpan_status_cmd;
+	sens_itf_cmd_wpan_strenght_t wpan_strength_cmd;
+	sens_itf_cmd_write_display_t write_display_cmd;
+	sens_itf_cmd_svr_addr_t svr_addr_cmd;
+	sens_itf_cmd_itf_version_t itf_version_cmd;
+	sens_itf_cmd_brd_id_t brd_id_cmd;
+	sens_itf_cmd_brd_status_t brd_status_cmd;
+	sens_itf_cmd_point_desc_t point_desc_cmd;
+	sens_itf_cmd_point_t point_value_cmd;
+};
+
+typedef struct sens_itf_cmd_req_hdr_s
+{
+	uint8_t size;
+	uint8_t addr;
+} sens_itf_cmd_req_hdr_t;
+
+typedef struct sens_itf_cmd_res_hdr_s
+{
+	uint8_t size;
+	uint8_t status;
+    uint8_t addr;
+} sens_itf_cmd_res_hdr_t;
+
+typedef struct sens_itf_cmd_req_s
+{
+	sens_itf_cmd_req_hdr_t hdr;
+	union sens_itf_cmds_u payload;
+	uint16_t crc;
+} sens_itf_cmd_req_t;
+
+typedef struct sens_itf_cmd_res_s
+{
+	sens_itf_cmd_res_hdr_t hdr;
+	union sens_itf_cmds_u payload;
+	uint16_t crc;
+} sens_itf_cmd_res_t;
+
+
+//extern uint8_t sens_itf_send_cmd(sens_itf_cmd_req_t * cmd, sens_itf_cmd_res_t * ans);
+//extern int sens_itf_send_cmd_async(const sens_itf_cmd_req_t * const cmd, const sens_itf_cmd_res_t * ans);
+
+extern uint8_t sens_itf_mote_init(void);
+extern uint8_t sens_itf_sensor_init(void);
+extern void sens_itf_mote_main(void);
+
+extern uint8_t sens_itf_unpack_point_value(sens_itf_cmd_point_t *point, uint8_t *buf);
+extern uint8_t sens_itf_pack_point_value(const sens_itf_cmd_point_t *point, uint8_t *buf);
+
+extern uint8_t sens_itf_unpack_cmd_res(sens_itf_cmd_res_t *cmd, uint8_t *frame, uint8_t frame_size);
+extern uint8_t sens_itf_unpack_cmd_req(sens_itf_cmd_req_t *cmd, uint8_t *frame, uint8_t frame_size);
+extern uint8_t sens_itf_pack_cmd_res  (sens_itf_cmd_res_t *cmd, uint8_t *frame);
+extern uint8_t sens_itf_pack_cmd_req  (sens_itf_cmd_req_t *cmd, uint8_t *frame);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENS_ITF_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_itf_sensor.cpp	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,477 @@
+#include <string.h>
+#include <stdint.h>
+#include "mbed.h"
+#include "sens_itf.h"
+#include "sens_util.h"
+#include "../util/buf_io.h"
+#include "../util/crc16.h"
+#include "../pt/pt.h"
+#include "SLCD.h"
+#include "MMA8451Q.h"
+
+#define SENS_ITF_SENSOR_DBG_FRAME     1
+#define SENS_ITF_DBG_FRAME 1
+#define SENS_ITF_SENSOR_NUM_OF_POINTS 5
+
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
+
+static uint8_t main_svr_addr[SENS_ITF_SERVER_ADDR_SIZE];
+static uint8_t secon_svr_addr[SENS_ITF_SERVER_ADDR_SIZE];
+static uint8_t rx_frame[SENS_ITF_MAX_FRAME_SIZE];
+static volatile uint8_t num_rx_bytes;
+static Timeout rx_trmout_timer ;
+static Ticker acq_data_timer;
+static sens_itf_point_ctrl_t sensor_points;
+static sens_itf_cmd_brd_id_t board_info;
+static struct pt pt_updt;
+static struct pt pt_data;
+static volatile uint8_t frame_timeout;
+static volatile uint8_t acq_data ;
+static DigitalOut  greenLED(LED1);
+static DigitalOut  redLED(LED2);
+static AnalogIn    lightSensor(PTE22);
+static SLCD        sLCD;
+static Serial      pcSerial(USBTX, USBRX);
+static MMA8451Q    acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
+static InterruptIn mode_switch(SW3);    
+static volatile uint8_t  view_mode;
+
+void scroll_message(char *message, unsigned char len)
+{
+    sLCD.All_Segments(0);
+    
+    for (int start = 0; start < len - 4; start++)
+    {
+        for (int digit = 0; digit < 4; digit++)
+            sLCD.putc(message[start + digit]);
+        wait(0.4);
+    }
+}
+
+static void dump_frame(uint8_t *frame, uint8_t size)
+{
+	int n,m;
+	char buf[64];
+	
+	buf[0] = buf[1] = buf[2] = buf[3] = ' ';
+	
+	for(n = 0, m = 4; n < size ; n++, m+=3)
+	{
+		sprintf(&buf[m],"%02X_",frame[n]);
+	}
+	
+	buf[m] = buf[m+1] = buf[m+2] = buf[m+3] = ' ';
+	buf[m+4] = '\0';
+	
+	m +=4;
+	scroll_message(buf,m);
+	
+}
+	
+static uint8_t sens_itf_get_point_type(uint8_t point)
+{
+    return sensor_points.points[point].desc.type;
+}
+
+static uint8_t sens_itf_get_number_of_points(void)
+{
+    return SENS_ITF_SENSOR_NUM_OF_POINTS;
+}
+
+static sens_itf_cmd_point_desc_t *sens_itf_get_point_desc(uint8_t point)
+{
+    sens_itf_cmd_point_desc_t *d = 0;
+
+    if (point < sens_itf_get_number_of_points())
+        d = &sensor_points.points[point].desc;
+
+    return d;
+}
+
+static sens_itf_cmd_point_t *sens_itf_get_point_value(uint8_t point)
+{
+    sens_itf_cmd_point_t *v = 0;
+
+    if (point < sens_itf_get_number_of_points())
+        v = &sensor_points.points[point].value;
+
+    return v;
+}
+
+static uint8_t sens_itf_set_point_value(uint8_t point, sens_itf_cmd_point_t *v)
+{
+    uint8_t ret = 0;
+
+    if (point < sens_itf_get_number_of_points())
+    {
+        sensor_points.points[point].value = *v;
+        ret = 1;
+    }
+    else
+    {
+        ret = 0;
+    }
+
+    return ret;
+}
+
+static sens_itf_cmd_brd_id_t *sens_itf_get_board_info(void)
+{
+    return &board_info;
+}
+
+static uint8_t sens_itf_sensor_send_frame(uint8_t *frame, uint8_t size)
+{
+    //dump_frame(frame, size);
+    
+    for(int n = 0 ; n < size ; n++)
+    	pcSerial.putc((unsigned int )frame[n]);
+    //pcSerial.puts((char *)frame,size); // puts returns the size sent ?
+    return size;
+}
+
+static uint8_t sens_itf_sensor_check_register_map(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+    uint8_t size = 0;
+    if ( // check global register map for valid address ranges
+                ((cmd->hdr.addr > SENS_ITF_REGMAP_SVR_SEC_ADDR) && 
+                (cmd->hdr.addr < SENS_ITF_REGMAP_POINT_DESC_1)) ||
+                (cmd->hdr.addr > SENS_ITF_REGMAP_WRITE_POINT_DATA_32) ||
+                // check local register map - reading
+                ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) && 
+                (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32) &&
+                ((cmd->hdr.addr - SENS_ITF_REGMAP_READ_POINT_DATA_1) >= sens_itf_get_number_of_points())) ||
+                // check local register map - writing
+                ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) && 
+                (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32) &&
+                ((cmd->hdr.addr - SENS_ITF_REGMAP_WRITE_POINT_DATA_1) >= sens_itf_get_number_of_points())))
+    {
+        sens_util_log(SENS_ITF_SENSOR_DBG_FRAME, "Invalid register address %02X",cmd->hdr.addr);
+        ans->hdr.status = SENS_ITF_ANS_REGISTER_NOT_IMPLEMENTED;
+        size = sens_itf_pack_cmd_res(ans, frame);
+    }
+    return size;
+}
+
+static uint8_t sens_itf_sensor_writings(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+    uint8_t size = 0;
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) && 
+        (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32))
+    {
+        uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_WRITE_POINT_DATA_1;
+        //sLCD.printf("R%dV%d",point,cmd->payload.point_value_cmd.value.u8);
+        //wait(0.5);
+        uint8_t acr = sens_itf_get_point_desc(point)->access_rights & SENS_ITF_ACCESS_WRITE_ONLY;
+            
+        if (acr)
+        {
+            ans->hdr.status = SENS_ITF_ANS_OK;
+            sens_itf_set_point_value(point,&cmd->payload.point_value_cmd);
+        }
+        else
+        {
+            sens_util_log(SENS_ITF_SENSOR_DBG_FRAME, "Point %d does not allow writings",point);                
+            ans->hdr.status = SENS_ITF_ANS_READY_ONLY;
+        }
+        size = sens_itf_pack_cmd_res(ans, frame);
+    }
+    return size;
+}
+
+static uint8_t sens_itf_sensor_readings(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+    uint8_t size = 0;
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+        (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32))
+    {
+        uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_READ_POINT_DATA_1;
+        uint8_t acr = sens_itf_get_point_desc(point)->access_rights & SENS_ITF_ANS_READY_ONLY;
+            
+        if (acr)
+        {
+            ans->hdr.status = SENS_ITF_ANS_OK;
+            ans->payload.point_value_cmd = *sens_itf_get_point_value(point);
+        }
+        else
+        {
+            sens_util_log(SENS_ITF_SENSOR_DBG_FRAME, "Point %d does not allow readings",point);                
+            ans->hdr.status = SENS_ITF_ANS_WRITE_ONLY;
+        }
+        size = sens_itf_pack_cmd_res(ans, frame);
+    }
+    return size;
+}
+
+static uint8_t sens_itf_check_other_cmds(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+    uint8_t size = 0;
+    switch (cmd->hdr.addr)
+    {
+        case SENS_ITF_REGMAP_ITF_VERSION:
+            ans->payload.itf_version_cmd.version = SENS_ITF_LATEST_VERSION;
+            break;
+        case SENS_ITF_REGMAP_BRD_ID:
+            memcpy(&ans->payload.brd_id_cmd,sens_itf_get_board_info(),sizeof(sens_itf_cmd_brd_id_t));
+            break;
+        case SENS_ITF_REGMAP_BRD_STATUS:
+            ans->payload.brd_status_cmd.status = 0; // TBD
+            break;
+        case SENS_ITF_REGMAP_BRD_CMD:
+            ans->payload.command_res_cmd.status = 0; // TBD
+            break;
+        case SENS_ITF_REGMAP_READ_BAT_STATUS:
+            ans->payload.bat_status_cmd.status = 0; // TBD
+            break;
+        case SENS_ITF_REGMAP_READ_BAT_CHARGE:
+            ans->payload.bat_charge_cmd.charge = 100; // TBD
+            break;
+        case SENS_ITF_REGMAP_SVR_MAIN_ADDR:
+            memcpy(ans->payload.svr_addr_cmd.addr,main_svr_addr, SENS_ITF_SERVER_ADDR_SIZE); 
+            break;
+        case SENS_ITF_REGMAP_SVR_SEC_ADDR:
+            memcpy(ans->payload.svr_addr_cmd.addr,secon_svr_addr, SENS_ITF_SERVER_ADDR_SIZE);
+            break;
+        default:
+        	break;
+
+    }
+    
+    if ((cmd->hdr.addr >= SENS_ITF_REGMAP_POINT_DESC_1) && (cmd->hdr.addr <= SENS_ITF_REGMAP_POINT_DESC_32))
+    {
+        uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_POINT_DESC_1;
+        memcpy(&ans->payload.point_desc_cmd, &sensor_points.points[point].desc, sizeof(sens_itf_cmd_point_desc_t));
+    }
+        
+    ans->hdr.status = SENS_ITF_ANS_OK;
+    size = sens_itf_pack_cmd_res(ans, frame);
+    return size;
+}
+static void sens_itf_process_cmd(uint8_t *frame, uint8_t num_rx_bytes)
+{
+    uint8_t ret;
+    uint8_t size = 0;
+    sens_itf_cmd_req_t cmd;
+    sens_itf_cmd_res_t ans;
+
+    ret = sens_itf_unpack_cmd_req(&cmd, frame, num_rx_bytes);
+
+    if (ret > 0)
+    {
+        ans.hdr.addr = cmd.hdr.addr;
+        
+        size = sens_itf_sensor_check_register_map(&cmd, &ans,frame);
+        if (size == 0)
+            size = sens_itf_sensor_writings(&cmd, &ans,frame);
+
+        if (size == 0)
+            size = sens_itf_sensor_readings(&cmd, &ans,frame);
+ 
+        if (size == 0)
+            size = sens_itf_check_other_cmds(&cmd, &ans,frame);
+
+        if (size == 0)
+        {
+            ans.hdr.status = SENS_ITF_ANS_ERROR;
+            sLCD.printf("   D");
+        }
+ 
+        size = sens_itf_pack_cmd_res(&ans,frame);
+        sens_itf_sensor_send_frame(frame, size);
+    }
+}
+
+void sens_itf_init_point_db(void)
+{
+    uint8_t n;
+    char *point_names[SENS_ITF_POINT_NAME_SIZE] = { "LIGHT", "LEDG", "ACCX", "ACCY", "ACCXZ" };
+    uint8_t data_types[SENS_ITF_POINT_NAME_SIZE] = {SENS_ITF_DT_U8, SENS_ITF_DT_U8, SENS_ITF_DT_FLOAT, SENS_ITF_DT_FLOAT, SENS_ITF_DT_FLOAT};
+    uint8_t access_rights[SENS_ITF_POINT_NAME_SIZE] = { SENS_ITF_ACCESS_READ_ONLY, SENS_ITF_ACCESS_WRITE_ONLY, SENS_ITF_ACCESS_READ_ONLY,
+        SENS_ITF_ACCESS_READ_ONLY, SENS_ITF_ACCESS_READ_ONLY};
+    uint32_t sampling_time[SENS_ITF_POINT_NAME_SIZE] = {4*10, 0, 4*15, 4*20, 4*25};
+
+	memset(&sensor_points, 0, sizeof(sensor_points));
+	memset(&board_info, 0, sizeof(board_info));
+	
+    strcpy((char *)board_info.model, "KL46Z");
+    strcpy((char *)board_info.manufactor, "TESLA");
+    board_info.sensor_id = 0xDEADBEEF;
+    board_info.hardware_revision = 0x01;
+    board_info.num_of_points = SENS_ITF_SENSOR_NUM_OF_POINTS;
+    board_info.cabalities = SENS_ITF_CAPABILITIES_DISPLAY |
+        SENS_ITF_CAPABILITIES_WPAN_STATUS | 
+        SENS_ITF_CAPABILITIES_BATTERY_STATUS;
+
+    sensor_points.num_of_points = SENS_ITF_SENSOR_NUM_OF_POINTS;
+
+    for (n = 0; n < SENS_ITF_SENSOR_NUM_OF_POINTS; n++)
+    {
+        strcpy((char *)sensor_points.points[n].desc.name, point_names[n]);
+        sensor_points.points[n].desc.type = data_types[n];
+        sensor_points.points[n].desc.unit = 0; // TDB
+        sensor_points.points[n].desc.access_rights = access_rights[n];
+        sensor_points.points[n].desc.sampling_time_x250ms = sampling_time[n];
+        sensor_points.points[n].value.type = data_types[n];
+    }
+}
+
+static void sens_itf_rx_tmrout_timer_func(void)
+{
+	//greenLED = greenLED == 1 ? 0 : 1; 
+    frame_timeout = 1;
+}
+
+static void sens_itf_acq_data_timer_func(void)
+{
+    redLED = redLED == 1 ? 0 : 1;   
+    acq_data = 1;
+}
+
+static void sens_itf_rx_tmrout_timer_reesched(void)
+{
+	rx_trmout_timer.detach();
+	rx_trmout_timer.attach_us(sens_itf_rx_tmrout_timer_func,500*1000);
+}
+
+// Serial or SPI interrupt, called when a new byte is received
+static void sens_itf_sensor_rx_byte(void)
+{
+    uint8_t value;
+    
+    // DISABLE INTERRUPTS
+    if (frame_timeout)
+        return;
+
+	value = (uint8_t) pcSerial.getc();
+	
+    if (num_rx_bytes < SENS_ITF_MAX_FRAME_SIZE)
+        rx_frame[num_rx_bytes] = value;
+    
+    num_rx_bytes++;
+    if (num_rx_bytes >= SENS_ITF_MAX_FRAME_SIZE)
+        num_rx_bytes = 0;
+
+    sens_itf_rx_tmrout_timer_reesched();
+    // ENABLE INTERRUPTS
+}
+
+uint8_t sens_itf_sensor_init(void)
+{
+
+    sens_itf_init_point_db();
+    memcpy(main_svr_addr,"1212121212121212",SENS_ITF_SERVER_ADDR_SIZE);
+    memcpy(secon_svr_addr,"aabbccddeeff1122",SENS_ITF_SERVER_ADDR_SIZE);
+    num_rx_bytes = 0;
+    acq_data = 0;
+    frame_timeout = 0;
+    greenLED = 0; 
+    redLED = 1;
+    sens_itf_rx_tmrout_timer_reesched();
+    acq_data_timer.attach(sens_itf_acq_data_timer_func,2);
+	pcSerial.attach(sens_itf_sensor_rx_byte);
+	
+    return 1;
+}
+
+static int pt_data_func(struct pt *pt)
+{
+    PT_BEGIN(pt);
+
+    while (1)
+    {
+        // wait a frame timeout
+        PT_WAIT_UNTIL(pt, frame_timeout == 1);
+
+        if (num_rx_bytes > 0)
+        {
+            // process it
+            sens_itf_process_cmd(rx_frame, num_rx_bytes);
+            num_rx_bytes = 0;
+        }
+
+        // restart reception
+        frame_timeout = 0;
+        sens_itf_rx_tmrout_timer_reesched();
+    }
+
+    PT_END(pt);
+}
+
+static int pt_updt_func(struct pt *pt)
+{
+    PT_BEGIN(pt);
+
+    while (1)
+    {
+	    char buf[5];    
+	    uint8_t v;
+	    
+        // wait job
+        PT_WAIT_UNTIL(pt, acq_data == 1);
+
+	    v = (uint8_t)(lightSensor.read()*100);  
+	    sensor_points.points[0].value.value.u8 = v;
+	    greenLED = sensor_points.points[1].value.value.u8;
+	    sensor_points.points[2].value.value.fp32 = 1.0 - abs(acc.getAccX());
+	    sensor_points.points[3].value.value.fp32 = 1.0 - abs(acc.getAccY());
+	    sensor_points.points[4].value.value.fp32 = 1.0 - abs(acc.getAccZ());
+	    
+	    sLCD.All_Segments(0);
+	    switch(view_mode)
+	    {
+	    	case 0:
+			  	sprintf(buf,"L %2d",v);
+	    		sLCD.printf("%s",buf);   	
+	    		break;
+	    	case 1:
+			  	sprintf(buf,"%4d",(uint16_t) (sensor_points.points[2].value.value.fp32*1000));
+	    		sLCD.printf("%s",buf);   	
+	    		break;
+	    	case 2:
+			  	sprintf(buf,"%4d",(uint16_t) (sensor_points.points[3].value.value.fp32*1000));
+	    		sLCD.printf("%s",buf);   	
+	    		break;
+	    	case 3:
+			  	sprintf(buf,"%4d",(uint16_t) (sensor_points.points[4].value.value.fp32*1000));
+	    		sLCD.printf("%s",buf);   	
+	    		break;
+	    	default:
+	  		  	break;	
+	    }
+   
+        acq_data = 0;
+    }
+
+    PT_END(pt);
+}
+
+void set_mode(void)
+{
+	view_mode = ++view_mode > 3 ? 0 : view_mode;
+}
+
+void main(void)
+{
+    frame_timeout = 0;
+    acq_data = 0;
+    view_mode = 0;
+
+    sLCD.All_Segments(0); 
+    sLCD.DP2(0);
+    sLCD.printf("INIT"); 
+	pcSerial.baud(115200);
+    sens_itf_sensor_init();
+    
+    mode_switch.rise(set_mode);
+    
+    PT_INIT(&pt_data);
+    PT_INIT(&pt_updt);
+
+	
+    while(1)
+    {
+        pt_data_func(&pt_data);
+        pt_updt_func(&pt_updt);
+    }    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_util.c	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "sens_util.h"
+
+#define MAX_LOG_BUF 256
+static char buffer[MAX_LOG_BUF];
+
+static volatile int sens_util_log_started = 0;
+
+void sens_util_assert(int cond)
+{
+    assert(cond);
+}
+
+const uint8_t *sens_util_strip_path(const uint8_t *filename)
+{
+	int pos;
+
+	pos = strlen(filename) - 1; // avoiding null terminator
+
+	while( (filename[pos] != '\\') && (pos > 0) ) 
+		pos--;
+
+	if(pos != 0) 
+		pos++; // removing "\"
+	
+	return &filename[pos];
+}
+
+void sens_util_log(int cond, const uint8_t *line, ...)
+{
+	va_list argp;
+   
+    if((!cond) || (!sens_util_log_started))
+		return;
+
+	va_start(argp, line);
+    vsnprintf(buffer,MAX_LOG_BUF,line, argp);
+    va_end(argp);
+    
+    buffer[MAX_LOG_BUF-1] = '\0';
+
+	// TODO
+	// define destination for this buffer: ethernet, serial, console, syslog ...
+	// 
+    printf("%s",buffer);
+}
+
+void sens_util_dump_frame(const uint8_t * const data, int len)
+{
+	int i, j, k;
+	uint8_t buf[50];
+
+	for(k = 0 ; k < len ; k += 16)
+	{
+		for(i = k, j = 0 ; ( i< (k+16) ) && ( i < len ) ; i++, j+=3 )
+			sprintf((char *)&buf[j],"%02X ",data[i]);
+		buf[j] = '\0';
+		sens_util_log(1,"%s",buf);
+	}
+}
+
+int sens_util_log_stop(void)
+{
+	if(sens_util_log_started)
+        sens_util_log_started  = 0;
+
+	return 0;
+}
+
+int sens_util_log_start(void)
+{
+	if(!sens_util_log_started)
+        sens_util_log_started  = 1;
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_util.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,78 @@
+/**
+    @file sens_util.h
+    @brief Utilities routines
+*/
+#ifndef __SENS_UTIL__
+#define __SENS_UTIL__ 
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+    @defgroup OSUTIL Utilities
+    @ingroup OSGLOBALS
+    @{
+*/
+
+/** 
+    Assertion like function.
+    
+    @param cond Assertion condition.
+ */
+extern void sens_util_assert(int cond);
+
+/**
+    Message log utility.
+    
+    @param cond Logs only when the condition is true.
+    @param line Variable parameters list like printf.
+*/
+extern void sens_util_log(int cond, const uint8_t *line, ...);
+
+/**
+    Start log.
+
+    @retval 1 Log not started.
+    @retval 0 Log started.
+*/
+extern int sens_util_log_start(void);
+
+/**
+	Stop log .
+
+@retval 1 Log not stopped.
+@retval 0 Log stopped.
+*/
+extern int sens_util_log_stop(void);
+
+/**
+    Remove path and return only the file name.
+    
+    @param filename file with full path name
+    @return filename without path
+*/
+extern const uint8_t *sens_util_strip_path(const uint8_t *filename);
+
+/**
+    Print a buffer in hexadecimal (16 byte per row).
+
+    @param data Data to be printed.
+    @param len Data length.
+*/
+extern void sens_util_dump_frame(const uint8_t *const data, int len);
+
+/**
+    @def SENS_UTIL_ASSERT
+    @brief Assertion macro
+*/
+#define SENS_UTIL_ASSERT(cond) sens_util_assert( !!(cond) )
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  __SENS_UTIL__ */
+
--- a/util.lib	Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-util#55459711bbbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/buf_io.c	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,395 @@
+#include <stdint.h>
+#include "buf_io.h"
+
+/* --- swap functions ----------------------------  */
+
+uint16_t buf_io_swap16(uint16_t orig_value)
+{
+    uint16_t value = ((orig_value & 0x00FF) << 8) | 
+                     ((orig_value & 0xFF00) >> 8) ;
+    return value;
+}
+
+uint32_t buf_io_swap32(uint32_t orig_value)
+{
+    uint32_t value = ((orig_value & 0x000000FF) << 24) | 
+                     ((orig_value & 0x0000FF00) << 8 ) |
+                     ((orig_value & 0x00FF0000) >> 8 ) |
+                     ((orig_value & 0xFF000000) >> 24);
+    return value;
+}
+
+void buf_io_swap16p(uint8_t *buf)
+{
+    uint8_t value[2];
+    value[1] = *buf++;
+    value[0] = *buf++;
+    *--buf = value[1];
+    *--buf = value[0];
+}
+
+void buf_io_swap32p(uint8_t *buf)
+{                   
+    uint8_t value[4];  
+    value[3] = *buf++;            
+    value[2] = *buf++;               
+    value[1] = *buf++;               
+    value[0] = *buf++;   
+    *--buf = value[3];               
+    *--buf = value[2];               
+    *--buf = value[1];               
+    *--buf = value[0];               
+}
+
+uint8_t buf_io_swap8b(uint8_t orig_value)
+{
+    uint8_t value = ((orig_value & 0x01) <<  7) |
+                    ((orig_value & 0x02) <<  5) |
+                    ((orig_value & 0x04) <<  3) |
+                    ((orig_value & 0x08) <<  1) |
+                    ((orig_value & 0x10) >>  1) |
+                    ((orig_value & 0x20) >>  3) |
+                    ((orig_value & 0x40) >>  5) |
+                    ((orig_value & 0x80) >>  7);
+    return value;
+}
+
+/* --- 8 bits GET functions ----------------------------  */
+
+uint8_t buf_io_get8_fl(uint8_t *buf)
+{
+    return buf[0];
+}
+
+uint8_t buf_io_get8_fb(uint8_t *buf)
+{
+    return buf[0];
+}
+
+uint8_t buf_io_get8_fl_apr(uint8_t **buf)
+{
+    uint8_t value = buf_io_get8_fl(*buf);
+    *buf += 1;
+    return value;
+}
+
+uint8_t buf_io_get8_fb_apr(uint8_t **buf)
+{
+    uint8_t value = buf_io_get8_fb(*buf);
+    *buf += 1;
+    return value;
+}
+
+/* --- 16 bits GET functions ----------------------------  */
+
+uint16_t buf_io_get16_fl(uint8_t *buf)
+{
+    uint16_t value = buf[0] | (buf[1] << 8);
+    return value;
+}
+
+uint16_t buf_io_get16_fb(uint8_t *buf)
+{
+    uint16_t value = buf[1] | (buf[0] << 8);
+    return value;
+}
+
+uint16_t buf_io_get16_fl_apr(uint8_t **buf)
+{
+    uint16_t value = buf_io_get16_fl(*buf);
+    *buf += 2;
+    return value;
+}
+
+uint16_t buf_io_get16_fb_apr(uint8_t **buf)
+{
+    uint16_t value = buf_io_get16_fb(*buf);
+    *buf += 2;
+    return value;
+}
+
+/* --- 32 bits GET functions ----------------------------  */
+
+uint32_t buf_io_get32_fl(uint8_t *buf)
+{
+    uint32_t value = buf[0] | (buf[1] << 8 ) | (buf[2] << 16) | (buf[3] << 24);
+    return value;
+}
+
+uint32_t buf_io_get32_fb(uint8_t *buf)
+{
+    uint32_t value = buf[3] | (buf[2] << 8 ) | (buf[1] << 16) | (buf[0] << 24);
+    return value;
+}
+
+uint32_t buf_io_get32_fl_apr(uint8_t **buf)
+{
+    uint32_t value = buf_io_get32_fl(*buf);
+    *buf += 4;
+    return value;
+}
+
+uint32_t buf_io_get32_fb_apr(uint8_t **buf)
+{
+    uint32_t value = buf_io_get32_fb(*buf);
+    *buf += 4;
+    return value;
+}
+
+/* --- 64 bits GET functions ----------------------------  */
+
+uint64_t buf_io_get64_fl(uint8_t *buf)
+{
+    uint8_t *p1 =  buf;
+    uint8_t *p2 = (buf + 4);
+    uint64_t v1 = p1[0] | (p1[1] << 8 ) | (p1[2] << 16) | (p1[3] << 24);
+    uint64_t v2 = p2[0] | (p2[1] << 8 ) | (p2[2] << 16) | (p2[3] << 24);
+    uint64_t value = (v2 << 32) | v1;
+    return value;
+}
+
+uint64_t buf_io_get64_fb(uint8_t *buf)
+{
+    uint8_t *p1 =  buf;
+    uint8_t *p2 = (buf + 4);
+    uint64_t v1 = p1[3] | (p1[2] << 8 ) | (p1[1] << 16) | (p1[0] << 24);
+    uint64_t v2 = p2[3] | (p2[2] << 8 ) | (p2[1] << 16) | (p2[0] << 24);
+    uint64_t value = (v1 << 32) | v2;
+    return value;
+}
+
+uint64_t buf_io_get64_fl_apr(uint8_t **buf)
+{
+    uint64_t value = buf_io_get64_fl(*buf);
+    *buf += 8;
+    return value;
+}
+
+uint64_t buf_io_get64_fb_apr(uint8_t **buf)
+{
+    uint64_t value = buf_io_get64_fb(*buf);
+    *buf += 8;
+    return value;
+}
+
+/* --- float GET functions ----------------------------  */
+
+float buf_io_getf_fl(uint8_t *buf)
+{
+    uint32_t value = buf_io_get32_fl(buf);
+    return *((float* )&value);
+}
+
+float buf_io_getf_fb(uint8_t *buf)
+{
+    uint32_t value = buf_io_get32_fb(buf);
+    return *((float* )&value);
+}
+
+float buf_io_getf_fl_apr(uint8_t **buf)
+{
+    float value = buf_io_getf_fl(*buf);
+    (*buf) += 4;
+    return value;
+}
+
+float buf_io_getf_fb_apr(uint8_t **buf)
+{
+    float value = buf_io_getf_fb(*buf);
+    (*buf) += 4;
+    return value;
+}
+
+/* --- double GET functions ----------------------------  */
+
+double buf_io_getd_fl(uint8_t *buf)
+{
+    uint64_t value = buf_io_get64_fl(buf);
+    return *((double* )&value);
+}
+
+double buf_io_getd_fb(uint8_t *buf)
+{
+    uint64_t value = buf_io_get64_fb(buf);
+    return *((double* )&value);
+}
+
+double buf_io_getd_fl_apr(uint8_t **buf)
+{
+    double value = buf_io_getd_fl(*buf);
+    (*buf) += 8;
+    return value;
+}
+
+double buf_io_getd_fb_apr(uint8_t **buf)
+{
+    double ret = buf_io_getd_fb(*buf);
+    (*buf) += 8;
+    return ret;
+}
+
+/* --- 8 bits PUT functions ----------------------------  */
+
+void buf_io_put8_tl(uint8_t value, uint8_t *buf)
+{
+    buf[0] = value;
+}
+
+void buf_io_put8_tb(uint8_t value, uint8_t *buf)
+{
+    buf[0] = value;
+}
+
+void buf_io_put8_tl_apr(uint8_t value, uint8_t **buf)
+{
+    buf_io_put8_tl(value,*buf);
+    *buf += 1;
+}
+
+void buf_io_put8_tb_apr(uint8_t value, uint8_t **buf)
+{
+    buf_io_put8_tb(value,*buf);
+    *buf += 1;
+}
+
+/* --- 16 bits PUT functions ----------------------------  */
+
+void buf_io_put16_tl(uint16_t value, uint8_t *buf)
+{
+    buf[0] = (uint8_t)(value     );
+    buf[1] = (uint8_t)(value >> 8);
+}
+
+void buf_io_put16_tb(uint16_t value, uint8_t *buf)
+{
+    buf[1] = (uint8_t)(value     );
+    buf[0] = (uint8_t)(value >> 8);
+}
+
+void buf_io_put16_tl_apr(uint16_t value, uint8_t **buf)
+{
+    buf_io_put16_tl(value,*buf);
+    *buf += 2;
+}
+
+void buf_io_put16_tb_apr(uint16_t value, uint8_t **buf)
+{
+    buf_io_put16_tb(value,*buf);
+    *buf += 2;
+}
+
+/* --- 32 bits PUT functions ----------------------------  */
+
+void buf_io_put32_tl(uint32_t value, uint8_t *buf)
+{
+    buf[0] = (uint8_t)(value      );
+    buf[1] = (uint8_t)(value >> 8 );
+    buf[2] = (uint8_t)(value >> 16);
+    buf[3] = (uint8_t)(value >> 24);
+}
+
+void buf_io_put32_tb(uint32_t value, uint8_t *buf)
+{
+    buf[3] = (uint8_t)(value      );
+    buf[2] = (uint8_t)(value >> 8 );
+    buf[1] = (uint8_t)(value >> 16);
+    buf[0] = (uint8_t)(value >> 24);
+}
+
+void buf_io_put32_tl_apr(uint32_t value, uint8_t **buf)
+{
+    buf_io_put32_tl(value,*buf);
+    *buf += 4;
+}
+
+void buf_io_put32_tb_apr(uint32_t value, uint8_t **buf)
+{
+    buf_io_put32_tb(value,*buf);
+    *buf += 4;
+}
+
+/* --- 64 bits PUT functions ----------------------------  */
+
+void buf_io_put64_tl(uint64_t value, uint8_t *buf)
+{
+    buf[0] = (uint8_t)(value      );
+    buf[1] = (uint8_t)(value >> 8 );
+    buf[2] = (uint8_t)(value >> 16);
+    buf[3] = (uint8_t)(value >> 24);
+    buf[4] = (uint8_t)(value >> 32);
+    buf[5] = (uint8_t)(value >> 40);
+    buf[6] = (uint8_t)(value >> 48);
+    buf[7] = (uint8_t)(value >> 56);
+}
+
+void buf_io_put64_tb(uint64_t value, uint8_t *buf)
+{
+    buf[7] = (uint8_t)(value      );
+    buf[6] = (uint8_t)(value >> 8 );
+    buf[5] = (uint8_t)(value >> 16);
+    buf[4] = (uint8_t)(value >> 24);
+    buf[3] = (uint8_t)(value >> 32);
+    buf[2] = (uint8_t)(value >> 40);
+    buf[1] = (uint8_t)(value >> 48);
+    buf[0] = (uint8_t)(value >> 56);
+}
+
+void buf_io_put64_tl_apr(uint64_t value, uint8_t **buf)
+{
+    buf_io_put64_tl(value,*buf);
+    *buf += 8;
+}
+
+void buf_io_put64_tb_apr(uint64_t value, uint8_t **buf)
+{
+    buf_io_put64_tb(value,*buf);
+    *buf += 8;
+}
+
+/* --- float PUT functions ----------------------------  */
+
+void buf_io_putf_tl(float value, uint8_t *buf)
+{
+    buf_io_put32_tl(*((uint32_t*) &value),buf);
+}
+
+void buf_io_putf_tb(float value, uint8_t *buf)
+{
+    buf_io_put32_tb(*((uint32_t*) &value),buf);
+}
+
+void buf_io_putf_tl_apr(float value, uint8_t **buf)
+{
+    buf_io_putf_tl(value,*buf);
+    *buf += 4;
+}
+
+void buf_io_putf_tb_apr(float value, uint8_t **buf)
+{
+    buf_io_putf_tb(value,*buf);
+    *buf += 4;
+}
+
+/* --- double PUT functions ----------------------------  */
+
+void buf_io_putd_tl(double value, uint8_t *buf)
+{
+    buf_io_put64_tl(*((uint64_t*) &value),buf);
+}
+
+void buf_io_putd_tb(double value, uint8_t *buf)
+{
+    buf_io_put64_tb(*((uint64_t*) &value),buf);
+}
+
+void buf_io_putd_tl_apr(double value, uint8_t **buf)
+{
+    buf_io_putd_tl(value,*buf);
+    *buf += 8;
+}
+
+void buf_io_putd_tb_apr(double value, uint8_t **buf)
+{
+    buf_io_putd_tb(value,*buf);
+    *buf += 8;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/buf_io.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,183 @@
+/**
+@file buf_io.c
+
+Several functions for handling data in buffers. 
+
+Basic functions:
+
+buf_io_[get|put][8|16|32|64|f|d]_[f|t][b|l]_ap[r]
+
+Notation:
+
+8|16|32|64|f|d = data size (f for float, d for double)
+[f|t][b|l] = from/to big/little
+ap[r] = add pointer [reference] at the end
+
+Check buf_io.c for a proper implementation of these functions for your platform.
+*/
+
+#ifndef __BUF_IO__
+#define __BUF_IO__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Pointer size */
+#define POINTER_SIZE (sizeof(void *)) 
+
+/** Number of elements in a array */
+#define NUM_OF_ELEMENTS_IN_ARRAY(a) (sizeof(a)/sizeof(a[0]))
+
+/** 
+  @name next/prev macro functions
+  Next/previous aligned address, avoiding data aborts in buffer operations.
+  @{
+*/
+#define __next_aligned_addr32(x)  (((x) + 0x03) & 0xFFFFFFFC)
+#define __next_aligned_addr16(x)  (((x) + 0x01) & 0xFFFFFFFE)
+#define __prev_aligned_addr32(x)  ((x) & 0xFFFFFFFC)
+#define __prev_aligned_addr16(x)  ((x) & 0xFFFFFFFE)
+/** @} */
+
+/** 
+  @name swap functions
+  Swap operations.
+  @{
+*/
+
+/** 
+  Swaps a 16 bits unsigned integer.
+  @param ucShort 16 bits unsigned integer to be swapped
+  @return 16 bits unsigned integer swapped
+  @{
+ */
+uint16_t buf_io_swap16 (uint16_t usShort);
+
+/** 
+  Swaps a 32 bits unsigned integer.
+  @param ulLong 32 bits unsigned integer to be swapped
+  @return 32 bits unsigned integer swapped
+  @{
+ */
+uint32_t buf_io_swap32 (uint32_t ulLong);
+
+/**
+  Swaps a 16 bits unsigned integer inside a buffer.
+  @param pucPtr Pointer where 16 bits unsigned integer is stored.
+*/
+void buf_io_swap16p(uint8_t *pucPtr);
+
+/**
+  Swaps a 32 bits unsigned integer inside a buffer.
+  @param pucPtr Pointer where 32 bits unsigned integer is stored.
+*/
+void buf_io_swap32p(uint8_t *pucPtr);
+
+/**
+  Swaps 8 bits unsigned integer in a byte.
+  @param ucChar 8 bits unsigned integer  to be bit swapped
+  @return 8 bits unsigned integer  swapped
+*/
+uint8_t  buf_io_swap8b (uint8_t ucChar);
+/** @} */
+
+/** 
+  @name endianess dependent functions (GET)
+  @{
+*/
+uint8_t buf_io_get8_fl       (uint8_t  *buf);
+uint8_t buf_io_get8_fb       (uint8_t  *buf);
+uint8_t buf_io_get8_fl_apr   (uint8_t **buf);
+uint8_t buf_io_get8_fb_apr   (uint8_t **buf);
+#define  buf_io_get8_fl_ap(x) buf_io_get8_fl_apr(&x)
+#define  buf_io_get8_fb_ap(x) buf_io_get8_fb_apr(&x)
+
+uint16_t buf_io_get16_fl       (uint8_t  *buf);
+uint16_t buf_io_get16_fb       (uint8_t  *buf);
+uint16_t buf_io_get16_fl_apr   (uint8_t **buf);
+uint16_t buf_io_get16_fb_apr   (uint8_t **buf);
+#define  buf_io_get16_fl_ap(x) buf_io_get16_fl_apr(&x)
+#define  buf_io_get16_fb_ap(x) buf_io_get16_fb_apr(&x)
+
+uint32_t  buf_io_get32_fl       (uint8_t  *buf);
+uint32_t  buf_io_get32_fb       (uint8_t  *buf);
+uint32_t  buf_io_get32_fl_apr   (uint8_t **buf);
+uint32_t  buf_io_get32_fb_apr   (uint8_t **buf);
+#define   buf_io_get32_fl_ap(x) buf_io_get32_fl_apr(&x)
+#define   buf_io_get32_fb_ap(x) buf_io_get32_fb_apr(&x)
+
+uint64_t buf_io_get64_fl       (uint8_t  *buf);
+uint64_t buf_io_get64_fb       (uint8_t  *buf);
+uint64_t buf_io_get64_fl_apr   (uint8_t **buf);
+uint64_t buf_io_get64_fb_apr   (uint8_t **buf);
+#define  buf_io_get64_fl_ap(x) buf_io_get64_fl_apr(&x)
+#define  buf_io_get64_fb_ap(x) buf_io_get64_fb_apr(&x)
+
+float   buf_io_getf_fl       (uint8_t *src_ptr);
+float   buf_io_getf_fb       (uint8_t *src_ptr);
+float   buf_io_getf_fl_apr   (uint8_t **src_ptr);
+float   buf_io_getf_fb_apr   (uint8_t **src_ptr);
+#define buf_io_getf_fl_ap(x) buf_io_getf_fl_apr(&x)
+#define buf_io_getf_fb_ap(x) buf_io_getf_fb_apr(&x)
+
+double  buf_io_getd_fl       (uint8_t *src_ptr);
+double  buf_io_getd_fb       (uint8_t *src_ptr);
+double  buf_io_getd_fl_apr   (uint8_t **src_ptr);
+double  buf_io_getd_fb_apr   (uint8_t **src_ptr);
+#define buf_io_getd_fl_ap(x) buf_io_getd_fl_apr(&x)
+#define buf_io_getd_fb_ap(x) buf_io_getd_fb_apr(&x)
+/** @} */
+
+/** 
+  @name endianess dependent functions (PUT)
+  @{
+*/
+void    buf_io_put8_tl         (uint8_t value, uint8_t  *buf);
+void    buf_io_put8_tb         (uint8_t value, uint8_t  *buf);
+void    buf_io_put8_tl_apr     (uint8_t value, uint8_t **buf);
+void    buf_io_put8_tb_apr     (uint8_t value, uint8_t **buf);
+#define buf_io_put8_tl_ap(v,x) buf_io_put8_tl_apr(v,&x) 
+#define buf_io_put8_tb_ap(v,x) buf_io_put8_tb_apr(v,&x) 
+
+void    buf_io_put16_tl         (uint16_t value, uint8_t  *buf);
+void    buf_io_put16_tb         (uint16_t value, uint8_t  *buf);
+void    buf_io_put16_tl_apr     (uint16_t value, uint8_t **buf);
+void    buf_io_put16_tb_apr     (uint16_t value, uint8_t **buf);
+#define buf_io_put16_tl_ap(v,x) buf_io_put16_tl_apr(v,&x) 
+#define buf_io_put16_tb_ap(v,x) buf_io_put16_tb_apr(v,&x) 
+
+void    buf_io_put32_tl         (uint32_t value, uint8_t  *buf);
+void    buf_io_put32_tb         (uint32_t value, uint8_t  *buf);
+void    buf_io_put32_tl_apr     (uint32_t value, uint8_t **buf);
+void    buf_io_put32_tb_apr     (uint32_t value, uint8_t **buf);
+#define buf_io_put32_tl_ap(v,x) buf_io_put32_tl_apr(v,&x) 
+#define buf_io_put32_tb_ap(v,x) buf_io_put32_tb_apr(v,&x) 
+
+void    buf_io_put64_tl         (uint64_t value, uint8_t  *buf);
+void    buf_io_put64_tb         (uint64_t value, uint8_t  *buf);
+void    buf_io_put64_tl_apr     (uint64_t value, uint8_t **buf);
+void    buf_io_put64_tb_apr     (uint64_t value, uint8_t **buf);
+#define buf_io_put64_tl_ap(v,x) buf_io_put64_tl_apr(v,&x) 
+#define buf_io_put64_tb_ap(v,x) buf_io_put64_tb_apr(v,&x) 
+
+void    buf_io_putf_tl          (float value, uint8_t *buf); 
+void    buf_io_putf_tb          (float value, uint8_t *buf); 
+void    buf_io_putf_tl_apr      (float value, uint8_t **buf); 
+void    buf_io_putf_tb_apr      (float value, uint8_t **buf); 
+#define buf_io_putf_tl_ap(v, x) buf_io_putf_tl_apr(v, &x) 
+#define buf_io_putf_tb_ap(v, x) buf_io_putf_tb_apr(v, &x) 
+
+void    buf_io_putd_tl          (double value, uint8_t *buf); 
+void    buf_io_putd_tb          (double value, uint8_t *buf); 
+void    buf_io_putd_tl_apr      (double value, uint8_t **buf); 
+void    buf_io_putd_tb_apr      (double value, uint8_t **buf); 
+#define buf_io_putd_tl_ap(v, x) buf_io_putd_tl_apr(v, &x) 
+#define buf_io_putd_tb_ap(v, x) buf_io_putd_tb_apr(v, &x) 
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BUF_IO__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/crc16.c	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,99 @@
+/* 
+ * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
+ * Copyright (c) 2006 Christian Walter <wolti@sil.at>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ *
+ * File: $Id: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $
+ */
+
+/* ----------------------- Platform includes --------------------------------*/
+#include <stdint.h>
+#include "crc16.h"
+
+static const uint8_t crc_hi_table[] = {
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
+    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+    0x00, 0xC1, 0x81, 0x40
+};
+
+static const uint8_t crc_low_table[] = {
+    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
+    0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
+    0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
+    0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
+    0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
+    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
+    0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
+    0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 
+    0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
+    0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
+    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
+    0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
+    0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 
+    0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
+    0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
+    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
+    0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
+    0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
+    0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
+    0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
+    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
+    0x41, 0x81, 0x80, 0x40
+};
+
+uint16_t crc16_calc(uint8_t * frame, uint16_t len)
+{
+    uint8_t           crc_hi = 0xFF;
+    uint8_t           crc_low = 0xFF;
+    int             iIndex;
+
+    while( len-- )
+    {
+        iIndex = crc_low ^ *( frame++ );
+        crc_low = ( uint8_t )( crc_hi ^ crc_hi_table[iIndex] );
+        crc_hi = crc_low_table[iIndex];
+    }
+
+    return ( uint16_t )( crc_hi << 8 | crc_low );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/crc16.h	Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,35 @@
+/* 
+ * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
+ * Copyright (c) 2006 Christian Walter <wolti@sil.at>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ *
+ */
+
+#ifndef _MB_CRC_H
+#define _MB_CRC_H
+
+uint16_t crc16_calc(uint8_t *frame, uint16_t len);
+
+#endif