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
bm019.cpp@0:6bb3a59b5028, 2016-04-22 (annotated)
- Committer:
- SandraK
- Date:
- Fri Apr 22 06:06:15 2016 +0000
- Revision:
- 0:6bb3a59b5028
initial commit of uart based bm019 firmware
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
SandraK | 0:6bb3a59b5028 | 1 | #include "bm019.h" |
SandraK | 0:6bb3a59b5028 | 2 | |
SandraK | 0:6bb3a59b5028 | 3 | volatile uint8_t rxBuffer[BM019_MAX_RX]; |
SandraK | 0:6bb3a59b5028 | 4 | |
SandraK | 0:6bb3a59b5028 | 5 | uint8_t BM019_CMD_IDN[] = {2,0x01,0x00}; |
SandraK | 0:6bb3a59b5028 | 6 | |
SandraK | 0:6bb3a59b5028 | 7 | uint8_t BM019_CMD_ECHO[] = {1,0x55}; |
SandraK | 0:6bb3a59b5028 | 8 | |
SandraK | 0:6bb3a59b5028 | 9 | uint8_t BM019_CMD_PROTOCOL_START[] = {2,0x02,0x02}; |
SandraK | 0:6bb3a59b5028 | 10 | uint8_t BM019_CMD_PROTOCOL_ISO_IEC_15693[] = {2,0x01,0x00}; |
SandraK | 0:6bb3a59b5028 | 11 | uint8_t BM019_CMD_PROTOCOL_OFF[] = {2,0x00,0x00}; |
SandraK | 0:6bb3a59b5028 | 12 | |
SandraK | 0:6bb3a59b5028 | 13 | uint8_t BM019_CMD_HYBERNATE[] = {15, |
SandraK | 0:6bb3a59b5028 | 14 | 0x07, //idle |
SandraK | 0:6bb3a59b5028 | 15 | 0x0E, //14 bytes |
SandraK | 0:6bb3a59b5028 | 16 | 0x08, //WU source low pulse irq |
SandraK | 0:6bb3a59b5028 | 17 | 0x04, 0x00, //Enter Control hybernate |
SandraK | 0:6bb3a59b5028 | 18 | 0x04, 0x00, //WU Control hybernate |
SandraK | 0:6bb3a59b5028 | 19 | 0x18, 0x00, //Leave Control hybernate |
SandraK | 0:6bb3a59b5028 | 20 | 0x00, //WU Period 0 |
SandraK | 0:6bb3a59b5028 | 21 | 0x00, //Osc Start |
SandraK | 0:6bb3a59b5028 | 22 | 0x00, //DAC Start |
SandraK | 0:6bb3a59b5028 | 23 | 0x00, 0x00, //DAC Data |
SandraK | 0:6bb3a59b5028 | 24 | 0x00, //Swing Count |
SandraK | 0:6bb3a59b5028 | 25 | 0x00 //Max Sleep |
SandraK | 0:6bb3a59b5028 | 26 | }; |
SandraK | 0:6bb3a59b5028 | 27 | |
SandraK | 0:6bb3a59b5028 | 28 | uint8_t BM019_CMD_ISO_IEC_15693_INVENTORY[] = {5, 0x04, //send recieve |
SandraK | 0:6bb3a59b5028 | 29 | 0x03,//length |
SandraK | 0:6bb3a59b5028 | 30 | 0x26, //options: |
SandraK | 0:6bb3a59b5028 | 31 | /* |
SandraK | 0:6bb3a59b5028 | 32 | 0 -> bit 0: Subcarrier 0 = ask, 1 =fsk |
SandraK | 0:6bb3a59b5028 | 33 | 1 -> bit 1: uplink data rate 0 = low, 1 = high |
SandraK | 0:6bb3a59b5028 | 34 | 1 -> bit 2: inventory flags 0 -> a), 1 -> b) |
SandraK | 0:6bb3a59b5028 | 35 | 0 -> bit 3: proto extension = 0 |
SandraK | 0:6bb3a59b5028 | 36 | a) |
SandraK | 0:6bb3a59b5028 | 37 | bit 4: select flag 0 = if(bit 5 = 1 address mode) |
SandraK | 0:6bb3a59b5028 | 38 | bit 5: address flag 1 = use address |
SandraK | 0:6bb3a59b5028 | 39 | bit 6: for write = 1, else 0 |
SandraK | 0:6bb3a59b5028 | 40 | bit 7: future usage, always 0 |
SandraK | 0:6bb3a59b5028 | 41 | b) |
SandraK | 0:6bb3a59b5028 | 42 | 0 -> bit 4: afi flag 0 = no afi, 1 = afi (Application family identification) |
SandraK | 0:6bb3a59b5028 | 43 | 1 -> bit 5: slot flag, 0 -> 16 slots, 1 -> 1 slot |
SandraK | 0:6bb3a59b5028 | 44 | 0 -> bit 6: for write = 1, else 0 |
SandraK | 0:6bb3a59b5028 | 45 | 0 -> bit 7: future usage, always 0 |
SandraK | 0:6bb3a59b5028 | 46 | |
SandraK | 0:6bb3a59b5028 | 47 | */ |
SandraK | 0:6bb3a59b5028 | 48 | 0x01, // inventory command |
SandraK | 0:6bb3a59b5028 | 49 | 0x00 // do not know why i sent it, maybe useless? |
SandraK | 0:6bb3a59b5028 | 50 | }; |
SandraK | 0:6bb3a59b5028 | 51 | |
SandraK | 0:6bb3a59b5028 | 52 | uint8_t BM019_CMD_READ[] = {5, |
SandraK | 0:6bb3a59b5028 | 53 | 0x04, //send recieve |
SandraK | 0:6bb3a59b5028 | 54 | 0x03, //length |
SandraK | 0:6bb3a59b5028 | 55 | 0x02, //options |
SandraK | 0:6bb3a59b5028 | 56 | 0x20, //read |
SandraK | 0:6bb3a59b5028 | 57 | 0x00 //Address |
SandraK | 0:6bb3a59b5028 | 58 | |
SandraK | 0:6bb3a59b5028 | 59 | }; |
SandraK | 0:6bb3a59b5028 | 60 | uint8_t BM019_CMD_READ_MULTI[] = {6, |
SandraK | 0:6bb3a59b5028 | 61 | 0x04, //send recieve |
SandraK | 0:6bb3a59b5028 | 62 | 0x00, //length |
SandraK | 0:6bb3a59b5028 | 63 | 0x02, //options |
SandraK | 0:6bb3a59b5028 | 64 | 0x23, //read |
SandraK | 0:6bb3a59b5028 | 65 | 0x00, //address |
SandraK | 0:6bb3a59b5028 | 66 | 0x00 //count |
SandraK | 0:6bb3a59b5028 | 67 | }; |
SandraK | 0:6bb3a59b5028 | 68 | enum BM019_PROTOCOL { |
SandraK | 0:6bb3a59b5028 | 69 | BM019_PROTOCOL_Field_OFF = 0x00, |
SandraK | 0:6bb3a59b5028 | 70 | BM019_PROTOCOL_ISO_IEC_15693 = 0x01, |
SandraK | 0:6bb3a59b5028 | 71 | //other not yet supported! |
SandraK | 0:6bb3a59b5028 | 72 | 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 |
SandraK | 0:6bb3a59b5028 | 73 | BM019_PROTOCOL_ISO_IEC_14443_Type_B = 0x03,// also NFC Forum Tag Type 4B |
SandraK | 0:6bb3a59b5028 | 74 | BM019_PROTOCOL_ISO_IEC_18092 = 0x04 // also NFC Forum Tag Type 3 |
SandraK | 0:6bb3a59b5028 | 75 | }; |
SandraK | 0:6bb3a59b5028 | 76 | |
SandraK | 0:6bb3a59b5028 | 77 | Serial serial(BM019_TX, BM019_RX); |
SandraK | 0:6bb3a59b5028 | 78 | |
SandraK | 0:6bb3a59b5028 | 79 | BM019_STATE stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 80 | |
SandraK | 0:6bb3a59b5028 | 81 | int write_read(uint8_t *tx_buf, int tx_len, int timeout = BM019_READY_TIMEOUT); //write, poll, read |
SandraK | 0:6bb3a59b5028 | 82 | |
SandraK | 0:6bb3a59b5028 | 83 | /*bool stateAtLeast(BM019_STATE requiredState) |
SandraK | 0:6bb3a59b5028 | 84 | { |
SandraK | 0:6bb3a59b5028 | 85 | if(stateBM019 < requiredState) |
SandraK | 0:6bb3a59b5028 | 86 | { |
SandraK | 0:6bb3a59b5028 | 87 | DEBUG("required state %d, having state %d",requiredState,stateBM019); |
SandraK | 0:6bb3a59b5028 | 88 | return false; |
SandraK | 0:6bb3a59b5028 | 89 | } |
SandraK | 0:6bb3a59b5028 | 90 | return true; |
SandraK | 0:6bb3a59b5028 | 91 | }*/ |
SandraK | 0:6bb3a59b5028 | 92 | |
SandraK | 0:6bb3a59b5028 | 93 | bool resetBM019() |
SandraK | 0:6bb3a59b5028 | 94 | { |
SandraK | 0:6bb3a59b5028 | 95 | if(stateBM019 < BM019_STATE_ANSWERING) { |
SandraK | 0:6bb3a59b5028 | 96 | DEBUG("IDN failed, bm019 not answering\n"); |
SandraK | 0:6bb3a59b5028 | 97 | return false; |
SandraK | 0:6bb3a59b5028 | 98 | } |
SandraK | 0:6bb3a59b5028 | 99 | DEBUG("BM019: reset\n"); |
SandraK | 0:6bb3a59b5028 | 100 | wait_ms(20); |
SandraK | 0:6bb3a59b5028 | 101 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 102 | return true; |
SandraK | 0:6bb3a59b5028 | 103 | } |
SandraK | 0:6bb3a59b5028 | 104 | |
SandraK | 0:6bb3a59b5028 | 105 | bool echoBM019(int timeout, bool log) |
SandraK | 0:6bb3a59b5028 | 106 | { |
SandraK | 0:6bb3a59b5028 | 107 | if(log) { |
SandraK | 0:6bb3a59b5028 | 108 | DEBUG("BM019: echo\n"); |
SandraK | 0:6bb3a59b5028 | 109 | } |
SandraK | 0:6bb3a59b5028 | 110 | int len = write_read(&BM019_CMD_ECHO[1],BM019_CMD_ECHO[0], timeout); |
SandraK | 0:6bb3a59b5028 | 111 | if(len>=1 && rxBuffer[0] == 0x55) { |
SandraK | 0:6bb3a59b5028 | 112 | stateBM019 = stateBM019 > BM019_STATE_ANSWERING ? stateBM019 : BM019_STATE_ANSWERING; |
SandraK | 0:6bb3a59b5028 | 113 | return true; |
SandraK | 0:6bb3a59b5028 | 114 | } else { |
SandraK | 0:6bb3a59b5028 | 115 | if(log) { |
SandraK | 0:6bb3a59b5028 | 116 | DEBUG("recievedlen: %d \n",len); |
SandraK | 0:6bb3a59b5028 | 117 | |
SandraK | 0:6bb3a59b5028 | 118 | for(int i = 0; i < len; i++) |
SandraK | 0:6bb3a59b5028 | 119 | DEBUG("rx[%d]: %#x\n",i,rxBuffer[i]); |
SandraK | 0:6bb3a59b5028 | 120 | } |
SandraK | 0:6bb3a59b5028 | 121 | } |
SandraK | 0:6bb3a59b5028 | 122 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 123 | return false; |
SandraK | 0:6bb3a59b5028 | 124 | } |
SandraK | 0:6bb3a59b5028 | 125 | |
SandraK | 0:6bb3a59b5028 | 126 | BM019_STATE getStateBM019() |
SandraK | 0:6bb3a59b5028 | 127 | { |
SandraK | 0:6bb3a59b5028 | 128 | return stateBM019; |
SandraK | 0:6bb3a59b5028 | 129 | } |
SandraK | 0:6bb3a59b5028 | 130 | |
SandraK | 0:6bb3a59b5028 | 131 | bool wakeBM019(int timeout) |
SandraK | 0:6bb3a59b5028 | 132 | { |
SandraK | 0:6bb3a59b5028 | 133 | DEBUG("BM019: wake\n"); |
SandraK | 0:6bb3a59b5028 | 134 | serial.send_break(); |
SandraK | 0:6bb3a59b5028 | 135 | wait_ms(timeout); |
SandraK | 0:6bb3a59b5028 | 136 | int t = 10; |
SandraK | 0:6bb3a59b5028 | 137 | |
SandraK | 0:6bb3a59b5028 | 138 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 139 | while(!echoBM019(10,false) && t > 0) { |
SandraK | 0:6bb3a59b5028 | 140 | wait_ms(10); |
SandraK | 0:6bb3a59b5028 | 141 | t--; |
SandraK | 0:6bb3a59b5028 | 142 | } |
SandraK | 0:6bb3a59b5028 | 143 | if(t<0) { |
SandraK | 0:6bb3a59b5028 | 144 | return false; |
SandraK | 0:6bb3a59b5028 | 145 | } |
SandraK | 0:6bb3a59b5028 | 146 | return true; |
SandraK | 0:6bb3a59b5028 | 147 | } |
SandraK | 0:6bb3a59b5028 | 148 | |
SandraK | 0:6bb3a59b5028 | 149 | void write(uint8_t *tx_buf, int tx_len, int timeout = BM019_READY_TIMEOUT) |
SandraK | 0:6bb3a59b5028 | 150 | { |
SandraK | 0:6bb3a59b5028 | 151 | if(timeout) { |
SandraK | 0:6bb3a59b5028 | 152 | Timer t; |
SandraK | 0:6bb3a59b5028 | 153 | t.start(); |
SandraK | 0:6bb3a59b5028 | 154 | for(int i = 0; i < tx_len; i++) { |
SandraK | 0:6bb3a59b5028 | 155 | while (!serial.writeable()) { |
SandraK | 0:6bb3a59b5028 | 156 | wait_ms(1); |
SandraK | 0:6bb3a59b5028 | 157 | if(t.read_ms()>timeout) { |
SandraK | 0:6bb3a59b5028 | 158 | return; |
SandraK | 0:6bb3a59b5028 | 159 | } |
SandraK | 0:6bb3a59b5028 | 160 | } |
SandraK | 0:6bb3a59b5028 | 161 | serial.putc(tx_buf[i]); |
SandraK | 0:6bb3a59b5028 | 162 | } |
SandraK | 0:6bb3a59b5028 | 163 | } else { |
SandraK | 0:6bb3a59b5028 | 164 | for(int i = 0; i < tx_len; i++) { |
SandraK | 0:6bb3a59b5028 | 165 | if (!serial.writeable()) { |
SandraK | 0:6bb3a59b5028 | 166 | return; |
SandraK | 0:6bb3a59b5028 | 167 | } |
SandraK | 0:6bb3a59b5028 | 168 | serial.putc(tx_buf[i]); |
SandraK | 0:6bb3a59b5028 | 169 | } |
SandraK | 0:6bb3a59b5028 | 170 | } |
SandraK | 0:6bb3a59b5028 | 171 | } |
SandraK | 0:6bb3a59b5028 | 172 | |
SandraK | 0:6bb3a59b5028 | 173 | int readBM019() |
SandraK | 0:6bb3a59b5028 | 174 | { |
SandraK | 0:6bb3a59b5028 | 175 | rxBuffer[0] = serial.getc(); |
SandraK | 0:6bb3a59b5028 | 176 | int len = 0; |
SandraK | 0:6bb3a59b5028 | 177 | if(rxBuffer[0] != 0x55) { |
SandraK | 0:6bb3a59b5028 | 178 | len = rxBuffer[1] = serial.getc(); |
SandraK | 0:6bb3a59b5028 | 179 | for(int i = 0; i < len && i < BM019_MAX_RX; i++) { |
SandraK | 0:6bb3a59b5028 | 180 | rxBuffer[i+2] = serial.getc(); |
SandraK | 0:6bb3a59b5028 | 181 | } |
SandraK | 0:6bb3a59b5028 | 182 | len += 2; |
SandraK | 0:6bb3a59b5028 | 183 | } else { |
SandraK | 0:6bb3a59b5028 | 184 | len = 1; |
SandraK | 0:6bb3a59b5028 | 185 | } |
SandraK | 0:6bb3a59b5028 | 186 | return len; |
SandraK | 0:6bb3a59b5028 | 187 | } |
SandraK | 0:6bb3a59b5028 | 188 | |
SandraK | 0:6bb3a59b5028 | 189 | int write_read(uint8_t *tx_buf, int tx_len, int timeout) |
SandraK | 0:6bb3a59b5028 | 190 | { |
SandraK | 0:6bb3a59b5028 | 191 | if(timeout) { |
SandraK | 0:6bb3a59b5028 | 192 | Timer t; |
SandraK | 0:6bb3a59b5028 | 193 | t.start(); |
SandraK | 0:6bb3a59b5028 | 194 | while (serial.readable()) { |
SandraK | 0:6bb3a59b5028 | 195 | serial.getc(); |
SandraK | 0:6bb3a59b5028 | 196 | if(t.read_ms()>timeout) { |
SandraK | 0:6bb3a59b5028 | 197 | return 0; |
SandraK | 0:6bb3a59b5028 | 198 | } |
SandraK | 0:6bb3a59b5028 | 199 | } |
SandraK | 0:6bb3a59b5028 | 200 | write(tx_buf, tx_len, timeout); |
SandraK | 0:6bb3a59b5028 | 201 | while (!serial.readable()) { |
SandraK | 0:6bb3a59b5028 | 202 | wait_ms(1); |
SandraK | 0:6bb3a59b5028 | 203 | if(t.read_ms()>timeout) { |
SandraK | 0:6bb3a59b5028 | 204 | return 0; |
SandraK | 0:6bb3a59b5028 | 205 | } |
SandraK | 0:6bb3a59b5028 | 206 | } |
SandraK | 0:6bb3a59b5028 | 207 | return readBM019(); |
SandraK | 0:6bb3a59b5028 | 208 | } else { |
SandraK | 0:6bb3a59b5028 | 209 | while (serial.readable()) { |
SandraK | 0:6bb3a59b5028 | 210 | serial.getc(); |
SandraK | 0:6bb3a59b5028 | 211 | } |
SandraK | 0:6bb3a59b5028 | 212 | write(tx_buf, tx_len, timeout); |
SandraK | 0:6bb3a59b5028 | 213 | while (!serial.readable()) { |
SandraK | 0:6bb3a59b5028 | 214 | return 0; |
SandraK | 0:6bb3a59b5028 | 215 | } |
SandraK | 0:6bb3a59b5028 | 216 | return readBM019(); |
SandraK | 0:6bb3a59b5028 | 217 | } |
SandraK | 0:6bb3a59b5028 | 218 | } |
SandraK | 0:6bb3a59b5028 | 219 | |
SandraK | 0:6bb3a59b5028 | 220 | bool setProtocolISO_EIC_15693BM019(BM019_PROTOCOL_ISO_IEC_15693_BYTE_0 configuration) |
SandraK | 0:6bb3a59b5028 | 221 | { |
SandraK | 0:6bb3a59b5028 | 222 | if(stateBM019 < BM019_STATE_ANSWERING) { |
SandraK | 0:6bb3a59b5028 | 223 | DEBUG("SETTING Protocol failed, bm019 not answering\n"); |
SandraK | 0:6bb3a59b5028 | 224 | return false; |
SandraK | 0:6bb3a59b5028 | 225 | } |
SandraK | 0:6bb3a59b5028 | 226 | DEBUG("SETTING Protocol to iso/iec 15693: %#x\n",configuration); |
SandraK | 0:6bb3a59b5028 | 227 | |
SandraK | 0:6bb3a59b5028 | 228 | int len = BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_ISO_IEC_15693[0]; |
SandraK | 0:6bb3a59b5028 | 229 | |
SandraK | 0:6bb3a59b5028 | 230 | uint8_t iso[BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_ISO_IEC_15693[0]]; |
SandraK | 0:6bb3a59b5028 | 231 | memcpy(iso,&BM019_CMD_PROTOCOL_START[1],BM019_CMD_PROTOCOL_START[0]); |
SandraK | 0:6bb3a59b5028 | 232 | memcpy(&iso[BM019_CMD_PROTOCOL_START[0]],&BM019_CMD_PROTOCOL_ISO_IEC_15693[1],BM019_CMD_PROTOCOL_ISO_IEC_15693[0]); |
SandraK | 0:6bb3a59b5028 | 233 | iso[len-1] = configuration; |
SandraK | 0:6bb3a59b5028 | 234 | |
SandraK | 0:6bb3a59b5028 | 235 | int recieved = write_read(iso,len,20); |
SandraK | 0:6bb3a59b5028 | 236 | if(recieved >= 2 && rxBuffer[0] == 0x00 && rxBuffer[1] == 0x00) { |
SandraK | 0:6bb3a59b5028 | 237 | stateBM019 = stateBM019 > BM019_STATE_PROTOCOL ? stateBM019 : BM019_STATE_PROTOCOL; |
SandraK | 0:6bb3a59b5028 | 238 | return true; |
SandraK | 0:6bb3a59b5028 | 239 | } else { |
SandraK | 0:6bb3a59b5028 | 240 | DEBUG("SETTING Protocol failed: %#x\n",rxBuffer[0]); |
SandraK | 0:6bb3a59b5028 | 241 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 242 | return false; |
SandraK | 0:6bb3a59b5028 | 243 | } |
SandraK | 0:6bb3a59b5028 | 244 | } |
SandraK | 0:6bb3a59b5028 | 245 | |
SandraK | 0:6bb3a59b5028 | 246 | bool setProtocolOFF() |
SandraK | 0:6bb3a59b5028 | 247 | { |
SandraK | 0:6bb3a59b5028 | 248 | if(stateBM019 < BM019_STATE_ANSWERING) { |
SandraK | 0:6bb3a59b5028 | 249 | DEBUG("SETTING Protocol failed, bm019 not answering\n"); |
SandraK | 0:6bb3a59b5028 | 250 | return false; |
SandraK | 0:6bb3a59b5028 | 251 | } |
SandraK | 0:6bb3a59b5028 | 252 | DEBUG("SETTING Protocol to OFF\n"); |
SandraK | 0:6bb3a59b5028 | 253 | |
SandraK | 0:6bb3a59b5028 | 254 | int len = BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_OFF[0]; |
SandraK | 0:6bb3a59b5028 | 255 | uint8_t off[BM019_CMD_PROTOCOL_START[0]+BM019_CMD_PROTOCOL_OFF[0]]; |
SandraK | 0:6bb3a59b5028 | 256 | memcpy(off,&BM019_CMD_PROTOCOL_START[1],BM019_CMD_PROTOCOL_START[0]); |
SandraK | 0:6bb3a59b5028 | 257 | memcpy(&off[BM019_CMD_PROTOCOL_START[0]],&BM019_CMD_PROTOCOL_OFF[1],BM019_CMD_PROTOCOL_OFF[0]); |
SandraK | 0:6bb3a59b5028 | 258 | |
SandraK | 0:6bb3a59b5028 | 259 | int recieved = write_read(off,len,20); |
SandraK | 0:6bb3a59b5028 | 260 | if(recieved >= 2 && rxBuffer[0] == 0x00 && rxBuffer[1] == 0x00) { |
SandraK | 0:6bb3a59b5028 | 261 | stateBM019 = BM019_STATE_ANSWERING; |
SandraK | 0:6bb3a59b5028 | 262 | return true; |
SandraK | 0:6bb3a59b5028 | 263 | } else { |
SandraK | 0:6bb3a59b5028 | 264 | DEBUG("SETTING Protocol failed: %#x\n",rxBuffer[0]); |
SandraK | 0:6bb3a59b5028 | 265 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 266 | return false; |
SandraK | 0:6bb3a59b5028 | 267 | } |
SandraK | 0:6bb3a59b5028 | 268 | } |
SandraK | 0:6bb3a59b5028 | 269 | |
SandraK | 0:6bb3a59b5028 | 270 | bool idnBM019(BM019_IDN *idn) |
SandraK | 0:6bb3a59b5028 | 271 | { |
SandraK | 0:6bb3a59b5028 | 272 | if(stateBM019 < BM019_STATE_ANSWERING) { |
SandraK | 0:6bb3a59b5028 | 273 | DEBUG("IDN failed, bm019 not answering\n"); |
SandraK | 0:6bb3a59b5028 | 274 | return false; |
SandraK | 0:6bb3a59b5028 | 275 | } |
SandraK | 0:6bb3a59b5028 | 276 | int len = write_read(&BM019_CMD_IDN[1],BM019_CMD_IDN[0]); |
SandraK | 0:6bb3a59b5028 | 277 | if(len == 17) { |
SandraK | 0:6bb3a59b5028 | 278 | memcpy(idn->deviceID,(const void *)&rxBuffer[2],13); |
SandraK | 0:6bb3a59b5028 | 279 | memcpy(idn->romCRC,(const void *)&rxBuffer[15],2); |
SandraK | 0:6bb3a59b5028 | 280 | return true; |
SandraK | 0:6bb3a59b5028 | 281 | } |
SandraK | 0:6bb3a59b5028 | 282 | return false; |
SandraK | 0:6bb3a59b5028 | 283 | |
SandraK | 0:6bb3a59b5028 | 284 | } |
SandraK | 0:6bb3a59b5028 | 285 | |
SandraK | 0:6bb3a59b5028 | 286 | bool hybernateBM019() |
SandraK | 0:6bb3a59b5028 | 287 | { |
SandraK | 0:6bb3a59b5028 | 288 | if(stateBM019 < BM019_STATE_ANSWERING) { |
SandraK | 0:6bb3a59b5028 | 289 | DEBUG("SETTING HYBERNATE failed, bm019 not answering\n"); |
SandraK | 0:6bb3a59b5028 | 290 | return false; |
SandraK | 0:6bb3a59b5028 | 291 | } |
SandraK | 0:6bb3a59b5028 | 292 | |
SandraK | 0:6bb3a59b5028 | 293 | DEBUG("HYBERNATE bm019 (FIELD_OFF and POWER_DOWN)\n"); |
SandraK | 0:6bb3a59b5028 | 294 | if(setProtocolOFF()) { |
SandraK | 0:6bb3a59b5028 | 295 | write(&BM019_CMD_HYBERNATE[1],BM019_CMD_HYBERNATE[0]); |
SandraK | 0:6bb3a59b5028 | 296 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 297 | return true; |
SandraK | 0:6bb3a59b5028 | 298 | } |
SandraK | 0:6bb3a59b5028 | 299 | return false; |
SandraK | 0:6bb3a59b5028 | 300 | } |
SandraK | 0:6bb3a59b5028 | 301 | |
SandraK | 0:6bb3a59b5028 | 302 | |
SandraK | 0:6bb3a59b5028 | 303 | bool inventoryISO_IES_15693BM019(BM019_TAG *tag, int timeout) |
SandraK | 0:6bb3a59b5028 | 304 | { |
SandraK | 0:6bb3a59b5028 | 305 | if(stateBM019 < BM019_STATE_PROTOCOL) { |
SandraK | 0:6bb3a59b5028 | 306 | DEBUG("inventory failed, bm019 not in protocol\n"); |
SandraK | 0:6bb3a59b5028 | 307 | return false; |
SandraK | 0:6bb3a59b5028 | 308 | } |
SandraK | 0:6bb3a59b5028 | 309 | |
SandraK | 0:6bb3a59b5028 | 310 | DEBUG("inventory.."); |
SandraK | 0:6bb3a59b5028 | 311 | |
SandraK | 0:6bb3a59b5028 | 312 | int len = write_read(&BM019_CMD_ISO_IEC_15693_INVENTORY[1],BM019_CMD_ISO_IEC_15693_INVENTORY[0]); |
SandraK | 0:6bb3a59b5028 | 313 | |
SandraK | 0:6bb3a59b5028 | 314 | DEBUG("got answer len()=%d\n",len); |
SandraK | 0:6bb3a59b5028 | 315 | for(int i = 0; i < len; i++) { |
SandraK | 0:6bb3a59b5028 | 316 | DEBUG("%#04x ",rxBuffer[i]); |
SandraK | 0:6bb3a59b5028 | 317 | } |
SandraK | 0:6bb3a59b5028 | 318 | DEBUG("\n"); |
SandraK | 0:6bb3a59b5028 | 319 | |
SandraK | 0:6bb3a59b5028 | 320 | if(rxBuffer[0] != EFrameRecvOK) { |
SandraK | 0:6bb3a59b5028 | 321 | DEBUG("got error %#04x\n",rxBuffer[0]); |
SandraK | 0:6bb3a59b5028 | 322 | return false; |
SandraK | 0:6bb3a59b5028 | 323 | } |
SandraK | 0:6bb3a59b5028 | 324 | |
SandraK | 0:6bb3a59b5028 | 325 | int tlen = rxBuffer[1]; |
SandraK | 0:6bb3a59b5028 | 326 | if(tlen < 11) { |
SandraK | 0:6bb3a59b5028 | 327 | DEBUG("to few bytes recieved \n"); |
SandraK | 0:6bb3a59b5028 | 328 | return false; |
SandraK | 0:6bb3a59b5028 | 329 | } |
SandraK | 0:6bb3a59b5028 | 330 | /* this does not work very good, maybe something misinterpreted from docs |
SandraK | 0:6bb3a59b5028 | 331 | if(rxBuffer[tlen-1] & 0x01) { |
SandraK | 0:6bb3a59b5028 | 332 | DEBUG("got collision \n"); |
SandraK | 0:6bb3a59b5028 | 333 | return false; |
SandraK | 0:6bb3a59b5028 | 334 | } |
SandraK | 0:6bb3a59b5028 | 335 | if(rxBuffer[tlen-1] & 0x02) { |
SandraK | 0:6bb3a59b5028 | 336 | DEBUG("got bad crc \n"); |
SandraK | 0:6bb3a59b5028 | 337 | return false; |
SandraK | 0:6bb3a59b5028 | 338 | }*/ |
SandraK | 0:6bb3a59b5028 | 339 | tag->crc[0] = rxBuffer[tlen-2]; |
SandraK | 0:6bb3a59b5028 | 340 | tag->crc[1] = rxBuffer[tlen-3]; |
SandraK | 0:6bb3a59b5028 | 341 | |
SandraK | 0:6bb3a59b5028 | 342 | for(int i = 0; i < 9; i++) { |
SandraK | 0:6bb3a59b5028 | 343 | tag->uid[i] = rxBuffer[11-i]; |
SandraK | 0:6bb3a59b5028 | 344 | } |
SandraK | 0:6bb3a59b5028 | 345 | return true; |
SandraK | 0:6bb3a59b5028 | 346 | |
SandraK | 0:6bb3a59b5028 | 347 | } |
SandraK | 0:6bb3a59b5028 | 348 | |
SandraK | 0:6bb3a59b5028 | 349 | int readBM019(uint8_t adr, uint8_t *buf, int len, int timeout) |
SandraK | 0:6bb3a59b5028 | 350 | { |
SandraK | 0:6bb3a59b5028 | 351 | if(stateBM019 < BM019_STATE_PROTOCOL) { |
SandraK | 0:6bb3a59b5028 | 352 | DEBUG("read failed, bm019 not in protocol\n"); |
SandraK | 0:6bb3a59b5028 | 353 | return -1; |
SandraK | 0:6bb3a59b5028 | 354 | } |
SandraK | 0:6bb3a59b5028 | 355 | uint8_t cmd[BM019_CMD_READ[0]]; |
SandraK | 0:6bb3a59b5028 | 356 | memcpy(cmd,&BM019_CMD_READ[1],BM019_CMD_READ[0]); |
SandraK | 0:6bb3a59b5028 | 357 | cmd[BM019_CMD_READ[0]-1] = adr & 0xFF; |
SandraK | 0:6bb3a59b5028 | 358 | |
SandraK | 0:6bb3a59b5028 | 359 | DEBUG("read at %#4X..\n",adr); |
SandraK | 0:6bb3a59b5028 | 360 | for(int i = 0; i < BM019_CMD_READ[0]; i++) { |
SandraK | 0:6bb3a59b5028 | 361 | DEBUG("%#04x ",cmd[i]); |
SandraK | 0:6bb3a59b5028 | 362 | } |
SandraK | 0:6bb3a59b5028 | 363 | int tx = write_read(cmd,BM019_CMD_READ[0]); |
SandraK | 0:6bb3a59b5028 | 364 | |
SandraK | 0:6bb3a59b5028 | 365 | DEBUG("got answer len()=%d\n",tx); |
SandraK | 0:6bb3a59b5028 | 366 | for(int i = 0; i < tx; i++) { |
SandraK | 0:6bb3a59b5028 | 367 | DEBUG("%#04x ",rxBuffer[i]); |
SandraK | 0:6bb3a59b5028 | 368 | } |
SandraK | 0:6bb3a59b5028 | 369 | DEBUG("\n"); |
SandraK | 0:6bb3a59b5028 | 370 | if(rxBuffer[0] != EFrameRecvOK) { |
SandraK | 0:6bb3a59b5028 | 371 | DEBUG("got error %#04x\n",rxBuffer[0]); |
SandraK | 0:6bb3a59b5028 | 372 | return -1; |
SandraK | 0:6bb3a59b5028 | 373 | } |
SandraK | 0:6bb3a59b5028 | 374 | |
SandraK | 0:6bb3a59b5028 | 375 | DEBUG("flags: %#04x\n",rxBuffer[2]); |
SandraK | 0:6bb3a59b5028 | 376 | int tlen = rxBuffer[1]-4; |
SandraK | 0:6bb3a59b5028 | 377 | if(tlen <=0) |
SandraK | 0:6bb3a59b5028 | 378 | return -1; |
SandraK | 0:6bb3a59b5028 | 379 | DEBUG("read resultet in %d bytes, copying %d bytes\n",rxBuffer[1],(tlen < len ? tlen : len)); |
SandraK | 0:6bb3a59b5028 | 380 | tlen = (tlen < len ? tlen : len); |
SandraK | 0:6bb3a59b5028 | 381 | memcpy(buf,(const void *)&rxBuffer[3],tlen); |
SandraK | 0:6bb3a59b5028 | 382 | |
SandraK | 0:6bb3a59b5028 | 383 | return tlen; |
SandraK | 0:6bb3a59b5028 | 384 | } |
SandraK | 0:6bb3a59b5028 | 385 | |
SandraK | 0:6bb3a59b5028 | 386 | int readMultiBM019(uint8_t adr, int count, uint8_t *buf, int len, int timeout) |
SandraK | 0:6bb3a59b5028 | 387 | { |
SandraK | 0:6bb3a59b5028 | 388 | if(stateBM019 < BM019_STATE_PROTOCOL) { |
SandraK | 0:6bb3a59b5028 | 389 | DEBUG("multi read failed, bm019 not in protocol\n"); |
SandraK | 0:6bb3a59b5028 | 390 | return -1; |
SandraK | 0:6bb3a59b5028 | 391 | } |
SandraK | 0:6bb3a59b5028 | 392 | uint8_t cmd[BM019_CMD_READ_MULTI[0]]; |
SandraK | 0:6bb3a59b5028 | 393 | memcpy(cmd,&BM019_CMD_READ_MULTI[1],BM019_CMD_READ_MULTI[0]); |
SandraK | 0:6bb3a59b5028 | 394 | cmd[BM019_CMD_READ_MULTI[0]-2] = adr & 0xFF; |
SandraK | 0:6bb3a59b5028 | 395 | cmd[BM019_CMD_READ_MULTI[0]-1] = (count-1) & 0xFF; |
SandraK | 0:6bb3a59b5028 | 396 | |
SandraK | 0:6bb3a59b5028 | 397 | DEBUG("multi read at %#4X for %d..\n",adr, count & 0xFF); |
SandraK | 0:6bb3a59b5028 | 398 | for(int i = 0; i < BM019_CMD_READ_MULTI[0]; i++) { |
SandraK | 0:6bb3a59b5028 | 399 | DEBUG("%#04x ",cmd[i]); |
SandraK | 0:6bb3a59b5028 | 400 | } |
SandraK | 0:6bb3a59b5028 | 401 | int tx = write_read(cmd,BM019_CMD_READ_MULTI[0]); |
SandraK | 0:6bb3a59b5028 | 402 | |
SandraK | 0:6bb3a59b5028 | 403 | DEBUG("got answer len()=%d\n",tx); |
SandraK | 0:6bb3a59b5028 | 404 | for(int i = 0; i < tx; i++) { |
SandraK | 0:6bb3a59b5028 | 405 | DEBUG("%02x ",rxBuffer[i]); |
SandraK | 0:6bb3a59b5028 | 406 | } |
SandraK | 0:6bb3a59b5028 | 407 | DEBUG("\n"); |
SandraK | 0:6bb3a59b5028 | 408 | if(rxBuffer[0] != EFrameRecvOK) { |
SandraK | 0:6bb3a59b5028 | 409 | DEBUG("got error %#04x\n",rxBuffer[0]); |
SandraK | 0:6bb3a59b5028 | 410 | return -1; |
SandraK | 0:6bb3a59b5028 | 411 | } |
SandraK | 0:6bb3a59b5028 | 412 | |
SandraK | 0:6bb3a59b5028 | 413 | DEBUG("flags: %#04x\n",rxBuffer[2]); |
SandraK | 0:6bb3a59b5028 | 414 | int tlen = rxBuffer[1]-4; |
SandraK | 0:6bb3a59b5028 | 415 | if(tlen <=0) |
SandraK | 0:6bb3a59b5028 | 416 | return -1; |
SandraK | 0:6bb3a59b5028 | 417 | DEBUG("read resultet in %d bytes, copying %d bytes\n",rxBuffer[1],(tlen < len ? tlen : len)); |
SandraK | 0:6bb3a59b5028 | 418 | tlen = (tlen < len ? tlen : len); |
SandraK | 0:6bb3a59b5028 | 419 | memcpy(buf,(const void *)&rxBuffer[3],tlen); |
SandraK | 0:6bb3a59b5028 | 420 | |
SandraK | 0:6bb3a59b5028 | 421 | return tlen; |
SandraK | 0:6bb3a59b5028 | 422 | } |
SandraK | 0:6bb3a59b5028 | 423 | bool initBM019() |
SandraK | 0:6bb3a59b5028 | 424 | { |
SandraK | 0:6bb3a59b5028 | 425 | DEBUG("BM019: init\n"); |
SandraK | 0:6bb3a59b5028 | 426 | serial.format(8,SerialBase::None,2); |
SandraK | 0:6bb3a59b5028 | 427 | serial.baud(57600); |
SandraK | 0:6bb3a59b5028 | 428 | serial.send_break(); |
SandraK | 0:6bb3a59b5028 | 429 | stateBM019 = BM019_STATE_UNKNOWN; |
SandraK | 0:6bb3a59b5028 | 430 | return true; |
SandraK | 0:6bb3a59b5028 | 431 | } |