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
bm019.cpp
- Committer:
- SandraK
- Date:
- 2016-04-16
- Revision:
- 0:d156731c291b
File content as of revision 0:d156731c291b:
#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 }; SPI spi(BM019_MOSI, BM019_MISO, BM019_CLK); DigitalOut ss(BM019_CS); DigitalOut wake(BM019_IRQ); 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"); ss=0; spi.write(0x01); ss=1; 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"); ss=0; wake = 0; wait_ms(10); wake = 1; ss = 1; 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; } int waitReady(int timeoutMS = 0) { int ready = 0; if(timeoutMS) { Timer t; t.start(); ss=0; while(!ready) { wait_ms(1); ready = spi.write(0x03) & 0x08; if(t.read_ms()>timeoutMS) { break; } } ss = 1; } else { ss=0; while(!ready) { wait_ms(1); ready = spi.write(0x03); ready = ready & 0x08; } ss = 1; } return ready; } void write(uint8_t *tx_buf, int tx_len) { ss=0; spi.write(0x00); for(int i = 0; i < tx_len; i++) { spi.write(tx_buf[i]); } ss=1; } int readBM019() { ss=0; spi.write(0x02); rxBuffer[0] = spi.write(0x00); int len = 0; if(rxBuffer[0] != 0x55) { len = rxBuffer[1] = spi.write(0x00); for(int i = 0; i < len && i < BM019_MAX_RX; i++) { rxBuffer[i+2] = spi.write(0x00); } len += 2; } else { len = 1; } ss=1; return len; } int write_read(uint8_t *tx_buf, int tx_len, int timeout) { write(tx_buf, tx_len); waitReady(timeout); 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"); spi.format(8,3); spi.frequency(1000000); stateBM019 = BM019_STATE_UNKNOWN; return true; }