microbit: BUGFIX: read callbacks on working

Changes to MicroBitLEDService class to ensure matrixCharacteristic remains
persistent. Needed to allow mbed read callbacks.
This commit is contained in:
Joe Finney 2015-09-08 13:55:15 +01:00
parent 7e18131849
commit 380b999440
2 changed files with 194 additions and 0 deletions

59
inc/MicroBitLEDService.h Normal file
View file

@ -0,0 +1,59 @@
#ifndef MICROBIT_LED_SERVICE_H
#define MICROBIT_LED_SERVICE_H
#include "MicroBit.h"
// UUIDs for our service and characteristics
extern const uint8_t MicroBitLEDServiceUUID[];
extern const uint8_t MicroBitLEDServiceMatrixUUID[];
extern const uint8_t MicroBitLEDServiceTextUUID[];
extern const uint8_t MicroBitLEDServiceScrollingSpeedUUID[];
/**
* Class definition for a MicroBit BLE Event Service.
* Provides a _ble gateway onto the MicroBit Message Bus.
*/
class MicroBitLEDService
{
public:
/**
* Constructor.
* Create a representation of the LEDService
* @param BLE The instance of a BLE device that we're running on.
*/
MicroBitLEDService(BLEDevice &_ble);
/**
* Callback. Invoked when any of our attributes are written via BLE.
*/
void onDataWritten(const GattWriteCallbackParams *params);
/**
* Callback. Invoked when any of our attributes are read via BLE.
*/
void onDataRead(GattReadAuthCallbackParams *params);
private:
// Bluetooth stack we're running on.
BLEDevice &ble;
// memory for our 8 bit control characteristics.
uint32_t matrixCharacteristicBuffer;
uint8_t textCharacteristicBuffer[MICROBIT_BLE_MAXIMUM_SCROLLTEXT];
uint8_t scrollingSpeedCharacteristicBuffer;
// Handles to access each characteristic when they are held by Soft Device.
GattAttribute::Handle_t matrixCharacteristicHandle;
GattAttribute::Handle_t textCharacteristicHandle;
GattAttribute::Handle_t scrollingSpeedCharacteristicHandle;
// We hold a copy of the GattCharacteristic, as mbed's BLE API requires this to provide read callbacks (pity!).
GattCharacteristic matrixCharacteristic;
};
#endif

View file

@ -0,0 +1,135 @@
/**
* Class definition for the custom MicroBit LED Service.
* Provides a BLE service to remotely read and write the state of the LED display.
*/
#include "MicroBit.h"
#include "ble/UUID.h"
#include "MicroBitLEDService.h"
/**
* Constructor.
* Create a representation of the LEDService
* @param _ble The instance of a BLE device that we're running on.
*/
MicroBitLEDService::MicroBitLEDService(BLEDevice &_ble) :
ble(_ble),
matrixCharacteristic(MicroBitLEDServiceMatrixUUID, (uint8_t *)&matrixCharacteristicBuffer, 0, sizeof(matrixCharacteristicBuffer),
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)
{
// Create the data structures that represent each of our characteristics in Soft Device.
GattCharacteristic textCharacteristic(MicroBitLEDServiceTextUUID, (uint8_t *)textCharacteristicBuffer, 0, MICROBIT_BLE_MAXIMUM_SCROLLTEXT,
GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
GattCharacteristic scrollingSpeedCharacteristic(MicroBitLEDServiceScrollingSpeedUUID, (uint8_t *)&scrollingSpeedCharacteristicBuffer, 0,
sizeof(scrollingSpeedCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
// Initialise our characteristic values.
matrixCharacteristicBuffer = 0;
textCharacteristicBuffer[0] = 0;
scrollingSpeedCharacteristicBuffer = MICROBIT_DEFAULT_SCROLL_SPEED;
matrixCharacteristic.setReadAuthorizationCallback(this, &MicroBitLEDService::onDataRead);
GattCharacteristic *characteristics[] = {&matrixCharacteristic, &textCharacteristic, &scrollingSpeedCharacteristic};
GattService service(MicroBitLEDServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
ble.addService(service);
matrixCharacteristicHandle = matrixCharacteristic.getValueHandle();
textCharacteristicHandle = textCharacteristic.getValueHandle();
scrollingSpeedCharacteristicHandle = scrollingSpeedCharacteristic.getValueHandle();
ble.updateCharacteristicValue(scrollingSpeedCharacteristicHandle, (const uint8_t *)&scrollingSpeedCharacteristicBuffer, sizeof(scrollingSpeedCharacteristicBuffer));
ble.updateCharacteristicValue(matrixCharacteristicHandle, (const uint8_t *)&matrixCharacteristicBuffer, sizeof(matrixCharacteristicBuffer));
ble.onDataWritten(this, &MicroBitLEDService::onDataWritten);
}
/**
* Callback. Invoked when any of our attributes are written via BLE.
*/
void MicroBitLEDService::onDataWritten(const GattWriteCallbackParams *params)
{
if (params->handle == matrixCharacteristicHandle && params->len >= 4)
{
uint32_t d = *((uint32_t *)params->data);
uint32_t mask = 0x01;
for (int x=0; x<5; x++)
{
for (int y=0; y<5; y++)
{
uBit.display.image.setPixelValue(x, y, (d & mask) ? 255 : 0);
mask = mask << 1;
}
}
}
else if (params->handle == textCharacteristicHandle)
{
// Create a ManagedString representation from the UTF8 data.
// We do this explicitly to control the length (in case the string is not NULL terminated!)
ManagedString s((char *)params->data, params->len);
// Start the string scrolling and we're done.
uBit.display.scrollAsync(s, (int) scrollingSpeedCharacteristicBuffer);
}
else if (params->handle == scrollingSpeedCharacteristicHandle && params->len >= sizeof(scrollingSpeedCharacteristicBuffer))
{
// Read the speed requested, and store it locally.
// We use this as the speed for all scroll operations subsquently initiated from BLE.
scrollingSpeedCharacteristicBuffer = *((uint8_t *)params->data);
}
}
/**
* Callback. Invoked when any of our attributes are read via BLE.
*/
void MicroBitLEDService::onDataRead(GattReadAuthCallbackParams *params)
{
if (params->handle == matrixCharacteristicHandle)
{
uint32_t mask = 0x01;
matrixCharacteristicBuffer = 0;
for (int x=0; x<5; x++)
{
for (int y=0; y<5; y++)
{
if (uBit.display.image.getPixelValue(x, y))
matrixCharacteristicBuffer |= mask;
mask = mask << 1;
}
}
ble.updateCharacteristicValue(matrixCharacteristicHandle, (const uint8_t *)&matrixCharacteristicBuffer, sizeof(matrixCharacteristicBuffer));
}
}
const uint8_t MicroBitLEDServiceUUID[] = {
0xe9,0x5d,0xd9,0x1d,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};
const uint8_t MicroBitLEDServiceMatrixUUID[] = {
0xe9,0x5d,0x7b,0x77,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};
const uint8_t MicroBitLEDServiceTextUUID[] = {
0xe9,0x5d,0x93,0xee,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};
const uint8_t MicroBitLEDServiceScrollingSpeedUUID[] = {
0xe9,0x5d,0x0d,0x2d,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};