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.
Dependencies: max32630fthr Adafruit_FeatherOLED USBDevice
BLE_ICARUS.cpp
00001 /******************************************************************************* 00002 * Copyright (C) Maxim Integrated Products, Inc., All rights Reserved. 00003 * 00004 * This software is protected by copyright laws of the United States and 00005 * of foreign countries. This material may also be protected by patent laws 00006 * and technology transfer regulations of the United States and of foreign 00007 * countries. This software is furnished under a license agreement and/or a 00008 * nondisclosure agreement and may only be used or reproduced in accordance 00009 * with the terms of those agreements. Dissemination of this information to 00010 * any party or parties not specified in the license agreement and/or 00011 * nondisclosure agreement is expressly prohibited. 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00017 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00019 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00020 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00021 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00022 * OTHER DEALINGS IN THE SOFTWARE. 00023 * 00024 * Except as contained in this notice, the name of Maxim Integrated 00025 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00026 * Products, Inc. Branding Policy. 00027 * 00028 * The mere transfer of this software does not imply any licenses 00029 * of trade secrets, proprietary technology, copyrights, patents, 00030 * trademarks, maskwork rights, or any other form of intellectual 00031 * property whatsoever. Maxim Integrated Products, Inc. retains all 00032 * ownership rights. 00033 ******************************************************************************* 00034 */ 00035 00036 #include "BLE_ICARUS.h" 00037 00038 #include "../../Utilities/mxm_assert.h" 00039 #include "queue.h" 00040 #include "Peripherals.h" 00041 #include "../../version.h" 00042 00043 00044 UUID customServiceUUID("00001523-1212-efde-1523-785feabcd123"); 00045 UUID notifyCharUUID( "00001011-1212-efde-1523-785feabcd123"); 00046 UUID configRWCharUUID("00001027-1212-efde-1523-785feabcd123"); 00047 00048 const static char DEVICE_NAME[] = FIRMWARE_VERSION; 00049 static const uint16_t uuid16_list[] = {0xFFFF}; //Custom UUID, FFFF is reserved for development 00050 00051 // BLE defines 00052 #define BLE_TICKER_PERIOD 0.050 //Ticker period in order of seconds 00053 #define BLE_CONN_INT_PACKET 2 //Ticker period in order of seconds 00054 #define BLE_NOTIFY_CHAR_ARR_SIZE 20 00055 #define BLE_READWRITE_CHAR_ARR_SIZE 16 00056 #define MAX_BLE_QUEUE 128 00057 // end of BLE defines 00058 00059 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER) 00060 Ticker TICKER_BLE; 00061 static volatile unsigned char BLE_CAN_TRANSFER = 0; 00062 00063 static void Ble_Can_Transfer_Toggle(){ 00064 BLE_CAN_TRANSFER = true; 00065 } 00066 00067 static inline char Ble_Can_Transfer_Check(){ 00068 return BLE_CAN_TRANSFER; 00069 } 00070 00071 static inline void Ble_Can_Transfer_Set(unsigned char en){ 00072 BLE_CAN_TRANSFER = en; 00073 } 00074 00075 #endif 00076 00077 /* Set Up custom Characteristics */ 00078 static uint8_t notifyValue[BLE_NOTIFY_CHAR_ARR_SIZE] = {0}; 00079 GattCharacteristic notifyChar(notifyCharUUID, notifyValue, BLE_NOTIFY_CHAR_ARR_SIZE, BLE_NOTIFY_CHAR_ARR_SIZE, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); 00080 00081 static uint8_t configValue[BLE_READWRITE_CHAR_ARR_SIZE] = {3,0,254,37}; 00082 ReadWriteArrayGattCharacteristic<uint8_t, sizeof(configValue)> writeChar(configRWCharUUID, configValue); 00083 00084 /* Set up custom service */ 00085 GattCharacteristic *characteristics[] = {&writeChar,¬ifyChar}; 00086 GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); 00087 00088 // Temporary Fixes to be removed 00089 volatile BLE_State bleState = BLE_STARTING; 00090 00091 // end of Temporary Fixes to be removed 00092 00093 // sc... 00094 struct queue_t BLEQUEUE; 00095 static uint8_t BLEOutBuffer[BLE_NOTIFY_CHAR_ARR_SIZE * MAX_BLE_QUEUE]; 00096 00097 static DSInterface *BLE_DS_INTERFACE; 00098 00099 00100 /* 00101 * Handle writes to writeCharacteristic 00102 */ 00103 void writeCharCallback(const GattWriteCallbackParams *params) 00104 { 00105 uint8_t data[BLE_READWRITE_CHAR_ARR_SIZE] = {0}; 00106 /* Check to see what characteristic was written, by handle */ 00107 printf("writeCharCallback %p\r\n", Thread::gettid()); 00108 if(params->handle == writeChar.getValueHandle()) { 00109 printf("Data received: length = %d, data = 0x",params->len); 00110 for(int x=0; x < params->len; x++) { 00111 if ((BLE_DS_INTERFACE != NULL) && (params->data[x] != 0)) { 00112 BLE_DS_INTERFACE->build_command((char)params->data[x]); 00113 } 00114 printf("%x-", params->data[x]); 00115 } 00116 printf("\n\r"); 00117 } 00118 /* Update the notifyChar with the value of writeChar */ 00119 BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(writeChar.getValueHandle(), data, BLE_READWRITE_CHAR_ARR_SIZE); 00120 } 00121 00122 /** 00123 * This function is called when the ble initialization process has failed 00124 */ 00125 void onBleInitError(BLE &ble, ble_error_t error) 00126 { 00127 printf("errro %d\r\n", __LINE__); 00128 /* Avoid compiler warnings */ 00129 (void) ble; 00130 (void) error; 00131 /* Initialization error handling should go here */ 00132 } 00133 00134 /* Restart Advertising on disconnection*/ 00135 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) 00136 { 00137 pr_debug("disconnectionCallback %p\r\n", Thread::gettid()); 00138 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER) 00139 TICKER_BLE.detach(); 00140 pr_debug("detached disconnectionCallback\r\n"); 00141 Ble_Can_Transfer_Set(false); 00142 #endif 00143 bleState = BLE_DISCONNECTED; 00144 BLE::Instance().gap().startAdvertising(); 00145 BLE_DS_INTERFACE->ds_set_ble_status(false); 00146 queue_reset(&BLEQUEUE); 00147 } 00148 00149 /* Connection */ 00150 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00151 { 00152 pr_err("connectionCallback %p\r\n", Thread::gettid()); 00153 00154 Gap::ConnectionParams_t newParams = { 00155 .minConnectionInterval = 6, /**< Minimum Connection Interval in 1.25 ms units, see BLE_GAP_CP_LIMITS.*/ 00156 .maxConnectionInterval = 9, /**< Maximum Connection Interval in 1.25 ms units, see BLE_GAP_CP_LIMITS.*/ 00157 .slaveLatency = 0, /**< Slave Latency in number of connection events, see BLE_GAP_CP_LIMITS.*/ 00158 .connectionSupervisionTimeout = 600 /**< Connection Supervision Timeout in 10 ms units, see BLE_GAP_CP_LIMITS.*/ 00159 }; 00160 00161 BLE::Instance().gap().updateConnectionParams(params->handle, &newParams); 00162 BLE::Instance().gap().stopAdvertising(); 00163 BLE_DS_INTERFACE->ds_set_ble_status(true); 00164 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER) 00165 TICKER_BLE.attach(&Ble_Can_Transfer_Toggle, BLE_TICKER_PERIOD); 00166 pr_debug("Attached connectionCallback\r\n"); 00167 #endif 00168 //m.sensor_enable(1); 00169 bleState = BLE_CONNECTED; 00170 } 00171 00172 /** 00173 * Callback triggered when the ble initialization process has finished 00174 */ 00175 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00176 { 00177 int ret; 00178 BLE& ble = params->ble; 00179 ble_error_t error = params->error; 00180 00181 if (error != BLE_ERROR_NONE) { 00182 printf("errro %d\r\n", __LINE__); 00183 /* In case of error, forward the error handling to onBleInitError */ 00184 onBleInitError(ble, error); 00185 printf("errro %d\r\n", __LINE__); 00186 return; 00187 } 00188 /* Ensure that it is the default instance of BLE */ 00189 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { 00190 printf("errro %d\r\n", __LINE__); 00191 return; 00192 } 00193 ble.gap().onDisconnection(disconnectionCallback); 00194 ble.gap().onConnection(connectionCallback); 00195 ble.gattServer().onDataWritten(writeCharCallback); 00196 /* Setup advertising */ 00197 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT 00198 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type 00199 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name 00200 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet 00201 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG); 00202 ble.gap().setAdvertisingInterval(100); // 100ms. 00203 /* Add our custom service */ 00204 ble.gattServer().addService(customService); 00205 printf("bleInitComplete\n"); 00206 ble.gap().startAdvertising(); 00207 00208 ret = queue_init(&BLEQUEUE, BLEOutBuffer, BLE_NOTIFY_CHAR_ARR_SIZE, BLE_NOTIFY_CHAR_ARR_SIZE * MAX_BLE_QUEUE); 00209 if(ret != 0) 00210 printf("queue_init has failed\r\n"); 00211 } 00212 00213 int BLE_Icarus_TransferData(uint8_t data_transfer[20]){ 00214 int ret; 00215 ret = BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(notifyChar.getValueHandle(), data_transfer, 20); 00216 return ret; 00217 } 00218 00219 int BLE_Icarus_TransferDataFromQueue(){ 00220 int ret; 00221 uint8_t data_transfer[20]; 00222 unsigned char i; 00223 00224 if (BLEQUEUE.num_item >= 1) { 00225 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER) 00226 if(!Ble_Can_Transfer_Check()) 00227 return 0; 00228 #endif 00229 for(i = 0; i < BLE_CONN_INT_PACKET; ++i){ 00230 ret = dequeue(&BLEQUEUE, data_transfer); 00231 if(ret < 0) 00232 break; 00233 pr_debug("dequeued data for tx, %d remain\r\n", BLEQUEUE.num_item); 00234 BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(notifyChar.getValueHandle(), data_transfer, 20); 00235 } 00236 #if defined(USE_BLE_TICKER_TO_CHECK_TRANSFER) 00237 TICKER_BLE.attach(&Ble_Can_Transfer_Toggle, BLE_TICKER_PERIOD); 00238 Ble_Can_Transfer_Set(false); 00239 #endif 00240 } 00241 00242 return 0; 00243 } 00244 00245 00246 //TODO: check that function for memory safety (no overflow should occur) 00247 int BLE_Icarus_AddtoQueue(uint8_t *data_transfer, int32_t buf_size, int32_t data_size) { 00248 int ret = 0; 00249 //printf("size is: %d\r\n", size); 00250 // TODO: Append a known character to the byte array in case size is 00251 // less than 20 bytes 00252 while ((data_size % BLE_NOTIFY_CHAR_ARR_SIZE) && data_size < buf_size) 00253 data_transfer[data_size++] = 0; 00254 mxm_assert_msg(!(data_size % 20), "BLE packet size must be multiple of 20 bytes"); 00255 00256 while(data_size > 0){ 00257 ret = enqueue(&BLEQUEUE, data_transfer); 00258 data_size -= BLE_NOTIFY_CHAR_ARR_SIZE; 00259 data_transfer += BLE_NOTIFY_CHAR_ARR_SIZE; 00260 } 00261 00262 if(ret != 0) 00263 printf("BLE_Icarus_AddtoQueue has failed\r\n"); 00264 00265 return ret; 00266 } 00267 00268 00269 int BLE_Icarus_SetDSInterface(DSInterface *comm_obj) { 00270 BLE_DS_INTERFACE = comm_obj; 00271 return 0; 00272 } 00273 00274 bool BLE_Icarus_Interface_Exists() 00275 { 00276 return (bleState == BLE_CONNECTED); 00277 } 00278 00279 int BLE_ICARUS_Get_Mac_Address(char MacAdress[6]){ 00280 /* Print out device MAC address to the console*/ 00281 Gap::AddressType_t addr_type; 00282 Gap::Address_t address; 00283 if(BLE::Instance().gap().getAddress(&addr_type, address) != 0) 00284 return -1; 00285 for (int i = 5; i >= 0; i--){ 00286 MacAdress[5-i] = address[i]; 00287 } 00288 pr_info("BLE_ADV_NAME:%s", DEVICE_NAME); 00289 return 0; 00290 }
Generated on Tue Jul 12 2022 20:09:28 by
