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

Dependencies:   BLE_API mbed nRF51822

Files at this revision

API Documentation at this revision

Comitter:
SandraK
Date:
Fri Apr 22 06:06:15 2016 +0000
Commit message:
initial commit of uart based bm019 firmware

Changed in this revision

BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
bm019.cpp Show annotated file Show diff for this revision Revisions of this file
bm019.h Show annotated file Show diff for this revision Revisions of this file
log.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_API.lib	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#66159681aa21
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bm019.cpp	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,431 @@
+#include "bm019.h"
+
+volatile uint8_t rxBuffer[BM019_MAX_RX];
+
+uint8_t BM019_CMD_IDN[] = {2,0x01,0x00};
+
+uint8_t BM019_CMD_ECHO[] = {1,0x55};
+
+uint8_t BM019_CMD_PROTOCOL_START[] = {2,0x02,0x02};
+uint8_t BM019_CMD_PROTOCOL_ISO_IEC_15693[] = {2,0x01,0x00};
+uint8_t BM019_CMD_PROTOCOL_OFF[] = {2,0x00,0x00};
+
+uint8_t BM019_CMD_HYBERNATE[] = {15,
+                                 0x07, //idle
+                                 0x0E, //14 bytes
+                                 0x08, //WU source low pulse irq
+                                 0x04, 0x00, //Enter Control hybernate
+                                 0x04, 0x00, //WU Control hybernate
+                                 0x18, 0x00, //Leave Control hybernate
+                                 0x00, //WU Period 0
+                                 0x00, //Osc Start
+                                 0x00, //DAC Start
+                                 0x00, 0x00, //DAC Data
+                                 0x00, //Swing Count
+                                 0x00  //Max Sleep
+                                };
+
+uint8_t BM019_CMD_ISO_IEC_15693_INVENTORY[] = {5, 0x04, //send recieve
+        0x03,//length
+        0x26, //options:
+        /*
+         0 -> bit 0: Subcarrier 0 = ask, 1 =fsk
+         1 -> bit 1: uplink data rate 0 = low, 1 = high
+         1 -> bit 2: inventory flags 0 -> a), 1 -> b)
+         0 -> bit 3: proto extension = 0
+         a)
+         bit 4: select flag 0 = if(bit 5 = 1 address mode)
+         bit 5: address flag 1 = use address
+         bit 6: for write = 1, else 0
+         bit 7: future usage, always 0
+         b)
+         0 -> bit 4: afi flag 0 = no afi, 1 = afi (Application family identification)
+         1 -> bit 5: slot flag, 0 -> 16 slots, 1 -> 1 slot
+         0 -> bit 6: for write = 1, else 0
+         0 -> bit 7: future usage, always 0
+
+         */
+        0x01, // inventory command
+        0x00 // do not know why i sent it, maybe useless?
+                                              };
+
+uint8_t BM019_CMD_READ[] = {5,
+                            0x04, //send recieve
+                            0x03, //length
+                            0x02, //options
+                            0x20, //read
+                            0x00  //Address
+
+                           };
+uint8_t BM019_CMD_READ_MULTI[] = {6,
+                                  0x04, //send recieve
+                                  0x00, //length
+                                  0x02, //options
+                                  0x23, //read
+                                  0x00, //address
+                                  0x00  //count
+                                 };
+enum BM019_PROTOCOL {
+    BM019_PROTOCOL_Field_OFF = 0x00,
+    BM019_PROTOCOL_ISO_IEC_15693 = 0x01,
+    //other not yet supported!
+    BM019_PROTOCOL_ISO_IEC_14443_Type_A = 0x02,// also NFC Forum Tag Type 1 (Topaz), NFC Forum Tag Type 2, NFC Forum Tag Type 4A
+    BM019_PROTOCOL_ISO_IEC_14443_Type_B = 0x03,// also NFC Forum Tag Type 4B
+    BM019_PROTOCOL_ISO_IEC_18092 = 0x04 // also NFC Forum Tag Type 3
+};
+
+Serial serial(BM019_TX, BM019_RX);
+
+BM019_STATE stateBM019 = BM019_STATE_UNKNOWN;
+
+int write_read(uint8_t *tx_buf, int tx_len, int timeout = BM019_READY_TIMEOUT); //write, poll, read
+
+/*bool stateAtLeast(BM019_STATE requiredState)
+{
+    if(stateBM019 < requiredState)
+    {
+        DEBUG("required state %d, having state %d",requiredState,stateBM019);
+        return false;
+    }
+    return true;
+}*/
+
+bool resetBM019()
+{
+    if(stateBM019 < BM019_STATE_ANSWERING) {
+        DEBUG("IDN failed, bm019 not answering\n");
+        return false;
+    }
+    DEBUG("BM019: reset\n");
+    wait_ms(20);
+    stateBM019 = BM019_STATE_UNKNOWN;
+    return true;
+}
+
+bool echoBM019(int timeout, bool log)
+{
+    if(log) {
+        DEBUG("BM019: echo\n");
+    }
+    int len = write_read(&BM019_CMD_ECHO[1],BM019_CMD_ECHO[0], timeout);
+    if(len>=1 && rxBuffer[0] == 0x55) {
+        stateBM019 = stateBM019 > BM019_STATE_ANSWERING ? stateBM019 : BM019_STATE_ANSWERING;
+        return true;
+    } else {
+        if(log) {
+            DEBUG("recievedlen: %d \n",len);
+
+            for(int i = 0; i < len; i++)
+                DEBUG("rx[%d]: %#x\n",i,rxBuffer[i]);
+        }
+    }
+    stateBM019 = BM019_STATE_UNKNOWN;
+    return false;
+}
+
+BM019_STATE getStateBM019()
+{
+    return stateBM019;
+}
+
+bool wakeBM019(int timeout)
+{
+    DEBUG("BM019: wake\n");
+    serial.send_break();
+    wait_ms(timeout);
+    int t = 10;
+
+    stateBM019 = BM019_STATE_UNKNOWN;
+    while(!echoBM019(10,false) && t > 0) {
+        wait_ms(10);
+        t--;
+    }
+    if(t<0) {
+        return false;
+    }
+    return true;
+}
+
+void write(uint8_t *tx_buf, int tx_len, int timeout = BM019_READY_TIMEOUT)
+{
+    if(timeout) {
+        Timer t;
+        t.start();
+        for(int i = 0; i < tx_len; i++) {
+            while (!serial.writeable()) {
+                wait_ms(1);
+                if(t.read_ms()>timeout) {
+                    return;
+                }
+            }
+            serial.putc(tx_buf[i]);
+        }
+    } else {
+        for(int i = 0; i < tx_len; i++) {
+            if (!serial.writeable()) {
+                return;
+            }
+            serial.putc(tx_buf[i]);
+        }
+    }
+}
+
+int readBM019()
+{
+    rxBuffer[0] = serial.getc();
+    int len = 0;
+    if(rxBuffer[0] != 0x55) {
+        len = rxBuffer[1] = serial.getc();
+        for(int i = 0; i < len && i < BM019_MAX_RX; i++) {
+            rxBuffer[i+2] = serial.getc();
+        }
+        len += 2;
+    } else {
+        len = 1;
+    }
+    return len;
+}
+
+int write_read(uint8_t *tx_buf, int tx_len, int timeout)
+{
+    if(timeout) {
+        Timer t;
+        t.start();
+        while (serial.readable()) {
+            serial.getc();
+            if(t.read_ms()>timeout) {
+                return 0;
+            }
+        }
+        write(tx_buf, tx_len, timeout);
+        while (!serial.readable()) {
+            wait_ms(1);
+            if(t.read_ms()>timeout) {
+                return 0;
+            }
+        }
+        return readBM019();
+    } else {
+        while (serial.readable()) {
+            serial.getc();
+        }
+        write(tx_buf, tx_len, timeout);
+        while (!serial.readable()) {
+            return 0;
+        }
+        return readBM019();
+    }
+}
+
+bool setProtocolISO_EIC_15693BM019(BM019_PROTOCOL_ISO_IEC_15693_BYTE_0 configuration)
+{
+    if(stateBM019 < BM019_STATE_ANSWERING) {
+        DEBUG("SETTING Protocol failed, bm019 not answering\n");
+        return false;
+    }
+    DEBUG("SETTING Protocol to iso/iec 15693: %#x\n",configuration);
+
+    int len = BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_ISO_IEC_15693[0];
+
+    uint8_t iso[BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_ISO_IEC_15693[0]];
+    memcpy(iso,&BM019_CMD_PROTOCOL_START[1],BM019_CMD_PROTOCOL_START[0]);
+    memcpy(&iso[BM019_CMD_PROTOCOL_START[0]],&BM019_CMD_PROTOCOL_ISO_IEC_15693[1],BM019_CMD_PROTOCOL_ISO_IEC_15693[0]);
+    iso[len-1] = configuration;
+
+    int recieved = write_read(iso,len,20);
+    if(recieved  >= 2 && rxBuffer[0] == 0x00 && rxBuffer[1] == 0x00) {
+        stateBM019 = stateBM019 > BM019_STATE_PROTOCOL ? stateBM019 : BM019_STATE_PROTOCOL;
+        return true;
+    } else {
+        DEBUG("SETTING Protocol failed: %#x\n",rxBuffer[0]);
+        stateBM019 = BM019_STATE_UNKNOWN;
+        return false;
+    }
+}
+
+bool setProtocolOFF()
+{
+    if(stateBM019 < BM019_STATE_ANSWERING) {
+        DEBUG("SETTING Protocol failed, bm019 not answering\n");
+        return false;
+    }
+    DEBUG("SETTING Protocol to OFF\n");
+
+    int len = BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_OFF[0];
+    uint8_t off[BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_OFF[0]];
+    memcpy(off,&BM019_CMD_PROTOCOL_START[1],BM019_CMD_PROTOCOL_START[0]);
+    memcpy(&off[BM019_CMD_PROTOCOL_START[0]],&BM019_CMD_PROTOCOL_OFF[1],BM019_CMD_PROTOCOL_OFF[0]);
+
+    int recieved = write_read(off,len,20);
+    if(recieved  >= 2 && rxBuffer[0] == 0x00 && rxBuffer[1] == 0x00) {
+        stateBM019 = BM019_STATE_ANSWERING;
+        return true;
+    } else {
+        DEBUG("SETTING Protocol failed: %#x\n",rxBuffer[0]);
+        stateBM019 = BM019_STATE_UNKNOWN;
+        return false;
+    }
+}
+
+bool idnBM019(BM019_IDN *idn)
+{
+    if(stateBM019 < BM019_STATE_ANSWERING) {
+        DEBUG("IDN failed, bm019 not answering\n");
+        return false;
+    }
+    int len = write_read(&BM019_CMD_IDN[1],BM019_CMD_IDN[0]);
+    if(len == 17) {
+        memcpy(idn->deviceID,(const void *)&rxBuffer[2],13);
+        memcpy(idn->romCRC,(const void *)&rxBuffer[15],2);
+        return true;
+    }
+    return false;
+
+}
+
+bool hybernateBM019()
+{
+    if(stateBM019 < BM019_STATE_ANSWERING) {
+        DEBUG("SETTING HYBERNATE failed, bm019 not answering\n");
+        return false;
+    }
+
+    DEBUG("HYBERNATE bm019 (FIELD_OFF and POWER_DOWN)\n");
+    if(setProtocolOFF()) {
+        write(&BM019_CMD_HYBERNATE[1],BM019_CMD_HYBERNATE[0]);
+        stateBM019 = BM019_STATE_UNKNOWN;
+        return true;
+    }
+    return false;
+}
+
+
+bool inventoryISO_IES_15693BM019(BM019_TAG *tag, int timeout)
+{
+    if(stateBM019 < BM019_STATE_PROTOCOL) {
+        DEBUG("inventory failed, bm019 not in protocol\n");
+        return false;
+    }
+
+    DEBUG("inventory..");
+
+    int len = write_read(&BM019_CMD_ISO_IEC_15693_INVENTORY[1],BM019_CMD_ISO_IEC_15693_INVENTORY[0]);
+
+    DEBUG("got answer len()=%d\n",len);
+    for(int i = 0; i < len; i++) {
+        DEBUG("%#04x ",rxBuffer[i]);
+    }
+    DEBUG("\n");
+
+    if(rxBuffer[0] != EFrameRecvOK) {
+        DEBUG("got error %#04x\n",rxBuffer[0]);
+        return false;
+    }
+
+    int tlen = rxBuffer[1];
+    if(tlen < 11) {
+        DEBUG("to few bytes recieved \n");
+        return false;
+    }
+    /* this does not work very good, maybe something misinterpreted from docs
+    if(rxBuffer[tlen-1] & 0x01) {
+        DEBUG("got collision \n");
+        return false;
+    }
+    if(rxBuffer[tlen-1] & 0x02) {
+        DEBUG("got bad crc \n");
+        return false;
+    }*/
+    tag->crc[0] = rxBuffer[tlen-2];
+    tag->crc[1] = rxBuffer[tlen-3];
+
+    for(int i = 0; i < 9; i++) {
+        tag->uid[i] = rxBuffer[11-i];
+    }
+    return true;
+
+}
+
+int readBM019(uint8_t adr, uint8_t *buf, int len, int timeout)
+{
+    if(stateBM019 < BM019_STATE_PROTOCOL) {
+        DEBUG("read failed, bm019 not in protocol\n");
+        return -1;
+    }
+    uint8_t cmd[BM019_CMD_READ[0]];
+    memcpy(cmd,&BM019_CMD_READ[1],BM019_CMD_READ[0]);
+    cmd[BM019_CMD_READ[0]-1] = adr & 0xFF;
+
+    DEBUG("read at %#4X..\n",adr);
+    for(int i = 0; i < BM019_CMD_READ[0]; i++) {
+        DEBUG("%#04x ",cmd[i]);
+    }
+    int tx = write_read(cmd,BM019_CMD_READ[0]);
+
+    DEBUG("got answer len()=%d\n",tx);
+    for(int i = 0; i < tx; i++) {
+        DEBUG("%#04x ",rxBuffer[i]);
+    }
+    DEBUG("\n");
+    if(rxBuffer[0] != EFrameRecvOK) {
+        DEBUG("got error %#04x\n",rxBuffer[0]);
+        return -1;
+    }
+
+    DEBUG("flags: %#04x\n",rxBuffer[2]);
+    int tlen = rxBuffer[1]-4;
+    if(tlen <=0)
+        return -1;
+    DEBUG("read resultet in %d bytes, copying %d bytes\n",rxBuffer[1],(tlen < len ? tlen : len));
+    tlen = (tlen < len ? tlen : len);
+    memcpy(buf,(const void *)&rxBuffer[3],tlen);
+
+    return tlen;
+}
+
+int readMultiBM019(uint8_t adr, int count, uint8_t *buf, int len, int timeout)
+{
+    if(stateBM019 < BM019_STATE_PROTOCOL) {
+        DEBUG("multi read failed, bm019 not in protocol\n");
+        return -1;
+    }
+    uint8_t cmd[BM019_CMD_READ_MULTI[0]];
+    memcpy(cmd,&BM019_CMD_READ_MULTI[1],BM019_CMD_READ_MULTI[0]);
+    cmd[BM019_CMD_READ_MULTI[0]-2] = adr & 0xFF;
+    cmd[BM019_CMD_READ_MULTI[0]-1] = (count-1) & 0xFF;
+
+    DEBUG("multi read at %#4X for %d..\n",adr, count & 0xFF);
+    for(int i = 0; i < BM019_CMD_READ_MULTI[0]; i++) {
+        DEBUG("%#04x ",cmd[i]);
+    }
+    int tx = write_read(cmd,BM019_CMD_READ_MULTI[0]);
+
+    DEBUG("got answer len()=%d\n",tx);
+    for(int i = 0; i < tx; i++) {
+        DEBUG("%02x ",rxBuffer[i]);
+    }
+    DEBUG("\n");
+    if(rxBuffer[0] != EFrameRecvOK) {
+        DEBUG("got error %#04x\n",rxBuffer[0]);
+        return -1;
+    }
+
+    DEBUG("flags: %#04x\n",rxBuffer[2]);
+    int tlen = rxBuffer[1]-4;
+    if(tlen <=0)
+        return -1;
+    DEBUG("read resultet in %d bytes, copying %d bytes\n",rxBuffer[1],(tlen < len ? tlen : len));
+    tlen = (tlen < len ? tlen : len);
+    memcpy(buf,(const void *)&rxBuffer[3],tlen);
+
+    return tlen;
+}
+bool initBM019()
+{
+    DEBUG("BM019: init\n");
+    serial.format(8,SerialBase::None,2);
+    serial.baud(57600);
+    serial.send_break();
+    stateBM019 = BM019_STATE_UNKNOWN;
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bm019.h	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,87 @@
+
+#ifndef BM019_H
+#define BM019_H
+
+#include "log.h"
+#include "mbed.h"
+
+#define BM019_TX p9
+#define BM019_RX p11
+
+#define BM019_MAX_RX 512
+#define BM019_READY_TIMEOUT 50 /* 0 for endless waiting else  ms to wait */
+
+enum BM019_PROTOCOL_ISO_IEC_15693_BYTE_0 {
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_0_NO_CRC = 0x00,
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_0_CRC = 0x01,
+
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_1_SINGLE_SUBCARRIER = 0x00,
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_1_DUAL_SUBCARRIER = 0x02,
+
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_2_100_MODULATION = 0x00,
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_2_10_MODULATION = 0x04,
+
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_3_RESPECT_312U_DELAY = 0x00,
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_3_WAIT_FOR_SOF = 0x08,
+
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_45_26_KBPS = 0x00,
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_45_52_KBPS = 0x10,
+    BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_45_6_KBPS = 0x20
+};
+
+enum BM019_CODES {
+    EFrameRecvOK    = 0x80, // Frame correctly received (additionally see CRC/Parity information)
+    EUserStop       = 0x85, // Stopped by user (used only in Card mode)
+    ECommError      = 0x86, // Hardware communication error
+    EFrameWaitTOut  = 0x87, // Frame wait time out (no valid reception)
+    EInvalidSof     = 0x88, // Invalid SOF
+    EBufOverflow    = 0x89, // Too many bytes received and data still arriving
+    EFramingError   = 0x8A, // if start bit = 1 or stop bit = 0
+    EEgtError       = 0x8B, // EGT time out
+    EInvalidLen     = 0x8C, // Valid for ISO/IEC 18092, if Length <3
+    ECrcError       = 0x8D, // CRC error, Valid only for ISO/IEC 18092
+    ERecvLost       = 0x8E, // When reception is lost without EOF received (or subcarrier was lost)
+    ENoField        = 0x8F, // When Listen command detects the absence of external field
+    EUnintByte      = 0x90, //Residual bits in last byte. Useful for ACK/NAK reception of ISO/IEC 14443 Type A.
+};
+
+enum BM019_STATE {
+    BM019_STATE_UNKNOWN   = 0, //intial condition
+    BM019_STATE_ANSWERING = 1, //if any communiaction has been successful
+    BM019_STATE_PROTOCOL  = 2, //a protocol (other then off) has been set
+
+};
+
+extern BM019_STATE stateBM019;
+
+struct BM019_IDN
+{
+    char deviceID[13];
+    char romCRC[2];
+};
+
+struct BM019_TAG {
+    uint8_t crc[2];
+    uint8_t uid[8];
+};
+
+BM019_STATE getStateBM019();
+
+bool initBM019();
+
+bool resetBM019();
+bool wakeBM019(int timeout = BM019_READY_TIMEOUT);
+bool hybernateBM019();
+
+bool idnBM019(BM019_IDN *idn);
+
+bool setProtocolOFF();
+bool setProtocolISO_EIC_15693BM019(BM019_PROTOCOL_ISO_IEC_15693_BYTE_0 configuration);
+
+bool echoBM019(int timeout = BM019_READY_TIMEOUT, bool log = true);
+
+bool inventoryISO_IES_15693BM019(BM019_TAG *tag, int timeout = BM019_READY_TIMEOUT);
+
+int readBM019(uint8_t adr, uint8_t *buf, int len, int timeout = BM019_READY_TIMEOUT);
+int readMultiBM019(uint8_t adr, int count, uint8_t *buf, int len, int timeout = BM019_READY_TIMEOUT);
+#endif /* BM019_H   */
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/log.h	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,18 @@
+
+#ifndef LOG_H
+#define LOG_H
+
+#define NEED_CONSOLE_OUTPUT 0 
+/* DO NOT Set to 1 !! 
+ * the nrf51 has only one uart and we need it for uart com
+ */
+
+#include "mbed.h"
+
+#if NEED_CONSOLE_OUTPUT
+#define DEBUG(...) { printf(__VA_ARGS__); }
+#else
+#define DEBUG(...) /* nothing */
+#endif /* #if NEED_CONSOLE_OUTPUT */
+
+#endif /* #if ndef LOG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,328 @@
+#include "mbed.h"
+#include "ble/BLE.h"
+
+#include "ble/services/UARTService.h"
+
+#include "log.h"
+/*
+ This is an example of using the implemented functions of the bm019-library with an nrf51, acting as UART-Service.
+ This code uses the spi version of the interface.
+ */
+#include "bm019.h"
+
+BLEDevice  ble;
+UARTService *uartServicePtr;
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
+{
+    DEBUG("Disconnected!\n\r");
+    DEBUG("Restarting the advertising process\n\r");
+    ble.startAdvertising();
+}
+char answer[512];
+
+Ticker ticker;
+void timerCallback(void)
+{
+    DEBUG("start timer callback");
+    sprintf(answer,"+.!");
+    DEBUG("writing beatpulse \"%s\" with len %d to ble\n",answer,strlen(answer));
+    int l = strlen(answer);
+    for(int i = 0; i*20 < strlen(answer); i++) {
+        int len = 20 < l ? 20 : l;
+        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t *)&answer[i*20], len);
+        l -= 20;
+    }
+    ticker.detach();
+}
+void onDataWritten(const GattWriteCallbackParams *params)
+{
+    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
+        uint16_t bytesRead = params->len;
+        bool handled = false;
+
+
+        for(int i = 0; !handled && i < bytesRead; i++) {
+            switch(params->data[i]) {
+                case '?': {
+                    DEBUG("Handle ?\n");
+                    switch(getStateBM019()) {
+                        case BM019_STATE_UNKNOWN:
+                            DEBUG("BM019 Status: unknown\n");
+                            sprintf(answer,"+?:0!");
+                            break;
+                        case BM019_STATE_ANSWERING:
+                            DEBUG("BM019 Status: answering\n");
+                            sprintf(answer,"+?:1!");
+                            break;
+                        case BM019_STATE_PROTOCOL:
+                            DEBUG("BM019 Status: protocol set\n");
+                            sprintf(answer,"+?:2!");
+                            break;
+                        default:
+                            sprintf(answer,"-?%d!",getStateBM019());
+                            DEBUG("BM019 Status: forgotten state\n");
+                    }
+                    handled = true;
+                }
+                break;
+
+                case 'b':
+                case 'B':
+                    DEBUG("Handling b\n");
+                    if(i + 5 <= bytesRead) {
+                        sprintf(answer,"+b!");
+                        int adr = 0;
+                        char b[3];
+                        b[0] = params->data[i+4];
+                        b[1] = params->data[i+5];
+                        b[2] = 0;
+                        sscanf(b,"%x",&adr);
+                        DEBUG("beat in %d sec\n",adr);
+                        ticker.attach(timerCallback, adr);
+                        i+=5;
+                        handled=true;
+                    } else {
+                        sprintf(answer,"-b!");
+                        handled=true;
+                    }
+
+                    break;
+                case 'h':
+                case 'H': {
+                    DEBUG("Handling h\n");
+                    if(hybernateBM019()) {
+                        sprintf(answer,"+h!");
+                    } else {
+                        DEBUG("BM019 did hybernate wake\n")
+                        sprintf(answer,"-h!");
+                    }
+                    handled=true;
+
+                }
+                break;
+
+                case 'w':
+                case 'W': {
+                    DEBUG("handle w\n")
+
+                    if(wakeBM019(100)) {
+                        DEBUG("BM019 did wake\n")
+                        sprintf(answer,"+w!");
+                    } else {
+                        DEBUG("BM019 did NOT wake\n")
+                        sprintf(answer,"-w!");
+                    }
+                    handled = true;
+                }
+                break;
+
+                case 'i':
+                case 'I': {
+                    DEBUG("handle i\n");
+                    BM019_IDN idn;
+                    if(idnBM019(&idn)) {
+                        sprintf(answer,"+i:");
+                        int i;
+                        for(i = 0; i < 13; i++) {
+                            sprintf(&answer[strlen(answer)],"%x",idn.deviceID[i]);
+                        }
+                        sprintf(&answer[strlen(answer)],":");
+                        sprintf(&answer[strlen(answer)],"%x%x!",idn.romCRC[0],idn.romCRC[1]);
+                        DEBUG("answered: %s",answer);
+                    } else {
+                        DEBUG("BM019 failed idn\n")
+                        sprintf(answer,"-i!");
+                    }
+
+                    handled = true;
+                }
+                break;
+
+                case 'p':
+                case 'P': {
+                    DEBUG("handle p\n");
+                    if(setProtocolISO_EIC_15693BM019((BM019_PROTOCOL_ISO_IEC_15693_BYTE_0)(
+                                                         BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_0_CRC |
+                                                         BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_1_SINGLE_SUBCARRIER |
+                                                         BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_2_10_MODULATION |
+                                                         BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_3_WAIT_FOR_SOF |
+                                                         BM019_PROTOCOL_ISO_IEC_15693_BYTE_0_45_26_KBPS)
+                                                    )) {
+                        DEBUG("BM019 proto\n")
+                        sprintf(answer,"+p!");
+                    } else {
+                        DEBUG("BM019 failed proto\n")
+                        sprintf(answer,"-p!");
+                    }
+
+                    handled = true;
+                }
+                break;
+
+                case 'r':
+                case 'R': {
+                    DEBUG("handle r\n");
+                    resetBM019();
+                    sprintf(answer,"+r!");
+                    handled = true;
+                }
+                break;
+
+                case 'e':
+                case 'E': {
+                    DEBUG("handle e\n");
+                    if(echoBM019()) {
+                        DEBUG("BM019 sent echo\n");
+                        sprintf(answer,"+e!");
+                    } else {
+                        DEBUG("BM019 NOT sent echo\n");
+                        sprintf(answer,"-e!");
+                    }
+                    handled = true;
+                }
+                break;
+
+                case 't':
+                case 'T': {
+                    DEBUG("handle t\n");
+                    BM019_TAG tag;
+                    if(inventoryISO_IES_15693BM019(&tag)) {
+                        DEBUG("BM019 answered inventory\n");
+                        sprintf(answer,"+t:");
+                        for(int i = 0; i < 8; i++) {
+                            sprintf(&answer[strlen(answer)],"%02x",tag.uid[i]);
+                        }
+                        sprintf(&answer[strlen(answer)],"!");
+                    } else {
+                        DEBUG("BM019 NOT answered inventory\n");
+                        sprintf(answer,"-t!");
+                    }
+                    handled = true;
+                }
+                break;
+
+                case 'd':
+                case 'D': {
+                    DEBUG("handle d\n");
+                    if(i + 5 <= bytesRead) {
+                        int adr = 0;
+                        char b[3];
+                        b[0] = params->data[i+4];
+                        b[1] = params->data[i+5];
+                        b[2] = 0;
+                        sscanf(b,"%x",&adr);
+                        DEBUG("read from %#04x\n",adr);
+                        i+=5;
+                        uint8_t rb[256];
+                        int l = readBM019(adr,rb,256);
+                        if(l>0) {
+                            DEBUG("BM019 answered read\n");
+                            sprintf(answer,"+d:");
+                            for(int i = 0; i < l; i++) {
+                                sprintf(&answer[strlen(answer)],"%02x",rb[i]);
+                            }
+                            sprintf(&answer[strlen(answer)],"!");
+                        } else {
+                            DEBUG("BM019 NOT answered read\n");
+                            sprintf(answer,"-d!");
+                        }
+                    } else {
+                        DEBUG("BM019 NOT answered read, no adr given\n");
+                        sprintf(answer,"-d!");
+                    }
+                    handled = true;
+                }
+                break;
+
+                case 'm':
+                case 'M': {
+                    DEBUG("handle multi d\n");
+                    if(i + 10 <= bytesRead) {
+                        int adr = 0;
+                        char b[3];
+                        b[0] = params->data[i+4];
+                        b[1] = params->data[i+5];
+                        b[2] = 0;
+                        sscanf(b,"%x",&adr);
+
+                        int count = 0;
+                        b[0] = params->data[i+9];
+                        b[1] = params->data[i+10];
+                        b[2] = 0;
+                        sscanf(b,"%x",&count);
+                        DEBUG("read from %#04x for %d\n",adr,count);
+                        i+=10;
+                        uint8_t rb[256];
+                        int l = readMultiBM019(adr,count,rb,256);
+                        if(l>0) {
+                            DEBUG("BM019 answered multi\n");
+                            sprintf(answer,"+m:");
+                            for(int i = 0; i < l; i++) {
+                                sprintf(&answer[strlen(answer)],"%02x",rb[i]);
+                            }
+                            sprintf(&answer[strlen(answer)],"!");
+                        } else {
+                            DEBUG("BM019 NOT answered multi\n");
+                            sprintf(answer,"-m!");
+                        }
+                    } else {
+                        DEBUG("BM019 NOT answered read, no adr&count given\n");
+                        sprintf(answer,"-m!");
+                    }
+                    handled = true;
+                }
+                break;
+            }
+        }
+
+        if(handled) {
+            DEBUG("writing \"%s\" with len %d to ble\n",answer,strlen(answer));
+            int l = strlen(answer);
+            for(int i = 0; i*20 < strlen(answer); i++) {
+                int len = 20 < l ? 20 : l;
+                ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), (uint8_t *)&answer[i*20], len);
+                l -= 20;
+            }
+
+        } else {
+            DEBUG("received %u bytes.. nothing handled.. echo\n", bytesRead);
+            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
+        }
+    }
+}
+
+int main(void)
+{
+    initBM019();
+
+    DEBUG("Initialising the nRF51822\n\r");
+    ble.init();
+    ble.onDisconnection(disconnectionCallback);
+    ble.onDataWritten(onDataWritten);
+
+    /* setup advertising */
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    //ble.setAdvertisingType(GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED);
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
+                                     (const uint8_t *)"BLE UART2NFC", sizeof("BLE UART2NFC") - 1);
+
+
+    /*ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
+                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
+    */
+
+    ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
+                               (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
+    ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */
+    //ble.setAdvertisingTimeout(0x1);
+    ble.startAdvertising();
+
+    UARTService uartService(ble);
+    uartServicePtr = &uartService;
+
+    while (true) {
+        ble.waitForEvent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/082adc85693f
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51822.lib	Fri Apr 22 06:06:15 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#f7faad332abc