ArmfulKST / Mbed 2 deprecated BLE_BBC_LSM303

Dependencies:   mbed AES BLE_API nRF51822 smallAES

Files at this revision

API Documentation at this revision

Comitter:
f3d
Date:
Mon Sep 30 10:38:33 2019 +0000
Parent:
1:b10a8955c2fc
Commit message:
Code for the LSM303 version of the BBC Microbit;

Changed in this revision

ADCService.h Show diff for this revision Revisions of this file
ButtonAService.h Show annotated file Show diff for this revision Revisions of this file
accelService.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
--- a/ADCService.h	Thu May 03 10:47:54 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Additional service to extend the basic LED example for the BBC microbit.
-#ifndef __BLE_ADC_SERVICE_H__
-#define __BLE_ADC_SERVICE_H__
-
-class ADCService {
-public:
-    const static uint16_t ADC_SERVICE_UUID              = 0xA002;
-    const static uint16_t ADC_VALUE_CHARACTERISTIC_UUID = 0xA003;
-
-    ADCService(BLEDevice &_ble, uint16_t initialValueForADCCharacteristic) :
-        ble(_ble), ADCValue(ADC_VALUE_CHARACTERISTIC_UUID, &initialValueForADCCharacteristic)
-    {
-        GattCharacteristic *charTable[] = {&ADCValue};
-        GattService         ADCService(ADC_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
-        ble.addService(ADCService);
-    }
-
-    GattAttribute::Handle_t getValueHandle() const {
-        return ADCValue.getValueHandle();
-    }
-    void updateADCValue(uint16_t newValue) {
-        ble.gattServer().write(ADCValue.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
-    }
-
-private:
-    BLEDevice                         &ble;
-    ReadWriteGattCharacteristic<uint16_t>  ADCValue;
-};
-
-#endif /* #ifndef __BLE_ADC_SERVICE_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ButtonAService.h	Mon Sep 30 10:38:33 2019 +0000
@@ -0,0 +1,51 @@
+#ifndef __BUTTONA_SERVICE_H__
+#define __BUTTONA_SERVICE_H__
+// Button A is on P0 bit 17 
+volatile uint32_t * P0OUT = (uint32_t *)0x50000504;
+volatile uint32_t * P0DIR = (uint32_t *)0x50000514;
+volatile uint32_t * P0IN  = (uint32_t *)0x50000510;
+volatile uint32_t * P0CONF  = (uint32_t *)(0x50000700);
+int8_t initialValue=0;
+class ButtonAService {
+public:
+    const static uint16_t BUTTONA_SERVICE_UUID              = 0x1eee;
+    const static uint16_t BUTTONA_STATE_CHARACTERISTIC_UUID = 0x2019;
+
+    ButtonAService(BLEDevice &_ble) :
+        ble(_ble), ButtonState(BUTTONA_STATE_CHARACTERISTIC_UUID,&initialValue,GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
+    {
+        GattCharacteristic *charTable[] = {&ButtonState};
+        GattService         btnService(BUTTONA_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+        ble.addService(btnService);
+        P0CONF[17] = 0;  // On power up, input buffer is not connected so must do this
+        PreviousButtonState = -1;
+    }
+
+    GattAttribute::Handle_t getValueHandle() const {
+        return ButtonState.getValueHandle();
+    }
+    void poll() {
+        uint8_t newValue = GetButtonAState();
+        if (newValue != PreviousButtonState)
+        {   
+            // only send an update if the button state has changed (reduces traffic)
+            ble.gattServer().write(this->getValueHandle(), (uint8_t *)&newValue, sizeof(uint8_t));        
+            PreviousButtonState = newValue;
+        }
+    }
+    uint8_t GetButtonAState()
+    {
+        if ((*P0IN & (1 << 17))==0)    
+            return 1;
+        else
+            return 0;
+    }
+
+private:
+    BLEDevice  &ble;
+    ReadOnlyGattCharacteristic<int8_t>  ButtonState;
+    uint8_t PreviousButtonState;
+    
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/accelService.h	Mon Sep 30 10:38:33 2019 +0000
@@ -0,0 +1,100 @@
+/* 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_ACCEL_SERVICE_H__
+#define __BLE_ACCEL_SERVICE_H__
+#include <mbed.h>
+// Accelerometer : LSM303
+I2C i2c(P0_30, P0_0); // SDA is on P0_30, SCL is on P0_0
+const int LSM303_ADDRESS = (0x19<<1); 
+//const int MMA8653_ID = 0x5a;
+class ACCELService {
+public:
+    const static uint16_t ACCEL_SERVICE_UUID = 0xA012;
+    const static uint16_t ACCEL_X_CHARACTERISTIC_UUID = 0xA013;
+    const static uint16_t ACCEL_Y_CHARACTERISTIC_UUID = 0xA014;
+    const static uint16_t ACCEL_Z_CHARACTERISTIC_UUID = 0xA015;
+
+    ACCELService(BLEDevice &_ble, int16_t initialValueForACCELCharacteristic) :
+        ble(_ble), AccelX(ACCEL_X_CHARACTERISTIC_UUID, &initialValueForACCELCharacteristic),AccelY(ACCEL_Y_CHARACTERISTIC_UUID, &initialValueForACCELCharacteristic),AccelZ(ACCEL_Z_CHARACTERISTIC_UUID, &initialValueForACCELCharacteristic)
+    {
+        GattCharacteristic *charTable[] = {&AccelX,&AccelY,&AccelZ};
+        GattService         AccelService(ACCEL_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+        ble.addService(AccelService);
+        // Wake the accelerometer from sleep mode by writing disabling low power mode, setting freq to 10Hz and enabling all three axes
+        char Data[8]; // Declare a buffer for data transfer    
+        int Status;
+        Data[0]=0x20;   // wake up LSM303 (max speed, all accel channels)
+        Data[1]=0x77;
+        Status = i2c.write(LSM303_ADDRESS,Data,2);  // Write data to register   
+       
+        Data[0]=0x23;   // enable high resolution mode
+        Data[1]=0x0e; 
+        Status = i2c.write(LSM303_ADDRESS,Data,2);  // Write data to register   
+    }
+
+    GattAttribute::Handle_t getValueHandle() const {
+        return AccelX.getValueHandle();
+    }
+    void updateAccelX(uint16_t newValue) {
+        ble.gattServer().write(AccelX.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
+    }
+    void updateAccelY(uint16_t newValue) {
+        ble.gattServer().write(AccelY.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
+    }
+    void updateAccelZ(uint16_t newValue) {
+        ble.gattServer().write(AccelZ.getValueHandle(), (uint8_t *)&newValue, sizeof(uint16_t));
+    }
+    void poll()
+    {
+        char Data[8]; // Declare a buffer for data transfer    
+        int Status;
+        int16_t X;
+                         
+        
+        Data[0]=0x80 + 0x28; // Register number 0x28 has the X data (2 bytes)
+        Status = i2c.write(LSM303_ADDRESS,Data,1,true);  // Write register number
+        Status = i2c.read(LSM303_ADDRESS,Data,2); // Read register contents
+        X = Data[1];
+        X = (X << 8) + Data[0];
+        
+        int16_t Y;
+        Data[0]=0x80 + 0x2a; // Register number 0x2a has the Y data (2 bytes)
+        Status = i2c.write(LSM303_ADDRESS,Data,1,true);  // Write register number
+        Status = i2c.read(LSM303_ADDRESS,Data,2); // Read register contents
+        Y = Data[1];
+        Y = (Y << 8) + Data[0];
+        
+        int16_t Z;
+        Data[0]=0x80 + 0x2c; // Register number 0x2c has the Z data (2 bytes)
+        Status = i2c.write(LSM303_ADDRESS,Data,1,true);  // Write register number
+        Status = i2c.read(LSM303_ADDRESS,Data,2); // Read register contents
+        Z = Data[1];
+        Z = (Z << 8) + Data[0];
+        
+        updateAccelX(X);
+        updateAccelY(Y);
+        updateAccelZ(Z);        
+        
+    }
+private:
+    BLEDevice &ble;
+    ReadOnlyGattCharacteristic<int16_t>  AccelX;
+    ReadOnlyGattCharacteristic<int16_t>  AccelY;
+    ReadOnlyGattCharacteristic<int16_t>  AccelZ;
+};
+
+#endif /* #ifndef __BLE_ACCEL_SERVICE_H__ */
--- a/main.cpp	Thu May 03 10:47:54 2018 +0000
+++ b/main.cpp	Mon Sep 30 10:38:33 2019 +0000
@@ -17,7 +17,8 @@
 #include "mbed.h"
 #include "ble/BLE.h"
 #include "LEDService.h"
-#include "ADCService.h"
+#include "ButtonAService.h"
+#include "accelService.h"
 
 /* 
  * All the LEDs on the micro:bit are part of the LED Matrix,
@@ -28,13 +29,15 @@
 DigitalOut col1(P0_4, 0);
 DigitalOut alivenessLED(P0_13, 0);
 DigitalOut actuatedLED(P0_14, 0);
-AnalogIn ADC(P0_3);
-uint16_t ADCResult=0;
-const static char     DEVICE_NAME[] = "MrPotatoHead";
-static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID,ADCService::ADC_SERVICE_UUID};
+
+const static char     DEVICE_NAME[] = "front1";
+//static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID,ACCELService::ACCEL_SERVICE_UUID,ButtonAService::BUTTONA_SERVICE_UUID};
+static const uint16_t uuid16_list[] = {ACCELService::ACCEL_SERVICE_UUID};
 
 LEDService *ledServicePtr;
-ADCService *ADCServicePtr;
+ButtonAService * btnAServicePtr;
+ACCELService *AccelServicePtr;
+
 Ticker ticker;
 
 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
@@ -44,7 +47,14 @@
 
 void periodicCallback(void)
 {
-    alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
+    
+    btnAServicePtr->poll();
+    AccelServicePtr->poll();
+    if (btnAServicePtr->GetButtonAState())
+        alivenessLED = 1;
+    else
+        alivenessLED = 0;
+            
 }
 
 /**
@@ -60,7 +70,8 @@
 }
 
 void onDataReadCallback(const GattReadCallbackParams *params) {
-    ADCResult=ADC.read_u16();
+  
+
 }
 /**
  * This function is called when the ble initialization process has failed
@@ -91,12 +102,13 @@
  
     ble.gap().onDisconnection(disconnectionCallback);
     ble.gattServer().onDataWritten(onDataWrittenCallback);
-    ble.gattServer().onDataRead(onDataReadCallback);
+    // ble.gattServer().onDataRead(onDataReadCallback); // Nordic Soft device will not call this so have to poll instead
 
     bool initialValueForLEDCharacteristic = false;
     ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic);
-    ADCServicePtr = new ADCService(ble,ADCResult);
-
+    btnAServicePtr = new ButtonAService(ble);
+    int16_t Tst=0;
+    AccelServicePtr = new ACCELService(ble,Tst);
     /* setup advertising */
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
@@ -108,7 +120,7 @@
 
 int main(void)
 {
-    ticker.attach(periodicCallback, 1); /* Blink LED every second */
+    ticker.attach(periodicCallback, 1); /* Poll devices every 100ms */
 
     BLE &ble = BLE::Instance();
     ble.init(bleInitComplete);
@@ -116,11 +128,7 @@
     /* SpinWait for initialization to complete. This is necessary because the
      * BLE object is used in the main loop below. */
     while (ble.hasInitialized()  == false) { /* spin loop */ }
-
     while (true) {
         ble.waitForEvent();
-        ADCResult=ADC.read_u16();
-        ADCServicePtr->updateADCValue(ADCResult);
-        
     }
 }