Merge pull request #209 from bluetooth-mdw/master

PWM Control characteristic added to IO Pin Service
master
Martin Woolley 7 years ago committed by GitHub
commit 3cf56b8f44
  1. 15
      inc/bluetooth/MicroBitIOPinService.h
  2. 42
      source/bluetooth/MicroBitIOPinService.cpp

@ -32,11 +32,13 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_IO_PIN_SERVICE_PINCOUNT 19
#define MICROBIT_IO_PIN_SERVICE_DATA_SIZE 10
#define MICROBIT_PWM_PIN_SERVICE_DATA_SIZE 2
// UUIDs for our service and characteristics
extern const uint8_t MicroBitIOPinServiceUUID[];
extern const uint8_t MicroBitIOPinServiceADConfigurationUUID[];
extern const uint8_t MicroBitIOPinServiceIOConfigurationUUID[];
extern const uint8_t MicroBitIOPinServicePWMControlUUID[];
extern const uint8_t MicroBitIOPinServiceDataUUID[];
extern MicroBitPin * const MicroBitIOPins[];
@ -49,6 +51,16 @@ struct IOData
uint8_t value;
};
/**
* PWM control type definition, as used to set PWM properties of one of more conpatible pins over BLE
*/
struct IOPWMData
{
uint8_t pin;
uint16_t value;
uint32_t period;
} __attribute__((packed));
/**
* Class definition for the custom MicroBit IOPin Service.
* Provides a BLE service to remotely read the state of the I/O Pin, and configure its behaviour.
@ -128,6 +140,7 @@ class MicroBitIOPinService : public MicroBitComponent
// memory for our 8 bit control characteristics.
uint32_t ioPinServiceADCharacteristicBuffer;
uint32_t ioPinServiceIOCharacteristicBuffer;
IOPWMData ioPinServicePWMCharacteristicBuffer[MICROBIT_PWM_PIN_SERVICE_DATA_SIZE];
IOData ioPinServiceDataCharacteristicBuffer[MICROBIT_IO_PIN_SERVICE_DATA_SIZE];
// Historic information about our pin data data.
@ -136,8 +149,8 @@ class MicroBitIOPinService : public MicroBitComponent
// Handles to access each characteristic when they are held by Soft Device.
GattAttribute::Handle_t ioPinServiceADCharacteristicHandle;
GattAttribute::Handle_t ioPinServiceIOCharacteristicHandle;
GattAttribute::Handle_t ioPinServicePWMCharacteristicHandle;
GattCharacteristic *ioPinServiceDataCharacteristic;
};
#endif

@ -49,6 +49,9 @@ MicroBitIOPinService::MicroBitIOPinService(BLEDevice &_ble, MicroBitIO &_io) :
// Create the IO characteristic, that defines whether each pin is treated as input or output
GattCharacteristic ioPinServiceIOCharacteristic(MicroBitIOPinServiceIOConfigurationUUID, (uint8_t *)&ioPinServiceIOCharacteristicBuffer, 0, sizeof(ioPinServiceIOCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
// Create the PWM characteristic, that allows up to 3 compatible pins to be used for PWM
GattCharacteristic ioPinServicePWMCharacteristic(MicroBitIOPinServicePWMControlUUID, (uint8_t *)&ioPinServicePWMCharacteristicBuffer, 0, sizeof(ioPinServicePWMCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
// Create the Data characteristic, that allows the actual read and write operations.
ioPinServiceDataCharacteristic = new GattCharacteristic(MicroBitIOPinServiceDataUUID, (uint8_t *)ioPinServiceDataCharacteristicBuffer, 0, sizeof(ioPinServiceDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
@ -57,22 +60,26 @@ MicroBitIOPinService::MicroBitIOPinService(BLEDevice &_ble, MicroBitIO &_io) :
ioPinServiceADCharacteristicBuffer = 0;
ioPinServiceIOCharacteristicBuffer = 0;
memset(ioPinServiceIOData, 0, sizeof(ioPinServiceIOData));
memset(ioPinServicePWMCharacteristicBuffer, 0, sizeof(ioPinServicePWMCharacteristicBuffer));
// Set default security requirements
ioPinServiceADCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
ioPinServiceIOCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
ioPinServicePWMCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
ioPinServiceDataCharacteristic->requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
GattCharacteristic *characteristics[] = {&ioPinServiceADCharacteristic, &ioPinServiceIOCharacteristic, ioPinServiceDataCharacteristic};
GattCharacteristic *characteristics[] = {&ioPinServiceADCharacteristic, &ioPinServiceIOCharacteristic, &ioPinServicePWMCharacteristic, ioPinServiceDataCharacteristic};
GattService service(MicroBitIOPinServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
ble.addService(service);
ioPinServiceADCharacteristicHandle = ioPinServiceADCharacteristic.getValueHandle();
ioPinServiceIOCharacteristicHandle = ioPinServiceIOCharacteristic.getValueHandle();
ioPinServicePWMCharacteristicHandle = ioPinServicePWMCharacteristic.getValueHandle();
ble.gattServer().write(ioPinServiceADCharacteristicHandle, (const uint8_t *)&ioPinServiceADCharacteristicBuffer, sizeof(ioPinServiceADCharacteristicBuffer));
ble.gattServer().write(ioPinServiceIOCharacteristicHandle, (const uint8_t *)&ioPinServiceIOCharacteristicBuffer, sizeof(ioPinServiceIOCharacteristicBuffer));
ble.gattServer().write(ioPinServicePWMCharacteristicHandle, (const uint8_t *)&ioPinServicePWMCharacteristicBuffer, sizeof(ioPinServicePWMCharacteristicBuffer));
ble.onDataWritten(this, &MicroBitIOPinService::onDataWritten);
fiber_add_idle_component(this);
@ -171,13 +178,40 @@ void MicroBitIOPinService::onDataWritten(const GattWriteCallbackParams *params)
}
}
// Check for writes to the PWM Control characteristic
if (params->handle == ioPinServicePWMCharacteristicHandle)
{
uint16_t len = params->len;
IOPWMData *pwm_data = (IOPWMData *)params->data;
//validate - len must be a multiple of 7 and greater than 0
if (len == 0) {
return;
}
bool is_valid_length = len % 7 == 0;
if (is_valid_length) {
uint8_t field_count = len / 7;
for (int i=0;i<field_count;i++) {
uint8_t pin = pwm_data[i].pin;
uint16_t value = pwm_data[i].value;
uint32_t period = pwm_data[i].period;
io.pin[pin].setAnalogValue(value);
io.pin[pin].setAnalogPeriodUs(period);
}
} else {
// there's no way to return an error response via the current mbed BLE API :-( See https://github.com/ARMmbed/ble/issues/181
return;
}
}
if (params->handle == ioPinServiceDataCharacteristic->getValueHandle())
{
// We have some pin data to change...
uint16_t len = params->len;
IOData *data = (IOData *)params->data;
// There may be multiple write operaitons... take each in turn and update the pin values
// There may be multiple write operations... take each in turn and update the pin values
while (len >= sizeof(IOData))
{
if (isOutput(data->pin))
@ -301,6 +335,10 @@ const uint8_t MicroBitIOPinServiceADConfigurationUUID[] = {
0xe9,0x5d,0x58,0x99,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};
const uint8_t MicroBitIOPinServicePWMControlUUID[] = {
0xe9,0x5d,0xd8,0x22,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};
const uint8_t MicroBitIOPinServiceDataUUID[] = {
0xe9,0x5d,0x8d,0x00,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
};

Loading…
Cancel
Save