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
main.cpp@0:d156731c291b, 2016-04-16 (annotated)
- Committer:
- SandraK
- Date:
- Sat Apr 16 14:00:28 2016 +0000
- Revision:
- 0:d156731c291b
- Child:
- 1:e4e03060b32f
initial Version of nfc2ble software, supports only limited modes and options so far
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:d156731c291b | 24 | void onDataWritten(const GattWriteCallbackParams *params) |
SandraK | 0:d156731c291b | 25 | { |
SandraK | 0:d156731c291b | 26 | if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) { |
SandraK | 0:d156731c291b | 27 | uint16_t bytesRead = params->len; |
SandraK | 0:d156731c291b | 28 | bool handled = false; |
SandraK | 0:d156731c291b | 29 | |
SandraK | 0:d156731c291b | 30 | |
SandraK | 0:d156731c291b | 31 | for(int i = 0; !handled && i < bytesRead; i++) { |
SandraK | 0:d156731c291b | 32 | switch(params->data[i]) { |
SandraK | 0:d156731c291b | 33 | case '?': { |
SandraK | 0:d156731c291b | 34 | DEBUG("Handle ?\n"); |
SandraK | 0:d156731c291b | 35 | switch(getStateBM019()) { |
SandraK | 0:d156731c291b | 36 | case BM019_STATE_UNKNOWN: |
SandraK | 0:d156731c291b | 37 | DEBUG("BM019 Status: unknown\n"); |
SandraK | 0:d156731c291b | 38 | sprintf(answer,"+?:0!"); |
SandraK | 0:d156731c291b | 39 | break; |
SandraK | 0:d156731c291b | 40 | case BM019_STATE_ANSWERING: |
SandraK | 0:d156731c291b | 41 | DEBUG("BM019 Status: answering\n"); |
SandraK | 0:d156731c291b | 42 | sprintf(answer,"+?:1!"); |
SandraK | 0:d156731c291b | 43 | break; |
SandraK | 0:d156731c291b | 44 | case BM019_STATE_PROTOCOL: |
SandraK | 0:d156731c291b | 45 | DEBUG("BM019 Status: protocol set\n"); |
SandraK | 0:d156731c291b | 46 | sprintf(answer,"+?:2!"); |
SandraK | 0:d156731c291b | 47 | break; |
SandraK | 0:d156731c291b | 48 | default: |
SandraK | 0:d156731c291b | 49 | sprintf(answer,"-?%d!",getStateBM019()); |
SandraK | 0:d156731c291b | 50 | DEBUG("BM019 Status: forgotten state\n"); |
SandraK | 0:d156731c291b | 51 | } |
SandraK | 0:d156731c291b | 52 | handled = true; |
SandraK | 0:d156731c291b | 53 | } |
SandraK | 0:d156731c291b | 54 | break; |
SandraK | 0:d156731c291b | 55 | |
SandraK | 0:d156731c291b | 56 | case 'h': |
SandraK | 0:d156731c291b | 57 | case 'H': { |
SandraK | 0:d156731c291b | 58 | DEBUG("Handling h\n"); |
SandraK | 0:d156731c291b | 59 | if(hybernateBM019()) { |
SandraK | 0:d156731c291b | 60 | sprintf(answer,"+h!"); |
SandraK | 0:d156731c291b | 61 | } else { |
SandraK | 0:d156731c291b | 62 | DEBUG("BM019 did hybernate wake\n") |
SandraK | 0:d156731c291b | 63 | sprintf(answer,"-h!"); |
SandraK | 0:d156731c291b | 64 | } |
SandraK | 0:d156731c291b | 65 | handled=true; |
SandraK | 0:d156731c291b | 66 | |
SandraK | 0:d156731c291b | 67 | } |
SandraK | 0:d156731c291b | 68 | break; |
SandraK | 0:d156731c291b | 69 | |
SandraK | 0:d156731c291b | 70 | case 'w': |
SandraK | 0:d156731c291b | 71 | case 'W': { |
SandraK | 0:d156731c291b | 72 | DEBUG("handle w\n") |
SandraK | 0:d156731c291b | 73 | |
SandraK | 0:d156731c291b | 74 | if(wakeBM019(100)) { |
SandraK | 0:d156731c291b | 75 | DEBUG("BM019 did wake\n") |
SandraK | 0:d156731c291b | 76 | sprintf(answer,"+w!"); |
SandraK | 0:d156731c291b | 77 | } else { |
SandraK | 0:d156731c291b | 78 | DEBUG("BM019 did NOT wake\n") |
SandraK | 0:d156731c291b | 79 | sprintf(answer,"-w!"); |
SandraK | 0:d156731c291b | 80 | } |
SandraK | 0:d156731c291b | 81 | handled = true; |
SandraK | 0:d156731c291b | 82 | } |
SandraK | 0:d156731c291b | 83 | break; |
SandraK | 0:d156731c291b | 84 | |
SandraK | 0:d156731c291b | 85 | case 'i': |
SandraK | 0:d156731c291b | 86 | case 'I': { |
SandraK | 0:d156731c291b | 87 | DEBUG("handle i\n"); |
SandraK | 0:d156731c291b | 88 | BM019_IDN idn; |
SandraK | 0:d156731c291b | 89 | if(idnBM019(&idn)) { |
SandraK | 0:d156731c291b | 90 | sprintf(answer,"+i:"); |
SandraK | 0:d156731c291b | 91 | int i; |
SandraK | 0:d156731c291b | 92 | for(i = 0; i < 13; i++) { |
SandraK | 0:d156731c291b | 93 | sprintf(&answer[strlen(answer)],"%x",idn.deviceID[i]); |
SandraK | 0:d156731c291b | 94 | } |
SandraK | 0:d156731c291b | 95 | sprintf(&answer[strlen(answer)],":"); |
SandraK | 0:d156731c291b | 96 | sprintf(&answer[strlen(answer)],"%x%x!",idn.romCRC[0],idn.romCRC[1]); |
SandraK | 0:d156731c291b | 97 | DEBUG("answered: %s",answer); |
SandraK | 0:d156731c291b | 98 | } else { |
SandraK | 0:d156731c291b | 99 | DEBUG("BM019 failed idn\n") |
SandraK | 0:d156731c291b | 100 | sprintf(answer,"-i!"); |
SandraK | 0:d156731c291b | 101 | } |
SandraK | 0:d156731c291b | 102 | |
SandraK | 0:d156731c291b | 103 | handled = true; |
SandraK | 0:d156731c291b | 104 | } |
SandraK | 0:d156731c291b | 105 | break; |
SandraK | 0:d156731c291b | 106 | |
SandraK | 0:d156731c291b | 107 | case 'p': |
SandraK | 0:d156731c291b | 108 | case 'P': { |
SandraK | 0:d156731c291b | 109 | DEBUG("handle p\n"); |
SandraK | 0:d156731c291b | 110 | if(setProtocolISO_EIC_15693BM019((BM019_PROTOCOL_ISO_IEC_15693_BYTE_0)( |
SandraK | 0:d156731c291b | 111 | BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_0_CRC | |
SandraK | 0:d156731c291b | 112 | BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_1_SINGLE_SUBCARRIER | |
SandraK | 0:d156731c291b | 113 | BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_2_10_MODULATION | |
SandraK | 0:d156731c291b | 114 | BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_3_WAIT_FOR_SOF | |
SandraK | 0:d156731c291b | 115 | BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_45_26_KBPS) |
SandraK | 0:d156731c291b | 116 | )) { |
SandraK | 0:d156731c291b | 117 | DEBUG("BM019 proto\n") |
SandraK | 0:d156731c291b | 118 | sprintf(answer,"+p!"); |
SandraK | 0:d156731c291b | 119 | } else { |
SandraK | 0:d156731c291b | 120 | DEBUG("BM019 failed proto\n") |
SandraK | 0:d156731c291b | 121 | sprintf(answer,"-p!"); |
SandraK | 0:d156731c291b | 122 | } |
SandraK | 0:d156731c291b | 123 | |
SandraK | 0:d156731c291b | 124 | handled = true; |
SandraK | 0:d156731c291b | 125 | } |
SandraK | 0:d156731c291b | 126 | break; |
SandraK | 0:d156731c291b | 127 | |
SandraK | 0:d156731c291b | 128 | case 'r': |
SandraK | 0:d156731c291b | 129 | case 'R': { |
SandraK | 0:d156731c291b | 130 | DEBUG("handle r\n"); |
SandraK | 0:d156731c291b | 131 | resetBM019(); |
SandraK | 0:d156731c291b | 132 | sprintf(answer,"+r!"); |
SandraK | 0:d156731c291b | 133 | handled = true; |
SandraK | 0:d156731c291b | 134 | } |
SandraK | 0:d156731c291b | 135 | break; |
SandraK | 0:d156731c291b | 136 | |
SandraK | 0:d156731c291b | 137 | case 'e': |
SandraK | 0:d156731c291b | 138 | case 'E': { |
SandraK | 0:d156731c291b | 139 | DEBUG("handle e\n"); |
SandraK | 0:d156731c291b | 140 | if(echoBM019()) { |
SandraK | 0:d156731c291b | 141 | DEBUG("BM019 sent echo\n"); |
SandraK | 0:d156731c291b | 142 | sprintf(answer,"+e!"); |
SandraK | 0:d156731c291b | 143 | } else { |
SandraK | 0:d156731c291b | 144 | DEBUG("BM019 NOT sent echo\n"); |
SandraK | 0:d156731c291b | 145 | sprintf(answer,"-e!"); |
SandraK | 0:d156731c291b | 146 | } |
SandraK | 0:d156731c291b | 147 | handled = true; |
SandraK | 0:d156731c291b | 148 | } |
SandraK | 0:d156731c291b | 149 | break; |
SandraK | 0:d156731c291b | 150 | |
SandraK | 0:d156731c291b | 151 | case 't': |
SandraK | 0:d156731c291b | 152 | case 'T': { |
SandraK | 0:d156731c291b | 153 | DEBUG("handle t\n"); |
SandraK | 0:d156731c291b | 154 | BM019_TAG tag; |
SandraK | 0:d156731c291b | 155 | if(inventoryISO_IES_15693BM019(&tag)) { |
SandraK | 0:d156731c291b | 156 | DEBUG("BM019 answered inventory\n"); |
SandraK | 0:d156731c291b | 157 | sprintf(answer,"+t:"); |
SandraK | 0:d156731c291b | 158 | for(int i = 0; i < 8; i++) { |
SandraK | 0:d156731c291b | 159 | sprintf(&answer[strlen(answer)],"%02x",tag.uid[i]); |
SandraK | 0:d156731c291b | 160 | } |
SandraK | 0:d156731c291b | 161 | sprintf(&answer[strlen(answer)],"!"); |
SandraK | 0:d156731c291b | 162 | } else { |
SandraK | 0:d156731c291b | 163 | DEBUG("BM019 NOT answered inventory\n"); |
SandraK | 0:d156731c291b | 164 | sprintf(answer,"-t!"); |
SandraK | 0:d156731c291b | 165 | } |
SandraK | 0:d156731c291b | 166 | handled = true; |
SandraK | 0:d156731c291b | 167 | } |
SandraK | 0:d156731c291b | 168 | break; |
SandraK | 0:d156731c291b | 169 | |
SandraK | 0:d156731c291b | 170 | case 'd': |
SandraK | 0:d156731c291b | 171 | case 'D': { |
SandraK | 0:d156731c291b | 172 | DEBUG("handle d\n"); |
SandraK | 0:d156731c291b | 173 | if(i + 5 <= bytesRead) { |
SandraK | 0:d156731c291b | 174 | int adr = 0; |
SandraK | 0:d156731c291b | 175 | char b[3]; |
SandraK | 0:d156731c291b | 176 | b[0] = params->data[i+4]; |
SandraK | 0:d156731c291b | 177 | b[1] = params->data[i+5]; |
SandraK | 0:d156731c291b | 178 | b[2] = 0; |
SandraK | 0:d156731c291b | 179 | sscanf(b,"%x",&adr); |
SandraK | 0:d156731c291b | 180 | DEBUG("read from %#04x\n",adr); |
SandraK | 0:d156731c291b | 181 | i+=5; |
SandraK | 0:d156731c291b | 182 | uint8_t rb[256]; |
SandraK | 0:d156731c291b | 183 | int l = readBM019(adr,rb,256); |
SandraK | 0:d156731c291b | 184 | if(l>0) { |
SandraK | 0:d156731c291b | 185 | DEBUG("BM019 answered read\n"); |
SandraK | 0:d156731c291b | 186 | sprintf(answer,"+d:"); |
SandraK | 0:d156731c291b | 187 | for(int i = 0; i < l; i++) { |
SandraK | 0:d156731c291b | 188 | sprintf(&answer[strlen(answer)],"%02x",rb[i]); |
SandraK | 0:d156731c291b | 189 | } |
SandraK | 0:d156731c291b | 190 | sprintf(&answer[strlen(answer)],"!"); |
SandraK | 0:d156731c291b | 191 | } else { |
SandraK | 0:d156731c291b | 192 | DEBUG("BM019 NOT answered read\n"); |
SandraK | 0:d156731c291b | 193 | sprintf(answer,"-d!"); |
SandraK | 0:d156731c291b | 194 | } |
SandraK | 0:d156731c291b | 195 | } else { |
SandraK | 0:d156731c291b | 196 | DEBUG("BM019 NOT answered read, no adr given\n"); |
SandraK | 0:d156731c291b | 197 | sprintf(answer,"-d!"); |
SandraK | 0:d156731c291b | 198 | } |
SandraK | 0:d156731c291b | 199 | handled = true; |
SandraK | 0:d156731c291b | 200 | } |
SandraK | 0:d156731c291b | 201 | break; |
SandraK | 0:d156731c291b | 202 | |
SandraK | 0:d156731c291b | 203 | case 'm': |
SandraK | 0:d156731c291b | 204 | case 'M': { |
SandraK | 0:d156731c291b | 205 | DEBUG("handle multi d\n"); |
SandraK | 0:d156731c291b | 206 | if(i + 10 <= bytesRead) { |
SandraK | 0:d156731c291b | 207 | int adr = 0; |
SandraK | 0:d156731c291b | 208 | char b[3]; |
SandraK | 0:d156731c291b | 209 | b[0] = params->data[i+4]; |
SandraK | 0:d156731c291b | 210 | b[1] = params->data[i+5]; |
SandraK | 0:d156731c291b | 211 | b[2] = 0; |
SandraK | 0:d156731c291b | 212 | sscanf(b,"%x",&adr); |
SandraK | 0:d156731c291b | 213 | |
SandraK | 0:d156731c291b | 214 | int count = 0; |
SandraK | 0:d156731c291b | 215 | b[0] = params->data[i+9]; |
SandraK | 0:d156731c291b | 216 | b[1] = params->data[i+10]; |
SandraK | 0:d156731c291b | 217 | b[2] = 0; |
SandraK | 0:d156731c291b | 218 | sscanf(b,"%x",&count); |
SandraK | 0:d156731c291b | 219 | DEBUG("read from %#04x for %d\n",adr,count); |
SandraK | 0:d156731c291b | 220 | i+=10; |
SandraK | 0:d156731c291b | 221 | uint8_t rb[256]; |
SandraK | 0:d156731c291b | 222 | int l = readMultiBM019(adr,count,rb,256); |
SandraK | 0:d156731c291b | 223 | if(l>0) { |
SandraK | 0:d156731c291b | 224 | DEBUG("BM019 answered multi\n"); |
SandraK | 0:d156731c291b | 225 | sprintf(answer,"+m:"); |
SandraK | 0:d156731c291b | 226 | for(int i = 0; i < l; i++) { |
SandraK | 0:d156731c291b | 227 | sprintf(&answer[strlen(answer)],"%02x",rb[i]); |
SandraK | 0:d156731c291b | 228 | } |
SandraK | 0:d156731c291b | 229 | sprintf(&answer[strlen(answer)],"!"); |
SandraK | 0:d156731c291b | 230 | } else { |
SandraK | 0:d156731c291b | 231 | DEBUG("BM019 NOT answered multi\n"); |
SandraK | 0:d156731c291b | 232 | sprintf(answer,"-m!"); |
SandraK | 0:d156731c291b | 233 | } |
SandraK | 0:d156731c291b | 234 | } else { |
SandraK | 0:d156731c291b | 235 | DEBUG("BM019 NOT answered read, no adr&count given\n"); |
SandraK | 0:d156731c291b | 236 | sprintf(answer,"-m!"); |
SandraK | 0:d156731c291b | 237 | } |
SandraK | 0:d156731c291b | 238 | handled = true; |
SandraK | 0:d156731c291b | 239 | } |
SandraK | 0:d156731c291b | 240 | break; |
SandraK | 0:d156731c291b | 241 | } |
SandraK | 0:d156731c291b | 242 | } |
SandraK | 0:d156731c291b | 243 | |
SandraK | 0:d156731c291b | 244 | if(handled) { |
SandraK | 0:d156731c291b | 245 | DEBUG("writing \"%s\" with len %d to ble\n",answer,strlen(answer)); |
SandraK | 0:d156731c291b | 246 | int l = strlen(answer); |
SandraK | 0:d156731c291b | 247 | for(int i = 0; i*20 < strlen(answer); i++) { |
SandraK | 0:d156731c291b | 248 | int len = 20 < l ? 20 : l; |
SandraK | 0:d156731c291b | 249 | ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t *)&answer[i*20], len); |
SandraK | 0:d156731c291b | 250 | l -= 20; |
SandraK | 0:d156731c291b | 251 | } |
SandraK | 0:d156731c291b | 252 | |
SandraK | 0:d156731c291b | 253 | } else { |
SandraK | 0:d156731c291b | 254 | DEBUG("received %u bytes.. nothing handled.. echo\n", bytesRead); |
SandraK | 0:d156731c291b | 255 | ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); |
SandraK | 0:d156731c291b | 256 | } |
SandraK | 0:d156731c291b | 257 | } |
SandraK | 0:d156731c291b | 258 | } |
SandraK | 0:d156731c291b | 259 | |
SandraK | 0:d156731c291b | 260 | int main(void) |
SandraK | 0:d156731c291b | 261 | { |
SandraK | 0:d156731c291b | 262 | initBM019(); |
SandraK | 0:d156731c291b | 263 | |
SandraK | 0:d156731c291b | 264 | DEBUG("Initialising the nRF51822\n\r"); |
SandraK | 0:d156731c291b | 265 | ble.init(); |
SandraK | 0:d156731c291b | 266 | ble.onDisconnection(disconnectionCallback); |
SandraK | 0:d156731c291b | 267 | ble.onDataWritten(onDataWritten); |
SandraK | 0:d156731c291b | 268 | |
SandraK | 0:d156731c291b | 269 | /* setup advertising */ |
SandraK | 0:d156731c291b | 270 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); |
SandraK | 0:d156731c291b | 271 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
SandraK | 0:d156731c291b | 272 | //ble.setAdvertisingType(GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED); |
SandraK | 0:d156731c291b | 273 | ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
SandraK | 0:d156731c291b | 274 | (const uint8_t *)"BLE UART2NFC", sizeof("BLE UART2NFC") - 1); |
SandraK | 0:d156731c291b | 275 | |
SandraK | 0:d156731c291b | 276 | |
SandraK | 0:d156731c291b | 277 | /*ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, |
SandraK | 0:d156731c291b | 278 | (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); |
SandraK | 0:d156731c291b | 279 | */ |
SandraK | 0:d156731c291b | 280 | |
SandraK | 0:d156731c291b | 281 | ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, |
SandraK | 0:d156731c291b | 282 | (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); |
SandraK | 0:d156731c291b | 283 | ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */ |
SandraK | 0:d156731c291b | 284 | //ble.setAdvertisingTimeout(0x1); |
SandraK | 0:d156731c291b | 285 | ble.startAdvertising(); |
SandraK | 0:d156731c291b | 286 | |
SandraK | 0:d156731c291b | 287 | UARTService uartService(ble); |
SandraK | 0:d156731c291b | 288 | uartServicePtr = &uartService; |
SandraK | 0:d156731c291b | 289 | |
SandraK | 0:d156731c291b | 290 | while (true) { |
SandraK | 0:d156731c291b | 291 | ble.waitForEvent(); |
SandraK | 0:d156731c291b | 292 | } |
SandraK | 0:d156731c291b | 293 | } |