【问题标题】:Transceive Failed on ISO15693 / Tag-it HF-IISO15693 / Tag-it HF-I 上的收发失败
【发布时间】:2013-08-13 14:15:08
【问题描述】:

我有一些 ISO15693 / Tag-it HF-I Plus 芯片,需要在上面写一些东西。这些芯片完全新鲜,我现在阅读了大量的 pdf 文件告诉我都是一样的。但是没有任何效果,而且我总是收到 Transceive Failed 错误。

我在收发命令中发送这些数据:

Byte:  <data>
0:     0x00 // pdf says the tag understands only flag = 0x00
1:     0x21 // write single block
2-10:  ID // needs to be send for this tag, only supports addressed mode
11:    0x00 // Block ID, try to write to block 0
12-16: DATA // LSB First
17-18: CRC16 // do i need to send this? and if yes, LSB first?

我尝试了非常不同的标志和写入模式,但它们都不起作用:

Flags: 0x01, 0x02, 0x20,0x22,0x42,0x40,0x80,0x82
Modes: 0x21,0xA2 (+ Vendor Mode 0x07)

这是我的写函数:

private void write(Tag tag) throws IOException, FormatException {
if (tag == null) {
    return;
}
NfcV nfc = NfcV.get(tag);
byte[] ID = tag.getId();

nfc.connect();

Log.d(TAG, "Data: " + new String(((EmergencyApplication) getApplication()).getData()));

byte[] data = ((EmergencyApplication) getApplication()).getData();
// NfcV Tag has 64 Blocks with 4 Byte
if ((data.length / 4) > 64) {
    // ERROR HERE!
    Log.d(TAG, "too much data...");
}

for (int i = 0; i < data.length; i++) {
    byte[] arrByte = new byte[17];

    // Flags
    arrByte[0] = 0x00; // Tag only supports flags = 0
    // Command
    arrByte[1] = 0x21;
    // ID
    Log.d(TAG, "Found ID length: " + ID.length + "... ID: " + Arrays.toString(ID));
    System.arraycopy(ID, 0, arrByte, 2, 8);
    // block number
    arrByte[10] = (byte) (i);

    // data
    // TODO send LSB first...
    System.arraycopy(data, i * 4, arrByte, 11, 4);

    // CRC 16 of all command
    byte[] check = new byte[15];
    System.arraycopy(arrByte, 0, check, 0, 15);
    int crc = CRC.crc16(check);
    arrByte[15] = (byte) (crc >> 8);
    arrByte[16] = (byte) (crc & 0xFF);

    Log.d(TAG, "Writing Data: " + Arrays.toString(arrByte));

    byte[] result = nfc.transceive(arrByte);
    Log.d(TAG, "got result: " + Arrays.toString(result));
}

nfc.close();
Toast.makeText(this, "wrote to tag", Toast.LENGTH_LONG).show();

}

这是 Nexus S 的另一个错误吗?我使用 Cyanogenmod 10.1.2,所以我认为 Tag Lost Bug 已修复...我显然可以读取标签,如果我使用 NFC Tag Info App,它会显示所有块清晰且可写。 我已经阅读了这些 PDF:

http://rfidshop.com.hk/datasheet%20tag/philip%20icode%20SLI.pdf - 我的标签数据表 http://www.waazaa.org/download/fcd-15693-3.pdf - ISO15693-3 数据表 http://www.ti.com/lit/ug/scbu003a/scbu003a.pdf - Tag-it HF-I Plus 数据表

我用这里的代码测试了阅读:Reading a NXP ICODE SLI-L tag with Android - 它适用于所有 64 个块,但写入仍然不起作用......即使标志 = 0x20......

编辑:我现在看到卡上的 DSFID 是 0x00,这意味着对于 ISO15693-3,卡根本不可写:

如果 VICC 不支持其编程,则 VICC 应 以零值 ('00') 响应

这是发送0x2B时的字节[]:

                                                     DSFID \  / AFI
                                                           |  |
                                                           v  v
infoRmation: [0, 15, 120, 40, -51, -51, 119, -128, 7, -32, 0, 0, 63, 3, -117]

【问题讨论】:

    标签: android nfc rfid iso-15693


    【解决方案1】:

    发现了一些东西,我想分享:

    • 不要先发送带 LSB 的数据,似乎收发命令在发送时会自动执行此操作
    • 不要使用寻址模式,android实现似乎有一些问题
    • 在标志中设置选项位 (0x40)。
    • 我的标签似乎支持快速模式(0x02),所以你可以设置或不设置
    • 不要设置CRC16,因为它是android添加的

    但最糟糕的是,标签在编译到标签编写器的时间内没有响应。您将收到Tag is lost. 异常,但数据将写入标签!所以解决的办法就是直接忽略这个异常,可能在写入后验证数据,如果不行再试。

    我目前写的代码是这样的:

    public static void write(Tag tag, byte[] data) throws IOException, FormatException,
    InterruptedException {
    if (tag == null) {
        return;
    }
    NfcV nfc = NfcV.get(tag);
    
    nfc.connect();
    
    Log.d(TAG, "Max Transceive Bytes: " + nfc.getMaxTransceiveLength());
    
    // NfcV Tag has 64 Blocks with 4 Byte
    if ((data.length / 4) > 64) {
        // ERROR HERE!
        Log.d(TAG, "too much data...");
    }
    
    if ((data.length % 4) != 0) {
        byte[] ndata = new byte[(data.length) + (4 - (data.length % 4))];
        Arrays.fill(ndata, (byte) 0x00);
        System.arraycopy(data, 0, ndata, 0, data.length);
        data = ndata;
    }
    
    byte[] arrByte = new byte[7];
    // Flags
    arrByte[0] = 0x42;
    // Command
    arrByte[1] = 0x21;
    
    for (int i = 0; i < (data.length / 4); i++) {
    
        // block number
        arrByte[2] = (byte) (i);
    
        // data, DONT SEND LSB FIRST!
        arrByte[3] = data[(i * 4)];
        arrByte[4] = data[(i * 4) + 1];
        arrByte[5] = data[(i * 4) + 2];
        arrByte[6] = data[(i * 4) + 3];
    
        Log.d(TAG, "Writing Data to block " + i + " [" + printHexString(arrByte) + "]");
        try {
        nfc.transceive(arrByte);
        } catch (IOException e) {
        if (e.getMessage().equals("Tag was lost.")) {
            // continue, because of Tag bug
        } else {
            throw e;
        }
        }
    }
    
    nfc.close();
    }
    

    而且效果很好。 如果有真正的错误,比如消息不明白,你会得到Transceive Failed消息。

    【讨论】:

    • 我还偶然发现了在向 ISO15693 芯片发送 transceive() 命令时超时太短。出于这个原因,我要求 Android 团队添加一个 settimeout() 方法。见linlk。让我们希望这将很快添加。
    • 为什么在“arrByte[0] = 0x42;”中发送标志 0x42?要写入 int NFC 标签,我使用方法 nfcv.transceive(new byte[] {0x42, 0x21, (byte) 00, 0x00,0x00, 0x72, 0x75});如果在标志中我发送 0 不要写你知道为什么 0x42 工作吗?谢谢
    • @RicardoPessoa 0x40 是选项位,必须为写入操作设置(根据 ISO 15693),0x02 是高速位,并非对每个芯片都有效。另请参阅ti.com/lit/an/sloa141/sloa141.pdf 第 20 页。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    相关资源
    最近更新 更多