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: BLE_API mbed nRF51822
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 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 #include "mbed.h" 00018 #include <string.h> 00019 #include <stddef.h> 00020 #include <Serial.h> 00021 #include "ble/services/iBeacon.h" 00022 #include "ble/services/UARTService.h" 00023 #include "ble/services/DFUService.h" 00024 #include "nrf.h" 00025 #include "nrf_sdm.h" 00026 00027 00028 extern "C" { 00029 #include "pstorage.h" 00030 } 00031 #include "nrf_error.h" 00032 00033 #define _DEBUG 00034 00035 BLE ble; 00036 UARTService *uarts; 00037 DFUService *dfus; 00038 iBeacon *ibeacon; 00039 pstorage_handle_t pstorageHandle; 00040 #ifdef _DEBUG 00041 Serial pc(USBTX, USBRX); 00042 #endif 00043 Ticker ticker; 00044 00045 // Struct to hold persistent data across power cycles 00046 typedef struct PersistentData_t { 00047 char name[32]; 00048 uint16_t majorNumber; 00049 uint16_t minorNumber; 00050 uint16_t txPower; 00051 } __attribute__ ((aligned (4))); 00052 PersistentData_t persistentData; 00053 static const int PERSISTENT_DATA_ALIGNED_SIZE = sizeof(PersistentData_t); 00054 00055 /* Dummy callback handler needed by Nordic's pstorage module. */ 00056 void pstorageNotificationCallback( 00057 pstorage_handle_t *p_handle, 00058 uint8_t op_code, 00059 uint32_t result, 00060 uint8_t * p_data, 00061 uint32_t data_len){ 00062 /* APP_ERROR_CHECK(result); */ 00063 } 00064 00065 void pstorageLoad(){ 00066 if (pstorage_init()!=NRF_SUCCESS) { 00067 } 00068 00069 pstorage_module_param_t pstorageParams = { 00070 .cb = pstorageNotificationCallback, 00071 .block_size = PERSISTENT_DATA_ALIGNED_SIZE, 00072 .block_count = 1 00073 }; 00074 pstorage_register(&pstorageParams, &pstorageHandle); 00075 if (pstorage_load( 00076 reinterpret_cast<uint8_t *>(&persistentData), 00077 &pstorageHandle, PERSISTENT_DATA_ALIGNED_SIZE, 0 00078 ) != NRF_SUCCESS) { 00079 // On failure zero out and let the service reset to defaults 00080 sprintf(persistentData.name,"INTELLIGENTLUMEN"); 00081 persistentData.majorNumber=1234; 00082 persistentData.minorNumber=5678; 00083 persistentData.txPower=54; 00084 } 00085 } 00086 00087 00088 00089 void pstorageSave() { 00090 pstorage_store( 00091 &pstorageHandle, 00092 reinterpret_cast<uint8_t *>(&persistentData), 00093 sizeof(PersistentData_t), 00094 0 /* offset */ 00095 ); 00096 wait(2); 00097 } 00098 00099 00100 00101 /* BLE UART data received callback */ 00102 void onDataWritten(const GattWriteCallbackParams *params) 00103 { 00104 char *bp = (char*)params->data; 00105 bp[params->len]=0; //Fix string end with zero. 00106 #ifdef _DEBUG 00107 pc.printf("%s\r\n",bp); 00108 #endif 00109 char *token; 00110 token = strtok(bp," ,"); 00111 if (token!=NULL) { 00112 #ifdef _DEBUG 00113 pc.printf("Recv: %s\r\n",token); 00114 #endif 00115 if (strcmp(token,"name")==0) { 00116 token = strtok(NULL," ,"); 00117 if (token==NULL) { 00118 #ifdef _DEBUG 00119 pc.printf("Cfg error: invalid name \r\n"); 00120 #endif 00121 return; 00122 } 00123 sprintf((char *)persistentData.name,"%s",token); 00124 } else if (strcmp(token,"major")==0) { 00125 token = strtok(NULL," ,"); 00126 if (token==NULL) { 00127 #ifdef _DEBUG 00128 pc.printf("Cfg error: invalid majorNumber \r\n"); 00129 #endif 00130 return; 00131 } 00132 persistentData.majorNumber=atoi(token); 00133 } else if (strcmp(token,"minor")==0) { 00134 token = strtok(NULL," ,"); 00135 if (token==NULL) { 00136 #ifdef _DEBUG 00137 pc.printf("Cfg error: invalid minorNumber \r\n"); 00138 #endif 00139 return; 00140 } 00141 persistentData.minorNumber=atoi(token); 00142 } else if (strcmp(token,"rssi")==0) { 00143 token = strtok(NULL," ,"); 00144 if (token==NULL) { 00145 #ifdef _DEBUG 00146 pc.printf("Cfg error: invalid txPower \r\n"); 00147 #endif 00148 return; 00149 } 00150 persistentData.txPower=atoi(token); 00151 #ifdef _DEBUG 00152 pc.printf("Cfg txPower:%i\r\n",persistentData.txPower); 00153 #endif 00154 } else if (strcmp(token,"save")==0) { 00155 pstorageSave(); 00156 #ifdef _DEBUG 00157 pc.printf("Config name:%s major:%i minor:%i tx:%i\r\n",persistentData.name,persistentData.majorNumber,persistentData.minorNumber,persistentData.txPower); 00158 #endif 00159 NVIC_SystemReset(); 00160 } else if (strcmp(token,"dfu")==0) { 00161 sd_power_gpregret_set(BOOTLOADER_DFU_START); 00162 sd_softdevice_disable(); 00163 sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR); 00164 NVIC_SystemReset(); 00165 } 00166 } 00167 } 00168 00169 00170 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) 00171 { 00172 #ifdef _DEBUG 00173 pc.printf("Connected!\n"); 00174 #endif 00175 } 00176 00177 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams) 00178 { 00179 #ifdef _DEBUG 00180 pc.printf("Disconnected!\n"); 00181 pc.printf("Restarting the advertising process\n"); 00182 #endif 00183 ble.startAdvertising(); 00184 } 00185 00186 00187 00188 int main(void) 00189 { 00190 const uint8_t uuid[] = {0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, 00191 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61}; 00192 #ifdef _DEBUG 00193 pc.baud(9600); 00194 pc.printf("INTELLIGENT LUMEN BEACON DFU v1.1\r\n"); 00195 #endif 00196 00197 /* Load mayor minor and txpower from storage */ 00198 pstorageLoad(); 00199 #ifdef _DEBUG 00200 pc.printf("Storage size:%i\r\n",PERSISTENT_DATA_ALIGNED_SIZE); 00201 pc.printf("Config name:%s mayor:%i minor:%i tx:%i\r\n",persistentData.name,persistentData.majorNumber,persistentData.minorNumber,persistentData.txPower); 00202 #endif 00203 00204 ble.init(); 00205 while (!ble.hasInitialized()) { wait(0.5);/* wait for BLE initialization */ } 00206 00207 ble.gap().onDisconnection(disconnectionCallback); 00208 ble.gap().onConnection(connectionCallback); 00209 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, 00210 (const uint8_t*)persistentData.name, strlen((const char*)persistentData.name)); 00211 00212 UARTService uartService(ble); 00213 uarts = &uartService; 00214 DFUService dfu(ble); 00215 dfus = &dfu; 00216 ibeacon = new iBeacon(ble, uuid, persistentData.majorNumber, persistentData.minorNumber, persistentData.txPower); 00217 00218 ble.onDataWritten(onDataWritten); 00219 00220 /* setup advertising */ 00221 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); 00222 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00223 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, 00224 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); 00225 ble.setAdvertisingInterval(100); /* 100ms; in multiples of 0.625ms. */ 00226 ble.gap().startAdvertising(); 00227 00228 00229 while (true) { 00230 ble.waitForEvent(); // allows or low power operation 00231 } 00232 }
Generated on Fri Jul 22 2022 03:43:04 by
1.7.2