VTT TinyNode, slightly modified code from example (https://developer.mbed.org/users/jejuho/code/VTT_NODEV3_BMP180_Si7021)

Dependencies:   BLE_API TMP_nrf51 mbed nRF51822

Fork of VTT_NODEV3_BMP180_Si7021 by Juho Eskeli

Files at this revision

API Documentation at this revision

Comitter:
jejuho
Date:
Tue Dec 08 11:58:59 2015 +0000
Child:
1:bd7fd35251ab
Commit message:
Works OK.

Changed in this revision

AT45.cpp Show annotated file Show diff for this revision Revisions of this file
AT45.h Show annotated file Show diff for this revision Revisions of this file
BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
LEDService.h Show annotated file Show diff for this revision Revisions of this file
LIS3DH.cpp Show annotated file Show diff for this revision Revisions of this file
LIS3DH.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
nrf_gpio.h Show annotated file Show diff for this revision Revisions of this file
nrf_gpiote.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AT45.cpp	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,1014 @@
+/* mbed AT45 Library, for driving the Atmel AT45 series Dataflash with Serial Interface (SPI)
+ * Copyright (c) 2012, Created by Steen Joergensen (stjo2809) inspired by Chris Styles AT45 library
+ *
+ * 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 "AT45.h"
+#include "nrf_delay.h"
+
+//=============================================================================
+// Public functions
+//=============================================================================
+
+AT45::AT45(SPI& spi, PinName ncs) : _spi(spi), _ncs(ncs)
+{    
+    
+    _pages = -1;        // number of pages
+    _pagesize = -1;     // size of pages 256/264, 512/528, 1024/1056
+    _devicesize = -1;   // In bytes
+    _deep_down = true; // variable for deep power down function (awake ?)
+    _deep_down_onoff = false; // variable for deep power down function (On/Off) 
+
+    _initialize();     // Populate all this stuff
+    
+}
+
+// This function returns the char
+char AT45::read_byte(int address) 
+{   
+    // return byte from address
+    return (_memread( address ));
+}  
+
+int AT45::read_page(char* data, int page)         
+{
+    int address = -1;
+    
+    if(_pagesize == 256)
+    {
+        address = page * 256;
+    }
+    else if(_pagesize == 264)
+    {
+        address = page * 512;
+    }
+    else if(_pagesize == 512)
+    {
+        address = page * 512;
+    }
+    else if(_pagesize == 528)
+    {
+        address = page * 1024;
+    }
+    else if(_pagesize == 1024)
+    {
+        address = page * 1024;
+    }
+    else if(_pagesize == 1056)
+    {
+        address = page * 2048;
+    }
+    else 
+    {
+        return (-1); // something isnt configured right
+    }
+                
+    _busy();        
+    _flashread(1,address); // read the first page of the block into SRAM buffer 1
+    _busy();               // Wait until First page has loaded into buffer 1
+        
+    // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread
+    _select();
+    _spi.write(0xd4);
+    _sendaddr (0x0);
+    _spi.write (0x0);   // dont care byte
+        
+    for(int i=0; i<_pagesize ;i++) 
+    {
+        data[i] = _spi.write (0x0);  
+    }
+    _deselect();            
+              
+    return (0);
+}
+int AT45::read_block(char *data, int block)  // under construction F&#65533;R CHECK AF MIC OG LERCHE
+{    
+    char temp_data[_pagesize];
+    int page_start;
+
+    if (block < _blocks || block == 0) {
+        page_start = block * 8;
+
+        for (int i=0; i<8; i++) {
+            read_page(temp_data, page_start);
+            //printf("%d Read round, Data is: %d\r\n",i,*temp_data);
+            page_start = page_start + 1;
+            for (int z=0; z<_pagesize ; z++) {
+                data[z+(_pagesize*i)] = temp_data[z];
+            }
+        }
+    } else {
+        //do nothing
+    }
+    //printf("Read done, Data is: %d\r\n",*data);
+    return (0);
+}
+     
+int AT45::read_block(char *data[], int block)       // under construction F&#65533; CHECK AF MIC OG LERCHE 
+{
+    char temp_data[_pagesize];
+    int page_start;
+    
+    if(block < _blocks || block == 0)   
+    {
+        page_start = block * 8;
+    
+        for(int i=0; i<8 ;i++)                         // 8 pages in a block
+        {
+            read_page(temp_data, page_start);
+            page_start = page_start + 1;
+            for(int z=0; z<_pagesize ;z++)
+            {
+                data[i][z] = temp_data[z];
+            }  
+        }
+    }
+    else
+    {
+        //do nothing   
+    }
+ 
+    return (0);
+}
+       
+// This function writes the char to the address supplied
+// Note : We pass the raw address to the underlying functions
+void AT45::write_byte(int address, char data) 
+{
+    _busy();   
+    _flashread(1,address);             // read the Flash page into SRAM buffer
+    _busy();                           // wait for the read to complete
+    _sramwrite(1,address,data);        // Write new data into SRAM
+    _busy();                           // Make sure flash isnt busy
+    _flashwrite(1,address);            // Write back to the page address
+}       
+      
+int AT45::write_page(char* data, int page)
+{
+    int address = -1;
+    
+    if(_pagesize == 256)
+    {
+        address = page * 256;
+    }
+    else if(_pagesize == 264)
+    {
+        address = page * 512;
+    }
+    else if(_pagesize == 512)
+    {
+        address = page * 512;
+    }
+    else if(_pagesize == 528)
+    {
+        address = page * 1024;
+    }
+    else if(_pagesize == 1024)
+    {
+        address = page * 1024;
+    }
+    else if(_pagesize == 1056)
+    {
+        address = page * 2048;
+    }
+    else 
+    {
+        return (-1); // something isnt configured right
+    }
+    
+    _select();
+    _spi.write(0x84); // writing to buffer #1
+    _sendaddr (0); // we are writing to the entire buffer
+
+    for(int i=0; i<_pagesize ;i++) 
+    {
+        _spi.write (data[i]);  
+    }
+    _deselect();        
+        
+    _busy(); // make sure the Flahs isnt busy
+                
+    // issue command to write buffer 1 to the appropraite flash page
+    _select();  
+    _spi.write (0x83);  
+    _sendaddr (_getpaddr(address));  
+    _deselect();
+    
+    return (0);   
+}
+int AT45::write_block(char *data, int block) // under construction F&#65533;R CHECK AF MIC OG LERCHE
+{    
+    
+    int page_start;
+    char page_arr[_pagesize];
+    
+    if (block < _blocks || block == 0) 
+    {
+        page_start = block * 8;
+        
+        for (int i=0; i<8 ; i++) 
+        {
+            // Copy data from *data at 0 to 511 _ 512 - 1023, and so on every round.  
+            memcpy(page_arr, &data[_pagesize*i], _pagesize); 
+            
+            write_page(page_arr, page_start);
+            page_start = page_start + 1;
+        }
+    } else {
+        //do nothing
+    }
+
+    return (0);
+}
+int AT45::write_block(char *data[], int block)      // under construction F&#65533; CHECK AF MIC OG LERCHE 
+{
+    char temp_data[_pagesize];
+    int page_start;
+    
+    if(block < _blocks || block == 0)   
+    {
+        page_start = block * 8;
+    
+        for(int i=0; i<8 ;i++) 
+        {
+            for(int z=0; z<_pagesize ;z++)
+            {
+               temp_data[z] = data[i][z];    
+            }   
+            write_page(temp_data, page_start);
+            page_start = page_start + 1;
+        }
+    }
+    else
+    {
+        //do nothing   
+    }
+ 
+    return (0);
+}
+
+int AT45::FAT_read(char* data, int page)          
+{
+    // For 256 byte pages, we read two pages
+    if((_pagesize == 256) || (_pagesize == 264)) 
+    {
+        int address = page * 512; // This is the start address of the 512 byte block
+           
+        _flashread(1,address); // read the first page of the block into SRAM buffer 1
+        _busy(); // Wait until First page has loaded into buffer 1
+        
+        // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread
+        _select();
+        _spi.write(0xd4);
+        _sendaddr (0x0);
+        _spi.write (0x0);   // dont care byte
+        
+        for(int i=0;i<256;i++) 
+        {
+            data[i] = _spi.write (0x0);  
+        }
+        _deselect();            
+                
+        _flashread(1,address+256); // read the second page of the block into SRAM buffer 2
+        _busy(); // Wait until second page has loaded into buffer 2
+        
+        // Now the second page is loaded, pull this out into the second half of the data buffer
+        // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread
+        _select();
+        _spi.write(0xd4);
+        _sendaddr (0x0);
+        _spi.write (0x0);   // dont care byte
+        
+        for(int i=0;i<256;i++) 
+        {
+            data[256+i] = _spi.write (0x0);  
+        }
+        _deselect();                
+        return (0);
+    }
+    
+    // For 512 byte pages, we read just the single page, transfer it    
+    else if((_pagesize == 512) || (_pagesize == 528)) 
+    {
+        int address = page * 512; // This is the start address of the 512 byte block
+    
+        _busy(); // Wait until First page has loaded into buffer 1
+        _flashread(1,address); // read the first page of the block into SRAM buffer 1
+        _busy(); // Wait until First page has loaded into buffer 1
+        
+        // Now the page has loaded, simply transfer it from the sram buffer to the data array
+        // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread
+        _select();
+        _spi.write(0xd4);
+        _sendaddr (0x0);
+        _spi.write (0x0);   // dont care byte
+        
+        for(int i=0;i<512;i++) 
+        {
+            data[i] = _spi.write (0x0);  
+        }
+        _deselect();            
+        return (0);
+    }
+
+    // For 1024 byte pages, we read just a single page, transfer half of it
+    else if((_pagesize == 1024) || (_pagesize == 1056)) 
+    {
+        int address = _getpaddr(page * 512); // This is the start address of the 512 byte block
+
+        _busy(); // Wait until First page has loaded into buffer 1
+    
+        _flashread(1,address); // read the first page of the block into SRAM buffer 1
+
+        _busy(); // Wait until First page has loaded into buffer 1
+        
+        // Now the page has loaded, simply transfer it from the sram buffer to the data array
+        // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread
+
+        _select();
+        _spi.write(0xd4);
+
+        if (page %2) // odd numbered block, read from adress 0x200
+        { 
+            _sendaddr (0x200);
+        }
+        else // even numbered block, then we are reading from sram buffer 0x0 
+        {
+            _sendaddr (0x0);
+        }
+
+        _spi.write (0x0);   // dont care byte
+        
+        for(int i=0;i<512;i++) 
+        {
+            data[i] = _spi.write (0x0);  
+        }
+        _deselect();            
+        return (0);
+    }
+    else 
+    {
+        return (-1); // something isnt configured right
+    }
+}
+       
+int AT45::FAT_write(char* data, int page)        
+{
+    // For 256 byte pages, we overwrite two pages
+    if((_pagesize == 256) || (_pagesize == 264))
+    {
+        
+        // fill the first buffer with the first half of the block
+        // do this directly, for better performance
+        _select();
+        _spi.write(0x84); // writing to buffer #1
+        _sendaddr (0); // we are writing to the entire buffer
+
+        for(int i=0;i<256;i++) {
+            _spi.write (data[i]);  
+        }
+        _deselect();        
+                
+        _flashwrite(1,(page*512));
+
+        // fill the buffer with the second half of the block
+        // do this directly, for better performance
+        _select();
+        _spi.write(0x84); // writing to buffer #1
+        _sendaddr (0); // we are writing to the entire buffer
+
+        for(int i=0;i<256;i++) {
+            _spi.write (data[256+i]);  
+        }
+        _deselect();        
+
+        _flashwrite(1,((page*512)+256));
+    }
+        
+    // For 512 byte pages, we overwrite a single page
+    else if((_pagesize == 512) || (_pagesize == 528)) 
+    {
+    
+        // fill the first buffer with the block data
+        // do this directly, for better performance
+        _select();
+        _spi.write(0x84); // writing to buffer #1
+        _sendaddr (0); // we are writing to the entire buffer
+
+        for(int i=0;i<512;i++) {
+            _spi.write (data[i]);  
+        }
+        _deselect();        
+        
+        _busy(); // make sure the Flahs isnt busy
+                
+        // issue command to write buffer 1 to the appropraite flash page
+        _select();  
+        _spi.write (0x83);  
+        _sendaddr (_getpaddr(page * 512));  
+        _deselect();                
+    }
+
+    // For 1024 byte pages, we do a read modify write
+    // must make sure we overwrite the right half of the page!
+    else if((_pagesize == 1024) || (_pagesize == 1056)) 
+    {
+
+        _busy(); // make sure the flash isnt busy
+
+        int address = _getpaddr(page*512);
+
+        // Read the page into sram
+        _flashread(1,address);  
+        
+        // wait for this operation to complete
+        _busy();
+        
+        // Overwrite the appropriate half
+        // do this directly, for better performance
+        _select();
+        _spi.write(0x84); // writing to buffer #1
+
+        if(page%2)  // this is an odd block number, overwrite second half of buffer 
+        {  
+            _sendaddr (0x200); // we are writing to the entire buffer
+        }
+        else        // this is an even block, overwrite the first half
+        {  
+            _sendaddr (0x0); // we are writing to the entire buffer
+        }
+
+        for(int i=0;i<512;i++) 
+        {
+            _spi.write (data[i]);  
+        }
+        _deselect();        
+        
+        // Write the page back
+        _busy();
+        _flashwrite(1,address); 
+    }
+    
+    // Something has gone wrong
+    else 
+    {
+        return (-1);
+    }
+    
+    return (0);
+}
+       
+// Erase the entire chip
+void AT45::chip_erase() 
+{ 
+    _busy(); // make sure flash isnt already in busy.
+
+    _select();
+    // 4 byte command sequence
+    _spi.write(0xc7);
+    _spi.write(0x94);
+    _spi.write(0x80);
+    _spi.write(0x9a);
+    _deselect();  
+
+    _busy(); // Make erase a blocking function
+}        
+
+// Erase one block  
+void AT45::block_erase(int block)      
+{
+    int address = -1;
+    
+    // Calculate page addresses
+    if(block < _blocks || block == 0)   
+    {
+        if(_pagesize == 256)
+        {
+            address = block * 2048;
+        }
+        else if(_pagesize == 264)
+        {
+            address = block * 4096;
+        }
+        else if(_pagesize == 512)
+        {
+            address = block * 4096;
+        }
+        else if(_pagesize == 528)
+        {
+            address = block * 8192;
+        }
+        else if(_pagesize == 1024)
+        {
+            address = block * 8192;
+        }
+        else if(_pagesize == 1056)
+        {
+            address = block * 16384;
+        }
+        
+        _busy();
+        _select();
+        _spi.write(0x50);
+        _sendaddr (address);
+        _deselect();
+        _busy();   
+    }
+    else
+    {
+        //do nothing   
+    }
+}
+
+// Erase one page       
+void AT45::page_erase(int page)
+{
+    int address = -1;
+    
+    // Calculate page addresses
+    if(page < _pages || page == 0)   
+    {
+        if(_pagesize == 256)
+        {
+            address = page * 256;
+        }
+        else if(_pagesize == 264)
+        {
+            address = page * 512;
+        }
+        else if(_pagesize == 512)
+        {
+            address = page * 512;
+        }
+        else if(_pagesize == 528)
+        {
+            address = page * 1024;
+        }
+        else if(_pagesize == 1024)
+        {
+            address = page * 1024;
+        }
+        else if(_pagesize == 1056)
+        {
+            address = page * 2048;
+        }
+        
+        _busy();
+        _select();
+        _spi.write(0x81);
+        _sendaddr (address);
+        _deselect();
+        _busy();   
+    }
+    else
+    {
+        //do nothing   
+    }
+}
+      
+// return the size of the part in bytes
+int AT45::device_size() 
+{ 
+    return _devicesize;
+}       
+
+// return the numbers of pages
+int AT45::pages() 
+{ 
+    return _pages;
+}       
+       
+// return the page size of the part in bytes
+int AT45::pagesize() 
+{ 
+    return _pagesize;
+}       
+       
+// A one-time programmable configuration
+void AT45::set_pageszie_to_binary()
+{
+    _busy(); // make sure flash isnt already in busy.
+
+    _select();
+    // 4 byte command sequence
+    _spi.write(0x3d);
+    _spi.write(0x2a);
+    _spi.write(0x80);
+    _spi.write(0xa6);
+    _deselect();  
+
+    _busy(); // Make erase a blocking function   
+}
+
+// Return the number of blocks in this device in accordance with the datasheet
+int AT45::blocks() 
+{  
+    return _blocks;
+}
+       
+// Return the Id of the part
+int AT45::id() 
+{ 
+    int id = 0;
+    _select();
+    _spi.write(0x9f);
+    id = (_spi.write(0x00) << 8);
+    id |= _spi.write(0x00);
+    _deselect();            
+    return id; 
+}
+         
+// return the Status
+int AT45::status() 
+{ 
+    int status = 0;
+    _select();
+    _spi.write(0xd7);
+    status = (_spi.write(0x00));
+    _deselect();            
+    return status; 
+}
+          
+// Make sure the Flash isnt already doing something
+void AT45::busy() 
+{
+    _busy();
+}
+
+void AT45::deep_power_down(bool _deep_down_onoff) 
+{
+    if(_deep_down_onoff == false) // Wake up from deep power down
+    {
+        _select();
+        _spi.write(0xab);
+        _deselect();
+        _deep_down = true;
+        // remenber to want 35uS before using the device.          
+    }
+    else if(_deep_down_onoff == true) // Go to deep power down
+    {
+        _busy();
+        _select();
+        _spi.write(0xb9);
+        _deselect();
+        _deep_down = false;
+    }
+    else
+    {
+        //do nothing   
+    }       
+}
+
+void AT45::ultra_deep_power_down(bool _deep_down_onoff) 
+{
+    if(_deep_down_onoff == false) // Wake up from deep power down
+    {
+        _select();
+        //_spi.write(0xab);
+                //wait 20ns
+                nrf_delay_us(1);
+        _deselect();
+        _deep_down = true;
+        // remenber to want 35uS before using the device.          
+    }
+    else if(_deep_down_onoff == true) // Go to deep power down
+    {
+        _busy();
+        _select();
+        _spi.write(0x79);
+        _deselect();
+        _deep_down = false;
+    }
+    else
+    {
+        //do nothing   
+    }       
+}
+
+bool AT45::is_it_awake()
+{
+    return _deep_down;
+}
+
+//=============================================================================
+// Private functions
+//=============================================================================
+
+void AT45::_initialize()
+{
+    int _id = 0;
+    int _status = 0;
+  
+    _id = id();
+    _id = id();
+    _status = status();
+    
+    if ((_id & 0x1f) == 0x3)  // 2Mbits 
+    { 
+        _devicesize = 262144; // Size in bytes
+        _pages = 1024;        // Number of pages
+        _blocks = 128;        // Number of blocks
+        if (_status & 0x1) 
+        {
+            _pagesize = 256;
+        }
+        else 
+        {
+            _pagesize = 264;
+        }    
+    }
+    else if ( (_id & 0x1f) == 0x4) // 4Mbits 
+    { 
+        _devicesize = 524288;
+        _pages = 2048;
+        _blocks = 256;        
+        if (_status & 0x1) 
+        {
+            _pagesize = 256;
+        }
+        else 
+        {
+            _pagesize = 264;
+        }    
+    }
+    else if ( (_id & 0x1f) == 0x5) // 8Mbits 
+    { 
+        _devicesize = 1048576;
+        _pages = 4096;
+        _blocks = 512;        
+        if (_status & 0x1) 
+        {
+            _pagesize = 256;
+        }
+        else 
+        {
+            _pagesize = 264;
+        }    
+    }
+    else if ( (_id & 0x1f) == 0x6) // 16Mbits 
+    { 
+        _devicesize = 2097152;
+        _pages = 4096;
+        _blocks = 512;        
+        if (_status & 0x1) 
+        {
+            _pagesize = 512;
+        }
+        else 
+        {
+            _pagesize = 528;
+        }
+    }
+    else if ( (_id & 0x1f) == 0x7) // 32Mbits 
+    { 
+        _devicesize = 4194304;
+        _pages = 8192;
+        _blocks = 1024;        
+        if (_status & 0x1) 
+        {
+            _pagesize = 512;
+        }
+        else 
+        {
+            _pagesize = 528;
+        }
+    }
+    else if ( (_id & 0x1f) == 0x8) // 64Mbits 
+    { 
+        _devicesize = 8388608;
+        _pages = 8192;
+        _blocks = 1024;
+        if (_status & 0x1) 
+        {
+            _pagesize = 1024;
+        }
+        else 
+        {
+            _pagesize = 1056;
+        }
+    }
+    else 
+    {
+        _devicesize = -1;
+        _pages = -1;
+        _pagesize = -1;
+        _blocks = -1;
+    }
+}
+
+void AT45::_select()
+{
+    _ncs = 0;    
+}
+
+void AT45::_deselect()
+{
+    _ncs = 1;
+}
+
+void AT45::_busy() {
+    volatile int iambusy = 1;  
+    while (iambusy) {
+        // if bit 7 is set, we can proceed
+        if ( status() & 0x80 ) {
+            iambusy = 0;}
+    }
+}
+
+// Write to an SRAM buffer
+// Note : We create buffer and page addresses in _sram and _flash        
+void AT45::_sramwrite(int buffer, int address, int data)
+{
+
+    int cmd = 0;
+    int baddr = 0;
+  
+    baddr = _getbaddr(address);
+  
+    _busy();
+  
+    _select();
+  
+    if (buffer == 1) 
+        {cmd = 0x84;}
+    else 
+        {cmd = 0x87;}
+
+    _spi.write(cmd);
+    _sendaddr (baddr);
+    _spi.write (data);  
+
+    _deselect();            
+}
+
+// Read from an SRAM buffer
+// Note : We create buffer and page addresses in _sram and _flash
+int AT45::_sramread(int buffer, int address) 
+{
+
+    int cmd = 0;
+    int baddr = 0;
+    int bufdata = 0;
+  
+    baddr = _getbaddr(address);
+  
+    _select();
+  
+    if(buffer == 1) 
+        {cmd = 0xd4;}
+    else 
+        {cmd = 0xd6;}
+  
+    _spi.write(cmd);
+    _sendaddr (baddr);
+    _spi.write (0x0);   // dont care byte
+    bufdata = _spi.write (0x0);  
+  
+    _deselect();            
+ 
+    return (bufdata);
+}
+
+// Write and SRAM buffer to main memory
+void AT45::_flashwrite (int buffer, int address)
+{
+
+    int cmd = 0;
+    int paddr = _getpaddr(address);
+ 
+    _busy();  // Check flash is not busy 
+    
+    _select();  
+
+    if (buffer == 1) 
+        {cmd = 0x83;}
+    else 
+        {cmd = 0x86;}
+      
+    _spi.write (cmd);  
+    _sendaddr (paddr);  
+    _deselect();     
+
+    _busy();  // Check flash is not busy 
+}
+
+// Read from Flash memory into SRAM buffer
+void AT45::_flashread (int buffer, int address) 
+{
+
+    int cmd = 0;
+    int paddr = _getpaddr(address); // calculate page address
+  
+    _busy();  // Check flash is not busy
+    _select();
+      
+    if (buffer == 1)
+        {cmd = 0x53;}
+    else
+        {cmd = 0x55;}
+
+    _spi.write (cmd);  
+    _sendaddr (paddr);
+    _deselect();            
+}
+
+// Read directly from main memory
+int AT45::_memread (int address) 
+{
+
+    int data = 0;        
+    int addr;
+
+    addr = _getpaddr(address) | _getbaddr(address);
+
+    _busy();
+
+    _select();
+
+    _spi.write (0xd2);  // Direct read command
+    _sendaddr (addr);
+  
+    // 4 dont care bytes
+    _spi.write (0x00);  
+    _spi.write (0x00);  
+    _spi.write (0x00);  
+    _spi.write (0x00);  
+  
+    // this one clocks the data
+    data = _spi.write (0x00);  
+    _deselect();            
+
+    _busy();
+
+    return data;
+}
+
+// Work out the page address
+// If we have a 2^N page size, it is just the top N bits
+// If we have non-2^N, we use the shifted address
+int AT45::_getpaddr(int address) 
+{
+
+    int paddr;
+
+    if (_pagesize == 256) {                 
+        paddr = address & 0xffffff00;}    
+    else if (_pagesize == 264) {                 
+        paddr = (address << 1) & 0xfffffe00;}
+    else if (_pagesize == 512) {                 
+        paddr = address & 0xfffffe00;}
+    else if (_pagesize == 528 ) {           
+       paddr = (address << 1) & 0xfffffc00;}
+    else if (_pagesize == 1024) {                 
+       paddr = address & 0xfffffc00;}
+    else if (_pagesize == 1056 ) {           
+        paddr = (address << 1) & 0xfffff800;}
+    else {
+        paddr = -1;}
+    
+    return (paddr);
+}
+
+// Clean the buffer address. This is the 8/9/10 LSBs
+int AT45::_getbaddr(int address) 
+{
+
+    int baddr;
+
+    if ((_pagesize == 256) || (_pagesize == 264 )) {
+        baddr = address & 0xff;}
+    else if ((_pagesize == 512) || (_pagesize == 528 )) {
+        baddr = address & 0x1ff;}
+    else if ((_pagesize == 1024) || (_pagesize == 1056 )) {
+        baddr = address & 0x3ff;}
+    else {
+        baddr = -1;}
+
+    return (baddr);
+}
+
+// Sends the three lest significant bytes of the supplied address
+void AT45::_sendaddr (int address) 
+{
+    _spi.write(address >> 16);
+    _spi.write(address >> 8);
+    _spi.write(address);      
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AT45.h	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,280 @@
+/* mbed AT45 Library, for driving the Atmel AT45 series Dataflash with Serial Interface (SPI)
+ * Copyright (c) 2012, Created by Steen Joergensen (stjo2809) inspired by Chris Styles AT45 library
+ *
+ * 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.
+ *
+ *
+ * This driver supports 021,041,081,161,321,641 variants of the AT45DBxxx family
+ *
+ * || Code || Density  || Page size || Pages || Package ||
+ * || 021  || 2        || 256       || 1024  || 8 SOIC  ||
+ * || 041  || 4        || 256       || 2048  || 8 SOIC  ||
+ * || 081  || 8        || 256       || 4096  || 8 SOIC  ||
+ * || 161  || 16       || 512       || 4096  || 8 SOIC  ||
+ * || 321  || 32       || 512       || 8192  || 8 SOIC  ||
+ * || 641  || 64       || 1024      || 8192  || 28 TSOP ||
+ */
+
+#include "mbed.h"
+
+#ifndef AT45_H
+#define AT45_H
+
+//=============================================================================
+// Functions Declaration
+//=============================================================================
+
+/** Interface to the Atmel AT45 series Dataflash with Serial Interface (SPI)
+ *
+ *  Using the driver:
+ *   - remenber to setup SPI in main routine.
+ *   - remenber to setup Chipselect in main routine.
+ *   - remenber to use FAT functions set pagesize to binary.
+ *
+ *  Limitations of using this driver:
+ *   - can't use lockdown functions.
+ *   - can't use protections functions.
+ *   - can't use security functions.
+ *
+ */
+class AT45 {
+public:        
+       /** Create an instance of the AT45 connected to specfied SPI pins, with the specified address.
+        *
+        * @param spi The mbed SPI instance (make in main routine)
+        * @param nCs The SPI chip select pin.
+        */
+       AT45(SPI& spi, PinName ncs);
+
+             void initialize() { _initialize(); }
+       
+       /** Read a byte.
+        *
+        * @param address The address of the byte to read.
+        * @return The data in the byte.
+        */
+       char read_byte(int address);
+
+       /** Read a page.
+        *
+        * @param data The data is pointer to a userdefined array that the page is read into.
+        * @param page The page number of the page to read (0 to device page size).
+        * @return Returns "0" or "-1" for error.
+        */
+       int read_page(char* data, int page);
+       
+       /** Read a block (from 1 dimension array).
+        *
+        * @param data The data is pointer to a userdefined array that holds 4096 bytes of the data that is read into.
+        * @param block The block number of the block to read (0 to device block size).
+        * @return Returns "0" or "-1" for error.
+        */        
+       int read_block(char *data, int block);
+       
+       /** Read a block (from 2 dimension array).
+        *
+        * Then using 2 dimension array, the array shall have a starting point like "read_block(data[0],0)"
+        * @param data The data is pointer to a userdefined array that holds 8 x 512 bytes of the data that is read into.
+        * @param block The block number of the block to read (0 to device block size).
+        * @return Returns "0" or "-1" for error.
+        */       
+       int read_block(char *data[], int block);
+
+       /** Write a byte.
+        *
+        * @param address The address to where the data is storage in the flash.
+        * @param data The data to write into the flash.
+        */       
+       void write_byte(int address, char data);
+       
+       /** Write a page.
+        *
+        * @param data The data is pointer to a userdefined array that holds the data to write into.
+        * @param page The page number of the page to write into (0 to device page size).
+        * @return Returns "0" or "-1" for error.
+        */
+       int write_page(char* data, int page);
+
+       /** Write a block (from 1 dimension array).
+        *
+        * @param data The data is pointer to a userdefined array that holds 4096 bytes of the data to write into.
+        * @param block The block number of the block to write into (0 to device block size).
+        * @return Returns "0" or "-1" for error.
+        */       
+       int write_block(char *data, int block);
+        
+       /** Write a block (from 2 dimension array).
+        *
+        * Then using 2 dimension array, the array shall have a starting point like "write_block(data[0],0)"
+        * @param data The data is pointer to a userdefined array that holds 8 x 512 bytes of the data to write into (remenber it has to be a 2 dimension array).
+        * @param block The block number of the block to write into (0 to device block size).
+        * @return Returns "0" or "-1" for error.
+        */       
+       int write_block(char *data[], int block);
+
+       /** FAT Read (512 bits).
+        *
+        * Remenber to set page size to binary.
+        * @param data The data is pointer to a userdefined array that the page is read into.
+        * @param page The page number of the page to read (0 to device page size).
+        * @return Returns "0".
+        */       
+       int FAT_read(char* data, int page);
+       
+       /** FAT Write (512bits).
+        *
+        * Remenber to set page size to binary.
+        * @param data The data is pointer to a userdefined array that holds the data to write into.
+        * @param page The page number of the page to write into (0 to device page size).
+        * @return Returns "0" or "-1" for error.
+        */       
+       int FAT_write(char* data, int page); 
+            
+       /** Function to erase the entire chip.
+        *
+        *  Issue:
+        *  In a certain percentage of units, the chip erase feature may not function correctly and may adversely affect device operation.
+        *  Therefore, it is recommended that the chip erase commands (opcodes C7H, 94H, 80H, and 9AH) not be used.
+        *  Workaround:
+        *  Use block erase (opcode 50H) as an alternative. The block erase function is not affected by the chip erase issue.
+        *  Resolution:
+        *  The chip erase feature may be fixed with a new revision of the device. Please contact Atmel for the estimated availability of
+        *  devices with the fix.
+        */
+       void chip_erase(void);
+       
+       /** Function to erase the selected block.
+        *
+        * @param block The selected block to erase.
+        */
+       void block_erase(int block);
+       
+       /** Function to erase the selected block.
+        *
+        * @param page The number of the page to erase.
+        */
+       void page_erase(int page);
+       
+       /** Device size in mbits.
+        *
+        * @return device size.
+        */
+       int device_size(void);
+       
+       /** Pages in flash.
+        *
+        * @return Numbers af pages.
+        */
+       int pages(void);
+       
+       /** Page size.
+        * 
+        * for 2-8 Mbits 256 or 264
+        * for 16-32 Mbits 512 or 528
+        * for 64 Mbits 1024 or 1056
+        *
+        * @return Page size.
+        */
+       int pagesize(void);
+
+       /** Function to set the page size to binary.
+        *
+        *  Remenber is a one-time programmable configuration.
+        *  Remenber to total power down after the functions has been run. 
+        */       
+       void set_pageszie_to_binary(void);
+       
+       /** blocks in flash.
+        *
+        * @return Numbers af blocks.
+        */       
+       int blocks(void);
+       
+       /** ID of the device.
+        *
+        * @return Manufacturer, Family and Density code.
+        */          
+       int id(void);
+       
+       /** Status register.
+        *
+        * @return The status register.
+        */           
+       int status(void);    // Status register
+       
+       /** busy ?.
+        *
+        * Function will want to the device is not busy.
+        */           
+       void busy(void); // Wait until Flash is not busy
+       
+       /** Deep Power Down.
+        *
+        * Remenber that you have to want 35uS after the wake up to use the device. 
+        * @param True = Activate and False = Wake Up.
+        */         
+       void deep_power_down(bool onoff);
+             void ultra_deep_power_down(bool onoff);
+        
+       /** Is the device deep power down.
+        *
+        * @return True = Activate and False = Awake.
+        */         
+       bool is_it_awake(void);
+
+private:    
+   
+        SPI _spi;
+        DigitalOut _ncs;    
+
+        int _pages;            // Integer number of pages
+        int _pagesize;         // page size, in bytes 
+        int _devicesize;       // device size in bytes
+        int _blocks;           // Number of blocks
+        bool _deep_down;       // True = the device is deep down
+        bool _deep_down_onoff; // variable for deep power down function (On/Off) 
+ 
+        // Helper routunes
+        void _initialize();          
+        void _select();
+        void _deselect();
+        void _busy (void);               
+    
+        // accessing SRAM buffers
+        void _sramwrite (int buffer, int address, int data);
+        int _sramread (int buffer, int address);
+    
+        // Transferring SRAM buffers to/from FLASH
+        void _flashwrite (int buffer, int paddr);
+        void _flashread (int buffer, int paddr);
+
+        // Reading FLASH directly
+        int _memread (int address);
+    
+        // Calculate page/subpage addresses
+        int _getpaddr (int);
+        int _getbaddr (int);
+    
+        // Send 3 byte address
+        void _sendaddr (int address);
+        
+};
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_API.lib	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#1a37289c954e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LEDService.h	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,42 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLE_LED_SERVICE_H__
+#define __BLE_LED_SERVICE_H__
+
+class LEDService {
+public:
+    const static uint16_t LED_SERVICE_UUID              = 0xA000;
+    const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;
+
+    LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) :
+        ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic)
+    {
+        GattCharacteristic *charTable[] = {&ledState};
+        GattService         ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+        ble.addService(ledService);
+    }
+
+    GattAttribute::Handle_t getValueHandle() const {
+        return ledState.getValueHandle();
+    }
+
+private:
+    BLEDevice                         &ble;
+    ReadWriteGattCharacteristic<bool>  ledState;
+};
+
+#endif /* #ifndef __BLE_LED_SERVICE_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS3DH.cpp	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,1614 @@
+#include "LIS3DH.h"
+
+LIS3DH::LIS3DH(PinName mosi, PinName miso, PinName ss, PinName sck):  _spi(mosi,miso,sck), _ss(ss){
+    // Make sure CS is high
+    _ss = 1; 
+    // Setup the spi for 8 bit data, high steady state clock,
+    // second edge capture, with a 1MHz clock rate
+    _spi.format(8,3);                   
+    _spi.frequency(8000000);        
+
+  
+}
+
+u8_t LIS3DH::InitLIS3DH(LIS3DH_Mode_t Mode, LIS3DH_ODR_t Odr, LIS3DH_Fullscale_t Grange)
+{
+    uint8_t response;
+    uint8_t Tmp;
+    
+    LIS3DH_GetWHO_AM_I(&Tmp);
+    
+    response = LIS3DH_SetODR(Odr);
+    
+    //set PowerMode 
+    response = LIS3DH_SetMode(Mode);
+    
+    //set Fullscale
+    response = LIS3DH_SetFullScale(Grange);
+    
+    //set axis Enable
+    response = LIS3DH_SetAxis(LIS3DH_X_ENABLE | LIS3DH_Y_ENABLE | LIS3DH_Z_ENABLE);
+    
+    return response;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetStatusAUX
+* Description    : Read the AUX status register
+* Input          : Char to empty by status register buffer
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetStatusAUX(u8_t* val) {
+  
+  if( !LIS3DH_ReadReg(LIS3DH_STATUS_AUX, val) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;  
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetStatusAUXBIT
+* Description    : Read the AUX status register BIT
+* Input          : LIS3DH_STATUS_AUX_321OR, LIS3DH_STATUS_AUX_3OR, LIS3DH_STATUS_AUX_2OR, LIS3DH_STATUS_AUX_1OR,
+                   LIS3DH_STATUS_AUX_321DA, LIS3DH_STATUS_AUX_3DA, LIS3DH_STATUS_AUX_2DA, LIS3DH_STATUS_AUX_1DA
+* Output         : None
+* Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetStatusAUXBit(u8_t statusBIT, u8_t* val) {
+  u8_t value;  
+  
+  if( !LIS3DH_ReadReg(LIS3DH_STATUS_AUX, &value) )
+    return MEMS_ERROR;
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_321OR){
+    if(value &= LIS3DH_STATUS_AUX_321OR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_3OR){
+    if(value &= LIS3DH_STATUS_AUX_3OR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }     
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_2OR){
+    if(value &= LIS3DH_STATUS_AUX_2OR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }    
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_1OR){
+    if(value &= LIS3DH_STATUS_AUX_1OR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_321DA){
+    if(value &= LIS3DH_STATUS_AUX_321DA) {     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_3DA){
+    if(value &= LIS3DH_STATUS_AUX_3DA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_2DA){
+    if(value &= LIS3DH_STATUS_AUX_2DA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_STATUS_AUX_1DA){
+    if(value &= LIS3DH_STATUS_AUX_1DA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }  
+  return MEMS_ERROR;
+}
+
+u8_t LIS3DH::SetLIS3DHActivityDetection(uint8_t Th, LIS3DH_Int1Mode_t Mode, uint8_t OnOff)
+{
+    uint8_t response;
+    
+    response = LIS3DH_SetInt1Pin(LIS3DH_CLICK_ON_PIN_INT1_DISABLE | LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE |              
+                    LIS3DH_I1_INT2_ON_PIN_INT1_DISABLE | LIS3DH_I1_DRDY1_ON_INT1_DISABLE | LIS3DH_I1_DRDY2_ON_INT1_DISABLE |
+                    LIS3DH_WTM_ON_INT1_DISABLE | LIS3DH_INT1_OVERRUN_DISABLE );
+    
+    //set Interrupt Threshold   
+    response = LIS3DH_SetInt1Threshold(Th);
+        
+ //set Interrupt configuration (all enabled)
+    if(OnOff)
+    {
+        response = LIS3DH_SetIntConfiguration(LIS3DH_INT1_ZHIE_ENABLE | LIS3DH_INT1_ZLIE_ENABLE |
+                                       LIS3DH_INT1_YHIE_ENABLE | LIS3DH_INT1_YLIE_ENABLE |
+                                       LIS3DH_INT1_XHIE_ENABLE | LIS3DH_INT1_XLIE_ENABLE ); 
+    }
+    else
+    {
+        response = LIS3DH_SetIntConfiguration(LIS3DH_INT1_ZHIE_DISABLE | LIS3DH_INT1_ZLIE_DISABLE |
+                                       LIS3DH_INT1_YHIE_DISABLE | LIS3DH_INT1_YLIE_DISABLE |
+                                       LIS3DH_INT1_XHIE_DISABLE | LIS3DH_INT1_XLIE_DISABLE ); 
+    }
+    
+    //set Interrupt Mode
+    response = LIS3DH_SetIntMode(Mode);
+    
+    return response;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetODR
+* Description    : Sets LIS3DH Output Data Rate
+* Input          : Output Data Rate
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetODR(LIS3DH_ODR_t ov){
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG1, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x0f;
+  value |= ov<<LIS3DH_ODR_BIT;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG1, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetMode
+* Description    : Sets LIS3DH Operating Mode
+* Input          : Modality (LIS3DH_NORMAL, LIS3DH_LOW_POWER, LIS3DH_POWER_DOWN)
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetMode(LIS3DH_Mode_t md) {
+  u8_t value;
+  u8_t value2;
+  static   u8_t ODR_old_value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG1, &value) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value2) )
+    return MEMS_ERROR;
+  
+  if((value & 0xF0)==0) 
+    value = value | (ODR_old_value & 0xF0); //if it comes from POWERDOWN  
+  
+  switch(md) {
+    
+  case LIS3DH_POWER_DOWN:
+    ODR_old_value = value;
+    value &= 0x0F;
+    break;
+    
+  case LIS3DH_NORMAL:
+    value &= 0xF7;
+    value |= (MEMS_RESET<<LIS3DH_LPEN);
+    value2 &= 0xF7;
+    value2 |= (MEMS_SET<<LIS3DH_HR);   //set HighResolution_BIT
+    break;
+    
+  case LIS3DH_LOW_POWER:        
+    value &= 0xF7;
+    value |=  (MEMS_SET<<LIS3DH_LPEN);
+    value2 &= 0xF7;
+    value2 |= (MEMS_RESET<<LIS3DH_HR); //reset HighResolution_BIT
+    break;
+    
+  default:
+    return MEMS_ERROR;
+  }
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG1, value) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value2) )
+    return MEMS_ERROR;  
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetAxis
+* Description    : Enable/Disable LIS3DH Axis
+* Input          : LIS3DH_X_ENABLE/DISABLE | LIS3DH_Y_ENABLE/DISABLE | LIS3DH_Z_ENABLE/DISABLE
+* Output         : None
+* Note           : You MUST use all input variable in the argument, as example
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetAxis(LIS3DH_Axis_t axis) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG1, &value) )
+    return MEMS_ERROR;
+  value &= 0xF8;
+  value |= (0x07 & axis);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG1, value) )
+    return MEMS_ERROR;   
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetFullScale
+* Description    : Sets the LIS3DH FullScale
+* Input          : LIS3DH_FULLSCALE_2/LIS3DH_FULLSCALE_4/LIS3DH_FULLSCALE_8/LIS3DH_FULLSCALE_16
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetFullScale(LIS3DH_Fullscale_t fs) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xCF;    
+  value |= (fs<<LIS3DH_FS);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetBDU
+* Description    : Enable/Disable Block Data Update Functionality
+* Input          : ENABLE/DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetBDU(State_t bdu) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x7F;
+  value |= (bdu<<LIS3DH_BDU);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetBLE
+* Description    : Set Endianess (MSB/LSB)
+* Input          : BLE_LSB / BLE_MSB
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetBLE(LIS3DH_Endianess_t ble) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xBF;  
+  value |= (ble<<LIS3DH_BLE);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetSelfTest
+* Description    : Set Self Test Modality
+* Input          : LIS3DH_SELF_TEST_DISABLE/ST_0/ST_1
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetSelfTest(LIS3DH_SelfTest_t st) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG4, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xF9;
+  value |= (st<<LIS3DH_ST);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG4, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_HPFClick
+* Description    : Enable/Disable High Pass Filter for click
+* Input          : MEMS_ENABLE/MEMS_DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_HPFClickEnable(State_t hpfe) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xFB;
+  value |= (hpfe<<LIS3DH_HPCLICK);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_HPFAOI1
+* Description    : Enable/Disable High Pass Filter for AOI on INT_1
+* Input          : MEMS_ENABLE/MEMS_DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_HPFAOI1Enable(State_t hpfe) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xFE;
+  value |= (hpfe<<LIS3DH_HPIS1);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_HPFAOI2
+* Description    : Enable/Disable High Pass Filter for AOI on INT_2
+* Input          : MEMS_ENABLE/MEMS_DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_HPFAOI2Enable(State_t hpfe) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xFD;
+  value |= (hpfe<<LIS3DH_HPIS2);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetHPFMode
+* Description    : Set High Pass Filter Modality
+* Input          : LIS3DH_HPM_NORMAL_MODE_RES/LIS3DH_HPM_REF_SIGNAL/
+           LIS3DH_HPM_NORMAL_MODE/LIS3DH_HPM_AUTORESET_INT
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetHPFMode(LIS3DH_HPFMode_t hpm) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x3F;
+  value |= (hpm<<LIS3DH_HPM);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetHPFCutOFF
+* Description    : Set High Pass CUT OFF Freq
+* Input          : HPFCF [0,3]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetHPFCutOFF(LIS3DH_HPFCutOffFreq_t hpf) {
+  u8_t value;
+  
+  if (hpf > 3)
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xCF;
+  value |= (hpf<<LIS3DH_HPCF);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+  
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetFilterDataSel
+* Description    : Set Filter Data Selection bypassed or sent to FIFO OUT register
+* Input          : MEMS_SET, MEMS_RESET
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetFilterDataSel(State_t state) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG2, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xF7;
+  value |= (state<<LIS3DH_FDS);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG2, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+  
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetTemperature
+* Description    : Sets LIS3DH Output Temperature
+* Input          : MEMS_ENABLE, MEMS_DISABLE
+* Output         : None
+* Note           : For Read Temperature by LIS3DH_OUT_AUX_3, LIS3DH_SetADCAux and LIS3DH_SetBDU 
+                   functions must be ENABLE
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetTemperature(State_t state){
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_TEMP_CFG_REG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xBF;
+  value |= state<<LIS3DH_TEMP_EN;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_TEMP_CFG_REG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetADCAux
+* Description    : Sets LIS3DH Output ADC
+* Input          : MEMS_ENABLE, MEMS_DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetADCAux(State_t state){
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_TEMP_CFG_REG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x7F;
+  value |= state<<LIS3DH_ADC_PD;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_TEMP_CFG_REG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetAuxRaw
+* Description    : Read the Aux Values Output Registers
+* Input          : Buffer to empty
+* Output         : Aux Values Registers buffer
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetAuxRaw(LIS3DH_Aux123Raw_t* buff) {
+  u8_t valueL;
+  u8_t valueH;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_1_L, &valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_1_H, &valueH) )
+    return MEMS_ERROR;
+  
+  buff->AUX_1 = (u16_t)( (valueH << 8) | valueL )/16;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_2_L, &valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_2_H, &valueH) )
+    return MEMS_ERROR;
+  
+  buff->AUX_2 = (u16_t)( (valueH << 8) | valueL )/16;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_L, &valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_H, &valueH) )
+    return MEMS_ERROR;
+  
+  buff->AUX_3 = (u16_t)( (valueH << 8) | valueL )/16;
+  
+  return MEMS_SUCCESS;  
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetInt1Pin
+* Description    : Set Interrupt1 pin Function
+* Input          :  LIS3DH_CLICK_ON_PIN_INT1_ENABLE/DISABLE    | LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE/DISABLE |              
+                    LIS3DH_I1_INT2_ON_PIN_INT1_ENABLE/DISABLE  | LIS3DH_I1_DRDY1_ON_INT1_ENABLE/DISABLE    |              
+                    LIS3DH_I1_DRDY2_ON_INT1_ENABLE/DISABLE     | LIS3DH_WTM_ON_INT1_ENABLE/DISABLE         |           
+                    LIS3DH_INT1_OVERRUN_ENABLE/DISABLE  
+* example        : SetInt1Pin(LIS3DH_CLICK_ON_PIN_INT1_ENABLE | LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE |              
+                    LIS3DH_I1_INT2_ON_PIN_INT1_DISABLE | LIS3DH_I1_DRDY1_ON_INT1_ENABLE | LIS3DH_I1_DRDY2_ON_INT1_ENABLE |
+                    LIS3DH_WTM_ON_INT1_DISABLE | LIS3DH_INT1_OVERRUN_DISABLE   ) 
+* Note           : To enable Interrupt signals on INT1 Pad (You MUST use all input variable in the argument, as example)
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetInt1Pin(LIS3DH_IntPinConf_t pinConf) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG3, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x00;
+  value |= pinConf;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG3, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetInt2Pin
+* Description    : Set Interrupt2 pin Function
+* Input          : LIS3DH_CLICK_ON_PIN_INT2_ENABLE/DISABLE   | LIS3DH_I2_INT1_ON_PIN_INT2_ENABLE/DISABLE |               
+                   LIS3DH_I2_INT2_ON_PIN_INT2_ENABLE/DISABLE | LIS3DH_I2_BOOT_ON_INT2_ENABLE/DISABLE |                   
+                   LIS3DH_INT_ACTIVE_HIGH/LOW
+* example        : LIS3DH_SetInt2Pin(LIS3DH_CLICK_ON_PIN_INT2_ENABLE/DISABLE | LIS3DH_I2_INT1_ON_PIN_INT2_ENABLE/DISABLE |               
+                   LIS3DH_I2_INT2_ON_PIN_INT2_ENABLE/DISABLE | LIS3DH_I2_BOOT_ON_INT2_ENABLE/DISABLE |                   
+                   LIS3DH_INT_ACTIVE_HIGH/LOW)
+* Note           : To enable Interrupt signals on INT2 Pad (You MUST use all input variable in the argument, as example)
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetInt2Pin(LIS3DH_IntPinConf_t pinConf) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG6, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x00;
+  value |= pinConf;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG6, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetClickCFG
+* Description    : Set Click Interrupt config Function
+* Input          : LIS3DH_ZD_ENABLE/DISABLE | LIS3DH_ZS_ENABLE/DISABLE  | LIS3DH_YD_ENABLE/DISABLE  | 
+                   LIS3DH_YS_ENABLE/DISABLE | LIS3DH_XD_ENABLE/DISABLE  | LIS3DH_XS_ENABLE/DISABLE 
+* example        : LIS3DH_SetClickCFG( LIS3DH_ZD_ENABLE | LIS3DH_ZS_DISABLE | LIS3DH_YD_ENABLE | 
+                               LIS3DH_YS_DISABLE | LIS3DH_XD_ENABLE | LIS3DH_XS_ENABLE)
+* Note           : You MUST use all input variable in the argument, as example
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetClickCFG(u8_t status) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CLICK_CFG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xC0;
+  value |= status;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CLICK_CFG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}  
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetClickTHS
+* Description    : Set Click Interrupt threshold
+* Input          : Click-click Threshold value [0-127]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetClickTHS(u8_t ths) {
+  
+  if(ths>127)     
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CLICK_THS, ths) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+} 
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetClickLIMIT
+* Description    : Set Click Interrupt Time Limit
+* Input          : Click-click Time Limit value [0-127]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetClickLIMIT(u8_t t_limit) {
+  
+  if(t_limit>127)     
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_TIME_LIMIT, t_limit) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+} 
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetClickLATENCY
+* Description    : Set Click Interrupt Time Latency
+* Input          : Click-click Time Latency value [0-255]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetClickLATENCY(u8_t t_latency) {
+  
+  if( !LIS3DH_WriteReg(LIS3DH_TIME_LATENCY, t_latency) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+} 
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetClickWINDOW
+* Description    : Set Click Interrupt Time Window
+* Input          : Click-click Time Window value [0-255]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetClickWINDOW(u8_t t_window) {
+  
+  if( !LIS3DH_WriteReg(LIS3DH_TIME_WINDOW, t_window) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetClickResponse
+* Description    : Get Click Interrupt Response by CLICK_SRC REGISTER
+* Input          : char to empty by Click Response Typedef
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetClickResponse(u8_t* res) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CLICK_SRC, &value) ) 
+    return MEMS_ERROR;
+  
+  value &= 0x7F;
+  
+  if((value & LIS3DH_IA)==0) {        
+    *res = LIS3DH_NO_CLICK;     
+    return MEMS_SUCCESS;
+  }
+  else {
+    if (value & LIS3DH_DCLICK){
+      if (value & LIS3DH_CLICK_SIGN){
+        if (value & LIS3DH_CLICK_Z) {
+          *res = LIS3DH_DCLICK_Z_N;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_Y) {
+          *res = LIS3DH_DCLICK_Y_N;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_X) {
+          *res = LIS3DH_DCLICK_X_N;   
+          return MEMS_SUCCESS;
+        }
+      }
+      else{
+        if (value & LIS3DH_CLICK_Z) {
+          *res = LIS3DH_DCLICK_Z_P;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_Y) {
+          *res = LIS3DH_DCLICK_Y_P;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_X) {
+          *res = LIS3DH_DCLICK_X_P;   
+          return MEMS_SUCCESS;
+        }
+      }       
+    }
+    else{
+      if (value & LIS3DH_CLICK_SIGN){
+        if (value & LIS3DH_CLICK_Z) {
+          *res = LIS3DH_SCLICK_Z_N;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_Y) {
+          *res = LIS3DH_SCLICK_Y_N;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_X) {
+          *res = LIS3DH_SCLICK_X_N;   
+          return MEMS_SUCCESS;
+        }
+      }
+      else{
+        if (value & LIS3DH_CLICK_Z) {
+          *res = LIS3DH_SCLICK_Z_P;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_Y) {
+          *res = LIS3DH_SCLICK_Y_P;   
+          return MEMS_SUCCESS;
+        }
+        if (value & LIS3DH_CLICK_X) {
+          *res = LIS3DH_SCLICK_X_P;   
+          return MEMS_SUCCESS;
+        }
+      }
+    }
+  }
+  return MEMS_ERROR;
+} 
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_Int1LatchEnable
+* Description    : Enable Interrupt 1 Latching function
+* Input          : ENABLE/DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_Int1LatchEnable(State_t latch) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xF7;
+  value |= latch<<LIS3DH_LIR_INT1;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+status_t LIS3DH::LIS3DH_ResetInt1Latch(void) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, &value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetIntConfiguration
+* Description    : Interrupt 1 Configuration (without LIS3DH_6D_INT)
+* Input          : LIS3DH_INT1_AND/OR | LIS3DH_INT1_ZHIE_ENABLE/DISABLE | LIS3DH_INT1_ZLIE_ENABLE/DISABLE...
+* Output         : None
+* Note           : You MUST use all input variable in the argument, as example
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetIntConfiguration(LIS3DH_Int1Conf_t ic) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_CFG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x40; 
+  value |= ic;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_INT1_CFG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+} 
+
+     
+/*******************************************************************************
+* Function Name  : LIS3DH_SetIntMode
+* Description    : Interrupt 1 Configuration mode (OR, 6D Movement, AND, 6D Position)
+* Input          : LIS3DH_INT_MODE_OR, LIS3DH_INT_MODE_6D_MOVEMENT, LIS3DH_INT_MODE_AND, 
+                   LIS3DH_INT_MODE_6D_POSITION
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetIntMode(LIS3DH_Int1Mode_t int_mode) {
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_CFG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x3F; 
+  value |= (int_mode<<LIS3DH_INT_6D);
+  
+  if( !LIS3DH_WriteReg(LIS3DH_INT1_CFG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetInt6D4DConfiguration
+* Description    : 6D, 4D Interrupt Configuration
+* Input          : LIS3DH_INT1_6D_ENABLE, LIS3DH_INT1_4D_ENABLE, LIS3DH_INT1_6D_4D_DISABLE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetInt6D4DConfiguration(LIS3DH_INT_6D_4D_t ic) {
+  u8_t value;
+  u8_t value2;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_CFG, &value) )
+    return MEMS_ERROR;
+  if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value2) )
+    return MEMS_ERROR;
+  
+  if(ic == LIS3DH_INT1_6D_ENABLE){
+    value &= 0xBF; 
+    value |= (MEMS_ENABLE<<LIS3DH_INT_6D);
+    value2 &= 0xFB; 
+    value2 |= (MEMS_DISABLE<<LIS3DH_D4D_INT1);
+  }
+  
+  if(ic == LIS3DH_INT1_4D_ENABLE){
+    value &= 0xBF; 
+    value |= (MEMS_ENABLE<<LIS3DH_INT_6D);
+    value2 &= 0xFB; 
+    value2 |= (MEMS_ENABLE<<LIS3DH_D4D_INT1);
+  }
+  
+  if(ic == LIS3DH_INT1_6D_4D_DISABLE){
+    value &= 0xBF; 
+    value |= (MEMS_DISABLE<<LIS3DH_INT_6D);
+    value2 &= 0xFB; 
+    value2 |= (MEMS_DISABLE<<LIS3DH_D4D_INT1);
+  }
+  
+  if( !LIS3DH_WriteReg(LIS3DH_INT1_CFG, value) )
+    return MEMS_ERROR;
+  if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value2) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_Get6DPosition
+* Description    : 6D, 4D Interrupt Position Detect
+* Input          : Byte to empty by POSITION_6D_t Typedef
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_Get6DPosition(u8_t* val){
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x7F;
+  
+  switch (value){
+  case LIS3DH_UP_SX:   
+    *val = LIS3DH_UP_SX;    
+    break;
+  case LIS3DH_UP_DX:   
+    *val = LIS3DH_UP_DX;    
+    break;
+  case LIS3DH_DW_SX:   
+    *val = LIS3DH_DW_SX;    
+    break;
+  case LIS3DH_DW_DX:   
+    *val = LIS3DH_DW_DX;    
+    break;
+  case LIS3DH_TOP:     
+    *val = LIS3DH_TOP;      
+    break;
+  case LIS3DH_BOTTOM:  
+    *val = LIS3DH_BOTTOM;   
+    break;
+  }
+  
+  return MEMS_SUCCESS;  
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetInt1Threshold
+* Description    : Sets Interrupt 1 Threshold
+* Input          : Threshold = [0,31]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetInt1Threshold(u8_t ths) {
+  if (ths > 127)
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_INT1_THS, ths) )
+    return MEMS_ERROR;    
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetInt1Duration
+* Description    : Sets Interrupt 1 Duration
+* Input          : Duration value
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetInt1Duration(LIS3DH_Int1Conf_t id) {
+  
+  if (id > 127)
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_WriteReg(LIS3DH_INT1_DURATION, id) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_FIFOModeEnable
+* Description    : Sets Fifo Modality
+* Input          : LIS3DH_FIFO_DISABLE, LIS3DH_FIFO_BYPASS_MODE, LIS3DH_FIFO_MODE, 
+           LIS3DH_FIFO_STREAM_MODE, LIS3DH_FIFO_TRIGGER_MODE
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_FIFOModeEnable(LIS3DH_FifoMode_t fm) {
+  u8_t value;  
+  
+  if(fm == LIS3DH_FIFO_DISABLE) { 
+    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0x1F;
+    value |= (LIS3DH_FIFO_BYPASS_MODE<<LIS3DH_FM);                     
+    
+    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )           //fifo mode bypass
+      return MEMS_ERROR;   
+    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0xBF;    
+    
+    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo disable
+      return MEMS_ERROR;   
+  }
+  
+  if(fm == LIS3DH_FIFO_BYPASS_MODE)   {  
+    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0xBF;
+    value |= MEMS_SET<<LIS3DH_FIFO_EN;
+    
+    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
+      return MEMS_ERROR;  
+    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0x1f;
+    value |= (fm<<LIS3DH_FM);                     //fifo mode configuration
+    
+    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
+      return MEMS_ERROR;
+  }
+  
+  if(fm == LIS3DH_FIFO_MODE)   {
+    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0xBF;
+    value |= MEMS_SET<<LIS3DH_FIFO_EN;
+    
+    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
+      return MEMS_ERROR;  
+    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0x1f;
+    value |= (fm<<LIS3DH_FM);                      //fifo mode configuration
+    
+    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
+      return MEMS_ERROR;
+  }
+  
+  if(fm == LIS3DH_FIFO_STREAM_MODE)   {  
+    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0xBF;
+    value |= MEMS_SET<<LIS3DH_FIFO_EN;
+    
+    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
+      return MEMS_ERROR;   
+    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0x1f;
+    value |= (fm<<LIS3DH_FM);                      //fifo mode configuration
+    
+    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
+      return MEMS_ERROR;
+  }
+  
+  if(fm == LIS3DH_FIFO_TRIGGER_MODE)   {  
+    if( !LIS3DH_ReadReg(LIS3DH_CTRL_REG5, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0xBF;
+    value |= MEMS_SET<<LIS3DH_FIFO_EN;
+    
+    if( !LIS3DH_WriteReg(LIS3DH_CTRL_REG5, value) )               //fifo enable
+      return MEMS_ERROR;    
+    if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+      return MEMS_ERROR;
+    
+    value &= 0x1f;
+    value |= (fm<<LIS3DH_FM);                      //fifo mode configuration
+    
+    if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
+      return MEMS_ERROR;
+  }
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetTriggerInt
+* Description    : Trigger event liked to trigger signal INT1/INT2
+* Input          : LIS3DH_TRIG_INT1/LIS3DH_TRIG_INT2
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetTriggerInt(LIS3DH_TrigInt_t tr) {
+  u8_t value;  
+  
+  if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xDF;
+  value |= (tr<<LIS3DH_TR); 
+  
+  if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_SetWaterMark
+* Description    : Sets Watermark Value
+* Input          : Watermark = [0,31]
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_SetWaterMark(u8_t wtm) {
+  u8_t value;
+  
+  if(wtm > 31)
+    return MEMS_ERROR;  
+  
+  if( !LIS3DH_ReadReg(LIS3DH_FIFO_CTRL_REG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0xE0;
+  value |= wtm; 
+  
+  if( !LIS3DH_WriteReg(LIS3DH_FIFO_CTRL_REG, value) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetStatusReg
+* Description    : Read the status register
+* Input          : char to empty by Status Reg Value
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetStatusReg(u8_t* val) {
+  if( !LIS3DH_ReadReg(LIS3DH_STATUS_REG, val) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;  
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetStatusBIT
+* Description    : Read the status register BIT
+* Input          : LIS3DH_STATUS_REG_ZYXOR, LIS3DH_STATUS_REG_ZOR, LIS3DH_STATUS_REG_YOR, LIS3DH_STATUS_REG_XOR,
+                   LIS3DH_STATUS_REG_ZYXDA, LIS3DH_STATUS_REG_ZDA, LIS3DH_STATUS_REG_YDA, LIS3DH_STATUS_REG_XDA, 
+           LIS3DH_DATAREADY_BIT
+           val: Byte to be filled with the status bit 
+* Output         : status register BIT
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetStatusBit(u8_t statusBIT, u8_t* val) {
+  u8_t value;  
+  
+  if( !LIS3DH_ReadReg(LIS3DH_STATUS_REG, &value) )
+    return MEMS_ERROR;
+  
+  switch (statusBIT){
+  case LIS3DH_STATUS_REG_ZYXOR:     
+    if(value &= LIS3DH_STATUS_REG_ZYXOR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  case LIS3DH_STATUS_REG_ZOR:       
+    if(value &= LIS3DH_STATUS_REG_ZOR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  case LIS3DH_STATUS_REG_YOR:       
+    if(value &= LIS3DH_STATUS_REG_YOR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }                                 
+  case LIS3DH_STATUS_REG_XOR:       
+    if(value &= LIS3DH_STATUS_REG_XOR){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }     
+  case LIS3DH_STATUS_REG_ZYXDA:     
+    if(value &= LIS3DH_STATUS_REG_ZYXDA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  case LIS3DH_STATUS_REG_ZDA:       
+    if(value &= LIS3DH_STATUS_REG_ZDA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  case LIS3DH_STATUS_REG_YDA:       
+    if(value &= LIS3DH_STATUS_REG_YDA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }   
+  case LIS3DH_STATUS_REG_XDA:       
+    if(value &= LIS3DH_STATUS_REG_XDA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }                                  
+    
+  }
+  return MEMS_ERROR;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetAccAxesRaw
+* Description    : Read the Acceleration Values Output Registers
+* Input          : buffer to empity by AxesRaw_t Typedef
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetAccAxesRaw(AxesRaw_t* buff) {
+  i16_t value;
+  u8_t *valueL = (u8_t *)(&value);
+  u8_t *valueH = ((u8_t *)(&value)+1);
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_X_L, valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_X_H, valueH) )
+    return MEMS_ERROR;
+  
+  buff->AXIS_X = value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_Y_L, valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_Y_H, valueH) )
+    return MEMS_ERROR;
+  
+  buff->AXIS_Y = value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_Z_L, valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_Z_H, valueH) )
+    return MEMS_ERROR;
+  
+  buff->AXIS_Z = value;
+  
+  return MEMS_SUCCESS; 
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetInt1Src
+* Description    : Reset Interrupt 1 Latching function
+* Input          : Char to empty by Int1 source value
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetInt1Src(u8_t* val) {
+  
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, val) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetInt1SrcBit
+* Description    : Reset Interrupt 1 Latching function
+* Input          : statusBIT: LIS3DH_INT_SRC_IA, LIS3DH_INT_SRC_ZH, LIS3DH_INT_SRC_ZL.....
+*                  val: Byte to be filled with the status bit
+* Output         : None
+* Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetInt1SrcBit(u8_t statusBIT, u8_t* val) {
+  u8_t value;  
+   
+  if( !LIS3DH_ReadReg(LIS3DH_INT1_SRC, &value) )
+      return MEMS_ERROR;
+   
+  if(statusBIT == LIS3DH_INT1_SRC_IA){
+    if(value &= LIS3DH_INT1_SRC_IA){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_INT1_SRC_ZH){
+    if(value &= LIS3DH_INT1_SRC_ZH){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_INT1_SRC_ZL){
+    if(value &= LIS3DH_INT1_SRC_ZL){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_INT1_SRC_YH){
+    if(value &= LIS3DH_INT1_SRC_YH){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_INT1_SRC_YL){
+    if(value &= LIS3DH_INT1_SRC_YL){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  if(statusBIT == LIS3DH_INT1_SRC_XH){
+    if(value &= LIS3DH_INT1_SRC_XH){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_INT1_SRC_XL){
+    if(value &= LIS3DH_INT1_SRC_XL){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  return MEMS_ERROR;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetFifoSourceReg
+* Description    : Read Fifo source Register
+* Input          : Byte to empty by FIFO source register value
+* Output         : None
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetFifoSourceReg(u8_t* val) {
+  
+  if( !LIS3DH_ReadReg(LIS3DH_FIFO_SRC_REG, val) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetFifoSourceBit
+* Description    : Read Fifo WaterMark source bit
+* Input          : statusBIT: LIS3DH_FIFO_SRC_WTM, LIS3DH_FIFO_SRC_OVRUN, LIS3DH_FIFO_SRC_EMPTY
+*          val: Byte to fill  with the bit value
+* Output         : None
+* Return         : Status of BIT [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetFifoSourceBit(u8_t statusBIT,  u8_t* val){
+  u8_t value;  
+  
+  if( !LIS3DH_ReadReg(LIS3DH_FIFO_SRC_REG, &value) )
+    return MEMS_ERROR;
+  
+  
+  if(statusBIT == LIS3DH_FIFO_SRC_WTM){
+    if(value &= LIS3DH_FIFO_SRC_WTM){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  
+  if(statusBIT == LIS3DH_FIFO_SRC_OVRUN){
+    if(value &= LIS3DH_FIFO_SRC_OVRUN){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  if(statusBIT == LIS3DH_FIFO_SRC_EMPTY){
+    if(value &= statusBIT == LIS3DH_FIFO_SRC_EMPTY){     
+      *val = MEMS_SET;
+      return MEMS_SUCCESS;
+    }
+    else{  
+      *val = MEMS_RESET;
+      return MEMS_SUCCESS;
+    }  
+  }
+  return MEMS_ERROR;
+}
+
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetFifoSourceFSS
+* Description    : Read current number of unread samples stored in FIFO
+* Input          : Byte to empty by FIFO unread sample value
+* Output         : None
+* Return         : Status [value of FSS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetFifoSourceFSS(u8_t* val){
+  u8_t value;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_FIFO_SRC_REG, &value) )
+    return MEMS_ERROR;
+  
+  value &= 0x1F;
+  
+  *val = value;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetTempRaw
+* Description    : Read the Temperature Values by AUX Output Registers OUT_3_H
+* Input          : Buffer to empty
+* Output         : Temperature Values Registers buffer
+* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetTempRaw(i8_t* buff) {
+  u8_t valueL;
+  u8_t valueH;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_L, &valueL) )
+    return MEMS_ERROR;
+  
+  if( !LIS3DH_ReadReg(LIS3DH_OUT_3_H, &valueH) )
+    return MEMS_ERROR;
+  
+  *buff = (i8_t)( valueH );
+  
+  return MEMS_SUCCESS;  
+}
+
+/*******************************************************************************
+* Function Name  : LIS3DH_GetWHO_AM_I
+* Description    : Read identification code by WHO_AM_I register
+* Input          : Char to empty by Device identification Value
+* Output         : None
+* Return         : Status [value of FSS]
+*******************************************************************************/
+status_t LIS3DH::LIS3DH_GetWHO_AM_I(u8_t* val){
+  
+  if( !LIS3DH_ReadReg(LIS3DH_WHO_AM_I, val) )
+    return MEMS_ERROR;
+  
+  return MEMS_SUCCESS;
+}
+
+/*******************************************************************************
+* Function Name     : LIS3DH_ReadReg
+* Description       : Generic Reading function. It must be fullfilled with either
+*           : I2C or SPI reading functions                  
+* Input         : Register Address
+* Output        : Data REad
+* Return        : None
+*******************************************************************************/
+u8_t LIS3DH::LIS3DH_ReadReg(u8_t Reg, u8_t* Data) {
+  
+  //To be completed with either I2c or SPI reading function
+  //i.e. *Data = SPI_Mems_Read_Reg( Reg );  
+    
+    _ss = 0;
+    _spi.write(0x80 | Reg);
+    signed char raw = _spi.write(0x00); 
+    _ss = 1;
+    
+    *Data=raw;
+    
+  return 1;
+}
+
+/*******************************************************************************
+* Function Name     : LIS3DH_WriteReg
+* Description       : Generic Writing function. It must be fullfilled with either
+*           : I2C or SPI writing function
+* Input         : Register Address, Data to be written
+* Output        : None
+* Return        : None
+*******************************************************************************/
+u8_t LIS3DH::LIS3DH_WriteReg(u8_t WriteAddr, u8_t Data) {
+  
+  //To be completed with either I2c or SPI writing function
+  //i.e. SPI_Mems_Write_Reg(WriteAddr, Data);  
+    
+    _ss = 0;
+    _spi.write(0x00 | WriteAddr);
+    _spi.write (Data);
+    _ss = 1;  
+    
+  return 1;
+}
+
+LIS3DH::~LIS3DH(){};
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS3DH.h	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,516 @@
+#ifndef LIS3DH_H
+#define LIS3DH_H
+
+#include "mbed.h"
+
+namespace mbed {
+
+#ifndef __ARCHDEP__TYPES
+#define __ARCHDEP__TYPES
+
+typedef unsigned char u8_t;
+typedef unsigned short int u16_t;
+typedef short int i16_t;
+typedef signed char i8_t;
+
+#endif /*__ARCHDEP__TYPES*/
+
+typedef u8_t LIS3DH_IntPinConf_t;
+typedef u8_t LIS3DH_Axis_t;
+typedef u8_t LIS3DH_Int1Conf_t;
+
+
+//define structure
+#ifndef __SHARED__TYPES
+#define __SHARED__TYPES
+
+typedef enum {
+  MEMS_SUCCESS              =       0x01,
+  MEMS_ERROR                =       0x00    
+} status_t;
+
+typedef enum {
+  MEMS_ENABLE               =       0x01,
+  MEMS_DISABLE              =       0x00    
+} State_t;
+
+typedef __packed struct {
+  i16_t AXIS_X;
+  i16_t AXIS_Y;
+  i16_t AXIS_Z;
+} AxesRaw_t;
+
+#endif /*__SHARED__TYPES*/
+
+typedef enum {  
+  LIS3DH_ODR_1Hz                =       0x01,       
+  LIS3DH_ODR_10Hz                      =        0x02,
+  LIS3DH_ODR_25Hz               =       0x03,
+  LIS3DH_ODR_50Hz               =       0x04,
+  LIS3DH_ODR_100Hz              =       0x05,   
+  LIS3DH_ODR_200Hz              =       0x06,
+  LIS3DH_ODR_400Hz              =       0x07,
+  LIS3DH_ODR_1620Hz_LP              =       0x08,
+  LIS3DH_ODR_1344Hz_NP_5367HZ_LP       =        0x09    
+} LIS3DH_ODR_t;
+
+typedef enum {
+  LIS3DH_POWER_DOWN                    =        0x00,
+  LIS3DH_LOW_POWER          =       0x01,
+  LIS3DH_NORMAL         =       0x02
+} LIS3DH_Mode_t;
+
+typedef enum {
+  LIS3DH_HPM_NORMAL_MODE_RES           =               0x00,
+  LIS3DH_HPM_REF_SIGNAL                =               0x01,
+  LIS3DH_HPM_NORMAL_MODE               =               0x02,
+  LIS3DH_HPM_AUTORESET_INT             =               0x03
+} LIS3DH_HPFMode_t;
+
+typedef enum {
+  LIS3DH_HPFCF_0                       =               0x00,
+  LIS3DH_HPFCF_1                       =               0x01,
+  LIS3DH_HPFCF_2                       =        0x02,
+  LIS3DH_HPFCF_3                       =               0x03
+} LIS3DH_HPFCutOffFreq_t;
+
+typedef struct {
+  u16_t AUX_1;
+  u16_t AUX_2;
+  u16_t AUX_3;
+} LIS3DH_Aux123Raw_t;
+
+typedef enum {
+  LIS3DH_FULLSCALE_2                   =               0x00,
+  LIS3DH_FULLSCALE_4                   =               0x01,
+  LIS3DH_FULLSCALE_8                   =               0x02,
+  LIS3DH_FULLSCALE_16                  =               0x03
+} LIS3DH_Fullscale_t;
+
+typedef enum {
+  LIS3DH_BLE_LSB            =       0x00,
+  LIS3DH_BLE_MSB            =       0x01
+} LIS3DH_Endianess_t;
+
+typedef enum {
+  LIS3DH_SELF_TEST_DISABLE             =               0x00,
+  LIS3DH_SELF_TEST_0                   =               0x01,
+  LIS3DH_SELF_TEST_1                   =               0x02
+} LIS3DH_SelfTest_t;
+
+typedef enum {
+  LIS3DH_FIFO_BYPASS_MODE              =               0x00,
+  LIS3DH_FIFO_MODE                     =               0x01,
+  LIS3DH_FIFO_STREAM_MODE              =               0x02,
+  LIS3DH_FIFO_TRIGGER_MODE             =               0x03,
+  LIS3DH_FIFO_DISABLE                  =               0x04
+} LIS3DH_FifoMode_t;
+
+typedef enum {
+  LIS3DH_TRIG_INT1                     =        0x00,
+  LIS3DH_TRIG_INT2          =       0x01
+} LIS3DH_TrigInt_t;
+
+typedef enum {
+  LIS3DH_SPI_4_WIRE                    =               0x00,
+  LIS3DH_SPI_3_WIRE                    =               0x01
+} LIS3DH_SPIMode_t;
+
+typedef enum {
+  LIS3DH_X_ENABLE                      =               0x01,
+  LIS3DH_X_DISABLE                     =               0x00,
+  LIS3DH_Y_ENABLE                      =               0x02,
+  LIS3DH_Y_DISABLE                     =               0x00,
+  LIS3DH_Z_ENABLE                      =               0x04,
+  LIS3DH_Z_DISABLE                     =               0x00    
+} LIS3DH_AXISenable_t;
+
+typedef enum {
+  LIS3DH_INT1_6D_4D_DISABLE            =               0x00,
+  LIS3DH_INT1_6D_ENABLE                =               0x01,
+  LIS3DH_INT1_4D_ENABLE                =               0x02 
+} LIS3DH_INT_6D_4D_t;
+
+typedef enum {
+  LIS3DH_UP_SX                         =               0x44,
+  LIS3DH_UP_DX                         =               0x42,
+  LIS3DH_DW_SX                         =               0x41,
+  LIS3DH_DW_DX                         =               0x48,
+  LIS3DH_TOP                           =               0x60,
+  LIS3DH_BOTTOM                        =               0x50
+} LIS3DH_POSITION_6D_t;
+
+typedef enum {
+  LIS3DH_INT_MODE_OR                   =               0x00,
+  LIS3DH_INT_MODE_6D_MOVEMENT          =               0x01,
+  LIS3DH_INT_MODE_AND                  =               0x02,
+  LIS3DH_INT_MODE_6D_POSITION          =               0x03  
+} LIS3DH_Int1Mode_t;
+
+
+//interrupt click response
+//  b7 = don't care   b6 = IA  b5 = DClick  b4 = Sclick  b3 = Sign  
+//  b2 = z      b1 = y     b0 = x
+typedef enum {
+LIS3DH_DCLICK_Z_P                      =               0x24,
+LIS3DH_DCLICK_Z_N                      =               0x2C,
+LIS3DH_SCLICK_Z_P                      =               0x14,
+LIS3DH_SCLICK_Z_N                      =               0x1C,
+LIS3DH_DCLICK_Y_P                      =               0x22,
+LIS3DH_DCLICK_Y_N                      =               0x2A,
+LIS3DH_SCLICK_Y_P                      =               0x12,
+LIS3DH_SCLICK_Y_N           =       0x1A,
+LIS3DH_DCLICK_X_P                      =               0x21,
+LIS3DH_DCLICK_X_N                      =               0x29,
+LIS3DH_SCLICK_X_P                      =               0x11,
+LIS3DH_SCLICK_X_N                      =               0x19,
+LIS3DH_NO_CLICK                        =               0x00
+} LIS3DH_Click_Response; 
+
+//TODO: start from here and manage the shared macros etc before this
+
+/* Exported constants --------------------------------------------------------*/
+
+#ifndef __SHARED__CONSTANTS
+#define __SHARED__CONSTANTS
+
+#define MEMS_SET                                        0x01
+#define MEMS_RESET                                      0x00
+
+#endif /*__SHARED__CONSTANTS*/
+
+
+//Register Definition
+#define LIS3DH_WHO_AM_I             0x0F  // device identification register (00110011 default value=0x33)
+
+// CONTROL REGISTER 1
+#define LIS3DH_CTRL_REG1                0x20
+#define LIS3DH_ODR_BIT                      BIT(4)
+#define LIS3DH_LPEN                 BIT(3)
+#define LIS3DH_ZEN                  BIT(2)
+#define LIS3DH_YEN                  BIT(1)
+#define LIS3DH_XEN                  BIT(0)
+
+//CONTROL REGISTER 2
+#define LIS3DH_CTRL_REG2                0x21
+#define LIS3DH_HPM                  BIT(6)
+#define LIS3DH_HPCF                 BIT(4)
+#define LIS3DH_FDS                  BIT(3)
+#define LIS3DH_HPCLICK                  BIT(2)
+#define LIS3DH_HPIS2                    BIT(1)
+#define LIS3DH_HPIS1                    BIT(0)
+
+//CONTROL REGISTER 3
+#define LIS3DH_CTRL_REG3                0x22
+#define LIS3DH_I1_CLICK             BIT(7)
+#define LIS3DH_I1_AOI1                  BIT(6)
+#define LIS3DH_I1_AOI2                      BIT(5)
+#define LIS3DH_I1_DRDY1             BIT(4)
+#define LIS3DH_I1_DRDY2             BIT(3)
+#define LIS3DH_I1_WTM                   BIT(2)
+#define LIS3DH_I1_ORUN                  BIT(1)
+
+//CONTROL REGISTER 6
+#define LIS3DH_CTRL_REG6                0x25
+#define LIS3DH_I2_CLICK             BIT(7)
+#define LIS3DH_I2_INT1                  BIT(6)
+#define LIS3DH_I2_BOOT                  BIT(4)
+#define LIS3DH_H_LACTIVE                BIT(1)
+
+//TEMPERATURE CONFIG REGISTER
+#define LIS3DH_TEMP_CFG_REG             0x1F
+#define LIS3DH_ADC_PD                       BIT(7)
+#define LIS3DH_TEMP_EN                  BIT(6)
+
+//CONTROL REGISTER 4
+#define LIS3DH_CTRL_REG4                0x23
+#define LIS3DH_BDU                  BIT(7)
+#define LIS3DH_BLE                  BIT(6)
+#define LIS3DH_FS                   BIT(4)
+#define LIS3DH_HR                   BIT(3)
+#define LIS3DH_ST                       BIT(1)
+#define LIS3DH_SIM                  BIT(0)
+
+//CONTROL REGISTER 5
+#define LIS3DH_CTRL_REG5                0x24
+#define LIS3DH_BOOT                                    BIT(7)
+#define LIS3DH_FIFO_EN                                 BIT(6)
+#define LIS3DH_LIR_INT1                                BIT(3)
+#define LIS3DH_D4D_INT1                                BIT(2)
+
+//REFERENCE/DATA_CAPTURE
+#define LIS3DH_REFERENCE_REG                        0x26
+#define LIS3DH_REF                          BIT(0)
+
+//STATUS_REG_AXIES
+#define LIS3DH_STATUS_REG               0x27
+#define LIS3DH_ZYXOR                                   BIT(7)
+#define LIS3DH_ZOR                                     BIT(6)
+#define LIS3DH_YOR                                     BIT(5)
+#define LIS3DH_XOR                                     BIT(4)
+#define LIS3DH_ZYXDA                                   BIT(3)
+#define LIS3DH_ZDA                                     BIT(2)
+#define LIS3DH_YDA                                     BIT(1)
+#define LIS3DH_XDA                                     BIT(0)
+
+//STATUS_REG_AUX
+#define LIS3DH_STATUS_AUX               0x07
+
+//INTERRUPT 1 CONFIGURATION
+#define LIS3DH_INT1_CFG             0x30
+#define LIS3DH_ANDOR                                   BIT(7)
+#define LIS3DH_INT_6D                                  BIT(6)
+#define LIS3DH_ZHIE                                    BIT(5)
+#define LIS3DH_ZLIE                                    BIT(4)
+#define LIS3DH_YHIE                                    BIT(3)
+#define LIS3DH_YLIE                                    BIT(2)
+#define LIS3DH_XHIE                                    BIT(1)
+#define LIS3DH_XLIE                                    BIT(0)
+
+//FIFO CONTROL REGISTER
+#define LIS3DH_FIFO_CTRL_REG                           0x2E
+#define LIS3DH_FM                                      BIT(6)
+#define LIS3DH_TR                                      BIT(5)
+#define LIS3DH_FTH                                     BIT(0)
+
+//CONTROL REG3 bit mask
+#define LIS3DH_CLICK_ON_PIN_INT1_ENABLE                0x80
+#define LIS3DH_CLICK_ON_PIN_INT1_DISABLE               0x00
+#define LIS3DH_I1_INT1_ON_PIN_INT1_ENABLE              0x40
+#define LIS3DH_I1_INT1_ON_PIN_INT1_DISABLE             0x00
+#define LIS3DH_I1_INT2_ON_PIN_INT1_ENABLE              0x20
+#define LIS3DH_I1_INT2_ON_PIN_INT1_DISABLE             0x00
+#define LIS3DH_I1_DRDY1_ON_INT1_ENABLE                 0x10
+#define LIS3DH_I1_DRDY1_ON_INT1_DISABLE                0x00
+#define LIS3DH_I1_DRDY2_ON_INT1_ENABLE                 0x08
+#define LIS3DH_I1_DRDY2_ON_INT1_DISABLE                0x00
+#define LIS3DH_WTM_ON_INT1_ENABLE                      0x04
+#define LIS3DH_WTM_ON_INT1_DISABLE                     0x00
+#define LIS3DH_INT1_OVERRUN_ENABLE                     0x02
+#define LIS3DH_INT1_OVERRUN_DISABLE                    0x00
+
+//CONTROL REG6 bit mask
+#define LIS3DH_CLICK_ON_PIN_INT2_ENABLE                0x80
+#define LIS3DH_CLICK_ON_PIN_INT2_DISABLE               0x00
+#define LIS3DH_I2_INT1_ON_PIN_INT2_ENABLE              0x40
+#define LIS3DH_I2_INT1_ON_PIN_INT2_DISABLE             0x00
+#define LIS3DH_I2_INT2_ON_PIN_INT2_ENABLE              0x20
+#define LIS3DH_I2_INT2_ON_PIN_INT2_DISABLE             0x00
+#define LIS3DH_I2_BOOT_ON_INT2_ENABLE                  0x10
+#define LIS3DH_I2_BOOT_ON_INT2_DISABLE                 0x00
+#define LIS3DH_INT_ACTIVE_HIGH                         0x00
+#define LIS3DH_INT_ACTIVE_LOW                          0x02
+
+//INT1_CFG bit mask
+#define LIS3DH_INT1_AND                                0x80
+#define LIS3DH_INT1_OR                                 0x00
+#define LIS3DH_INT1_ZHIE_ENABLE                        0x20
+#define LIS3DH_INT1_ZHIE_DISABLE                       0x00
+#define LIS3DH_INT1_ZLIE_ENABLE                        0x10
+#define LIS3DH_INT1_ZLIE_DISABLE                       0x00
+#define LIS3DH_INT1_YHIE_ENABLE                        0x08
+#define LIS3DH_INT1_YHIE_DISABLE                       0x00
+#define LIS3DH_INT1_YLIE_ENABLE                        0x04
+#define LIS3DH_INT1_YLIE_DISABLE                       0x00
+#define LIS3DH_INT1_XHIE_ENABLE                        0x02
+#define LIS3DH_INT1_XHIE_DISABLE                       0x00
+#define LIS3DH_INT1_XLIE_ENABLE                        0x01
+#define LIS3DH_INT1_XLIE_DISABLE                       0x00
+
+//INT1_SRC bit mask
+#define LIS3DH_INT1_SRC_IA                             0x40
+#define LIS3DH_INT1_SRC_ZH                             0x20
+#define LIS3DH_INT1_SRC_ZL                             0x10
+#define LIS3DH_INT1_SRC_YH                             0x08
+#define LIS3DH_INT1_SRC_YL                             0x04
+#define LIS3DH_INT1_SRC_XH                             0x02
+#define LIS3DH_INT1_SRC_XL                             0x01
+
+//INT1 REGISTERS
+#define LIS3DH_INT1_THS                                0x32
+#define LIS3DH_INT1_DURATION                           0x33
+
+//INTERRUPT 1 SOURCE REGISTER
+#define LIS3DH_INT1_SRC             0x31
+
+//FIFO Source Register bit Mask
+#define LIS3DH_FIFO_SRC_WTM                            0x80
+#define LIS3DH_FIFO_SRC_OVRUN                          0x40
+#define LIS3DH_FIFO_SRC_EMPTY                          0x20
+  
+//INTERRUPT CLICK REGISTER
+#define LIS3DH_CLICK_CFG                0x38
+//INTERRUPT CLICK CONFIGURATION bit mask
+#define LIS3DH_ZD_ENABLE                               0x20
+#define LIS3DH_ZD_DISABLE                              0x00
+#define LIS3DH_ZS_ENABLE                               0x10
+#define LIS3DH_ZS_DISABLE                              0x00
+#define LIS3DH_YD_ENABLE                               0x08
+#define LIS3DH_YD_DISABLE                              0x00
+#define LIS3DH_YS_ENABLE                               0x04
+#define LIS3DH_YS_DISABLE                              0x00
+#define LIS3DH_XD_ENABLE                               0x02
+#define LIS3DH_XD_DISABLE                              0x00
+#define LIS3DH_XS_ENABLE                               0x01
+#define LIS3DH_XS_DISABLE                              0x00
+
+//INTERRUPT CLICK SOURCE REGISTER
+#define LIS3DH_CLICK_SRC                               0x39
+//INTERRUPT CLICK SOURCE REGISTER bit mask
+#define LIS3DH_IA                                      0x40
+#define LIS3DH_DCLICK                                  0x20
+#define LIS3DH_SCLICK                                  0x10
+#define LIS3DH_CLICK_SIGN                              0x08
+#define LIS3DH_CLICK_Z                                 0x04
+#define LIS3DH_CLICK_Y                                 0x02
+#define LIS3DH_CLICK_X                                 0x01
+
+//Click-click Register
+#define LIS3DH_CLICK_THS                               0x3A
+#define LIS3DH_TIME_LIMIT                              0x3B
+#define LIS3DH_TIME_LATENCY                            0x3C
+#define LIS3DH_TIME_WINDOW                             0x3D
+
+//OUTPUT REGISTER
+#define LIS3DH_OUT_X_L                  0x28
+#define LIS3DH_OUT_X_H                  0x29
+#define LIS3DH_OUT_Y_L                  0x2A
+#define LIS3DH_OUT_Y_H                  0x2B
+#define LIS3DH_OUT_Z_L                  0x2C
+#define LIS3DH_OUT_Z_H                  0x2D
+
+//AUX REGISTER
+#define LIS3DH_OUT_1_L                  0x08
+#define LIS3DH_OUT_1_H                  0x09
+#define LIS3DH_OUT_2_L                  0x0A
+#define LIS3DH_OUT_2_H                  0x0B
+#define LIS3DH_OUT_3_L                  0x0C
+#define LIS3DH_OUT_3_H                  0x0D
+
+//STATUS REGISTER bit mask
+#define LIS3DH_STATUS_REG_ZYXOR                        0x80    // 1 :   new data set has over written the previous one
+                            // 0    :   no overrun has occurred (default)   
+#define LIS3DH_STATUS_REG_ZOR                          0x40    // 0 :   no overrun has occurred (default)
+                            // 1    :   new Z-axis data has over written the previous one
+#define LIS3DH_STATUS_REG_YOR                          0x20    // 0 :   no overrun has occurred (default)
+                            // 1    :   new Y-axis data has over written the previous one
+#define LIS3DH_STATUS_REG_XOR                          0x10    // 0 :   no overrun has occurred (default)
+                            // 1    :   new X-axis data has over written the previous one
+#define LIS3DH_STATUS_REG_ZYXDA                        0x08    // 0 :   a new set of data is not yet avvious one
+                                                        // 1    :   a new set of data is available 
+#define LIS3DH_STATUS_REG_ZDA                          0x04    // 0 :   a new data for the Z-Axis is not availvious one
+                                                        // 1    :   a new data for the Z-Axis is available
+#define LIS3DH_STATUS_REG_YDA                          0x02    // 0 :   a new data for the Y-Axis is not available
+                                                        // 1    :   a new data for the Y-Axis is available
+#define LIS3DH_STATUS_REG_XDA                          0x01    // 0 :   a new data for the X-Axis is not available
+
+#define LIS3DH_DATAREADY_BIT                           LIS3DH_STATUS_REG_ZYXDA
+
+
+//STATUS AUX REGISTER bit mask
+#define LIS3DH_STATUS_AUX_321OR                         0x80
+#define LIS3DH_STATUS_AUX_3OR                           0x40
+#define LIS3DH_STATUS_AUX_2OR                           0x20
+#define LIS3DH_STATUS_AUX_1OR                           0x10
+#define LIS3DH_STATUS_AUX_321DA                         0x08
+#define LIS3DH_STATUS_AUX_3DA                           0x04
+#define LIS3DH_STATUS_AUX_2DA                           0x02
+#define LIS3DH_STATUS_AUX_1DA                           0x01
+
+#define LIS3DH_MEMS_I2C_ADDRESS                 0x33
+
+//FIFO REGISTERS
+#define LIS3DH_FIFO_CTRL_REG                    0x2E
+#define LIS3DH_FIFO_SRC_REG                 0x2F
+
+
+/* Exported macro ------------------------------------------------------------*/
+
+#ifndef __SHARED__MACROS
+
+#define __SHARED__MACROS
+#define ValBit(VAR,Place)         (VAR & (1<<Place))
+#define BIT(x) ( (x) )
+
+#endif /*__SHARED__MACROS*/
+
+class LIS3DH
+{
+public:  
+    LIS3DH(PinName mosi, PinName miso, PinName ss, PinName sck);
+    ~LIS3DH();
+    
+    //own functions 
+    u8_t InitLIS3DH(LIS3DH_Mode_t Mode, LIS3DH_ODR_t Odr, LIS3DH_Fullscale_t Grange);
+    u8_t SetLIS3DHActivityDetection(uint8_t Th, LIS3DH_Int1Mode_t Mode, uint8_t OnOff);
+
+    //Sensor Configuration Functions
+    status_t LIS3DH_SetODR(LIS3DH_ODR_t ov);
+    status_t LIS3DH_SetMode(LIS3DH_Mode_t md);
+    status_t LIS3DH_SetAxis(LIS3DH_Axis_t axis);
+    status_t LIS3DH_SetFullScale(LIS3DH_Fullscale_t fs);
+    status_t LIS3DH_SetBDU(State_t bdu);
+  status_t LIS3DH_SetBLE(LIS3DH_Endianess_t ble);
+  status_t LIS3DH_SetSelfTest(LIS3DH_SelfTest_t st);
+    status_t LIS3DH_SetTemperature(State_t state);
+    status_t LIS3DH_SetADCAux(State_t state);
+
+  //Filtering Functions
+  status_t LIS3DH_HPFClickEnable(State_t hpfe);
+  status_t LIS3DH_HPFAOI1Enable(State_t hpfe);
+  status_t LIS3DH_HPFAOI2Enable(State_t hpfe);
+  status_t LIS3DH_SetHPFMode(LIS3DH_HPFMode_t hpf);
+  status_t LIS3DH_SetHPFCutOFF(LIS3DH_HPFCutOffFreq_t hpf);
+  status_t LIS3DH_SetFilterDataSel(State_t state);
+
+    //Interrupt Functions
+    status_t LIS3DH_SetInt1Pin(LIS3DH_IntPinConf_t pinConf);
+    status_t LIS3DH_SetInt2Pin(LIS3DH_IntPinConf_t pinConf);
+  status_t LIS3DH_Int1LatchEnable(State_t latch);
+    status_t LIS3DH_ResetInt1Latch(void);
+    status_t LIS3DH_SetIntConfiguration(LIS3DH_Int1Conf_t ic);
+    status_t LIS3DH_SetInt1Threshold(u8_t ths);
+  status_t LIS3DH_SetInt1Duration(LIS3DH_Int1Conf_t id);
+    status_t LIS3DH_SetIntMode(LIS3DH_Int1Mode_t ic);
+  status_t LIS3DH_SetClickCFG(u8_t status);
+    status_t LIS3DH_SetClickTHS(u8_t ths);
+    status_t LIS3DH_SetClickLIMIT(u8_t t_limit);
+    status_t LIS3DH_SetClickLATENCY(u8_t t_latency);
+    status_t LIS3DH_SetClickWINDOW(u8_t t_window);
+  status_t LIS3DH_SetInt6D4DConfiguration(LIS3DH_INT_6D_4D_t ic);
+  status_t LIS3DH_GetInt1Src(u8_t* val);
+  status_t LIS3DH_GetInt1SrcBit(u8_t statusBIT, u8_t* val);
+
+  //FIFO Functions
+  status_t LIS3DH_FIFOModeEnable(LIS3DH_FifoMode_t fm);
+  status_t LIS3DH_SetWaterMark(u8_t wtm);
+  status_t LIS3DH_SetTriggerInt(LIS3DH_TrigInt_t tr);
+  status_t LIS3DH_GetFifoSourceReg(u8_t* val);
+  status_t LIS3DH_GetFifoSourceBit(u8_t statusBIT, u8_t* val);
+  status_t LIS3DH_GetFifoSourceFSS(u8_t* val);
+
+    //Other Reading Functions   
+  status_t LIS3DH_GetStatusReg(u8_t* val);
+  status_t LIS3DH_GetStatusBit(u8_t statusBIT, u8_t* val);
+  status_t LIS3DH_GetStatusAUXBit(u8_t statusBIT, u8_t* val);
+  status_t LIS3DH_GetStatusAUX(u8_t* val);
+
+    status_t LIS3DH_GetAccAxesRaw(AxesRaw_t* buff);
+  status_t LIS3DH_GetAuxRaw(LIS3DH_Aux123Raw_t* buff);
+  status_t LIS3DH_GetClickResponse(u8_t* val);
+    status_t LIS3DH_GetTempRaw(i8_t* val);
+    status_t LIS3DH_GetWHO_AM_I(u8_t* val);
+  status_t LIS3DH_Get6DPosition(u8_t* val);
+  
+private:
+    u8_t LIS3DH_ReadReg(u8_t Reg, u8_t* Data);
+    u8_t LIS3DH_WriteReg(u8_t WriteAddr, u8_t Data);
+        
+    
+protected:
+    SPI  _spi;
+    DigitalOut _ss;
+  
+};
+} //Namespace
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,249 @@
+#include "mbed.h"
+#include "ble/BLE.h"
+
+#define USE_DFU
+
+#ifdef USE_DFU
+#include "DFUService.h"
+#endif
+
+#include "AT45.h"
+#include "LIS3DH.h"
+
+//interrupt /gpio configuration
+#include "nrf_gpio.h"
+#include "nrf_gpiote.h"
+#include "nrf_soc.h"
+
+//SPI stuff
+#define MOSI p8
+#define MISO p9
+#define SCLK p7
+#define CS p2
+
+//#include "app_error.h"
+//void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) { }
+
+//const static char     DEVICE_NAME[]        = "BAc0N";
+//static const uint16_t uuid16_list[]        = {GattService::UUID_STREAMING_SERVICE};
+
+BLE        ble;
+
+static LIS3DH lis(MOSI, MISO, CS, SCLK);    
+                                                                                            
+#define LED_0 p20
+#define LED_1 p23
+//#define LED_2 p24
+DigitalOut myled1(LED_0);
+DigitalOut myled2(LED_1);
+//DigitalOut myled3(LED_2);
+
+//#define UART_TX p17
+//#define UART_RX p18
+//Serial pc(UART_TX, UART_RX); // tx, rx
+
+
+/** @brief Function for initializing the GPIO Tasks/Events peripheral.
+*/
+static void gpiote_init(void)
+{
+        // Configure accelerometer interrupt pin
+    nrf_gpio_cfg_input(3, NRF_GPIO_PIN_PULLDOWN);
+        //nrf_gpio_cfg_input(4, NRF_GPIO_PIN_PULLDOWN);
+    
+    // Configure GPIOTE channel 0 to generate event when MOTION_INTERRUPT_PIN_NUMBER goes from Low to High
+    nrf_gpiote_event_config(0, 3, NRF_GPIOTE_POLARITY_LOTOHI);   //accelerometer int1
+        //nrf_gpiote_event_config(1, 4, NRF_GPIOTE_POLARITY_LOTOHI);   //accelerometer int2
+
+    // Enable interrupt for NRF_GPIOTE->EVENTS_IN[0] event
+    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Msk;
+        //NRF_GPIOTE->INTENSET |= GPIOTE_INTENSET_IN1_Msk;
+}
+
+extern "C"
+void GPIOTE_IRQHandler(void)
+{
+    // Event causing the interrupt must be cleared
+    NRF_GPIOTE->EVENTS_IN[0]  = 0;
+    //NRF_GPIOTE->EVENTS_IN[1]  = 0;
+    lis.LIS3DH_ResetInt1Latch();
+    
+    myled1 = !myled1;
+    myled2 = !myled2;
+}
+
+void disconnect_input_buffers()
+{
+    for(uint8_t i = 0; i < 3; i++)
+    {
+                    NRF_GPIO->PIN_CNF[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+    }   
+    //Omit accelerometer interrupt pins (3&4)
+    for(uint8_t i = 5; i < 21; i++)
+    {
+                    NRF_GPIO->PIN_CNF[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+    }   
+    //Omit I2C pins (21 & 22)
+    for(uint8_t i = 23; i < 31; i++)
+    {
+                    NRF_GPIO->PIN_CNF[i] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+    }
+}
+
+__packed struct ApplicationData_t {
+    uint16_t                    applicationSpecificId; /* An ID used to identify temperature value in the manufacture specific AD data field */
+    //TMP_nrf51::tmpSensorValue_t tmpSensorValue;        /* User defined application data */
+    int8_t                      accel_temp;
+    //uint16_t lis;
+    AxesRaw_t                   accel_raw;        
+};
+
+void setupApplicationData(ApplicationData_t &appData)
+{
+    static const uint16_t APP_SPECIFIC_ID_TEST = 0xFEFE;
+    appData.applicationSpecificId = APP_SPECIFIC_ID_TEST;
+    //appData.tmpSensorValue        = tempSensor.get();
+    lis.LIS3DH_GetAccAxesRaw(&appData.accel_raw);
+    lis.LIS3DH_GetTempRaw(&appData.accel_temp);
+    //uint8_t asdf; 
+    //lis.LIS3DH_GetWHO_AM_I(&asdf);
+    //uint8_t val = 100;
+    //appData.lis = (asdf << 8) | val;
+    
+    //appData.lis = lis.whoami();
+}
+ 
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    ble.gap().startAdvertising();
+}
+
+void senseCallback(void)
+{   
+    ApplicationData_t appData;  
+    setupApplicationData(appData);
+    ble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));             
+}
+
+int main() 
+{
+    
+    //LEDS off
+    myled1 = 0;
+    myled2 = 0;
+    //myled3 = 0;
+    
+    //Without this setup CS lines of AT45 & LIS3DH are in conflict, causing huge current consumption
+    //i.e. both are connected to same SPI interface at the same time
+    #if defined(TARGET_NRF51822_NODE_V3_OTA) || defined(TARGET_NRF51822_NODE_V3) || defined(TARGET_NRF51822_NODE_V3_BOOT)   
+    DigitalOut LIS_CS_0(CS);
+    LIS_CS_0 = 1; //not selected
+    
+    DigitalOut AT_CS(p5);
+    DigitalOut AT_RS(p6);
+
+    AT_CS = 1; //not selected
+    AT_RS = 0; //asserted == reset state
+    wait_ms(100);
+    AT_RS = 1;
+    #endif
+    
+    //Initialize SPI interface
+    SPI spi(MOSI, MISO, SCLK); // mosi, miso, sclk
+    spi.format(8,3);
+    spi.frequency(8000000); 
+    //setup AT45 dataflash to powersaving mode
+    AT45* flash = new AT45(spi, p5);    
+    flash->ultra_deep_power_down(true); 
+    
+    //Accelerometer interrupt pin configuration
+    gpiote_init();  
+    
+    //Disconnect input buffers to save power
+    //disabled for testing
+    //disconnect_input_buffers();
+    
+    //Initialize LIS3DH driver
+    lis.InitLIS3DH(LIS3DH_NORMAL, LIS3DH_ODR_100Hz, LIS3DH_FULLSCALE_2);    //Init Acc-sensor
+    //lis.LIS3DH_SetTemperature(MEMS_ENABLE);
+    //lis.LIS3DH_SetADCAux(MEMS_ENABLE);
+    //lis.LIS3DH_SetBDU(MEMS_ENABLE);
+    //enable threshold to generate interrupt
+    lis.SetLIS3DHActivityDetection(3, LIS3DH_INT_MODE_6D_POSITION, 1);
+    //disable...
+    //lis.SetLIS3DHActivityDetection(20, LIS3DH_INT_MODE_OR, 0);
+    
+    // Enable GPIOTE interrupt in Nested Vector Interrupt Controller.
+    NVIC_ClearPendingIRQ(GPIOTE_IRQn);
+    NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set << GPIOTE_INTENSET_PORT_Pos;
+    NVIC_SetPriority(GPIOTE_IRQn, 1);
+    NVIC_EnableIRQ(GPIOTE_IRQn);
+    //sd_nvic_EnableIRQ(GPIOTE_IRQn);
+    
+    //osDelay(osWaitForever); 
+    //Was Getting 13.2uA with these settings (flash deep power down).
+    //With ultra deep power down 7.8uA... rose back to ~11uA??? Seems to fluctuate. Now getting 9.4... IO issue?
+    //Now getting 5.4uA
+    
+    //device current
+    //3.8uA idle (SYSTEM-ON base current with 32 kB RAM enabled.). Executing code from flash memory 4.1uA. From ram 2.4uA
+    //32.768 kHz crystal oscillator 0.4uA / 32.768 kHz RC oscillator (32k RCOSC) 1.1uA (kumpi on?)
+    //RTC Timer (LFCLK source) 0.1uA
+    //==3.8 + (0.4) + 0.1uA + 5*0.1 (digitalout active) = 4.8uA
+    
+    //(watchdog) 0.1uA
+    //GPIO as input = 22uA (Run current with 1 or more GPIOTE active channels in Input mode.)
+    //as output 0.1A (Run current with 1 or more GPIOTE active channels in Output mode)
+    
+    //Peripherals current
+    //BMP 180 0.1uA standby, 5uA standard mode, 7uA high resolution mode
+    //LIS3DH 0.5uA standby mode, varies a lot in measurement mode
+    //Si7021  0.06uA standby mode, 150uA active
+    //AT45 Ultra deep power down 0,4uA, deep power down 5uA. Standby 25uA. 11mA active
+    //== 0.1uA + 0.5uA + 0.06uA + 0.4uA = 1.06uA
+    
+    //total should be ~5.86 (or 5.46 depending on whether oscillator is included in system idle current)
+    
+    //Initialize BLE stuff
+    ble.init();
+    ble.gap().onDisconnection(disconnectionCallback);
+    
+    #ifdef USE_DFU
+    DFUService dfu(ble);
+    #endif
+    
+    /* Setup advertising. */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);
+    ApplicationData_t appData;
+    setupApplicationData(appData);
+    //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+    //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&appData, sizeof(ApplicationData_t));
+    
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    //ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(100); /* 1000ms. */
+    ble.gap().startAdvertising();
+    
+    Ticker ticker;
+    ticker.attach(senseCallback, 0.1);
+  
+    ///Could have main loop here doing something
+    while(true) {
+        ble.waitForEvent();
+   }     
+}
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/165afa46840b
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51822.lib	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#bcfe7a90edb9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nrf_gpio.h	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,422 @@
+#ifndef NRF_GPIO_H__
+#define NRF_GPIO_H__
+
+#include "nrf51.h"
+#include "nrf51_bitfields.h"
+
+/**
+ * @defgroup nrf_gpio GPIO abstraction
+ * @{
+ * @ingroup nrf_drivers
+ * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports.
+ *
+ * Here, the GPIO ports are defined as follows:
+ * - Port 0 -> pin 0-7
+ * - Port 1 -> pin 8-15
+ * - Port 2 -> pin 16-23
+ * - Port 3 -> pin 24-31
+ */
+
+/**
+ * @enum nrf_gpio_port_dir_t
+ * @brief Enumerator used for setting the direction of a GPIO port.
+ */
+typedef enum
+{
+    NRF_GPIO_PORT_DIR_OUTPUT,       ///<  Output
+    NRF_GPIO_PORT_DIR_INPUT         ///<  Input
+} nrf_gpio_port_dir_t;
+
+/**
+ * @enum nrf_gpio_pin_dir_t
+ * Pin direction definitions.
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_DIR_INPUT,   ///< Input
+    NRF_GPIO_PIN_DIR_OUTPUT   ///< Output
+} nrf_gpio_pin_dir_t;
+
+/**
+ * @enum nrf_gpio_port_select_t
+ * @brief Enumerator used for selecting between port 0 - 3.
+ */
+typedef enum
+{
+    NRF_GPIO_PORT_SELECT_PORT0 = 0,           ///<  Port 0 (GPIO pin 0-7)
+    NRF_GPIO_PORT_SELECT_PORT1,               ///<  Port 1 (GPIO pin 8-15)
+    NRF_GPIO_PORT_SELECT_PORT2,               ///<  Port 2 (GPIO pin 16-23)
+    NRF_GPIO_PORT_SELECT_PORT3,               ///<  Port 3 (GPIO pin 24-31)
+} nrf_gpio_port_select_t;
+
+/**
+ * @enum nrf_gpio_pin_pull_t
+ * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_NOPULL   = GPIO_PIN_CNF_PULL_Disabled,                 ///<  Pin pullup resistor disabled
+    NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown,                 ///<  Pin pulldown resistor enabled
+    NRF_GPIO_PIN_PULLUP   = GPIO_PIN_CNF_PULL_Pullup,                   ///<  Pin pullup resistor enabled
+} nrf_gpio_pin_pull_t;
+
+/**
+ * @enum nrf_gpio_pin_sense_t
+ * @brief Enumerator used for selecting the pin to sense high or low level on the pin input.
+ */
+typedef enum
+{
+    NRF_GPIO_PIN_NOSENSE    = GPIO_PIN_CNF_SENSE_Disabled,              ///<  Pin sense level disabled.
+    NRF_GPIO_PIN_SENSE_LOW  = GPIO_PIN_CNF_SENSE_Low,                   ///<  Pin sense low level.
+    NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High,                  ///<  Pin sense high level.
+} nrf_gpio_pin_sense_t;
+
+/**
+ * @brief Function for configuring the GPIO pin range as outputs with normal drive strength.
+ *        This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @note For configuring only one pin as output use @ref nrf_gpio_cfg_output
+ *       Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
+ */
+static __INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    for (; pin_range_start <= pin_range_end; pin_range_start++)
+    {
+        NRF_GPIO->PIN_CNF[pin_range_start] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+    }
+}
+
+/**
+ * @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input.
+ *
+ * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high)
+ *
+ * @note  For configuring only one pin as input use @ref nrf_gpio_cfg_input
+ *        Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
+ */
+static __INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    for (; pin_range_start <= pin_range_end; pin_range_start++)
+    {
+        NRF_GPIO->PIN_CNF[pin_range_start] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (pull_config << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
+    }
+}
+
+/**
+ * @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_number specifies the pin number of gpio pin numbers to be configured (allowed values 0-30)
+ *
+ * @note  Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
+ */
+static __INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    NRF_GPIO->PIN_CNF[pin_number] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                            | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                            | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+                                            | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
+                                            | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+}
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *
+ * @param pin_number specifies the pin number of gpio pin numbers to be configured (allowed values 0-30)
+ *
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high)
+ *
+ * @note  Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
+ */
+static __INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    NRF_GPIO->PIN_CNF[pin_number] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (pull_config << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
+}
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
+ *        This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
+ *        Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable.
+ *
+ * @param pin_number specifies the pin number of gpio pin numbers to be configured (allowed values 0-30).
+ *
+ * @param pull_config state of the pin pull resistor (no pull, pulled down or pulled high).
+ *
+ * @param sense_config sense level of the pin (no sense, sense low or sense high).
+ */
+static __INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config)
+{
+    /*lint -e{845} // A zero has been given as right argument to operator '|'" */
+    NRF_GPIO->PIN_CNF[pin_number] = (sense_config << GPIO_PIN_CNF_SENSE_Pos)
+                                        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+                                        | (pull_config << GPIO_PIN_CNF_PULL_Pos)
+                                        | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
+                                        | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
+}
+
+/**
+ * @brief Function for setting the direction for a GPIO pin.
+ *
+ * @param pin_number specifies the pin number [0:31] for which to
+ * set the direction.
+ *
+ * @param direction specifies the direction
+ */
+static __INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction)
+{
+    if(direction == NRF_GPIO_PIN_DIR_INPUT)
+    {
+        NRF_GPIO->PIN_CNF[pin_number] =
+          (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
+        | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
+        | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
+        | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
+        | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
+    }
+    else
+    {
+        NRF_GPIO->DIRSET = (1UL << pin_number);
+    }
+}
+
+/**
+ * @brief Function for setting a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * set.
+ */
+static __INLINE void nrf_gpio_pin_set(uint32_t pin_number)
+{
+    NRF_GPIO->OUTSET = (1UL << pin_number);
+}
+
+/**
+ * @brief Function for clearing a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * clear.
+ */
+static __INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
+{
+    NRF_GPIO->OUTCLR = (1UL << pin_number);
+}
+
+/**
+ * @brief Function for toggling a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * toggle.
+ */
+static __INLINE void nrf_gpio_pin_toggle(uint32_t pin_number)
+{
+    const uint32_t pin_bit   = 1UL << pin_number;
+    const uint32_t pin_state = ((NRF_GPIO->OUT >> pin_number) & 1UL);
+    
+    if (pin_state == 0)
+    {
+        // Current state low, set high.
+        NRF_GPIO->OUTSET = pin_bit;        
+    }
+    else
+    {
+        // Current state high, set low.    
+        NRF_GPIO->OUTCLR = pin_bit;       
+    }
+}
+
+/**
+ * @brief Function for writing a value to a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * write.
+ *
+ * @param value specifies the value to be written to the pin.
+ * @arg 0 clears the pin
+ * @arg >=1 sets the pin.
+ */
+static __INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value)
+{
+    if (value == 0)
+    {
+        nrf_gpio_pin_clear(pin_number);
+    }
+    else
+    {
+        nrf_gpio_pin_set(pin_number);
+    }
+}
+
+/**
+ * @brief Function for reading the input level of a GPIO pin.
+ *
+ * Note that the pin must have input connected for the value
+ * returned from this function to be valid.
+ *
+ * @param pin_number specifies the pin number [0:31] to
+ * read.
+ *
+ * @return
+ * @retval 0 if the pin input level is low.
+ * @retval 1 if the pin input level is high.
+ * @retval > 1 should never occur.
+ */
+static __INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number)
+{
+    return  ((NRF_GPIO->IN >> pin_number) & 1UL);
+}
+
+/**
+ * @brief Generic function for writing a single byte of a 32 bit word at a given
+ * address.
+ *
+ * This function should not be called from outside the nrf_gpio
+ * abstraction layer.
+ *
+ * @param word_address is the address of the word to be written.
+ *
+ * @param byte_no is the the word byte number (0-3) to be written.
+ *
+ * @param value is the value to be written to byte "byte_no" of word
+ * at address "word_address"
+ */
+static __INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value)
+{
+    *((volatile uint8_t*)(word_address) + byte_no) = value;
+}
+
+/**
+ * @brief Generic function for reading a single byte of a 32 bit word at a given
+ * address.
+ *
+ * This function should not be called from outside the nrf_gpio
+ * abstraction layer.
+ *
+ * @param word_address is the address of the word to be read.
+ *
+ * @param byte_no is the the byte number (0-3) of the word to be read.
+ *
+ * @return byte "byte_no" of word at address "word_address".
+ */
+static __INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no)
+{
+    return (*((const volatile uint8_t*)(word_address) + byte_no));
+}
+
+/**
+ * @brief Function for setting the direction of a port.
+ *
+ * @param port is the port for which to set the direction.
+ *
+ * @param dir direction to be set for this port.
+ */
+static __INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir)
+{
+    if (dir == NRF_GPIO_PORT_DIR_OUTPUT)
+    {
+        nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF);
+    }
+    else
+    {
+        nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL);
+    }
+}
+
+/**
+ * @brief Function for reading a GPIO port.
+ *
+ * @param port is the port to read.
+ *
+ * @return the input value on this port.
+ */
+static __INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port)
+{
+    return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port);
+}
+
+/**
+ * @brief Function for writing to a GPIO port.
+ *
+ * @param port is the port to write.
+ *
+ * @param value is the value to write to this port.
+ *
+ * @sa nrf_gpio_port_dir_set()
+ */
+static __INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value)
+{
+    nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value);
+}
+
+/**
+ * @brief Function for setting individual pins on GPIO port.
+ *
+ * @param port is the port for which to set the pins.
+ *
+ * @param set_mask is a mask specifying which pins to set. A bit
+ * set to 1 indicates that the corresponding port pin shall be
+ * set.
+ *
+ * @sa nrf_gpio_port_dir_set()
+ */
+static __INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask)
+{
+    nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask);
+}
+
+/**
+ * @brief Function for clearing individual pins on GPIO port.
+ *
+ * @param port is the port for which to clear the pins.
+ *
+ * @param clr_mask is a mask specifying which pins to clear. A bit
+ * set to 1 indicates that the corresponding port pin shall be
+ * cleared.
+ *
+ * @sa nrf_gpio_port_dir_set()
+ */
+static __INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask)
+{
+    nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask);
+}
+
+/** @} */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nrf_gpiote.h	Tue Dec 08 11:58:59 2015 +0000
@@ -0,0 +1,153 @@
+/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+#ifndef NRF_GPIOTE_H__
+#define NRF_GPIOTE_H__
+
+#include "nrf.h"
+
+/**
+* @defgroup nrf_gpiote GPIOTE abstraction
+* @{
+* @ingroup nrf_drivers
+* @brief GPIOTE abstraction for configuration of channels.
+*/
+
+
+ /**
+ * @enum nrf_gpiote_polarity_t
+ * @brief Polarity for GPIOTE channel enumerator.
+ */
+typedef enum
+{
+  NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi,       ///<  Low to high
+  NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo,       ///<  High to low
+  NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle        ///<  Toggle
+} nrf_gpiote_polarity_t;
+
+
+ /**
+ * @enum nrf_gpiote_outinit_t
+ * @brief Initial output value for GPIOTE channel enumerator.
+ */
+typedef enum
+{
+  NRF_GPIOTE_INITIAL_VALUE_LOW  = GPIOTE_CONFIG_OUTINIT_Low,       ///<  Low to high
+  NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High       ///<  High to low
+} nrf_gpiote_outinit_t;
+
+
+/**
+ * @brief Function for configuring GPIOTE channel as output, setting the properly desired output level.
+ *
+ *
+ * @param channel_number specifies the GPIOTE channel [0:3] to configure as an output channel.
+ * @param pin_number specifies the pin number [0:30] to use in the GPIOTE channel.
+ * @param polarity specifies the desired polarity in the output GPIOTE channel.
+ * @param initial_value specifies the initial value of the GPIOTE channel input after the channel configuration.
+ */
+static __INLINE void nrf_gpiote_task_config(uint32_t channel_number, uint32_t pin_number, nrf_gpiote_polarity_t polarity, nrf_gpiote_outinit_t initial_value)
+{
+    /* Check if the output desired is high or low */
+    if (initial_value == NRF_GPIOTE_INITIAL_VALUE_LOW)
+    {
+        /* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
+        on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the 
+        correct state in GPIOTE but not in the OUT register. */
+        NRF_GPIO->OUTCLR = (1 << pin_number);
+        
+        /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
+        NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task       << GPIOTE_CONFIG_MODE_Pos)     |
+                                             (31UL                          << GPIOTE_CONFIG_PSEL_Pos)     |
+                                             (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);                                    
+    } 
+    else 
+    {
+        /* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
+        on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the 
+        correct state in GPIOTE but not in the OUT register. */
+        NRF_GPIO->OUTSET = (1 << pin_number);
+        
+        /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
+        NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task       << GPIOTE_CONFIG_MODE_Pos)     |
+                                             (31UL                          << GPIOTE_CONFIG_PSEL_Pos)     |
+                                             (GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
+    }
+
+    /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
+    __NOP();
+    __NOP();
+    __NOP(); 
+
+    /* Launch the task to take the GPIOTE channel output to the desired level */
+    NRF_GPIOTE->TASKS_OUT[channel_number] = 1;
+    
+
+    /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly. 
+       If it does not, the channel output inheritance sets the proper level. */
+    NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos)     |
+                                         ((uint32_t)pin_number    << GPIOTE_CONFIG_PSEL_Pos)     |
+                                         ((uint32_t)polarity      << GPIOTE_CONFIG_POLARITY_Pos) |
+                                         ((uint32_t)initial_value << GPIOTE_CONFIG_OUTINIT_Pos);
+
+    /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
+    __NOP();
+    __NOP();
+    __NOP(); 
+}
+
+/**
+ * @brief Function for configuring GPIOTE channel as input, automatically clearing an event that appears in some cases under configuration.
+ *
+ * Note that when configuring the channel as input an event might be triggered. Care of disabling interrupts
+ * for that channel is left to the user.
+ *
+ * @param channel_number specifies the GPIOTE channel [0:3] to configure as an input channel.
+ * @param pin_number specifies the pin number [0:30] to use in the GPIOTE channel.
+ * @param polarity specifies the desired polarity in the output GPIOTE channel.
+ */
+static __INLINE void nrf_gpiote_event_config(uint32_t channel_number, uint32_t pin_number, nrf_gpiote_polarity_t polarity)
+{   
+    /* Configure the channel as the caller expects */
+    NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos)     |
+                                         ((uint32_t)pin_number     << GPIOTE_CONFIG_PSEL_Pos)     |
+                                         ((uint32_t)polarity       << GPIOTE_CONFIG_POLARITY_Pos);
+
+    /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
+    __NOP();
+    __NOP();
+    __NOP();
+    
+    /* Clear the event that appears in some cases */
+    NRF_GPIOTE->EVENTS_IN[channel_number] = 0; 
+}
+
+
+/**
+ * @brief Function for unconfiguring GPIOTE channel.
+ *
+ *
+ * Note that when unconfiguring the channel, the pin is configured as GPIO PIN_CNF configuration.
+ *
+ * @param channel_number specifies the GPIOTE channel [0:3] to unconfigure.
+ */
+static __INLINE void nrf_gpiote_unconfig(uint32_t channel_number)
+{   
+    /* Unonfigure the channel as the caller expects */
+    NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Disabled   << GPIOTE_CONFIG_MODE_Pos) |
+                                         (31UL                          << GPIOTE_CONFIG_PSEL_Pos) |
+                                         (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
+}
+
+
+/** @} */
+
+#endif