it compiles at the very least. Starter code for buffering accelerator values before sending them off.
Dependencies: BLE_API i2c-serial-conflict nRF51822
Fork of accel_to_blenano_i2c by
Revision 10:602c516971ec, committed 2017-05-01
- Comitter:
- znew711
- Date:
- Mon May 01 04:30:39 2017 +0000
- Parent:
- 9:c175975679dc
- Commit message:
- it compiles at least
Changed in this revision
ButtonService.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 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ButtonService.h Mon May 01 04:30:39 2017 +0000 @@ -0,0 +1,44 @@ +/* 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_BUTTON_SERVICE_H__ +#define __BLE_BUTTON_SERVICE_H__ + +class ButtonService { +public: + const static uint16_t BUTTON_SERVICE_UUID = 0xA000; + const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001; + + ButtonService(BLE &_ble, uint8_t* start) : + ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, start, 2, 20, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) + { + GattCharacteristic *charTable[] = {&buttonState}; + GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(buttonService); + } + + //void updateButtonState(uint8_t newState) { + void updateButtonState(uint8_t *newState) { + //ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(uint8_t)); + ble.gattServer().write(buttonState.getValueHandle(), newState, 20); + } + +private: + BLE &ble; + GattCharacteristic buttonState; +}; + +#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */
--- a/main.cpp Wed Apr 26 00:54:35 2017 +0000 +++ b/main.cpp Mon May 01 04:30:39 2017 +0000 @@ -18,13 +18,14 @@ */ #include "mbed.h" +#include "ble/BLE.h" #include "wire.h" +#include "ButtonService.h" #define BLE_Nano //#define nRF_51822 #define LIS331HH -//#define LIS3DH #ifdef nRF_51822 #define SCL 28 @@ -83,7 +84,7 @@ #define DATARATE_100HZ 0b01 // 100Hz #define DATARATE_50HZ 0b00 // 50Hz #define DATARATE_POWERDOWN 0 // Power down -#define DATARATE_NORMALMODE 0b001 +#define DATARATE_NORMAL_MODE 0b001 #define DATARATE_LOWPOWER_0.5HZ 0b010 #define DATARATE_LOWPOWER_1HZ 0b011 #define DATARATE_LOWPOWER_2HZ 0b100 @@ -91,12 +92,121 @@ #define DATARATE_LOWPOWER_10HZ 0b110 #endif +#define PACKET_SIZE 20 +#define QUEUE_SIZE 20 +const static char DEVICE_NAME[] = "LUMBERJACK_NANO"; +static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID}; + +struct packetQueue +{ + uint16_t size; + uint16_t nextPacketToSend; + uint16_t nextSampleToSave; + uint16_t liveSamples; + uint8_t packets[QUEUE_SIZE][PACKET_SIZE]; +}; + +packetQueue pq; + +void addToQueue(uint8_t* packet) { + for (int i = 0; i < PACKET_SIZE; i++) { + pq.packets[pq.nextSampleToSave][i] = packet[i]; + } + if (pq.nextPacketToSend == pq.nextSampleToSave && pq.liveSamples > 0) { + pq.nextSampleToSave = (pq.nextSampleToSave + 1) % QUEUE_SIZE; + pq.nextPacketToSend = (pq.nextPacketToSend + 1) % QUEUE_SIZE; + } else { + pq.liveSamples += 1; + pq.nextSampleToSave = (pq.nextSampleToSave + 1) % QUEUE_SIZE; + } + return; +} + +uint8_t* removeFromQueue() { + if (pq.nextSampleToSave != pq.nextPacketToSend && pq.liveSamples > 0) { + pq.liveSamples -= 1; + uint8_t* old = pq.packets[pq.nextPacketToSend]; + pq.nextPacketToSend = (pq.nextPacketToSend + 1) % QUEUE_SIZE; + return old; + } else { + return NULL; + } +} + Serial pc(USBTX, USBRX); TwoWire Wire = TwoWire(NRF_TWI0); +static ButtonService *buttonServicePtr; +bool isThereAConnection = false; + +void sleep(unsigned int mseconds) +{ + clock_t goal = mseconds + clock(); + while (goal > clock()); +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) +{ + BLE::Instance().gap().startAdvertising(); + isThereAConnection = false; +} + +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) +{ + pc.printf("Connection recieved!\r\n"); + isThereAConnection = true; +} + +/** + * This function is called when the ble initialization process has failled + */ +void onBleInitError(BLE &ble, ble_error_t error) +{ + /* Initialization error handling should go here */ +} + +/** + * Callback triggered when the ble initialization process has finished + */ +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.gap().onConnection(connectionCallback); + + /* Setup primary service */ + uint8_t initial_value[20] = {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0}; + buttonServicePtr = new ButtonService(ble, initial_value); + + /* 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(1000); /* 1000ms. */ + pc.printf("start advertising now \r\n"); + ble.gap().startAdvertising(); +} + void AT24C512_WriteBytes(uint16_t addr, uint8_t *pbuf, uint16_t length, uint16_t i2cAddr) { Wire.beginTransmission(i2cAddr); @@ -152,6 +262,8 @@ AT24C512_ReadBytes(base, low, 1, i2cAddr); AT24C512_ReadBytes(base + 1, high, 1, i2cAddr); uint16_t res = low[0] | (high[0] << 8); + delete[] low; + delete[] high; return res; } @@ -162,6 +274,7 @@ val[0] |= (range << 4); // write in our new range pc.printf("REG_CTRL4 after setRange: 0x%x\r\n", *val); AT24C512_WriteBytes(REG_CTRL4, val, 1, i2cAddr); + delete[] val; } //Set whether we want to use high resolution or not @@ -177,6 +290,7 @@ val[0] = final; pc.printf("REG_CTRL4 after setHiRes: 0x%x\r\n", *val); AT24C512_WriteBytes(REG_CTRL4, val, 1, i2cAddr); + delete[] val; } void setAxisStatus(uint8_t axis, bool enable, uint16_t i2cAddr) { @@ -189,26 +303,37 @@ final = setBit(current[0], axis, 0); } current[0] = final; + AT24C512_WriteBytes(REG_CTRL1, current, 1, i2cAddr); + + AT24C512_ReadBytes(REG_CTRL1, current, 1, i2cAddr); pc.printf("REG_CTRL1 after setAxisStatus: 0x%x\r\n", *current); - AT24C512_WriteBytes(REG_CTRL1, current, 1, i2cAddr); + delete[] current; } void setDataRate(uint8_t dataRate, uint16_t i2cAddr) { uint8_t* val = new uint8_t[1]; AT24C512_ReadBytes(REG_CTRL1, val, 1, i2cAddr); - pc.printf("REG_CTRL1: 0x%x\r\n", *val); + pc.printf("REG_CTRL1 before data rate set: 0x%x\r\n", *val); val[0] &= 0b11100111; //d val[0] |= (dataRate << 3); - pc.printf("REG_CTRL1: 0x%x\r\n", *val); AT24C512_WriteBytes(REG_CTRL1, val, 1, i2cAddr); + + AT24C512_ReadBytes(REG_CTRL1, val, 1, i2cAddr); + pc.printf("REG_CTRL1 after data rate set: 0x%x\r\n", *val); + delete[] val; } void setPowerMode(uint8_t powerMode, uint16_t i2cAddr) { uint8_t* val = new uint8_t[1]; + AT24C512_ReadBytes(REG_CTRL1, val, 1, i2cAddr); val[0] &= 0b11111; - val[0] |= powerMode << 5; - pc.printf("REG_CTRL1: 0x%x\r\n", *val); + val[0] |= (powerMode << 5); + //pc.printf("writing this to REG_CTRL1: 0x%x\r\n", *val); AT24C512_WriteBytes(REG_CTRL1, val, 1, i2cAddr); + + AT24C512_ReadBytes(REG_CTRL1, val, 1, i2cAddr); + pc.printf("REG_CTRL1 after power mode set: 0x%x\r\n", *val); + delete[] val; } void setBDU(bool bdu, uint16_t i2cAddr) @@ -225,6 +350,7 @@ val[0] = final; pc.printf("REG_CTRL4 after setBDU: 0x%x\r\n", *val); AT24C512_WriteBytes(REG_CTRL4, val, 1, i2cAddr); + delete[] val; } uint16_t getX(uint16_t i2cAddr) @@ -258,18 +384,19 @@ setAxisStatus(AXIS_Z, true, ADDR_ONE); setDataRate(DATARATE_400HZ, ADDR_ONE); setPowerMode(DATARATE_NORMAL_MODE, ADDR_ONE); - setHighResolution(true, ADDR_ONE); + //setHighResolution(true, ADDR_ONE); setBDU(true, ADDR_ONE); - setRange(RANGE_2G, ADDR_ONE); + //setRange(RANGE_2G, ADDR_ONE); + setAxisStatus(AXIS_X, true, ADDR_TWO); setAxisStatus(AXIS_Y, true, ADDR_TWO); setAxisStatus(AXIS_Z, true, ADDR_TWO); setDataRate(DATARATE_400HZ, ADDR_TWO); setPowerMode(DATARATE_NORMAL_MODE, ADDR_TWO); - setHighResolution(true, ADDR_TWO); + //setHighResolution(true, ADDR_TWO); setBDU(true, ADDR_TWO); - setRange(RANGE_2G, ADDR_TWO); + //setRange(RANGE_2G, ADDR_TWO); uint8_t* val = new uint8_t[1]; *val = 0x80; @@ -280,38 +407,29 @@ uint8_t* whoami = new uint8_t[1]; AT24C512_ReadBytes(REG_WHOAMI, whoami, 1, ADDR_ONE); - pc.printf("REG_WHOAMI should be 0x33: 0x%x\r\n", *whoami); + pc.printf("REG_WHOAMI should be 0x32: 0x%x\r\n", *whoami); AT24C512_ReadBytes(REG_WHOAMI, whoami, 1, ADDR_TWO); - pc.printf("REG_WHOAMI should be 0x33: 0x%x\r\n", *whoami); + pc.printf("REG_WHOAMI should be 0x32: 0x%x\r\n", *whoami); AT24C512_ReadBytes(0x1F, whoami, 1, ADDR_ONE); - /* - ble.init(); - ble.onDisconnection(disconnectionCallback); - //pc.attach( uartCB , pc.RxIrq); + BLE &ble = BLE::Instance(); + ble.init(bleInitComplete); - // setup advertising - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); - ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, - (const uint8_t *)"LUMBERJACK", sizeof("LUMBERJACK") - 1); - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, - (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid)); - // 100ms; in multiples of 0.625ms. - ble.setAdvertisingInterval(160); - - ble.addService(uartService); + pc.printf("entering spin loop\r\n"); + /* 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("leaving spin loop\r\n"); - ble.startAdvertising(); - pc.printf("Advertising Start \r\n"); - - uint16_t data = new uint16_t[6]; - */ + pq.size = QUEUE_SIZE; + pq.nextPacketToSend = 0; + pq.nextSampleToSave = 0; + pq.liveSamples = 0; while(1) { - pc.printf("Read data from AT24C512\r\n"); + //pc.printf("Read data from AT24C512\r\n"); uint16_t x1 = getX(ADDR_ONE); uint16_t y1 = getY(ADDR_ONE); uint16_t z1 = getZ(ADDR_ONE); @@ -319,18 +437,19 @@ uint16_t x2 = getX(ADDR_TWO); uint16_t y2 = getY(ADDR_TWO); uint16_t z2 = getZ(ADDR_TWO); + + pc.printf("Accel one: x %d y %d z %d\r\n", (int16_t)x1, (int16_t)y1, (int16_t)z1); pc.printf("Accel two: x %d y %d z %d\r\n", (int16_t)x2, (int16_t)y2, (int16_t)z2); pc.printf("\r\n"); - /* - data[0] = x1; - data[1] = y1; - data[2] = z1; - data[3] = x2; - data[4] = y2; - data[5] = z2; - ble.gattServer().write(0x15, data, sizeof(data)); - */ + + if(isThereAConnection) { + pc.printf("sending Notification\r\n"); + uint8_t values[20] = {(uint8_t)x1, (uint8_t)(x1 >> 8), (uint8_t)y1, (uint8_t)(y1 >> 8), (uint8_t)z1, (uint8_t)(z1 >> 8), + (uint8_t)x2, (uint8_t)(x2 >> 8), (uint8_t)y2, (uint8_t)(y2 >> 8), (uint8_t)z2, (uint8_t)(z2 >> 8), + 0, 0, 0, 0, 0, 0, 0, 0}; + buttonServicePtr->updateButtonState(values); + } wait(1); }