sa
Fork of nRF51822 by
Revision 542:1bf9c597f44f, committed 2016-01-11
- Comitter:
- vcoubard
- Date:
- Mon Jan 11 10:19:02 2016 +0000
- Parent:
- 541:884f95bf5351
- Child:
- 543:53215259c0d2
- Commit message:
- Synchronized with git rev e15d59a7
Author: Vincent Coubard
Add Characteristic Descriptor Discovery implementation
Changed in this revision
--- a/module.json Mon Jan 11 10:19:02 2016 +0000 +++ b/module.json Mon Jan 11 10:19:02 2016 +0000 @@ -1,6 +1,6 @@ { "name": "ble-nrf51822", - "version": "2.0.2", + "version": "2.0.3", "description": "Nordic stack and drivers for the mbed BLE API.", "keywords": [ "Bluetooth",
--- a/source/btle/btle.cpp Mon Jan 11 10:19:02 2016 +0000 +++ b/source/btle/btle.cpp Mon Jan 11 10:19:02 2016 +0000 @@ -183,6 +183,7 @@ break; } nRF5xGap::getInstance().processDisconnectionEvent(handle, reason); + // TODO: close pending discoveries break; }
--- a/source/btle/btle_discovery.cpp Mon Jan 11 10:19:02 2016 +0000 +++ b/source/btle/btle_discovery.cpp Mon Jan 11 10:19:02 2016 +0000 @@ -1,99 +1,116 @@ -/* 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 "nRF5xServiceDiscovery.h" -#include "nRF5xGattClient.h" - -#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) -void bleGattcEventHandler(const ble_evt_t *p_ble_evt) -{ - nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery; - - switch (p_ble_evt->header.evt_id) { - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - switch (p_ble_evt->evt.gattc_evt.gatt_status) { - case BLE_GATT_STATUS_SUCCESS: - sdSingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp); - break; - - case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: - default: - sdSingleton.terminate(); - break; - } - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - switch (p_ble_evt->evt.gattc_evt.gatt_status) { - case BLE_GATT_STATUS_SUCCESS: - sdSingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp); - break; - - case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: - default: - sdSingleton.terminateCharacteristicDiscovery(); - break; - } - break; - - case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: - if (sdSingleton.isActive()) { - sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp); - } - break; - - case BLE_GATTC_EVT_READ_RSP: { - GattReadCallbackParams response = { - .connHandle = p_ble_evt->evt.gattc_evt.conn_handle, - .handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle, - .offset = p_ble_evt->evt.gattc_evt.params.read_rsp.offset, - .len = p_ble_evt->evt.gattc_evt.params.read_rsp.len, - .data = p_ble_evt->evt.gattc_evt.params.read_rsp.data, - }; - nRF5xGattClient::getInstance().processReadResponse(&response); - } - break; - - case BLE_GATTC_EVT_WRITE_RSP: { - GattWriteCallbackParams response = { - .connHandle = p_ble_evt->evt.gattc_evt.conn_handle, - .handle = p_ble_evt->evt.gattc_evt.params.write_rsp.handle, - .writeOp = (GattWriteCallbackParams::WriteOp_t)(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op), - .offset = p_ble_evt->evt.gattc_evt.params.write_rsp.offset, - .len = p_ble_evt->evt.gattc_evt.params.write_rsp.len, - .data = p_ble_evt->evt.gattc_evt.params.write_rsp.data, - }; - nRF5xGattClient::getInstance().processWriteResponse(&response); - } - break; - - case BLE_GATTC_EVT_HVX: { - GattHVXCallbackParams params; - params.connHandle = p_ble_evt->evt.gattc_evt.conn_handle; - params.handle = p_ble_evt->evt.gattc_evt.params.hvx.handle; - params.type = static_cast<HVXType_t>(p_ble_evt->evt.gattc_evt.params.hvx.type); - params.len = p_ble_evt->evt.gattc_evt.params.hvx.len; - params.data = p_ble_evt->evt.gattc_evt.params.hvx.data; - - nRF5xGattClient::getInstance().processHVXEvent(¶ms); - } - break; - } - - sdSingleton.progressCharacteristicDiscovery(); - sdSingleton.progressServiceDiscovery(); -} -#endif +/* 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 "nRF5xServiceDiscovery.h" +#include "nRF5xCharacteristicDescriptorDiscoverer.h" +#include "nRF5xGattClient.h" + +#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) +void bleGattcEventHandler(const ble_evt_t *p_ble_evt) +{ + nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery; + nRF5xCharacteristicDescriptorDiscoverer &characteristicDescriptorDiscoverer = + nRF5xGattClient::getInstance().characteristicDescriptorDiscoverer; + + switch (p_ble_evt->header.evt_id) { + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + switch (p_ble_evt->evt.gattc_evt.gatt_status) { + case BLE_GATT_STATUS_SUCCESS: + sdSingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp); + break; + + case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: + default: + sdSingleton.terminate(); + break; + } + break; + + case BLE_GATTC_EVT_CHAR_DISC_RSP: + switch (p_ble_evt->evt.gattc_evt.gatt_status) { + case BLE_GATT_STATUS_SUCCESS: + sdSingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp); + break; + + case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: + default: + sdSingleton.terminateCharacteristicDiscovery(); + break; + } + break; + + case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: + if (sdSingleton.isActive()) { + sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp); + } + break; + + case BLE_GATTC_EVT_READ_RSP: { + GattReadCallbackParams response = { + .connHandle = p_ble_evt->evt.gattc_evt.conn_handle, + .handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle, + .offset = p_ble_evt->evt.gattc_evt.params.read_rsp.offset, + .len = p_ble_evt->evt.gattc_evt.params.read_rsp.len, + .data = p_ble_evt->evt.gattc_evt.params.read_rsp.data, + }; + nRF5xGattClient::getInstance().processReadResponse(&response); + } + break; + + case BLE_GATTC_EVT_WRITE_RSP: { + GattWriteCallbackParams response = { + .connHandle = p_ble_evt->evt.gattc_evt.conn_handle, + .handle = p_ble_evt->evt.gattc_evt.params.write_rsp.handle, + .writeOp = (GattWriteCallbackParams::WriteOp_t)(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op), + .offset = p_ble_evt->evt.gattc_evt.params.write_rsp.offset, + .len = p_ble_evt->evt.gattc_evt.params.write_rsp.len, + .data = p_ble_evt->evt.gattc_evt.params.write_rsp.data, + }; + nRF5xGattClient::getInstance().processWriteResponse(&response); + } + break; + + case BLE_GATTC_EVT_HVX: { + GattHVXCallbackParams params; + params.connHandle = p_ble_evt->evt.gattc_evt.conn_handle; + params.handle = p_ble_evt->evt.gattc_evt.params.hvx.handle; + params.type = static_cast<HVXType_t>(p_ble_evt->evt.gattc_evt.params.hvx.type); + params.len = p_ble_evt->evt.gattc_evt.params.hvx.len; + params.data = p_ble_evt->evt.gattc_evt.params.hvx.data; + + nRF5xGattClient::getInstance().processHVXEvent(¶ms); + } + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: { + uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + + if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { + characteristicDescriptorDiscoverer.terminate(conn_handle); + return; + } + + characteristicDescriptorDiscoverer.process( + conn_handle, + /* discoveredDescriptors */ p_ble_evt->evt.gattc_evt.params.desc_disc_rsp + ); + } break; + } + + sdSingleton.progressCharacteristicDiscovery(); + sdSingleton.progressServiceDiscovery(); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/nRF5xCharacteristicDescriptorDiscoverer.cpp Mon Jan 11 10:19:02 2016 +0000 @@ -0,0 +1,168 @@ +#include "nRF5xCharacteristicDescriptorDiscoverer.h" +#include "ble_err.h" +#include "mbed-drivers/mbed_error.h" +#include "ble/DiscoveredCharacteristicDescriptor.h" + + + +namespace { + void emptyDiscoveryCallback(const CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t*) { } + void emptyTerminationCallback(const CharacteristicDescriptorDiscovery::TerminationCallbackParams_t*) { } +} + +nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount) : + maximumConcurrentConnectionsCount(concurrentConnectionsCount), + discoveryRunning(new Discovery[concurrentConnectionsCount]) { + +} + +nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() { + delete [] discoveryRunning; +} + +ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback +) { + Gap::Handle_t connHandle = characteristic.getConnectionHandle(); + // it is ok to deduce that the start handle for descriptors is after + // the characteristic declaration and the characteristic value declaration + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] (3.3) + Gap::Handle_t descriptorStartHandle = characteristic.getDeclHandle() + 2; + Gap::Handle_t descriptorEndHandle = characteristic.getLastHandle(); + + // check if their is any descriptor to discover + if (descriptorEndHandle < descriptorStartHandle) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = { + characteristic + }; + terminationCallback.call(&termParams); + return BLE_ERROR_NONE; + } + + // check if we can run this discovery + if (isConnectionInUse(connHandle)) { + return BLE_STACK_BUSY; + } + + // get a new discovery slot, if none are available, just return + Discovery* discovery = getAvailableDiscoverySlot(); + if(discovery == NULL) { + return BLE_STACK_BUSY; + } + + // try to launch the discovery + ble_gattc_handle_range_t discoveryRange = { + descriptorStartHandle, + descriptorEndHandle + }; + uint32_t err = sd_ble_gattc_descriptors_discover(characteristic.getConnectionHandle(), &discoveryRange); + switch(err) { + case NRF_SUCCESS: + // commit the new discovery to its slot + *discovery = Discovery( + characteristic, + discoveryCallback, + terminationCallback + ); + + return BLE_ERROR_NONE; + case BLE_ERROR_INVALID_CONN_HANDLE: + return BLE_ERROR_INVALID_PARAM; + case NRF_ERROR_INVALID_ADDR: + return BLE_ERROR_PARAM_OUT_OF_RANGE; + case NRF_ERROR_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} + +bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const { + return findRunningDiscovery(characteristic) != NULL; +} + +void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) { + Discovery* discovery = findRunningDiscovery(characteristic); + if(discovery) { + discovery->onDiscovery = emptyDiscoveryCallback; + // call terminate anyway + discovery->terminate(); + discovery->onTerminate = emptyTerminationCallback; + } +} + +void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) { + Discovery* discovery = findRunningDiscovery(handle); + if(!discovery) { + error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!"); + } + + for (uint16_t i = 0; i < descriptors.count; ++i) { + discovery->process( + descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid) + ); + } +} + +void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle) { + Discovery* discovery = findRunningDiscovery(handle); + if(!discovery) { + error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!"); + } + discovery->terminate(); + removeDiscovery(discovery); +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i].characteristic == characteristic) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i].characteristic == characteristic) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i].characteristic.getConnectionHandle() == handle) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +void nRF5xCharacteristicDescriptorDiscoverer::removeDiscovery(Discovery* discovery) { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(&discoveryRunning[i] == discovery) { + discoveryRunning[i] = Discovery(); + } + } +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i] == Discovery()) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) { + return findRunningDiscovery(connHandle) != NULL; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/nRF5xCharacteristicDescriptorDiscoverer.h Mon Jan 11 10:19:02 2016 +0000 @@ -0,0 +1,133 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 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 __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ +#define __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ + +#include "ble/Gap.h" +#include "ble/DiscoveredCharacteristic.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "ble/GattClient.h" +#include "ble_gattc.h" + +/** + * @brief Manage the discovery of Characteristic descriptors + * @details is a bridge beetween BLE API and nordic stack regarding Characteristic + * Descriptor discovery. The BLE API can launch, monitorate and ask for termination + * of a discovery. The nordic stack will provide new descriptors and indicate when + * the discovery is done + */ +class nRF5xCharacteristicDescriptorDiscoverer +{ + typedef CharacteristicDescriptorDiscovery::DiscoveryCallback_t DiscoveryCallback_t; + typedef CharacteristicDescriptorDiscovery::TerminationCallback_t TerminationCallback_t; + +public: + nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount = 3); + + ~nRF5xCharacteristicDescriptorDiscoverer(); + + /** + * Launch a new characteristic descriptor discovery for a given + * DiscoveredCharacteristic. + * @note: this will be called by BLE API side + */ + ble_error_t launch( + const DiscoveredCharacteristic& characteristic, + const DiscoveryCallback_t& callback, + const TerminationCallback_t& terminationCallback + ); + + /** + * @brief indicate if a characteristic descriptor discovery is active for a + * given DiscoveredCharacteristic + * @note: this will be called by BLE API side + */ + bool isActive(const DiscoveredCharacteristic& characteristic) const; + + /** + * @brief reauest the termination of characteristic descriptor discovery + * for a give DiscoveredCharacteristic + * @note: this will be called by BLE API side + */ + void requestTerminate(const DiscoveredCharacteristic& characteristic); + + /** + * @brief process descriptors discovered from the nordic stack + */ + void process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors); + + /** + * @brief Called by the nordic stack when the discovery is over. + */ + void terminate(uint16_t handle); + +private: + nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&); + nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&); + + struct Discovery { + Discovery() : characteristic(), onDiscovery(), onTerminate() { } + + Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) : + characteristic(c), + onDiscovery(dCb), + onTerminate(tCb) { + } + + DiscoveredCharacteristic characteristic; + DiscoveryCallback_t onDiscovery; + TerminationCallback_t onTerminate; + + void process(GattAttribute::Handle_t handle, const UUID& uuid) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + characteristic, + DiscoveredCharacteristicDescriptor( + characteristic.getGattClient(), + characteristic.getConnectionHandle(), + handle, + uuid + ) + }; + onDiscovery.call(¶ms); + } + + void terminate() { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + characteristic + }; + onTerminate.call(¶ms); + } + + friend bool operator==(const Discovery& lhs, const Discovery& rhs) { + return lhs.characteristic == rhs.characteristic && + lhs.onDiscovery == rhs.onDiscovery && + lhs.onTerminate == lhs.onTerminate; + } + }; + + Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic); + Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const; + Discovery* findRunningDiscovery(uint16_t handle); + void removeDiscovery(Discovery* discovery); + Discovery* getAvailableDiscoverySlot(); + bool isConnectionInUse(uint16_t connHandle); + + size_t maximumConcurrentConnectionsCount; + Discovery *discoveryRunning; +}; + +#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/ \ No newline at end of file
--- a/source/nRF5xGattClient.cpp Mon Jan 11 10:19:02 2016 +0000 +++ b/source/nRF5xGattClient.cpp Mon Jan 11 10:19:02 2016 +0000 @@ -1,38 +1,59 @@ -/* 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 "nRF5xGattClient.h" - -nRF5xGattClient & -nRF5xGattClient::getInstance(void) { - static nRF5xGattClient* nRFGattClientSingleton = NULL; - if (nRFGattClientSingleton == NULL) { - nRFGattClientSingleton = new nRF5xGattClient(); - } - return *nRFGattClientSingleton; -} - -#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) -ble_error_t -nRF5xGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t sc, - ServiceDiscovery::CharacteristicCallback_t cc, - const UUID &matchingServiceUUIDIn, - const UUID &matchingCharacteristicUUIDIn) -{ - return discovery.launch(connectionHandle, sc, cc, matchingServiceUUIDIn, matchingCharacteristicUUIDIn); -} +/* 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 "nRF5xGattClient.h" + +nRF5xGattClient & +nRF5xGattClient::getInstance(void) { + static nRF5xGattClient* nRFGattClientSingleton = NULL; + if (nRFGattClientSingleton == NULL) { + nRFGattClientSingleton = new nRF5xGattClient(); + } + return *nRFGattClientSingleton; +} + +#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) +ble_error_t +nRF5xGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUIDIn, + const UUID &matchingCharacteristicUUIDIn) +{ + return discovery.launch(connectionHandle, sc, cc, matchingServiceUUIDIn, matchingCharacteristicUUIDIn); +} + +ble_error_t nRF5xGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + CharacteristicDescriptorDiscovery::DiscoveryCallback_t discoveryCallback, + CharacteristicDescriptorDiscovery::TerminationCallback_t terminationCallback) +{ + return characteristicDescriptorDiscoverer.launch( + characteristic, + discoveryCallback, + terminationCallback + ); +} + +bool nRF5xGattClient::isCharacteristicDiscoveryActive(const DiscoveredCharacteristic& characteristic) const { + return characteristicDescriptorDiscoverer.isActive(characteristic); +} + +void nRF5xGattClient::terminateCharacteristicDiscovery(const DiscoveredCharacteristic& characteristic) { + return characteristicDescriptorDiscoverer.requestTerminate(characteristic); +} + #endif \ No newline at end of file
--- a/source/nRF5xGattClient.h Mon Jan 11 10:19:02 2016 +0000 +++ b/source/nRF5xGattClient.h Mon Jan 11 10:19:02 2016 +0000 @@ -1,167 +1,191 @@ -/* 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 __NRF51822_GATT_CLIENT_H__ -#define __NRF51822_GATT_CLIENT_H__ - -#include "ble/GattClient.h" -#include "nRF5xServiceDiscovery.h" - -class nRF5xGattClient : public GattClient -{ -public: - static nRF5xGattClient &getInstance(); - - /** - * When using S110, all Gatt client features will return - * BLE_ERROR_NOT_IMPLEMENTED - */ -#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) - - /** - * Launch service discovery. Once launched, service discovery will remain - * active with callbacks being issued back into the application for matching - * services/characteristics. isActive() can be used to determine status; and - * a termination callback (if setup) will be invoked at the end. Service - * discovery can be terminated prematurely if needed using terminate(). - * - * @param connectionHandle - * Handle for the connection with the peer. - * @param sc - * This is the application callback for matching service. Taken as - * NULL by default. Note: service discovery may still be active - * when this callback is issued; calling asynchronous BLE-stack - * APIs from within this application callback might cause the - * stack to abort service discovery. If this becomes an issue, it - * may be better to make local copy of the discoveredService and - * wait for service discovery to terminate before operating on the - * service. - * @param cc - * This is the application callback for matching characteristic. - * Taken as NULL by default. Note: service discovery may still be - * active when this callback is issued; calling asynchronous - * BLE-stack APIs from within this application callback might cause - * the stack to abort service discovery. If this becomes an issue, - * it may be better to make local copy of the discoveredCharacteristic - * and wait for service discovery to terminate before operating on the - * characteristic. - * @param matchingServiceUUID - * UUID based filter for specifying a service in which the application is - * interested. By default it is set as the wildcard UUID_UNKNOWN, - * in which case it matches all services. If characteristic-UUID - * filter (below) is set to the wildcard value, then a service - * callback will be invoked for the matching service (or for every - * service if the service filter is a wildcard). - * @param matchingCharacteristicUUIDIn - * UUID based filter for specifying characteristic in which the application - * is interested. By default it is set as the wildcard UUID_UKNOWN - * to match against any characteristic. If both service-UUID - * filter and characteristic-UUID filter are used with non- wildcard - * values, then only a single characteristic callback is - * invoked for the matching characteristic. - * - * @Note Using wildcard values for both service-UUID and characteristic- - * UUID will result in complete service discovery--callbacks being - * called for every service and characteristic. - * - * @return - * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. - */ - virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t sc = NULL, - ServiceDiscovery::CharacteristicCallback_t cc = NULL, - const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), - const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); - - virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { - discovery.onTermination(callback); - } - - /** - * Is service-discovery currently active? - */ - virtual bool isServiceDiscoveryActive(void) const { - return discovery.isActive(); - } - - /** - * Terminate an ongoing service-discovery. This should result in an - * invocation of the TerminationCallback if service-discovery is active. - */ - virtual void terminateServiceDiscovery(void) { - discovery.terminate(); - } - - virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { - uint32_t rc = sd_ble_gattc_read(connHandle, attributeHandle, offset); - if (rc == NRF_SUCCESS) { - return BLE_ERROR_NONE; - } - switch (rc) { - case NRF_ERROR_BUSY: - return BLE_STACK_BUSY; - case BLE_ERROR_INVALID_CONN_HANDLE: - case NRF_ERROR_INVALID_STATE: - case NRF_ERROR_INVALID_ADDR: - default: - return BLE_ERROR_INVALID_STATE; - } - } - - virtual ble_error_t write(GattClient::WriteOp_t cmd, Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, size_t length, const uint8_t *value) const { - ble_gattc_write_params_t writeParams; - writeParams.write_op = cmd; - writeParams.flags = 0; /* this is inconsequential */ - writeParams.handle = attributeHandle; - writeParams.offset = 0; - writeParams.len = length; - writeParams.p_value = const_cast<uint8_t *>(value); - - uint32_t rc = sd_ble_gattc_write(connHandle, &writeParams); - if (rc == NRF_SUCCESS) { - return BLE_ERROR_NONE; - } - switch (rc) { - case NRF_ERROR_BUSY: - return BLE_STACK_BUSY; - case BLE_ERROR_NO_TX_BUFFERS: - return BLE_ERROR_NO_MEM; - case BLE_ERROR_INVALID_CONN_HANDLE: - case NRF_ERROR_INVALID_STATE: - case NRF_ERROR_INVALID_ADDR: - default: - return BLE_ERROR_INVALID_STATE; - } - } - -public: - nRF5xGattClient() : discovery(this) { - /* empty */ - } - - friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); - -private: - nRF5xGattClient(const nRF5xGattClient &); - const nRF5xGattClient& operator=(const nRF5xGattClient &); - -private: - nRF5xServiceDiscovery discovery; - -#endif // if !S110 -}; - +/* 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 __NRF51822_GATT_CLIENT_H__ +#define __NRF51822_GATT_CLIENT_H__ + +#include "ble/GattClient.h" +#include "nRF5xServiceDiscovery.h" +#include "nRF5xCharacteristicDescriptorDiscoverer.h" + +class nRF5xGattClient : public GattClient +{ +public: + static nRF5xGattClient &getInstance(); + + /** + * When using S110, all Gatt client features will return + * BLE_ERROR_NOT_IMPLEMENTED + */ +#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) + + /** + * Launch service discovery. Once launched, service discovery will remain + * active with callbacks being issued back into the application for matching + * services/characteristics. isActive() can be used to determine status; and + * a termination callback (if setup) will be invoked at the end. Service + * discovery can be terminated prematurely if needed using terminate(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Taken as + * NULL by default. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param cc + * This is the application callback for matching characteristic. + * Taken as NULL by default. Note: service discovery may still be + * active when this callback is issued; calling asynchronous + * BLE-stack APIs from within this application callback might cause + * the stack to abort service discovery. If this becomes an issue, + * it may be better to make local copy of the discoveredCharacteristic + * and wait for service discovery to terminate before operating on the + * characteristic. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. By default it is set as the wildcard UUID_UNKNOWN, + * in which case it matches all services. If characteristic-UUID + * filter (below) is set to the wildcard value, then a service + * callback will be invoked for the matching service (or for every + * service if the service filter is a wildcard). + * @param matchingCharacteristicUUIDIn + * UUID based filter for specifying characteristic in which the application + * is interested. By default it is set as the wildcard UUID_UKNOWN + * to match against any characteristic. If both service-UUID + * filter and characteristic-UUID filter are used with non- wildcard + * values, then only a single characteristic callback is + * invoked for the matching characteristic. + * + * @Note Using wildcard values for both service-UUID and characteristic- + * UUID will result in complete service discovery--callbacks being + * called for every service and characteristic. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { + discovery.onTermination(callback); + } + + /** + * Is service-discovery currently active? + */ + virtual bool isServiceDiscoveryActive(void) const { + return discovery.isActive(); + } + + /** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ + virtual void terminateServiceDiscovery(void) { + discovery.terminate(); + } + + /** + * @brief Implementation of GattClient::discoverCharacteristicDescriptors + * @see GattClient::discoverCharacteristicDescriptors + */ + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + CharacteristicDescriptorDiscovery::DiscoveryCallback_t discoveryCallback, + CharacteristicDescriptorDiscovery::TerminationCallback_t terminationCallback + ); + + /** + * @brief Implementation of GattClient::isCharacteristicDiscoveryActive + * @see GattClient::isCharacteristicDiscoveryActive + */ + virtual bool isCharacteristicDiscoveryActive(const DiscoveredCharacteristic& characteristic) const; + + /** + * @brief Implementation of GattClient::terminateCharacteristicDiscovery + * @see GattClient::terminateCharacteristicDiscovery + */ + virtual void terminateCharacteristicDiscovery(const DiscoveredCharacteristic& characteristic); + + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { + uint32_t rc = sd_ble_gattc_read(connHandle, attributeHandle, offset); + if (rc == NRF_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (rc) { + case NRF_ERROR_BUSY: + return BLE_STACK_BUSY; + case BLE_ERROR_INVALID_CONN_HANDLE: + case NRF_ERROR_INVALID_STATE: + case NRF_ERROR_INVALID_ADDR: + default: + return BLE_ERROR_INVALID_STATE; + } + } + + virtual ble_error_t write(GattClient::WriteOp_t cmd, Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, size_t length, const uint8_t *value) const { + ble_gattc_write_params_t writeParams; + writeParams.write_op = cmd; + writeParams.flags = 0; /* this is inconsequential */ + writeParams.handle = attributeHandle; + writeParams.offset = 0; + writeParams.len = length; + writeParams.p_value = const_cast<uint8_t *>(value); + + uint32_t rc = sd_ble_gattc_write(connHandle, &writeParams); + if (rc == NRF_SUCCESS) { + return BLE_ERROR_NONE; + } + switch (rc) { + case NRF_ERROR_BUSY: + return BLE_STACK_BUSY; + case BLE_ERROR_NO_TX_BUFFERS: + return BLE_ERROR_NO_MEM; + case BLE_ERROR_INVALID_CONN_HANDLE: + case NRF_ERROR_INVALID_STATE: + case NRF_ERROR_INVALID_ADDR: + default: + return BLE_ERROR_INVALID_STATE; + } + } + +public: + nRF5xGattClient() : discovery(this) { + /* empty */ + } + + friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); + +private: + nRF5xGattClient(const nRF5xGattClient &); + const nRF5xGattClient& operator=(const nRF5xGattClient &); + +private: + nRF5xServiceDiscovery discovery; + nRF5xCharacteristicDescriptorDiscoverer characteristicDescriptorDiscoverer; + +#endif // if !S110 +}; + #endif // ifndef __NRF51822_GATT_CLIENT_H__ \ No newline at end of file
--- a/source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h Mon Jan 11 10:19:02 2016 +0000 +++ b/source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h Mon Jan 11 10:19:02 2016 +0000 @@ -1,319 +1,299 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @defgroup nrf_wdt_hal WDT HAL - * @{ - * @ingroup nrf_wdt - * - * @brief Hardware abstraction layer for accessing the watchdog timer (WDT) peripheral. - */ - -#ifndef NRF_WDT_H__ -#define NRF_WDT_H__ - -#include <stddef.h> -#include <stdbool.h> -#include <stdint.h> - -#include "nrf.h" - -#define NRF_WDT_CHANNEL_NUMBER 0x8UL -#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/ - -#define NRF_WDT_TASK_SET 1UL -#define NRF_WDT_EVENT_CLEAR 0UL - -/** - * @enum nrf_wdt_task_t - * @brief WDT tasks. - */ -typedef enum -{ - /*lint -save -e30 -esym(628,__INTADDR__)*/ - NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */ - /*lint -restore*/ -} nrf_wdt_task_t; - -/** - * @enum nrf_wdt_event_t - * @brief WDT events. - */ -typedef enum -{ - /*lint -save -e30*/ - NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */ - /*lint -restore*/ -} nrf_wdt_event_t; - -/** - * @enum nrf_wdt_behaviour_t - * @brief WDT behavior in CPU SLEEP or HALT mode. - */ -typedef enum -{ - NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */ - NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */ - NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */ - NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */ -} nrf_wdt_behaviour_t; - -/** - * @enum nrf_wdt_rr_register_t - * @brief WDT reload request registers. - */ -typedef enum -{ - NRF_WDT_RR0 = 0, /**< Reload request register 0. */ - NRF_WDT_RR1, /**< Reload request register 1. */ - NRF_WDT_RR2, /**< Reload request register 2. */ - NRF_WDT_RR3, /**< Reload request register 3. */ - NRF_WDT_RR4, /**< Reload request register 4. */ - NRF_WDT_RR5, /**< Reload request register 5. */ - NRF_WDT_RR6, /**< Reload request register 6. */ - NRF_WDT_RR7 /**< Reload request register 7. */ -} nrf_wdt_rr_register_t; - -/** - * @enum nrf_wdt_int_mask_t - * @brief WDT interrupts. - */ -typedef enum -{ - NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */ -} nrf_wdt_int_mask_t; - -/** - * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted. - * - * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode. - */ -__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour) -{ - NRF_WDT->CONFIG = behaviour; -} - - -/** - * @brief Function for starting the watchdog. - * - * @param[in] task Task. - */ -__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task) -{ - *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET; -} - - -/** - * @brief Function for clearing the WDT event. - * - * @param[in] event Event. - */ -__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event) -{ - *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR; -} - - -/** - * @brief Function for retrieving the state of the WDT event. - * - * @param[in] event Event. - * - * @retval true If the event is set. - * @retval false If the event is not set. - */ -__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event) -{ - return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event)); -} - - -/** - * @brief Function for enabling a specific interrupt. - * - * @param[in] int_mask Interrupt. - */ -__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask) -{ - NRF_WDT->INTENSET = int_mask; -} - - -/** - * @brief Function for retrieving the state of given interrupt. - * - * @param[in] int_mask Interrupt. - * - * @retval true Interrupt is enabled. - * @retval false Interrupt is not enabled. - */ -__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask) -{ - return (bool)(NRF_WDT->INTENSET & int_mask); -} - - -/** - * @brief Function for disabling a specific interrupt. - * - * @param[in] int_mask Interrupt. - */ -__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask) -{ - NRF_WDT->INTENCLR = int_mask; -} - - -/** - * @brief Function for returning the address of a specific WDT task register. - * - * @param[in] task Task. - */ -__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task) -{ - return ((uint32_t)NRF_WDT + task); -} - - -/** - * @brief Function for returning the address of a specific WDT event register. - * - * @param[in] event Event. - * - * @retval address of requested event register - */ -__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event) -{ - return ((uint32_t)NRF_WDT + event); -} - - -/** - * @brief Function for retrieving the watchdog status. - * - * @retval true If the watchdog is started. - * @retval false If the watchdog is not started. - */ -__STATIC_INLINE bool nrf_wdt_started(void) -{ - return (bool)(NRF_WDT->RUNSTATUS); -} - - -/** - * @brief Function for retrieving the watchdog reload request status. - * - * @param[in] rr_register Reload request register to check. - * - * @retval true If a reload request is running. - * @retval false If no reload request is running. - */ -__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register) -{ - return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL); -} - - -/** - * @brief Function for setting the watchdog reload value. - * - * @param[in] reload_value Watchdog counter initial value. - */ -__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value) -{ - NRF_WDT->CRV = reload_value; -} - - -/** - * @brief Function for retrieving the watchdog reload value. - * - * @retval Reload value. - */ -__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void) -{ - return (uint32_t)NRF_WDT->CRV; -} - - -/** - * @brief Function for enabling a specific reload request register. - * - * @param[in] rr_register Reload request register to enable. - */ -__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register) -{ - NRF_WDT->RREN |= 0x1UL << rr_register; -} - - -/** - * @brief Function for disabling a specific reload request register. - * - * @param[in] rr_register Reload request register to disable. - */ -__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register) -{ - NRF_WDT->RREN &= ~(0x1UL << rr_register); -} - - -/** - * @brief Function for retrieving the status of a specific reload request register. - * - * @param[in] rr_register Reload request register to check. - * - * @retval true If the reload request register is enabled. - * @retval false If the reload request register is not enabled. - */ -__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register) -{ - return (bool)(NRF_WDT->RREN & (0x1UL << rr_register)); -} - - -/** - * @brief Function for setting a specific reload request register. - * - * @param[in] rr_register Reload request register to set. - */ -__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register) -{ - NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE; -} - - -#endif - +/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Nordic Semiconductor ASA. + * Terms and conditions of usage are described in detail in NORDIC + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ + +/** + * @defgroup nrf_wdt_hal WDT HAL + * @{ + * @ingroup nrf_wdt + * + * @brief Hardware abstraction layer for accessing the watchdog timer (WDT) peripheral. + */ + +#ifndef NRF_WDT_H__ +#define NRF_WDT_H__ + +#include <stddef.h> +#include <stdbool.h> +#include <stdint.h> + +#include "nrf.h" + +#define NRF_WDT_CHANNEL_NUMBER 0x8UL +#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/ + +#define NRF_WDT_TASK_SET 1UL +#define NRF_WDT_EVENT_CLEAR 0UL + +/** + * @enum nrf_wdt_task_t + * @brief WDT tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */ + /*lint -restore*/ +} nrf_wdt_task_t; + +/** + * @enum nrf_wdt_event_t + * @brief WDT events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */ + /*lint -restore*/ +} nrf_wdt_event_t; + +/** + * @enum nrf_wdt_behaviour_t + * @brief WDT behavior in CPU SLEEP or HALT mode. + */ +typedef enum +{ + NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */ + NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */ + NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */ + NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */ +} nrf_wdt_behaviour_t; + +/** + * @enum nrf_wdt_rr_register_t + * @brief WDT reload request registers. + */ +typedef enum +{ + NRF_WDT_RR0 = 0, /**< Reload request register 0. */ + NRF_WDT_RR1, /**< Reload request register 1. */ + NRF_WDT_RR2, /**< Reload request register 2. */ + NRF_WDT_RR3, /**< Reload request register 3. */ + NRF_WDT_RR4, /**< Reload request register 4. */ + NRF_WDT_RR5, /**< Reload request register 5. */ + NRF_WDT_RR6, /**< Reload request register 6. */ + NRF_WDT_RR7 /**< Reload request register 7. */ +} nrf_wdt_rr_register_t; + +/** + * @enum nrf_wdt_int_mask_t + * @brief WDT interrupts. + */ +typedef enum +{ + NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */ +} nrf_wdt_int_mask_t; + +/** + * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted. + * + * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode. + */ +__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour) +{ + NRF_WDT->CONFIG = behaviour; +} + + +/** + * @brief Function for starting the watchdog. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET; +} + + +/** + * @brief Function for clearing the WDT event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR; +} + + +/** + * @brief Function for retrieving the state of the WDT event. + * + * @param[in] event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event)); +} + + +/** + * @brief Function for enabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask) +{ + NRF_WDT->INTENSET = int_mask; +} + + +/** + * @brief Function for retrieving the state of given interrupt. + * + * @param[in] int_mask Interrupt. + * + * @retval true Interrupt is enabled. + * @retval false Interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask) +{ + return (bool)(NRF_WDT->INTENSET & int_mask); +} + + +/** + * @brief Function for disabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask) +{ + NRF_WDT->INTENCLR = int_mask; +} + + +/** + * @brief Function for returning the address of a specific WDT task register. + * + * @param[in] task Task. + */ +__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task) +{ + return ((uint32_t)NRF_WDT + task); +} + + +/** + * @brief Function for returning the address of a specific WDT event register. + * + * @param[in] event Event. + * + * @retval address of requested event register + */ +__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event) +{ + return ((uint32_t)NRF_WDT + event); +} + + +/** + * @brief Function for retrieving the watchdog status. + * + * @retval true If the watchdog is started. + * @retval false If the watchdog is not started. + */ +__STATIC_INLINE bool nrf_wdt_started(void) +{ + return (bool)(NRF_WDT->RUNSTATUS); +} + + +/** + * @brief Function for retrieving the watchdog reload request status. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If a reload request is running. + * @retval false If no reload request is running. + */ +__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL); +} + + +/** + * @brief Function for setting the watchdog reload value. + * + * @param[in] reload_value Watchdog counter initial value. + */ +__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value) +{ + NRF_WDT->CRV = reload_value; +} + + +/** + * @brief Function for retrieving the watchdog reload value. + * + * @retval Reload value. + */ +__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void) +{ + return (uint32_t)NRF_WDT->CRV; +} + + +/** + * @brief Function for enabling a specific reload request register. + * + * @param[in] rr_register Reload request register to enable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN |= 0x1UL << rr_register; +} + + +/** + * @brief Function for disabling a specific reload request register. + * + * @param[in] rr_register Reload request register to disable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN &= ~(0x1UL << rr_register); +} + + +/** + * @brief Function for retrieving the status of a specific reload request register. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If the reload request register is enabled. + * @retval false If the reload request register is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(NRF_WDT->RREN & (0x1UL << rr_register)); +} + + +/** + * @brief Function for setting a specific reload request register. + * + * @param[in] rr_register Reload request register to set. + */ +__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE; +} + + +#endif + /** @} */ \ No newline at end of file