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