ongoing Development Project for interfacing a BM019 Module with nrf51-dk, acting as a nfc 2 ble bridge. Base project for opensource blueReader Device

Dependencies:   BLE_API mbed nRF51822

Committer:
SandraK
Date:
Thu Apr 21 19:09:42 2016 +0000
Revision:
1:e4e03060b32f
Parent:
0:d156731c291b
added hearthbeat-mode for iOS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
SandraK 0:d156731c291b 1 #include "mbed.h"
SandraK 0:d156731c291b 2 #include "ble/BLE.h"
SandraK 0:d156731c291b 3
SandraK 0:d156731c291b 4 #include "ble/services/UARTService.h"
SandraK 0:d156731c291b 5
SandraK 0:d156731c291b 6 #include "log.h"
SandraK 0:d156731c291b 7 /*
SandraK 0:d156731c291b 8 This is an example of using the implemented functions of the bm019-library with an nrf51, acting as UART-Service.
SandraK 0:d156731c291b 9 This code uses the spi version of the interface.
SandraK 0:d156731c291b 10 */
SandraK 0:d156731c291b 11 #include "bm019.h"
SandraK 0:d156731c291b 12
SandraK 0:d156731c291b 13 BLEDevice ble;
SandraK 0:d156731c291b 14 UARTService *uartServicePtr;
SandraK 0:d156731c291b 15
SandraK 0:d156731c291b 16 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
SandraK 0:d156731c291b 17 {
SandraK 0:d156731c291b 18 DEBUG("Disconnected!\n\r");
SandraK 0:d156731c291b 19 DEBUG("Restarting the advertising process\n\r");
SandraK 0:d156731c291b 20 ble.startAdvertising();
SandraK 0:d156731c291b 21 }
SandraK 0:d156731c291b 22 char answer[512];
SandraK 0:d156731c291b 23
SandraK 1:e4e03060b32f 24 Ticker ticker;
SandraK 1:e4e03060b32f 25 void timerCallback(void)
SandraK 1:e4e03060b32f 26 {
SandraK 1:e4e03060b32f 27 DEBUG("start timer callback");
SandraK 1:e4e03060b32f 28 sprintf(answer,"+.!");
SandraK 1:e4e03060b32f 29 DEBUG("writing beatpulse \"%s\" with len %d to ble\n",answer,strlen(answer));
SandraK 1:e4e03060b32f 30 int l = strlen(answer);
SandraK 1:e4e03060b32f 31 for(int i = 0; i*20 < strlen(answer); i++) {
SandraK 1:e4e03060b32f 32 int len = 20 < l ? 20 : l;
SandraK 1:e4e03060b32f 33 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t *)&answer[i*20], len);
SandraK 1:e4e03060b32f 34 l -= 20;
SandraK 1:e4e03060b32f 35 }
SandraK 1:e4e03060b32f 36 ticker.detach();
SandraK 1:e4e03060b32f 37 }
SandraK 0:d156731c291b 38 void onDataWritten(const GattWriteCallbackParams *params)
SandraK 0:d156731c291b 39 {
SandraK 0:d156731c291b 40 if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
SandraK 0:d156731c291b 41 uint16_t bytesRead = params->len;
SandraK 0:d156731c291b 42 bool handled = false;
SandraK 0:d156731c291b 43
SandraK 0:d156731c291b 44
SandraK 0:d156731c291b 45 for(int i = 0; !handled && i < bytesRead; i++) {
SandraK 0:d156731c291b 46 switch(params->data[i]) {
SandraK 0:d156731c291b 47 case '?': {
SandraK 0:d156731c291b 48 DEBUG("Handle ?\n");
SandraK 0:d156731c291b 49 switch(getStateBM019()) {
SandraK 0:d156731c291b 50 case BM019_STATE_UNKNOWN:
SandraK 0:d156731c291b 51 DEBUG("BM019 Status: unknown\n");
SandraK 0:d156731c291b 52 sprintf(answer,"+?:0!");
SandraK 0:d156731c291b 53 break;
SandraK 0:d156731c291b 54 case BM019_STATE_ANSWERING:
SandraK 0:d156731c291b 55 DEBUG("BM019 Status: answering\n");
SandraK 0:d156731c291b 56 sprintf(answer,"+?:1!");
SandraK 0:d156731c291b 57 break;
SandraK 0:d156731c291b 58 case BM019_STATE_PROTOCOL:
SandraK 0:d156731c291b 59 DEBUG("BM019 Status: protocol set\n");
SandraK 0:d156731c291b 60 sprintf(answer,"+?:2!");
SandraK 0:d156731c291b 61 break;
SandraK 0:d156731c291b 62 default:
SandraK 0:d156731c291b 63 sprintf(answer,"-?%d!",getStateBM019());
SandraK 0:d156731c291b 64 DEBUG("BM019 Status: forgotten state\n");
SandraK 0:d156731c291b 65 }
SandraK 0:d156731c291b 66 handled = true;
SandraK 0:d156731c291b 67 }
SandraK 0:d156731c291b 68 break;
SandraK 0:d156731c291b 69
SandraK 1:e4e03060b32f 70 case 'b':
SandraK 1:e4e03060b32f 71 case 'B':
SandraK 1:e4e03060b32f 72 DEBUG("Handling b\n");
SandraK 1:e4e03060b32f 73 if(i + 5 <= bytesRead) {
SandraK 1:e4e03060b32f 74 sprintf(answer,"+b!");
SandraK 1:e4e03060b32f 75 int adr = 0;
SandraK 1:e4e03060b32f 76 char b[3];
SandraK 1:e4e03060b32f 77 b[0] = params->data[i+4];
SandraK 1:e4e03060b32f 78 b[1] = params->data[i+5];
SandraK 1:e4e03060b32f 79 b[2] = 0;
SandraK 1:e4e03060b32f 80 sscanf(b,"%x",&adr);
SandraK 1:e4e03060b32f 81 DEBUG("beat in %d sec\n",adr);
SandraK 1:e4e03060b32f 82 ticker.attach(timerCallback, adr);
SandraK 1:e4e03060b32f 83 i+=5;
SandraK 1:e4e03060b32f 84 handled=true;
SandraK 1:e4e03060b32f 85 } else {
SandraK 1:e4e03060b32f 86 sprintf(answer,"-b!");
SandraK 1:e4e03060b32f 87 handled=true;
SandraK 1:e4e03060b32f 88 }
SandraK 1:e4e03060b32f 89
SandraK 1:e4e03060b32f 90 break;
SandraK 0:d156731c291b 91 case 'h':
SandraK 0:d156731c291b 92 case 'H': {
SandraK 0:d156731c291b 93 DEBUG("Handling h\n");
SandraK 0:d156731c291b 94 if(hybernateBM019()) {
SandraK 0:d156731c291b 95 sprintf(answer,"+h!");
SandraK 0:d156731c291b 96 } else {
SandraK 0:d156731c291b 97 DEBUG("BM019 did hybernate wake\n")
SandraK 0:d156731c291b 98 sprintf(answer,"-h!");
SandraK 0:d156731c291b 99 }
SandraK 0:d156731c291b 100 handled=true;
SandraK 0:d156731c291b 101
SandraK 0:d156731c291b 102 }
SandraK 0:d156731c291b 103 break;
SandraK 0:d156731c291b 104
SandraK 0:d156731c291b 105 case 'w':
SandraK 0:d156731c291b 106 case 'W': {
SandraK 0:d156731c291b 107 DEBUG("handle w\n")
SandraK 0:d156731c291b 108
SandraK 0:d156731c291b 109 if(wakeBM019(100)) {
SandraK 0:d156731c291b 110 DEBUG("BM019 did wake\n")
SandraK 0:d156731c291b 111 sprintf(answer,"+w!");
SandraK 0:d156731c291b 112 } else {
SandraK 0:d156731c291b 113 DEBUG("BM019 did NOT wake\n")
SandraK 0:d156731c291b 114 sprintf(answer,"-w!");
SandraK 0:d156731c291b 115 }
SandraK 0:d156731c291b 116 handled = true;
SandraK 0:d156731c291b 117 }
SandraK 0:d156731c291b 118 break;
SandraK 0:d156731c291b 119
SandraK 0:d156731c291b 120 case 'i':
SandraK 0:d156731c291b 121 case 'I': {
SandraK 0:d156731c291b 122 DEBUG("handle i\n");
SandraK 0:d156731c291b 123 BM019_IDN idn;
SandraK 0:d156731c291b 124 if(idnBM019(&idn)) {
SandraK 0:d156731c291b 125 sprintf(answer,"+i:");
SandraK 0:d156731c291b 126 int i;
SandraK 0:d156731c291b 127 for(i = 0; i < 13; i++) {
SandraK 0:d156731c291b 128 sprintf(&answer[strlen(answer)],"%x",idn.deviceID[i]);
SandraK 0:d156731c291b 129 }
SandraK 0:d156731c291b 130 sprintf(&answer[strlen(answer)],":");
SandraK 0:d156731c291b 131 sprintf(&answer[strlen(answer)],"%x%x!",idn.romCRC[0],idn.romCRC[1]);
SandraK 0:d156731c291b 132 DEBUG("answered: %s",answer);
SandraK 0:d156731c291b 133 } else {
SandraK 0:d156731c291b 134 DEBUG("BM019 failed idn\n")
SandraK 0:d156731c291b 135 sprintf(answer,"-i!");
SandraK 0:d156731c291b 136 }
SandraK 0:d156731c291b 137
SandraK 0:d156731c291b 138 handled = true;
SandraK 0:d156731c291b 139 }
SandraK 0:d156731c291b 140 break;
SandraK 0:d156731c291b 141
SandraK 0:d156731c291b 142 case 'p':
SandraK 0:d156731c291b 143 case 'P': {
SandraK 0:d156731c291b 144 DEBUG("handle p\n");
SandraK 0:d156731c291b 145 if(setProtocolISO_EIC_15693BM019((BM019_PROTOCOL_ISO_IEC_15693_BYTE_0)(
SandraK 0:d156731c291b 146 BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_0_CRC |
SandraK 0:d156731c291b 147 BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_1_SINGLE_SUBCARRIER |
SandraK 0:d156731c291b 148 BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_2_10_MODULATION |
SandraK 0:d156731c291b 149 BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_3_WAIT_FOR_SOF |
SandraK 0:d156731c291b 150 BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_45_26_KBPS)
SandraK 0:d156731c291b 151 )) {
SandraK 0:d156731c291b 152 DEBUG("BM019 proto\n")
SandraK 0:d156731c291b 153 sprintf(answer,"+p!");
SandraK 0:d156731c291b 154 } else {
SandraK 0:d156731c291b 155 DEBUG("BM019 failed proto\n")
SandraK 0:d156731c291b 156 sprintf(answer,"-p!");
SandraK 0:d156731c291b 157 }
SandraK 0:d156731c291b 158
SandraK 0:d156731c291b 159 handled = true;
SandraK 0:d156731c291b 160 }
SandraK 0:d156731c291b 161 break;
SandraK 0:d156731c291b 162
SandraK 0:d156731c291b 163 case 'r':
SandraK 0:d156731c291b 164 case 'R': {
SandraK 0:d156731c291b 165 DEBUG("handle r\n");
SandraK 0:d156731c291b 166 resetBM019();
SandraK 0:d156731c291b 167 sprintf(answer,"+r!");
SandraK 0:d156731c291b 168 handled = true;
SandraK 0:d156731c291b 169 }
SandraK 0:d156731c291b 170 break;
SandraK 0:d156731c291b 171
SandraK 0:d156731c291b 172 case 'e':
SandraK 0:d156731c291b 173 case 'E': {
SandraK 0:d156731c291b 174 DEBUG("handle e\n");
SandraK 0:d156731c291b 175 if(echoBM019()) {
SandraK 0:d156731c291b 176 DEBUG("BM019 sent echo\n");
SandraK 0:d156731c291b 177 sprintf(answer,"+e!");
SandraK 0:d156731c291b 178 } else {
SandraK 0:d156731c291b 179 DEBUG("BM019 NOT sent echo\n");
SandraK 0:d156731c291b 180 sprintf(answer,"-e!");
SandraK 0:d156731c291b 181 }
SandraK 0:d156731c291b 182 handled = true;
SandraK 0:d156731c291b 183 }
SandraK 0:d156731c291b 184 break;
SandraK 0:d156731c291b 185
SandraK 0:d156731c291b 186 case 't':
SandraK 0:d156731c291b 187 case 'T': {
SandraK 0:d156731c291b 188 DEBUG("handle t\n");
SandraK 0:d156731c291b 189 BM019_TAG tag;
SandraK 0:d156731c291b 190 if(inventoryISO_IES_15693BM019(&tag)) {
SandraK 0:d156731c291b 191 DEBUG("BM019 answered inventory\n");
SandraK 0:d156731c291b 192 sprintf(answer,"+t:");
SandraK 0:d156731c291b 193 for(int i = 0; i < 8; i++) {
SandraK 0:d156731c291b 194 sprintf(&answer[strlen(answer)],"%02x",tag.uid[i]);
SandraK 0:d156731c291b 195 }
SandraK 0:d156731c291b 196 sprintf(&answer[strlen(answer)],"!");
SandraK 0:d156731c291b 197 } else {
SandraK 0:d156731c291b 198 DEBUG("BM019 NOT answered inventory\n");
SandraK 0:d156731c291b 199 sprintf(answer,"-t!");
SandraK 0:d156731c291b 200 }
SandraK 0:d156731c291b 201 handled = true;
SandraK 0:d156731c291b 202 }
SandraK 0:d156731c291b 203 break;
SandraK 0:d156731c291b 204
SandraK 0:d156731c291b 205 case 'd':
SandraK 0:d156731c291b 206 case 'D': {
SandraK 0:d156731c291b 207 DEBUG("handle d\n");
SandraK 0:d156731c291b 208 if(i + 5 <= bytesRead) {
SandraK 0:d156731c291b 209 int adr = 0;
SandraK 0:d156731c291b 210 char b[3];
SandraK 0:d156731c291b 211 b[0] = params->data[i+4];
SandraK 0:d156731c291b 212 b[1] = params->data[i+5];
SandraK 0:d156731c291b 213 b[2] = 0;
SandraK 0:d156731c291b 214 sscanf(b,"%x",&adr);
SandraK 0:d156731c291b 215 DEBUG("read from %#04x\n",adr);
SandraK 0:d156731c291b 216 i+=5;
SandraK 0:d156731c291b 217 uint8_t rb[256];
SandraK 0:d156731c291b 218 int l = readBM019(adr,rb,256);
SandraK 0:d156731c291b 219 if(l>0) {
SandraK 0:d156731c291b 220 DEBUG("BM019 answered read\n");
SandraK 0:d156731c291b 221 sprintf(answer,"+d:");
SandraK 0:d156731c291b 222 for(int i = 0; i < l; i++) {
SandraK 0:d156731c291b 223 sprintf(&answer[strlen(answer)],"%02x",rb[i]);
SandraK 0:d156731c291b 224 }
SandraK 0:d156731c291b 225 sprintf(&answer[strlen(answer)],"!");
SandraK 0:d156731c291b 226 } else {
SandraK 0:d156731c291b 227 DEBUG("BM019 NOT answered read\n");
SandraK 0:d156731c291b 228 sprintf(answer,"-d!");
SandraK 0:d156731c291b 229 }
SandraK 0:d156731c291b 230 } else {
SandraK 0:d156731c291b 231 DEBUG("BM019 NOT answered read, no adr given\n");
SandraK 0:d156731c291b 232 sprintf(answer,"-d!");
SandraK 0:d156731c291b 233 }
SandraK 0:d156731c291b 234 handled = true;
SandraK 0:d156731c291b 235 }
SandraK 0:d156731c291b 236 break;
SandraK 0:d156731c291b 237
SandraK 0:d156731c291b 238 case 'm':
SandraK 0:d156731c291b 239 case 'M': {
SandraK 0:d156731c291b 240 DEBUG("handle multi d\n");
SandraK 0:d156731c291b 241 if(i + 10 <= bytesRead) {
SandraK 0:d156731c291b 242 int adr = 0;
SandraK 0:d156731c291b 243 char b[3];
SandraK 0:d156731c291b 244 b[0] = params->data[i+4];
SandraK 0:d156731c291b 245 b[1] = params->data[i+5];
SandraK 0:d156731c291b 246 b[2] = 0;
SandraK 0:d156731c291b 247 sscanf(b,"%x",&adr);
SandraK 0:d156731c291b 248
SandraK 0:d156731c291b 249 int count = 0;
SandraK 0:d156731c291b 250 b[0] = params->data[i+9];
SandraK 0:d156731c291b 251 b[1] = params->data[i+10];
SandraK 0:d156731c291b 252 b[2] = 0;
SandraK 0:d156731c291b 253 sscanf(b,"%x",&count);
SandraK 0:d156731c291b 254 DEBUG("read from %#04x for %d\n",adr,count);
SandraK 0:d156731c291b 255 i+=10;
SandraK 0:d156731c291b 256 uint8_t rb[256];
SandraK 0:d156731c291b 257 int l = readMultiBM019(adr,count,rb,256);
SandraK 0:d156731c291b 258 if(l>0) {
SandraK 0:d156731c291b 259 DEBUG("BM019 answered multi\n");
SandraK 0:d156731c291b 260 sprintf(answer,"+m:");
SandraK 0:d156731c291b 261 for(int i = 0; i < l; i++) {
SandraK 0:d156731c291b 262 sprintf(&answer[strlen(answer)],"%02x",rb[i]);
SandraK 0:d156731c291b 263 }
SandraK 0:d156731c291b 264 sprintf(&answer[strlen(answer)],"!");
SandraK 0:d156731c291b 265 } else {
SandraK 0:d156731c291b 266 DEBUG("BM019 NOT answered multi\n");
SandraK 0:d156731c291b 267 sprintf(answer,"-m!");
SandraK 0:d156731c291b 268 }
SandraK 0:d156731c291b 269 } else {
SandraK 0:d156731c291b 270 DEBUG("BM019 NOT answered read, no adr&count given\n");
SandraK 0:d156731c291b 271 sprintf(answer,"-m!");
SandraK 0:d156731c291b 272 }
SandraK 0:d156731c291b 273 handled = true;
SandraK 0:d156731c291b 274 }
SandraK 0:d156731c291b 275 break;
SandraK 0:d156731c291b 276 }
SandraK 0:d156731c291b 277 }
SandraK 0:d156731c291b 278
SandraK 0:d156731c291b 279 if(handled) {
SandraK 0:d156731c291b 280 DEBUG("writing \"%s\" with len %d to ble\n",answer,strlen(answer));
SandraK 0:d156731c291b 281 int l = strlen(answer);
SandraK 0:d156731c291b 282 for(int i = 0; i*20 < strlen(answer); i++) {
SandraK 0:d156731c291b 283 int len = 20 < l ? 20 : l;
SandraK 0:d156731c291b 284 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t *)&answer[i*20], len);
SandraK 0:d156731c291b 285 l -= 20;
SandraK 0:d156731c291b 286 }
SandraK 0:d156731c291b 287
SandraK 0:d156731c291b 288 } else {
SandraK 0:d156731c291b 289 DEBUG("received %u bytes.. nothing handled.. echo\n", bytesRead);
SandraK 0:d156731c291b 290 ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
SandraK 0:d156731c291b 291 }
SandraK 0:d156731c291b 292 }
SandraK 0:d156731c291b 293 }
SandraK 0:d156731c291b 294
SandraK 0:d156731c291b 295 int main(void)
SandraK 0:d156731c291b 296 {
SandraK 0:d156731c291b 297 initBM019();
SandraK 0:d156731c291b 298
SandraK 0:d156731c291b 299 DEBUG("Initialising the nRF51822\n\r");
SandraK 0:d156731c291b 300 ble.init();
SandraK 0:d156731c291b 301 ble.onDisconnection(disconnectionCallback);
SandraK 0:d156731c291b 302 ble.onDataWritten(onDataWritten);
SandraK 0:d156731c291b 303
SandraK 0:d156731c291b 304 /* setup advertising */
SandraK 0:d156731c291b 305 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
SandraK 0:d156731c291b 306 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
SandraK 0:d156731c291b 307 //ble.setAdvertisingType(GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED);
SandraK 0:d156731c291b 308 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
SandraK 0:d156731c291b 309 (const uint8_t *)"BLE UART2NFC", sizeof("BLE UART2NFC") - 1);
SandraK 1:e4e03060b32f 310
SandraK 1:e4e03060b32f 311
SandraK 0:d156731c291b 312 /*ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
SandraK 0:d156731c291b 313 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
SandraK 1:e4e03060b32f 314 */
SandraK 0:d156731c291b 315
SandraK 1:e4e03060b32f 316 ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
SandraK 1:e4e03060b32f 317 (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
SandraK 0:d156731c291b 318 ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */
SandraK 0:d156731c291b 319 //ble.setAdvertisingTimeout(0x1);
SandraK 0:d156731c291b 320 ble.startAdvertising();
SandraK 0:d156731c291b 321
SandraK 0:d156731c291b 322 UARTService uartService(ble);
SandraK 0:d156731c291b 323 uartServicePtr = &uartService;
SandraK 1:e4e03060b32f 324
SandraK 0:d156731c291b 325 while (true) {
SandraK 0:d156731c291b 326 ble.waitForEvent();
SandraK 0:d156731c291b 327 }
SandraK 0:d156731c291b 328 }