project_sensor

Dependencies:   project mbed nRF51822

Files at this revision

API Documentation at this revision

Comitter:
didierlauwerys
Date:
Sun May 28 16:26:53 2017 +0000
Commit message:
spi_ctrl

Changed in this revision

BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
adxl345.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
spi_master.cpp Show annotated file Show diff for this revision Revisions of this file
spi_master.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_API.lib	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/MDS_2/code/project/#d3985c47e5c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adxl345.h	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,118 @@
+#define DEVID 0x00
+#define THRESH_TAP 0x1D
+#define OFSX 0x1E
+#define OFSY 0x1F
+#define OFSZ 0x20
+#define DUR 0x21
+#define Latent 0x22
+#define Window 0x23
+#define THRESH_ACT 0x24
+#define THRESH_INACT 0x25
+#define TIME_INACT 0x26
+#define ACT_INACT_CTL 0x27
+#define THRESH_FF 0x28
+#define TIME_FF 0x29
+#define TAP_AXES 0x2A
+#define ACT_TAP_STATUS 0x2B
+#define BW_RATE 0x2C
+#define POWER_CTL 0x2D
+#define INT_ENABLE 0x2E
+#define INT_MAP 0x2F
+#define INT_SOURCE 0x30
+#define DATA_FORMAT 0x31
+#define DATAX0 0x32
+#define DATAX1 0x33
+#define DATAY0 0x34
+#define DATAY1 0x35
+#define DATAZ0 0x36
+#define DATAZ1 0x37
+#define FIFO_CTL 0x38
+#define FIFO_STATUS 0x39
+
+struct data_member_t {
+    uint8_t data_x0;
+    uint8_t data_x1;
+    uint8_t data_y0;
+    uint8_t data_y1;
+    uint8_t data_z0;
+    uint8_t data_z1;
+};
+
+
+#define THRESH_TAP_INIT 0x00
+    // Not used->reset interrupt
+#define OFSX_INIT 0x00
+#define OFSY_INIT 0x00
+#define OFSZ_INIT 0x00
+    // No ofsets
+#define DUR_INIT 0x00
+    // Disable single/double tap function
+#define Latent_INIT 0x00
+    // Disable double tap function
+#define Window_INIT 0x00
+    // Disable double tap function
+#define THRESH_ACT_INIT 0x0A
+    // 62.5mg/LSB
+#define THRESH_INACT_INIT 0x09
+    // 62.5mg/LSB
+#define TIME_INACT_INIT 0x08
+    // 1s/LSB
+    // Wait 8 seconds after inactivity
+#define ACT_INACT_CTL_INIT 0xF8
+    // D7 ACT AC/DC   1
+    // D6 ACT_X_EN    1
+    // D5 ACT_Y_EN    1
+    // D4 ACT_Z_EN    1
+    // D3 INACT AC/DC 1
+    // D2 INACT_X_EN  0
+    // D1 INACT_Y_EN  0
+    // D0 INACT_Z_EN  0
+#define THRESH_FF_INIT 0x00
+    // Not used->reset interrupt
+#define TIME_FF_INIT 0x00
+    // Not used->reset interrupt
+#define TAP_AXES_INIT 0x00
+    // Disable taps
+#define BW_RATE_INIT 0x0F
+    // D7-D5         000
+    // D4 LOW_POWER  0
+    // D3-D0 RATE    1111       (1.6kHz)
+#define POWER_CTL_INIT 0x00
+    // D7-D6         00
+    // D5 Link       0
+    // D4 AUTO_SLEEP 0
+    // D3 Measure    0
+    // D2 Sleep      0
+    // D1-D0 Wakeup  00         (8Hz)
+#define INT_ENABLE_INIT 0x80
+    // D7 DATA_READY 1
+    // D6 SINGLE_TAP 0
+    // D5 DOUBLE_TAP 0
+    // D4 Activity   0
+    // D3 Inactivity 0
+    // D2 FREE_FALL  0
+    // D1 Watermark  0
+    // D0 Overrun    0
+#define INT_MAP_INIT 0x00
+    // All set to INT1 pin
+    // D7 DATA_READY 0
+    // D6 SINGLE_TAP 0
+    // D5 DOUBLE_TAP 0
+    // D4 Activity   0
+    // D3 Inactivity 0
+    // D2 FREE_FALL  0
+    // D1 Watermark  0
+    // D0 Overrun    0
+#define DATA_FORMAT_INIT 0x0F
+    // D7 SELF_TEST  0
+    // D6 SPI        0            (4-wire)
+    // D5 INT_INVERT 0            (Active high)
+    // D4            0
+    // D3 FULL_RES   1
+    // D2 Justify    1            (Left justified MSB first)
+    // D1-D0 Range   11           (16g)
+#define FIFO_CTL_INIT 0x3F
+    // D7-D6 FIFO_MODE 00         (Bypass)
+    // D5 Trigger      1
+    // D4-D0 SAMPLES   11111
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,339 @@
+using namespace std;
+
+#include "mbed.h"
+#include "spi_master.h"
+#include "adxl345.h"
+#include "ble/BLE.h"
+#include "ble/Gap.h"
+#include "ble/UUID.h"
+#include "ble/GattCharacteristic.h"
+#include "ble/GattCallbackParamTypes.h"
+#include "ble/GattServer.h"
+
+//#define CS      P0_7                                //chipselect
+#define MOSI    P0_9                                //Master Out Slave In
+#define MISO    P0_11                               //Master In Slave Out
+#define SCK     P0_8                                //Clock
+//additional IO
+#define ON_SW   P0_28                               //ON/OFF switch
+#define BEPB    P0_29                               //Enable/disable bluetooth push button
+#define CHARACT_DATA 0
+
+#define MIN_CONN_INTERVAL 10 //250 milliseconds
+#define MAX_CONN_INTERVAL 30 //350 milliseconds
+
+DigitalOut spi_cs(P0_28);
+DigitalIn int1(P0_15);
+DigitalIn location(P0_07);
+SPIClass SPI1(NRF_SPI1);
+data_member_t data[513];
+BLEDevice ble;
+Gap::Handle_t connectionHandle = 0xFFFF;
+
+/*SET UUID*/
+const UUID GATT_SERVICE = "88888888-5555-4444-1111-777777777777";
+const UUID ADV_DATA = "11001100-2200-3300-4400-550055005500";
+const UUID RECV_DATA = "22002200-3300-4400-5500-660066006600";
+char *compbuf= new char[26];
+uint16_t compbufLen=0;
+char *sendbuf= new char[26];
+char *sendbufaddr=sendbuf;
+uint16_t sendbufLen=20*sizeof(uint8_t);
+char *readystr = "data ready";
+uint16_t readyLen = sizeof("data ready");
+char *startstr = "START";
+uint16_t startLen = sizeof("START");
+char *sendstr = "SEND";
+uint16_t sendLen = sizeof("SEND");
+bool data_ready;
+uint16_t sendindex;
+uint8_t *AdvData= new uint8_t[26];
+uint16_t AdvDataLen=0;
+uint8_t *RcvData= new uint8_t[26];
+uint16_t RcvDataLen=0;
+uint8_t devnr = 1;
+unsigned count;
+/* Device Name, simpel discovey */
+const static char DEVICE_NAME[] = "Trump";
+GattCharacteristic gattchar = GattCharacteristic(ADV_DATA, AdvData, AdvDataLen, 26, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
+GattCharacteristic rxCharacteristic = GattCharacteristic(RECV_DATA, RcvData, RcvDataLen, 26, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);// | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
+
+GattCharacteristic *CHARACT_ARRAY[] = {&gattchar,&rxCharacteristic};
+GattService gatt_service(GATT_SERVICE,CHARACT_ARRAY,2);
+GattAttribute::Handle_t writeHandle;
+GattAttribute::Handle_t readHandle;
+
+
+    
+
+bool poll_start_send_data(uint8_t *compare_str, uint8_t comp_length){
+    uint16_t bufLen = 27;
+    uint8_t *rdbuf= new uint8_t[bufLen];
+    ble.readCharacteristicValue(readHandle,rdbuf,&bufLen);
+    for (uint8_t i=0 ; i<comp_length-1 ; i++)
+    {
+        if (*(rdbuf+i*sizeof(uint8_t)) != *(compare_str+i*sizeof(uint8_t)))
+        {
+            delete rdbuf;
+            return false;
+        }
+    }
+    delete rdbuf;
+    return true;
+}
+
+void Flash_Buff_WriteBytes(uint8_t addr, uint8_t pbuf)
+{    
+    spi_cs = 0;
+    wait_us(200);      
+    SPI1.transfer((uint8_t)addr);     
+    SPI1.transfer(pbuf);       
+    
+    wait_us(200);
+    spi_cs = 1;
+}
+
+void Flash_Buff_ReadBytes(uint8_t addr, uint8_t *pbuf)
+{    
+    spi_cs = 0;
+    wait_us(20);
+          
+    SPI1.transfer((uint8_t)addr|0x80);     
+    *pbuf = SPI1.transfer(0x00);
+    
+    wait_us(20);
+    spi_cs = 1;
+}
+
+void init_adxl()
+{
+    Flash_Buff_WriteBytes(INT_ENABLE, 0x00);
+    Flash_Buff_WriteBytes(THRESH_TAP, THRESH_TAP_INIT);
+    Flash_Buff_WriteBytes(OFSX, OFSX_INIT);
+    Flash_Buff_WriteBytes(OFSY, OFSY_INIT);
+    Flash_Buff_WriteBytes(OFSZ, OFSZ_INIT);
+    Flash_Buff_WriteBytes(DUR, DUR_INIT);
+    Flash_Buff_WriteBytes(Latent, Latent_INIT);
+    Flash_Buff_WriteBytes(Window, Window_INIT);
+    Flash_Buff_WriteBytes(THRESH_ACT, THRESH_ACT_INIT);
+    Flash_Buff_WriteBytes(THRESH_INACT, THRESH_INACT_INIT);
+    Flash_Buff_WriteBytes(TIME_INACT, TIME_INACT_INIT);
+    Flash_Buff_WriteBytes(ACT_INACT_CTL, ACT_INACT_CTL_INIT);
+    Flash_Buff_WriteBytes(THRESH_FF, THRESH_FF_INIT);
+    Flash_Buff_WriteBytes(TIME_FF, TIME_FF_INIT);
+    Flash_Buff_WriteBytes(TAP_AXES, TAP_AXES_INIT);
+    Flash_Buff_WriteBytes(BW_RATE, BW_RATE_INIT);
+    Flash_Buff_WriteBytes(POWER_CTL, POWER_CTL_INIT);
+    Flash_Buff_WriteBytes(INT_MAP, INT_MAP_INIT);
+    Flash_Buff_WriteBytes(DATA_FORMAT, DATA_FORMAT_INIT);
+    Flash_Buff_WriteBytes(FIFO_CTL, FIFO_CTL_INIT);
+    Flash_Buff_WriteBytes(POWER_CTL, POWER_CTL_INIT | 0x08);
+    Flash_Buff_WriteBytes(INT_ENABLE, INT_ENABLE_INIT);
+}
+
+void read_data(uint16_t index)
+{
+    spi_cs = 0;
+    wait_us(20);
+    
+    SPI1.transfer((uint8_t)(DATAX0|0xC0));
+    data[index].data_x0 = SPI1.transfer(0x00)^0x80;
+    data[index].data_x1 = SPI1.transfer(0x00);
+    data[index].data_y0 = SPI1.transfer(0x00)^0x80;
+    data[index].data_y1 = SPI1.transfer(0x00);
+    data[index].data_z0 = SPI1.transfer(0x00)^0x80;
+    data[index].data_z1 = SPI1.transfer(0x00);
+    
+    wait_us(20);
+    spi_cs = 1;
+}
+
+
+/* WHEN CONNECTION ...  */
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
+    if (params->role == Gap::CENTRAL) {
+        connectionHandle = params->handle;
+    }
+}
+
+
+/* Restart advertising when the peer disconnects */
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    BLE::Instance().gap().startAdvertising();
+}
+
+/*This function is called when the ble initialization process has failed*/
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+    /* Avoid compiler warnings, library said to do this */
+    (void) ble;
+    (void) error;
+    
+    /* Initialization error handling should go here */
+}
+
+void dataSentCallback(unsigned count)
+{
+    SPI1.transfer(0xCC);
+    sendindex+=1;
+    memcpy(sendbufaddr+0*sizeof(uint8_t), &sendindex, sizeof(uint16_t));
+    memcpy(sendbufaddr+2*sizeof(uint8_t), &(data[sendindex].data_x0), sizeof(uint8_t));
+    memcpy(sendbufaddr+3*sizeof(uint8_t), &(data[sendindex].data_x1), sizeof(uint8_t));
+    memcpy(sendbufaddr+4*sizeof(uint8_t), &(data[sendindex].data_y0), sizeof(uint8_t));
+    memcpy(sendbufaddr+5*sizeof(uint8_t), &(data[sendindex].data_y1), sizeof(uint8_t));
+    memcpy(sendbufaddr+6*sizeof(uint8_t), &(data[sendindex].data_z0), sizeof(uint8_t));
+    memcpy(sendbufaddr+7*sizeof(uint8_t), &(data[sendindex].data_z1), sizeof(uint8_t));
+    sendindex+=1;
+    memcpy(sendbufaddr+8*sizeof(uint8_t), &(data[sendindex].data_x0), sizeof(uint8_t));
+    memcpy(sendbufaddr+9*sizeof(uint8_t), &(data[sendindex].data_x1), sizeof(uint8_t));
+    memcpy(sendbufaddr+10*sizeof(uint8_t), &(data[sendindex].data_y0), sizeof(uint8_t));
+    memcpy(sendbufaddr+11*sizeof(uint8_t), &(data[sendindex].data_y1), sizeof(uint8_t));
+    memcpy(sendbufaddr+12*sizeof(uint8_t), &(data[sendindex].data_z0), sizeof(uint8_t));
+    memcpy(sendbufaddr+13*sizeof(uint8_t), &(data[sendindex].data_z1), sizeof(uint8_t));
+    sendindex+=1;
+    memcpy(sendbufaddr+14*sizeof(uint8_t), &(data[sendindex].data_x0), sizeof(uint8_t));
+    memcpy(sendbufaddr+15*sizeof(uint8_t), &(data[sendindex].data_x1), sizeof(uint8_t));
+    memcpy(sendbufaddr+16*sizeof(uint8_t), &(data[sendindex].data_y0), sizeof(uint8_t));
+    memcpy(sendbufaddr+17*sizeof(uint8_t), &(data[sendindex].data_y1), sizeof(uint8_t));
+    memcpy(sendbufaddr+18*sizeof(uint8_t), &(data[sendindex].data_z0), sizeof(uint8_t));
+    memcpy(sendbufaddr+19*sizeof(uint8_t), &(data[sendindex].data_z1), sizeof(uint8_t));
+    if(sendindex>=512)
+        data_ready=false;
+    
+}
+
+/*Callback triggered when ble initialization process has finished*/
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+    BLE&        ble   = params->ble;
+    ble_error_t error = params->error;
+
+/* In case of error, forward the error handling to onBleInitError */
+    if (error != BLE_ERROR_NONE) {
+        onBleInitError(ble, error);
+        return;
+    }
+
+    /* Ensure that it is the default instance of BLE */
+    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+        return;
+    }
+    
+    /* Set device name characteristic data */
+    ble.gap().setDeviceName((const uint8_t *) DEVICE_NAME);
+    
+    ble.gattServer().onDataSent(dataSentCallback);
+        
+    
+    /* callback when disconnected */
+    ble.gap().onDisconnection(disconnectionCallback);
+
+    /* Sacrifice 3B of 31B to some Advertising Flags (see nrfconnect toolbox for flag parameters :) ) */
+    // for
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);// say this device can be discovered by other BLE supportingdevices
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // say that a connection can be set ( connectable) and that it does not matter with who it connects (unidirected)
+
+    
+    /* Sacrifice another 2B of 31B (actually 29B) to AdvType overhead, rest goes to AdvData array --> about 26B of actual sendable data :o */
+    //Overhead  = 1B Length, 1B Type
+    //Type = AdvData
+    //Length = sizeof(AdvData)
+    //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, AdvData, sizeof(AdvData));
+
+    /*fill in device name as local name*/
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+
+    /* Set advertising interval. Longer interval == Less radiothingies use == longer battery life :) */
+    ble.gap().setAdvertisingInterval(20); /* 100ms */
+    
+
+
+    ble.addService(gatt_service);
+
+    //ble.gap().addData(GapAdvertisingData::SERVICE_DATA, (uint8_t *)AdvData, sizeof(AdvData));
+    /* Start advertising */
+    ble.gap().startAdvertising(); //start sending advertising packets
+    
+    ble.initializeSecurity();
+    //end
+}
+
+
+main() {
+    wait_ms(1);
+    data_ready=false;
+    BLE& ble = BLE::Instance();
+    ble.init(bleInitComplete);
+    spi_cs = 1;
+    if (location==1) {
+        char *waitingstr = "waiting1";
+        uint16_t waitingLen = sizeof("waiting1"); }
+    else if(location==0) {
+        char *waitingstr = "waiting0";
+        uint16_t waitingLen = sizeof("waiting0"); }
+    uint16_t index;
+    for(uint16_t i=0; i<513;i++){
+        data[i].data_x0=(uint8_t)0;
+        data[i].data_x1=(uint8_t)0;
+        data[i].data_y0=(uint8_t)0;
+        data[i].data_y1=(uint8_t)0;
+        data[i].data_z0=(uint8_t)0;
+        data[i].data_z1=(uint8_t)0;
+    }
+    SPI1.begin(SCK, MOSI, MISO);
+    init_adxl();
+    writeHandle = gattchar.getValueHandle();
+    readHandle = rxCharacteristic.getValueHandle();
+    
+    while(1)
+    {
+        ble.gattServer().write(writeHandle,(uint8_t *)waitingstr, waitingLen);
+        while (poll_start_send_data((uint8_t *)startstr, startLen) != true)
+        {   
+            ble.waitForEvent();
+        }
+        //SPI
+        Flash_Buff_WriteBytes(POWER_CTL, POWER_CTL_INIT | 0x08);
+        for (index=0 ; index<513 ; index++){
+            while(!int1){wait_us(1);}
+            read_data(index);
+        }
+        Flash_Buff_WriteBytes(POWER_CTL, POWER_CTL_INIT | 0x04);
+        ble.gattServer().write(writeHandle,(uint8_t *)readystr, readyLen);
+        //condition to send data
+        while (poll_start_send_data((uint8_t *)sendstr, sendLen) != true)
+        {   
+            ble.waitForEvent();
+        }
+        index=0;
+        sendindex=2;
+        data_ready=true;
+        memcpy(sendbufaddr+0*sizeof(uint8_t), &index, sizeof(uint16_t));
+        memcpy(sendbufaddr+2*sizeof(uint8_t), &(data[index].data_x0), sizeof(uint8_t));
+        memcpy(sendbufaddr+3*sizeof(uint8_t), &(data[index].data_x1), sizeof(uint8_t));
+        memcpy(sendbufaddr+4*sizeof(uint8_t), &(data[index].data_y0), sizeof(uint8_t));
+        memcpy(sendbufaddr+5*sizeof(uint8_t), &(data[index].data_y1), sizeof(uint8_t));
+        memcpy(sendbufaddr+6*sizeof(uint8_t), &(data[index].data_z0), sizeof(uint8_t));
+        memcpy(sendbufaddr+7*sizeof(uint8_t), &(data[index].data_z1), sizeof(uint8_t));
+        memcpy(sendbufaddr+8*sizeof(uint8_t), &(data[index+1].data_x0), sizeof(uint8_t));
+        memcpy(sendbufaddr+9*sizeof(uint8_t), &(data[index+1].data_x1), sizeof(uint8_t));
+        memcpy(sendbufaddr+10*sizeof(uint8_t), &(data[index+1].data_y0), sizeof(uint8_t));
+        memcpy(sendbufaddr+11*sizeof(uint8_t), &(data[index+1].data_y1), sizeof(uint8_t));
+        memcpy(sendbufaddr+12*sizeof(uint8_t), &(data[index+1].data_z0), sizeof(uint8_t));
+        memcpy(sendbufaddr+13*sizeof(uint8_t), &(data[index+1].data_z1), sizeof(uint8_t));
+        memcpy(sendbufaddr+14*sizeof(uint8_t), &(data[index+2].data_x0), sizeof(uint8_t));
+        memcpy(sendbufaddr+15*sizeof(uint8_t), &(data[index+2].data_x1), sizeof(uint8_t));
+        memcpy(sendbufaddr+16*sizeof(uint8_t), &(data[index+2].data_y0), sizeof(uint8_t));
+        memcpy(sendbufaddr+17*sizeof(uint8_t), &(data[index+2].data_y1), sizeof(uint8_t));
+        memcpy(sendbufaddr+18*sizeof(uint8_t), &(data[index+2].data_z0), sizeof(uint8_t));
+        memcpy(sendbufaddr+19*sizeof(uint8_t), &(data[index+2].data_z1), sizeof(uint8_t));
+        wait(2);
+        while (data_ready == true)
+        {   
+            ble.gattServer().write(writeHandle, (uint8_t *)sendbufaddr, sendbufLen);
+            ble.waitForEvent();
+            
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/4336505e4b1c
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51822.lib	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#3cc0718d98d0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi_master.cpp	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,236 @@
+/*
+
+Copyright (c) 2012-2014 RedBearLab
+
+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 "spi_master.h"
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+SPIClass::SPIClass(NRF_SPI_Type *_spi) : spi(_spi)
+{
+    //do nothing
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::setCPOL( bool active_low)
+{
+    if(active_low)
+    {
+        spi->CONFIG |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
+    }
+    else
+    {
+        spi->CONFIG |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
+    }
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::setCPHA( bool trailing)
+{
+    if(trailing)
+    {
+        spi->CONFIG |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
+    }
+    else
+    {
+        spi->CONFIG |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
+    }
+
+}
+
+/**********************************************************************
+name :
+function : MSBFIRST, LSBFIRST
+**********************************************************************/
+void SPIClass::setBitORDER( BitOrder  bit)
+{
+    if(bit == MSBFIRST)
+    {
+        spi->CONFIG |= (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos);
+    }
+    else
+    {
+        spi->CONFIG |= (SPI_CONFIG_ORDER_LsbFirst << SPI_CONFIG_ORDER_Pos);
+    }
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::setFrequency(uint8_t speed)
+{
+    if (speed == 0)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_125K;
+    }
+    else if (speed == 1)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_250K;
+    }
+    else if (speed == 2)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_500K;
+    }
+    else if (speed == 3)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_1M;
+    }
+    else if (speed == 4)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_2M;
+    }
+    else if (speed == 5)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_4M;
+    }
+    else if (speed == 6)
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_8M;
+    }
+    else
+    {
+        spi->FREQUENCY = SPI_FREQUENCY_4M;
+    }   
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::setSPIMode( uint8_t mode )
+{
+    if (SPI_MODE0 == mode)
+    {
+        setCPOL(0);
+        setCPHA(0);     
+    }
+    else if (mode == SPI_MODE1)
+    {
+        setCPOL(0);
+        setCPHA(1);
+    }
+    else if (mode == SPI_MODE2)
+    {
+        setCPOL(1);
+        setCPHA(0);
+    }
+    else if (mode == SPI_MODE3)
+    {
+        setCPOL(1);
+        setCPHA(1);
+    }
+    else
+    {
+        setCPOL(0);
+        setCPHA(0);         
+    }
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::begin(uint32_t sck, uint32_t mosi, uint32_t miso)
+{
+
+        SCK_Pin = sck;
+        MOSI_Pin = mosi;
+        MISO_Pin = miso;
+        
+        NRF_GPIO->PIN_CNF[SCK_Pin] = (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_Output << GPIO_PIN_CNF_DIR_Pos);    
+                                        
+        NRF_GPIO->PIN_CNF[MOSI_Pin] = (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_Output << GPIO_PIN_CNF_DIR_Pos);
+                                        
+        NRF_GPIO->PIN_CNF[MISO_Pin] = (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);                                     
+        spi->PSELSCK  = SCK_Pin;
+        spi->PSELMOSI = MOSI_Pin;
+        spi->PSELMISO = MISO_Pin;       
+        
+        setFrequency(3);
+        setSPIMode(SPI_MODE3);
+        setBitORDER(MSBFIRST);
+        
+        spi->EVENTS_READY = 0;
+        spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
+    
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::begin()
+{
+    begin(SCK, MOSI, MISO);
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+uint8_t SPIClass::transfer(uint8_t data)
+{
+    while( spi->EVENTS_READY != 0U );
+    
+    spi->TXD = (uint32_t)data;
+    
+    while(spi->EVENTS_READY == 0);
+    
+    data = (uint8_t)spi->RXD;
+    
+    spi->EVENTS_READY = 0;
+    
+    return data;
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+void SPIClass::endTransfer()
+{
+    spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
+}
+
+/**********************************************************************
+name :
+function : 
+**********************************************************************/
+
+//SPIClass SPI(NRF_SPI1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi_master.h	Sun May 28 16:26:53 2017 +0000
@@ -0,0 +1,84 @@
+/*
+
+Copyright (c) 2012-2014 RedBearLab
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
+and associated documentation files (the "Software"), to deal in the Software without restriction, 
+including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
+subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef _SPI_MASTER_H_
+#define _SPI_MASTER_H_
+
+#include "mbed.h"
+
+#define SPI_FREQUENCY_125K 0x02000000UL
+#define SPI_FREQUENCY_250K 0x04000000UL
+#define SPI_FREQUENCY_500K 0x08000000UL
+#define SPI_FREQUENCY_1M   0x10000000UL
+#define SPI_FREQUENCY_2M   0x20000000UL
+#define SPI_FREQUENCY_4M   0x40000000UL
+#define SPI_FREQUENCY_8M   0x80000000UL
+
+#define SPI_125K 0
+#define SPI_250K 1
+#define SPI_500K 2
+#define SPI_1M   3
+#define SPI_2M   4
+#define SPI_4M   5
+#define SPI_8M   6
+
+#define SPI_MODE0 0
+#define SPI_MODE1 1
+#define SPI_MODE2 2
+#define SPI_MODE3 3
+
+#define CS      P0_28                                //chipselect
+#define MOSI    P0_9                                //Master Out Slave In
+#define MISO    P0_11                               //Master In Slave Out
+#define SCK     P0_8 
+
+typedef enum{
+    
+    MSBFIRST = 0,
+    LSBFIRST = 1
+    
+}BitOrder;
+
+class SPIClass
+{
+    public:
+        SPIClass(NRF_SPI_Type *_spi);
+    
+        void begin();
+        void begin(uint32_t sck, uint32_t mosi, uint32_t miso);
+        uint8_t transfer(uint8_t data);
+        void endTransfer();
+            
+        void setSPIMode( uint8_t mode );
+        void setFrequency(uint8_t speed );
+        void setBitORDER( BitOrder  bit);
+        void setCPHA( bool trailing);
+        void setCPOL( bool active_low);
+        
+        
+    private:
+        NRF_SPI_Type *spi;
+        
+        uint32_t SCK_Pin;
+        uint32_t MOSI_Pin;
+        uint32_t MISO_Pin;
+
+};
+
+#endif