Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of LinkNode-Test by
nRF5xGap.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __NRF5x_GAP_H__ 00018 #define __NRF5x_GAP_H__ 00019 00020 #include "mbed.h" 00021 #include "ble/blecommon.h" 00022 #include "ble.h" 00023 #include "ble/GapAdvertisingParams.h" 00024 #include "ble/GapAdvertisingData.h" 00025 #include "ble/Gap.h" 00026 #include "ble/GapScanningParams.h" 00027 00028 #include "nrf_soc.h" 00029 00030 extern "C" { 00031 #include "ble_radio_notification.h " 00032 } 00033 00034 #include "btle_security.h" 00035 00036 void radioNotificationStaticCallback(bool param); 00037 00038 /**************************************************************************/ 00039 /*! 00040 \brief 00041 00042 */ 00043 /**************************************************************************/ 00044 class nRF5xGap : public Gap 00045 { 00046 public: 00047 static nRF5xGap &getInstance(); 00048 00049 /* Functions that must be implemented from Gap */ 00050 virtual ble_error_t setAddress(AddressType_t type, const Address_t address); 00051 virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address); 00052 virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &); 00053 00054 virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MIN);} 00055 virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);} 00056 virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MAX);} 00057 00058 virtual ble_error_t startAdvertising(const GapAdvertisingParams &); 00059 virtual ble_error_t stopAdvertising(void); 00060 virtual ble_error_t connect(const Address_t, Gap::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams); 00061 virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason); 00062 virtual ble_error_t disconnect(DisconnectionReason_t reason); 00063 00064 virtual ble_error_t setDeviceName(const uint8_t *deviceName); 00065 virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); 00066 virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance); 00067 virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP); 00068 00069 virtual ble_error_t setTxPower(int8_t txPower); 00070 virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP); 00071 00072 void setConnectionHandle(uint16_t con_handle); 00073 uint16_t getConnectionHandle(void); 00074 00075 virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); 00076 virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); 00077 virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); 00078 00079 virtual ble_error_t initRadioNotification(void) { 00080 if (ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationStaticCallback) == NRF_SUCCESS) { 00081 return BLE_ERROR_NONE; 00082 } 00083 00084 return BLE_ERROR_UNSPECIFIED; 00085 } 00086 00087 /* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */ 00088 #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) 00089 virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) { 00090 ble_gap_scan_params_t scanParams = { 00091 .active = scanningParams.getActiveScanning(), /**< If 1, perform active scanning (scan requests). */ 00092 .selective = 0, /**< If 1, ignore unknown devices (non whitelisted). */ 00093 .p_whitelist = NULL, /**< Pointer to whitelist, NULL if none is given. */ 00094 .interval = scanningParams.getInterval(), /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00095 .window = scanningParams.getWindow(), /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ 00096 .timeout = scanningParams.getTimeout(), /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ 00097 }; 00098 00099 if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) { 00100 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00101 } 00102 00103 return BLE_ERROR_NONE; 00104 } 00105 00106 virtual ble_error_t stopScan(void) { 00107 if (sd_ble_gap_scan_stop() == NRF_SUCCESS) { 00108 return BLE_ERROR_NONE; 00109 } 00110 00111 return BLE_STACK_BUSY; 00112 } 00113 #endif 00114 00115 private: 00116 bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */ 00117 Timeout radioNotificationTimeout; 00118 00119 /* 00120 * A helper function to post radio notification callbacks with low interrupt priority. 00121 */ 00122 void postRadioNotificationCallback(void) { 00123 #ifdef YOTTA_CFG_MBED_OS 00124 /* 00125 * In mbed OS, all user-facing BLE events (interrupts) are posted to the 00126 * MINAR scheduler to be executed as callbacks in thread mode. MINAR guards 00127 * its critical sections from interrupts by acquiring CriticalSectionLock, 00128 * which results in a call to sd_nvic_critical_region_enter(). Thus, it is 00129 * safe to invoke MINAR APIs from interrupt context as long as those 00130 * interrupts are blocked by sd_nvic_critical_region_enter(). 00131 * 00132 * Radio notifications are a special case for the above. The Radio 00133 * Notification IRQ is handled at a very high priority--higher than the 00134 * level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification 00135 * events can preempt MINAR's critical sections. Using MINAR APIs (such as 00136 * posting an event) directly in processRadioNotification() may result in a 00137 * race condition ending in a hard-fault. 00138 * 00139 * The solution is to *not* call MINAR APIs directly from the Radio 00140 * Notification handling; i.e. to do the bulk of RadioNotification 00141 * processing at a reduced priority which respects MINAR's critical 00142 * sections. Unfortunately, on a cortex-M0, there is no clean way to demote 00143 * priority for the currently executing interrupt--we wouldn't want to 00144 * demote the radio notification handling anyway because it is sensitive to 00145 * timing, and the system expects to finish this handling very quickly. The 00146 * workaround is to employ a Timeout to trigger 00147 * postRadioNotificationCallback() after a very short delay (~0 us) and post 00148 * the MINAR callback that context. 00149 * 00150 * !!!WARNING!!! Radio notifications are very time critical events. The 00151 * current solution is expected to work under the assumption that 00152 * postRadioNotificationCalback() will be executed BEFORE the next radio 00153 * notification event is generated. 00154 */ 00155 minar::Scheduler::postCallback( 00156 mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam) 00157 ); 00158 #else 00159 /* 00160 * In mbed classic, all user-facing BLE events execute callbacks in interrupt 00161 * mode. Radio Notifications are a special case because its IRQ is handled at 00162 * a very high priority. Thus Radio Notification events can preempt other 00163 * operations that require interaction with the SoftDevice such as advertising 00164 * payload updates and changing the Gap state. Therefore, executing a Radio 00165 * Notification callback directly from processRadioNotification() may result 00166 * in a race condition ending in a hard-fault. 00167 * 00168 * The solution is to *not* execute the Radio Notification callback directly 00169 * from the Radio Notification handling; i.e. to do the bulk of the 00170 * Radio Notification processing at a reduced priority. Unfortunately, on a 00171 * cortex-M0, there is no clean way to demote priority for the currently 00172 * executing interrupt--we wouldn't want to demote the radio notification 00173 * handling anyway because it is sensitive to timing, and the system expects 00174 * to finish this handling very quickly. The workaround is to employ a Timeout 00175 * to trigger postRadioNotificationCallback() after a very short delay (~0 us) 00176 * and execute the callback in that context. 00177 * 00178 * !!!WARNING!!! Radio notifications are very time critical events. The 00179 * current solution is expected to work under the assumption that 00180 * postRadioNotificationCalback() will be executed BEFORE the next radio 00181 * notification event is generated. 00182 */ 00183 radioNotificationCallback.call(radioNotificationCallbackParam); 00184 #endif /* #ifdef YOTTA_CFG_MBED_OS */ 00185 } 00186 00187 /** 00188 * A helper function to process radio-notification events; to be called internally. 00189 * @param param [description] 00190 */ 00191 void processRadioNotificationEvent(bool param) { 00192 radioNotificationCallbackParam = param; 00193 radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0); 00194 } 00195 friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */ 00196 00197 private: 00198 uint16_t m_connectionHandle; 00199 nRF5xGap() { 00200 m_connectionHandle = BLE_CONN_HANDLE_INVALID; 00201 } 00202 00203 nRF5xGap(nRF5xGap const &); 00204 void operator=(nRF5xGap const &); 00205 }; 00206 00207 #endif // ifndef __NRF5x_GAP_H__
Generated on Tue Jul 12 2022 16:00:20 by
