![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Demo program for use with MMA8653 based boards
Dependencies: mbed AES BLE_API nRF51822 smallAES
main.cpp
- Committer:
- f3d
- Date:
- 2020-11-02
- Revision:
- 8:75b1454df04f
- Parent:
- 6:0038b9f778a5
File content as of revision 8:75b1454df04f:
/* 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. */ #include "mbed.h" #include "ble/BLE.h" #include "BLEservice.h" void bleInitComplete(BLE::InitializationCompleteCallbackContext *params); void onBleInitError(BLE &ble, ble_error_t error); void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params); Ticker ticker; Serial pc(P0_24, P0_25); const static char DEVICE_NAME[] = "Test2020"; #define LED_SERVICE 0xA000 #define BTN_SERVICE 0x1eee #define ACCEL_SERVICE 0xA012 #define TEMP_SERVICE 0xA022 static const uint16_t uuid16_list[] = {LED_SERVICE,BTN_SERVICE,ACCEL_SERVICE,TEMP_SERVICE}; BLEservice * LED; BLEservice * Button; BLEservice *Accel; BLEservice *Temp; const int MMA8653_ADDRESS = (0x1d<<1); const int MMA8653_ID = 0x5a; DigitalOut col1(P0_4, 0); DigitalOut alivenessLED(P0_13, 0); DigitalOut actuatedLED(P0_14, 0); I2C i2c(P0_30, P0_0); // SDA is on P0_30, SCL is on P0_0 const int LSM303_ACCEL_ADDRESS = (0x19<<1); // Will use the built-in temperature sensor in the NRF51822 for the MMA8653 device #define TEMP_BASE 0x4000C000 #define TEMP_START (*(volatile uint32_t *)(TEMP_BASE + 0)) #define TEMP_STOP (*(volatile uint32_t *)(TEMP_BASE + 4)) #define TEMP_DATARDY (*(volatile uint32_t *)(TEMP_BASE + 0x100)) #define TEMP_READING (*(volatile uint32_t *)(TEMP_BASE + 0x508)) void initTemp() { //init code for temp sensor char Data[8]; // Declare a buffer for data transfer int Status; Data[0] =0x1f; Data[1] = 0b11000000; i2c.write(LSM303_ACCEL_ADDRESS,Data,2); Data[0] = 0x23; Data[1] = 0b10000000; i2c.write(LSM303_ACCEL_ADDRESS,Data,2); } int readTemperature() { TEMP_START = 1; // enable the temperature sensor while (TEMP_DATARDY == 0); return (TEMP_READING/4); // rough estimate of temperature within the NRF51822 } void pollTemp() { int16_t T=readTemperature(); pc.printf("T=%d\r\n",T); Temp->writeCharacteristic(0,T); } void initLED() { actuatedLED = 0; } void pollLED() { uint16_t Value; Value = LED->readCharacteristic(0); actuatedLED = Value; } DigitalIn ButtonA(P0_17); DigitalIn ButtonB(P0_26); void initButton() { } void pollButton() { uint16_t ValueA = ButtonA; pc.printf("Button A = %d\r\n",ValueA); Button->writeCharacteristic(0,ValueA); uint16_t ValueB = ButtonB; pc.printf("Button B = %d\r\n",ValueB); Button->writeCharacteristic(1,ValueB); } void initAccel() { // Wake the accelerometer from sleep mode by writing 1 to register number 0x2a char Data[8]; // Declare a buffer for data transfer int Status; Data[0]=0x2a; Data[1]=1; Status = i2c.write(MMA8653_ADDRESS,Data,2); // Write data to register } void pollAccel() { char Data[8]; // Declare a buffer for data transfer int Status; int16_t X; Data[0]=0x01; // Register number 1 has the X data (2 bytes) Status = i2c.write(MMA8653_ADDRESS,Data,1,true); // Write register number Status = i2c.read(MMA8653_ADDRESS,Data,2); // Read register contents X = Data[0]; X = (X << 8) + Data[1]; X = X >> 6; // only 10 bits of data are available int16_t Y; Data[0]=0x03; // Register number 3 has the Y data (2 bytes) Status = i2c.write(MMA8653_ADDRESS,Data,1,true); // Write register number Status = i2c.read(MMA8653_ADDRESS,Data,2); // Read register contents Y = Data[0]; Y = (Y << 8) + Data[1]; Y = Y >> 6; // only 10 bits of data are available int16_t Z; Data[0]=0x05; // Register number 1 has the Z data (2 bytes) Status = i2c.write(MMA8653_ADDRESS,Data,1,true); // Write register number Status = i2c.read(MMA8653_ADDRESS,Data,2); // Read register contents Z = Data[0]; Z = (Z << 8) + Data[1]; Z = Z >> 6; // only 10 bits of data are available pc.printf("X : %d , Y %d , Z %d \r\n",X,Y,Z); Accel->writeCharacteristic(0,X); Accel->writeCharacteristic(1,Y); Accel->writeCharacteristic(2,Z); } void onDataWrittenCallback(const GattWriteCallbackParams *params) { pc.printf("Got writeback for %d\r\n",params->handle); } void tick() { } void pollIO() { pc.printf("Poll\r\n"); LED->poll(); Button->poll(); Accel->poll(); Temp->poll(); } int main(void) { BLE &ble = BLE::Instance(); ble.init(bleInitComplete); /* 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 */ } pc.printf("BLE init complete\r\n"); uint16_t LED_char_array[]={0xabcd}; pc.printf("Creating LED Service\r\n"); LED = new BLEservice(ble,LED_SERVICE,1,LED_char_array,initLED,pollLED); LED->init(); pc.printf("LED service ready\r\n"); uint16_t Button_char_array[]={0x2021,0x2022}; pc.printf("Creating Button Service\r\n"); Button = new BLEservice(ble,BTN_SERVICE,2,Button_char_array,initButton,pollButton,1); Button->init(); pc.printf("Button service ready\r\n"); uint16_t Accel_char_array[]={0xA013,0xA014,0xA015}; pc.printf("Creating Accel Service\r\n"); Accel = new BLEservice(ble,ACCEL_SERVICE,3,Accel_char_array,initAccel,pollAccel); Accel->init(); pc.printf("Accel service ready\r\n"); uint16_t Temp_char_array[]={0xf00d}; pc.printf("Creating Temp Service\r\n"); Temp = new BLEservice(ble,TEMP_SERVICE,1,Temp_char_array,initTemp,pollTemp); Temp->init(); pc.printf("Temp service ready\r\n"); ticker.attach(tick, 1); /* wake from sleep every 100ms */ while (1) { pollIO(); ble.waitForEvent(); } } void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE& ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { /* In case of error, forward the error handling to onBleInitError */ onBleInitError(ble, error); return; } /* Ensure that it is the default instance of BLE */ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onDisconnection(disconnectionCallback); ble.gattServer().onDataWritten(onDataWrittenCallback); // ble.gattServer().onDataRead(onDataReadCallback); // Nordic Soft device will not call this so have to poll instead /* 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)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(500); /* 500ms. */ pc.printf("Starting advertising\r\n"); ble.gap().startAdvertising(); } void onBleInitError(BLE &ble, ble_error_t error) { /* Initialization error handling should go here */ pc.printf("BLE init error\r\n"); } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { pc.printf("Disconnected, restarting advertising\r\n"); BLE::Instance().gap().startAdvertising(); }