cancel
Showing results for 
Search instead for 
Did you mean: 

iso15693WriteBlock appears to set the first byte to zero

TimLong
Associate III

I'm attempting to use iso15693WriteBlock to write blocks of 4 bytes to a ST25DV04K tag. Everything appears to work and I don't get an error. However, when I read back the memory, the first byte of each block has been set to zero, and bytes 1 through 3 contain bytes 0 through 2 of my data. It's like there's an off-by-one error, but without any documentation or source code for the library I have zero chance of working out where. Any ideas appreciated. For completeness, here is the code I'm using to write the block:

    /// <summary>
    ///     Writes a single block of data to the specified NFC tag using passive communication. The block size is determined by
    ///     the tag's native block size.
    /// </summary>
    /// <param name="tag">The NFC tag to which the data will be written. Must be obtained from <see cref="InventoryRequest" />.</param>
    /// <param name="blockNumber">The block number on the tag where the data will be written.</param>
    /// <param name="bytes">The data to write, represented as a read-only span of bytes.</param>
    /// <exception cref="NfcException">Thrown if the radio access layer reports an error during the operation.</exception>
    public void PassiveWriteBlock(INfcTagType5 tag, int blockNumber, ReadOnlyMemory<byte> bytes)
    {
        var  txLength = (uint)bytes.Length;
        uint rxLength = 32;                  // unused but required by the API, leave plenty of overhead for things like CRCs.
        var  rxBuff   = new sbyte[rxLength]; // unused but required by the API
        SelectTag(tag);
        try
        {
            var blockBuffer = bytes.ToArray(); // creates a new byte array and copies the bytes into it.
            var error = ST25R391xNativeMethods
                .iso15693WriteBlock(Handle, tag.Uid, (byte)blockNumber, blockBuffer, txLength, rxBuff, ref rxLength, false);
            error.ThrowOnError();
        }
        finally
        {
            DeselectTag(tag);
        }
    }

I'm attempting to write the ASCII equivalent to "1234" into block 40, so I'm sending in a byte array 0x31,0x32,0x33,0x34 and I have verified in the debugger that this is exactly what is getting passed into iso15693WriteBlock in the byte[] data parameter and that the data_size parameter is 4. So where's my first byte going?

This discussion is locked. Please start a new topic to ask your question.
1 ACCEPTED SOLUTION

Accepted Solutions
Brian TIDAL
ST Employee

Hi,

The first byte of the Read Single Block command is the response flag followed by the 4-byte data. See ST25DV02K datasheet section 7.6.6 Read Single Block.

I would suggest to read the content of the memory through an NFC enabled phone using the ST25 NFC Tap app and to check the content.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

4 REPLIES 4
Brian TIDAL
ST Employee

Hi,

The first byte of the Read Single Block command is the response flag followed by the 4-byte data. See ST25DV02K datasheet section 7.6.6 Read Single Block.

I would suggest to read the content of the memory through an NFC enabled phone using the ST25 NFC Tap app and to check the content.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Ulysses HERNIOSUS
ST Employee

Hi,

the firmware for STM32L476 is available in source, you could instrument there to see what you are receiving.

Are you sure the issue happens on writing and not on reading? How do you verify the content? Same method through the DLL or also using a mobile (app)?

This .ToArray() really generates a plain C buffer? Which language is this?

BR, Ulysses

I believe you are correct - when verified with the ST app it seems that the write is actually working and it's the read that is problematic.I would not have guessed that the first byte of the returned buffer is anything other than the block data.

This kind of problem would certainly be a lot easier to track down if the library source were available. It seems an odd omission given that all the source for the firmware of the eval board is available for download. I believe it is authored in Qt based on the dependency on QtCore.dll. Is there any possibility of getting the Qt source for the library? That would also potentially allow me to make a 64-bit version, the lack of which is a very severe limitation. Is there any chance at all of getting the source code?

Your colleague Brian TIDAL has the solution - the write is actually working but I hadn't realized there is a header byte in the data returned by read. That's my off-by-one error.

FYI, the code I posted is C#. Yes. .ToArray() in this case is guaranteed to produce a buffer of contiguous memory of 4 bytes. The ReadOnlyMemory<bytes> parameter is where this guarantee comes from, it is actually a 1-block view into a much larger buffer that maps to the entire tag memory, 512 bytes in this case. ReadOnlyMemory<T> and ReadOnlySpan<T> are relatively new C# features that are designed exactly for passing around sub-slices of contiguous memory areas.